source: dev/trunk/abdev/BasicCompiler64/Compile_Var.cpp@ 168

Last change on this file since 168 was 159, checked in by dai_9181, 17 years ago

プロジェクト内を整理。jengaライブラリのベースを作成。

File size: 31.9 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4//変数
5Variables globalVars;
6int AllGlobalVarSize;
7int AllInitGlobalVarSize;
8
9int AllLocalVarSize;
10
11
12void SetRelativeOffset( Type &resultType, RELATIVE_VAR *pRelativeVar,const char *lpPtrOffset){
13 /////////////////////////////////////////////
14 // 先頭ポインタをr12に取得してメモリへ退避
15 /////////////////////////////////////////////
16
17 SetReg_WholeVariable(DEF_INT64,pRelativeVar,REG_R11);
18
19 //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用
20 pobj_sf->push(REG_R11);
21
22
23 ////////////////////////////////
24 // 添え字を計算する
25 ////////////////////////////////
26
27 int reg=REG_NON;
28 Type type;
29 NumOpe( &reg, lpPtrOffset, Type(), type );
30 if( !type.IsWhole() ){
31 SetError(46,NULL,cp);
32 }
33 ExtendTypeTo64(type.GetBasicType(),reg);
34
35 if(reg==REG_R14){
36 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
37 pobj_sf->pop(REG_R14);
38 }
39
40 if( resultType.PtrLevel() ){
41 resultType.PtrLevelDown();
42
43 int typeSize = resultType.GetSize();
44 if(typeSize>=2){
45 //imul reg,i2
46 op_imul_RV(sizeof(_int64),reg,typeSize);
47 }
48 }
49 else{
50 //エラー
51 SetError(1,NULL,cp);
52 return;
53 }
54
55
56 //////////////////////////////
57 // 先頭ポインタに添え字を加算
58 //////////////////////////////
59
60 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
61 pobj_sf->pop(REG_R11);
62
63 //add r11,reg
64 op_add64_reg(REG_R11,reg);
65}
66void SetRelativeOffset( RELATIVE_VAR &relativeVar ){
67 if(relativeVar.dwKind==VAR_DIRECTMEM){
68 //mov r11,qword ptr[r11]
69 op_mov_RM(sizeof(_int64),REG_R11,REG_R11,0,MOD_BASE);
70 }
71 else{
72 //直接参照に切り替え
73 SetVarPtrToReg(REG_R12,&relativeVar);
74 relativeVar.dwKind=VAR_DIRECTMEM;
75
76 //mov r11,qword ptr[r12]
77 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
78 }
79}
80bool GetArrayOffset(const int *SubScripts,char *array, const Type &type){
81 extern HANDLE hHeap;
82 int i,i2,i3,i4;
83 char temporary[VN_SIZE],*pParm[MAX_PARMS];
84
85 for(i=0,i2=0,i3=0;;i++,i2++){
86 if(array[i]=='('){
87 i4=GetStringInPare(temporary+i2,array+i);
88 i+=i4-1;
89 i2+=i4-1;
90 continue;
91 }
92 if(array[i]=='['){
93 i4=GetStringInBracket(temporary+i2,array+i);
94 i+=i4-1;
95 i2+=i4-1;
96 continue;
97 }
98 if(array[i]==','||array[i]=='\0'){
99 if(SubScripts[i3]==-1){
100 for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
101 return false;
102 }
103
104 temporary[i2]=0;
105
106 pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
107 lstrcpy(pParm[i3],temporary);
108
109 i3++;
110
111 if(array[i]=='\0'){
112 if(SubScripts[i3]!=-1){
113 for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
114 return false;
115 }
116 break;
117 }
118
119 i2=-1;
120 continue;
121 }
122 temporary[i2]=array[i];
123 }
124
125 //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用
126 pobj_sf->push(REG_R11);
127
128 //xor r12,r12
129 op_zero_reg(REG_R12);
130
131 for(i=i3-1;i>=0;i--){
132 //mov qword ptr[rsp+offset],r12 ※スタックフレームを利用
133 pobj_sf->push(REG_R12);
134
135 int reg=REG_NON;
136 Type type;
137 BOOL bUseHeap;
138 NumOpe( &reg, pParm[i], Type( DEF_LONG ), type, &bUseHeap );
139 if( type.IsObject() ){
140 //キャスト演算子のオーバーロードに対応する
141 CallCastOperatorProc(reg,
142 type,
143 bUseHeap, Type(DEF_LONG) );
144 type.SetBasicType( DEF_LONG );
145 }
146
147 if( !type.IsWhole() ){
148 SetError(46,NULL,cp);
149 }
150 ExtendTypeTo64( type.GetBasicType(), reg );
151
152 if(reg==REG_R14){
153 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
154 pobj_sf->pop(REG_R14);
155 }
156
157 //mov r12,qword ptr[rsp+offset] ※スタックフレームを利用
158 pobj_sf->pop(REG_R12);
159
160 for(i2=i+1,i4=1;i2<i3;i2++) i4*=SubScripts[i2]+1;
161
162 //imul reg,i4
163 op_imul_RV(sizeof(_int64),reg,i4);
164
165 //add r12,reg
166 op_add64_reg(REG_R12,reg);
167
168 HeapDefaultFree(pParm[i]);
169 }
170
171 //imul r12,TypeSize
172 OpBuffer[obp++]=(char)0x4D;
173 OpBuffer[obp++]=(char)0x69;
174 OpBuffer[obp++]=(char)0xE4;
175 *((long *)(OpBuffer+obp))=type.GetSize();
176 obp+=sizeof(long);
177
178 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
179 pobj_sf->pop(REG_R11);
180
181 //add r11,r12
182 OpBuffer[obp++]=(char)0x4D;
183 OpBuffer[obp++]=(char)0x03;
184 OpBuffer[obp++]=(char)0xDC;
185
186 return true;
187}
188bool _member_offset(bool isErrorEnabled, bool isWriteAccess, const CClass &objClass, const char *member, RELATIVE_VAR *pRelativeVar, Type &resultType, BOOL bPrivateAccess){
189
190 //////////////////////////////////////
191 // クラス、配列の構成要素を解析する
192 //////////////////////////////////////
193
194 char VarName[VN_SIZE]; //変数名
195 char array[VN_SIZE]; //第1次配列
196 char lpPtrOffset[VN_SIZE]; //第2次配列
197 char NestMember[VN_SIZE]; //入れ子メンバ
198 CClass::RefType refType;
199 lstrcpy(VarName,member);
200 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false;
201
202
203 ////////////////////////////
204 // メンバオフセットを取得
205 ////////////////////////////
206
207 int memberIndex;
208 int offset = objClass.GetMemberOffset( VarName, &memberIndex );
209 if( memberIndex == objClass.GetDynamicMembers().size() ){
210 if(isErrorEnabled) SetError(103,VarName,cp);
211 return false;
212 }
213
214 CMember *pMember = objClass.GetDynamicMembers()[memberIndex];
215
216
217 //アクセシビリティをチェック
218 if(&objClass==pobj_CompilingClass){
219 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
220 if(pMember->IsNoneAccess()){
221 if(isErrorEnabled) SetError(107,VarName,cp);
222 return false;
223 }
224 }
225 else{
226 if((bPrivateAccess==0&&pMember->IsPrivate())||
227 pMember->IsNoneAccess()){
228 if(isErrorEnabled) SetError(107,VarName,cp);
229 return false;
230 }
231 else if(bPrivateAccess==0&&pMember->IsProtected()){
232 if(isErrorEnabled) SetError(108,VarName,cp);
233 return false;
234 }
235 }
236
237 //Const定義の場合は書き込みアクセスを制限する
238 //※コンストラクタをコンパイル中の場合は例外的に許可する
239 if( pMember->IsConst() && //定数メンバである
240 isWriteAccess && //書き込みアクセスを要求されている
241 objClass.IsCompilingConstructor() == false //コンストラクタ コンパイル中を除く
242 ){
243 //Const定義の変数に書き込みアクセスをしようとした場合
244 SetError(61,VarName,cp);
245 }
246
247 resultType = pMember->GetType();
248
249 //ポインタ変数の場合
250 if( resultType.IsPointer() ){
251 if(pMember->SubScripts[0]==-1){
252 lstrcpy(lpPtrOffset,array);
253 array[0]=0;
254 }
255 }
256 else{
257 if(lpPtrOffset[0]){
258 if(isErrorEnabled) SetError(16,member,cp);
259 return false;
260 }
261 }
262
263 if(offset){
264 //add r11,offset
265 OpBuffer[obp++]=(char)0x49;
266 OpBuffer[obp++]=(char)0x81;
267 OpBuffer[obp++]=(char)0xC3;
268 *((long *)(OpBuffer+obp))=offset;
269 obp+=sizeof(long);
270 }
271
272 if(array[0]){
273 //配列オフセット
274 if(!GetArrayOffset(pMember->SubScripts,array,pMember->GetType())){
275 if(isErrorEnabled) SetError(14,member,cp);
276 }
277 }
278 else if(pMember->SubScripts[0]!=-1){
279 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
280 }
281
282 if(NestMember[0]){
283 //入れ子構造の場合
284
285 if( resultType.IsObject() || resultType.IsStruct() ){
286 if( refType != CClass::Dot ){
287 if(isErrorEnabled) SetError(104,member,cp);
288 return false;
289 }
290
291 if( resultType.IsObject() ){
292 // 参照内容へのポインタを抽出
293 SetRelativeOffset( *pRelativeVar );
294 }
295 }
296 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
297 //構造体ポインタ型メンバ変数
298
299 if(lpPtrOffset[0]){
300 //pObj[n].member
301 if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() )
302 && refType != CClass::Dot ){
303 if(isErrorEnabled) SetError(104,member,cp);
304 return false;
305 }
306
307 //直接参照に切り替え
308 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
309 pRelativeVar->dwKind=VAR_DIRECTMEM;
310
311 lpPtrOffset[0]=0;
312 }
313 else{
314 //pObj->member
315 if( (resultType.IsObjectPtr() || resultType.IsStructPtr() )
316 && refType != CClass::Pointer ){
317 if(isErrorEnabled) SetError(104,member,cp);
318 return false;
319 }
320
321 SetRelativeOffset( *pRelativeVar );
322 }
323 }
324 else if( resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_OBJECT,2)
325 || resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_STRUCT,2)){
326 //構造体ポインタのポインタ型メンバ変数
327
328 if(lpPtrOffset[0]){
329 //ppObj[n]->member
330 if( refType != CClass::Pointer ){
331 if(isErrorEnabled) SetError(104,member,cp);
332 return false;
333 }
334
335 //直接参照に切り替え
336 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
337 pRelativeVar->dwKind=VAR_DIRECTMEM;
338
339 lpPtrOffset[0]=0;
340
341 //mov r11,qword ptr[r11]
342 op_mov_RM(sizeof(_int64),REG_R11,REG_R11,0,MOD_BASE);
343 }
344 else{
345 if(isErrorEnabled) SetError(104,member,cp);
346 return false;
347 }
348 }
349
350 if(!_member_offset(
351 isErrorEnabled,
352 isWriteAccess,
353 pMember->GetType().GetClass(),
354 NestMember,
355 pRelativeVar,
356 resultType,
357 0)) return false;
358 }
359
360 if(lpPtrOffset[0]){
361 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
362 pRelativeVar->dwKind=VAR_DIRECTMEM;
363 }
364
365 return true;
366}
367
368int LocalVar_ThisPtrOffset;
369void SetThisPtrToReg(int reg){
370 //自身のオブジェクトのThisポインタをregにコピー
371
372 RELATIVE_VAR RelativeVar;
373 RelativeVar.dwKind=VAR_LOCAL;
374 RelativeVar.bOffsetOffset=0;
375 RelativeVar.offset=-LocalVar_ThisPtrOffset;
376
377 SetReg_WholeVariable(DEF_PTR_VOID,&RelativeVar,reg);
378}
379bool GetVarOffset(bool isErrorEnabled,bool isWriteAccess,const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss){
380 char variable[VN_SIZE];
381
382 if(NameBuffer[0]=='.'){
383 GetWithName(variable);
384 lstrcat(variable,NameBuffer);
385 }
386 else lstrcpy(variable,NameBuffer);
387
388 // 名前空間を分離
389 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
390 Smoothie::meta.namespaceScopesCollection.SplitNamespace( variable, namespaceStr, simpleName );
391
392 // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
393 CClass::RefType refType;
394 char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
395 GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
396
397 // 名前空間を分離していた場合は結合
398 char VarName[VN_SIZE];
399 if( namespaceStr[0] ){
400 sprintf( VarName, "%s.%s", namespaceStr, simpleName );
401 }
402 else{
403 lstrcpy( VarName, simpleName );
404 }
405
406 const int *pSubScripts;
407 bool bConst = false;
408
409
410 if( UserProc::IsLocalAreaCompiling() ){
411 //////////////////
412 // ローカル変数
413 //////////////////
414
415 const Variable *pVar = UserProc::CompilingUserProc().localVars.BackSearch( VarName );
416 if( pVar ){
417 //ポインタ変数の場合
418 if( pVar->IsPointer() ){
419 if( !pVar->IsArray() ){
420 lstrcpy(lpPtrOffset,array);
421 array[0]=0;
422 }
423 }
424 else{
425 if(lpPtrOffset[0]){
426 SetError(16,variable,cp);
427 pRelativeVar->dwKind=NON_VAR;
428 return false;
429 }
430 }
431
432 pRelativeVar->offset=-pVar->offset;
433 pRelativeVar->bOffsetOffset=0;
434 if( pVar->IsRef() ){
435 // 参照型
436 pRelativeVar->dwKind = VAR_REFLOCAL;
437 }
438 else pRelativeVar->dwKind=VAR_LOCAL;
439 resultType = *pVar;
440 pSubScripts=pVar->GetSubScriptsPtr();
441 bConst = pVar->IsConst();
442
443 goto ok;
444 }
445 }
446
447
448 if(pobj_CompilingClass){
449 //////////////////////
450 // クラスメンバの参照
451 //////////////////////
452
453 if(lstrcmpi(variable,"This")==0){
454 //自身のオブジェクトのThisポインタをr11にコピー
455 SetThisPtrToReg(REG_R11);
456
457 pRelativeVar->dwKind=VAR_DIRECTMEM;
458
459 resultType.SetType( DEF_OBJECT, pobj_CompilingClass );
460 return true;
461 }
462
463 if(memicmp(variable,"This.",5)==0){
464 //Thisオブジェクトのメンバを参照するとき
465 SlideString(variable+5,-5);
466 lstrcpy(VarName,variable);
467 }
468 else{
469 //クラス内メンバを参照するとき(通常)
470
471 bool isFound = false;
472 BOOST_FOREACH( CMember *pMember, pobj_CompilingClass->GetDynamicMembers() ){
473 if( pMember->GetName() == VarName ){
474 isFound = true;
475 break;
476 }
477 }
478 if( !isFound ) goto NonClassMember;
479 }
480
481 //Const修飾子のメソッド内でメンバ書き込みアクセスが発生したとき
482 //(コンストラクタ、デストラクタ内を除く)
483 const CMethod *pMethod = pobj_DBClass->GetNowCompilingMethodInfo();
484 if( isWriteAccess &&
485 pMethod->IsConst() &&
486 pobj_CompilingClass->IsCompilingConstructor() == false &&
487 pobj_CompilingClass->IsCompilingDestructor() == false
488 ){
489 SetError(131, NULL, cp );
490 }
491
492 //自身のオブジェクトのThisポインタをr11にコピー
493 SetThisPtrToReg(REG_R11);
494
495 pRelativeVar->dwKind=VAR_DIRECTMEM;
496 if(!_member_offset(
497 isErrorEnabled,
498 isWriteAccess,
499 *pobj_CompilingClass,
500 variable,
501 pRelativeVar,
502 resultType,1)) return false;
503 return true;
504 }
505
506NonClassMember:
507
508 {
509 const Variable *pVar;
510
511 //////////////////////////
512 // 静的ローカル変数
513 // ※"Static.Object.Method.Variable"
514 //////////////////////////
515
516 char temporary[VN_SIZE];
517 if( UserProc::IsLocalAreaCompiling() ){
518 GetNowStaticVarFullName(VarName,temporary);
519
520 pVar = globalVars.Find( temporary );
521 if( pVar ){
522 goto GlobalOk;
523 }
524 }
525
526
527 //////////////////////////
528 // クラスの静的メンバ
529 //////////////////////////
530
531 if(member[0]){
532 lstrcpy(temporary,member);
533
534 // TODO: 名前空間を考慮したコードになっていない
535
536 char tempMember[VN_SIZE];
537 char tempArray[VN_SIZE];
538 {
539 CClass::RefType refType;
540 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember, refType );
541 }
542
543 int typeDefIndex = Smoothie::meta.typeDefs.GetIndex( VarName );
544 if( typeDefIndex != -1 ){
545 // TypeDef後の型名だったとき
546 lstrcpy( VarName, Smoothie::meta.typeDefs[typeDefIndex].GetBaseName().c_str() );
547 }
548
549 char temp2[VN_SIZE];
550 sprintf(temp2,"%s.%s",VarName,temporary);
551 pVar = globalVars.Find( temp2 );
552 if( pVar ){
553 lstrcpy(member,tempMember);
554 lstrcpy(array,tempArray);
555 goto GlobalOk;
556 }
557 }
558
559 if(pobj_CompilingClass){
560 //自身のクラスから静的メンバを参照する場合
561 char temp2[VN_SIZE];
562 sprintf(temp2,"%s.%s",pobj_CompilingClass->GetName().c_str(),VarName);
563 pVar = globalVars.Find( temp2 );
564 if( pVar ){
565 goto GlobalOk;
566 }
567 }
568
569 /////////////////////
570 // グローバル変数
571 /////////////////////
572
573 pVar = globalVars.BackSearch( VarName );
574 if( pVar ){
575 goto GlobalOk;
576 }
577
578 if(isErrorEnabled) SetError(3,variable,cp);
579 pRelativeVar->dwKind=NON_VAR;
580 return false;
581
582
583
584GlobalOk:
585 //ポインタ変数の場合
586 if( pVar->IsPointer() ){
587 if( !pVar->IsArray() ){
588 lstrcpy(lpPtrOffset,array);
589 array[0]=0;
590 }
591 }
592 else{
593 if(lpPtrOffset[0]){
594 SetError(16,variable,cp);
595 pRelativeVar->dwKind=NON_VAR;
596 return false;
597 }
598 }
599
600 pRelativeVar->offset=pVar->offset;
601 pRelativeVar->bOffsetOffset=0;
602 if( pVar->IsRef() ){
603 // 参照型
604 pRelativeVar->dwKind = VAR_REFGLOBAL;
605 }
606 else pRelativeVar->dwKind=VAR_GLOBAL;
607 resultType = *pVar;
608 pSubScripts=pVar->GetSubScriptsPtr();
609 bConst = pVar->IsConst();
610 }
611
612
613
614ok:
615
616 if( bConst && isWriteAccess ){
617 //Const定義の変数に書き込みアクセスをしようとした場合
618 if( resultType.IsObject() ){
619 //オブジェクト定数
620 SetError(130, VarName, cp );
621 }
622 else{
623 //一般のConst変数
624 SetError(61,VarName,cp);
625 }
626 }
627
628 if(array[0]==0&&pSubScripts[0]!=-1){
629 //配列の先頭ポインタを示す場合
630 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
631 if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM);
632 return true;
633 }
634
635 if( array[0] || member[0] ){
636 //xor r11,r11(r11を0に初期化する)
637 //※r11は変数ベースアドレスからの相対オフセットを示す
638 op_zero_reg(REG_R11);
639
640 pRelativeVar->bOffsetOffset=1;
641 }
642 if(array[0]){
643 if(!GetArrayOffset(pSubScripts,array,resultType)){
644 SetError(14,variable,cp);
645 pRelativeVar->dwKind=NON_VAR;
646 return false;
647 }
648 }
649 if(member[0]){
650 if( resultType.IsObject() || resultType.IsStruct() ){
651 //実態オブジェクトのメンバを参照(obj.member)
652 if( refType != CClass::Dot ){
653 SetError(104,VarName,cp);
654 pRelativeVar->dwKind=NON_VAR;
655 return false;
656 }
657
658 if( resultType.IsObject() ){
659 // 参照内容へのポインタを抽出
660 SetRelativeOffset( *pRelativeVar );
661 }
662 }
663 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
664 //ポインタオブジェクトが示すメンバを参照
665 if(lpPtrOffset[0]){
666 //pObj[n].member
667 if( refType != CClass::Dot ){
668 SetError(104,VarName,cp);
669 pRelativeVar->dwKind=NON_VAR;
670 return false;
671 }
672 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
673 pRelativeVar->dwKind=VAR_DIRECTMEM;
674 }
675 else{
676 //pObj->member
677 if( refType != CClass::Pointer ){
678 SetError(104,VarName,cp);
679 pRelativeVar->dwKind=NON_VAR;
680 return false;
681 }
682
683 SetVarPtrToReg(REG_R12,pRelativeVar);
684 pRelativeVar->dwKind=VAR_DIRECTMEM;
685
686 //mov r11,qword ptr[r12]
687 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
688 }
689 }
690 else if( resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_STRUCT,2)){
691 //ポインタオブジェクトが示すメンバを参照
692 if(lpPtrOffset[0]){
693 //ppObj[n]->member
694 if( refType != CClass::Pointer ){
695 SetError(104,VarName,cp);
696 pRelativeVar->dwKind=NON_VAR;
697 return false;
698 }
699
700 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
701 pRelativeVar->dwKind=VAR_DIRECTMEM;
702
703
704 SetVarPtrToReg(REG_R12,pRelativeVar);
705
706 //mov r11,qword ptr[r12]
707 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
708 }
709 else{
710 SetError(104,VarName,cp);
711 pRelativeVar->dwKind=NON_VAR;
712 return false;
713 }
714 }
715 else{
716 SetError(102,VarName,cp);
717 pRelativeVar->dwKind=NON_VAR;
718 return false;
719 }
720
721 if(!_member_offset(
722 isErrorEnabled,
723 isWriteAccess,
724 resultType.GetClass(),
725 member,pRelativeVar,resultType,0)) return false;
726
727 return true;
728 }
729
730 if(lpPtrOffset[0]){
731 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
732 pRelativeVar->dwKind=VAR_DIRECTMEM;
733 }
734
735 return true;
736}
737
738bool SetInitGlobalData(int offset,const Type &type,const int *SubScripts,const char *lpszInitBuf){
739 extern BYTE *initGlobalBuf;
740 int i,i2,i3;
741 char temporary[VN_SIZE];
742 char InitBuf[VN_SIZE];
743 lstrcpy( InitBuf, lpszInitBuf );
744
745 if(InitBuf[0]=='['){
746 SlideString(InitBuf+1,-1);
747 InitBuf[lstrlen(InitBuf)-1]=0;
748
749 int typeSize = type.GetSize();
750
751 if(SubScripts[0]!=-1){
752 typeSize*=JumpSubScripts(SubScripts+1);
753 i=0;
754 i2=0;
755 while(1){
756 if(SubScripts[0]<i2){
757 SetError(41,0,cp);
758 return 0;
759 }
760 i=GetOneParameter(InitBuf,i,temporary);
761 if(!SetInitGlobalData(
762 offset+i2*typeSize,
763 type,
764 SubScripts+1,
765 temporary)) return false;
766 i2++;
767 if(InitBuf[i]=='\0') break;
768 }
769 return true;
770 }
771
772 if(type.IsStruct()){
773 const CClass &objClass = type.GetClass();
774
775 int i = 0;
776 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
777 if(InitBuf[i]=='\0'){
778 SetError(41,0,cp);
779 return false;
780 }
781
782 i=GetOneParameter(InitBuf,i,temporary);
783
784 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
785
786 if(!SetInitGlobalData(offset+i3,
787 pMember->GetType(),
788 pMember->SubScripts,
789 temporary)) return false;
790 }
791 return true;
792 }
793
794 SetError(41,0,cp);
795 return false;
796 }
797
798
799 ///////////////////////////////////////
800 // 単発式([]で囲まれていない)
801 ///////////////////////////////////////
802
803 if( type.IsObject() || type.IsStruct() ){
804 //オブジェクトまたは構造体の場合はありえない
805 SetError(300,NULL,cp);
806 return false;
807 }
808
809 if(SubScripts[0]!=-1){
810 SetError(41,0,cp);
811 return false;
812 }
813
814 double dbl;
815 _int64 i64data;
816 Type calcType;
817
818 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
819 //動的データだった場合
820 return false;
821 }
822 if( calcType.IsReal() ){
823 memcpy(&dbl,&i64data,sizeof(double));
824 i64data=(_int64)dbl;
825 }
826 else dbl=(double)i64data;
827
828 //型チェック
829 CheckDifferentType(
830 type,
831 calcType,
832 0,0);
833
834 if( type.IsDouble() ){
835 *(double *)(initGlobalBuf+offset)=(double)dbl;
836 }
837 else if( type.IsSingle() ){
838 *(float *)(initGlobalBuf+offset)=(float)dbl;
839 }
840 else if( type.Is64() || type.IsPointer() ){
841 if(type.GetBasicType()==typeOfPtrChar){
842 //文字列定数のとき
843
844 char *temp;
845 temp=(char *)i64data;
846 i2=dataTable.AddString( temp );
847 HeapDefaultFree(temp);
848
849 //mov rax,DataPos
850 op_mov_RV(sizeof(_int64),REG_RAX,i2);
851 obp-=sizeof(long);
852 pobj_DataTableSchedule->add();
853 obp+=sizeof(long);
854
855 //mov qword ptr[offset],rax
856 op_mov_MR(sizeof(_int64),REG_RAX,0,offset,MOD_DISP32);
857 obp-=sizeof(long);
858 pobj_GlobalVarSchedule->add();
859 obp+=sizeof(long);
860 }
861 else{
862 *(_int64 *)(initGlobalBuf+offset)=i64data;
863 }
864 }
865 else if( type.IsDWord() || type.IsLong() ){
866 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
867 }
868 else if( type.IsWord() || type.IsInteger() ){
869 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
870 }
871 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
872 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
873 }
874
875 return true;
876}
877bool InitLocalVar(int offset,const Type &type,const int *SubScripts,const char *lpszInitBuf){
878 int i,i2,i3;
879 char temporary[VN_SIZE];
880 char InitBuf[VN_SIZE];
881 lstrcpy( InitBuf, lpszInitBuf );
882
883 if(InitBuf[0]=='['){
884 SlideString(InitBuf+1,-1);
885 InitBuf[lstrlen(InitBuf)-1]=0;
886
887 int typeSize = type.GetSize();
888
889 if(SubScripts[0]!=-1){
890 typeSize*=JumpSubScripts(SubScripts+1);
891 i=0;
892 i2=0;
893 while(1){
894 if(SubScripts[0]<i2){
895 SetError(41,0,cp);
896 return false;
897 }
898 i=GetOneParameter(InitBuf,i,temporary);
899 if(!InitLocalVar(
900 offset+i2*typeSize,
901 type,
902 SubScripts+1,
903 temporary)) return false;
904 i2++;
905 if(InitBuf[i]=='\0') break;
906 }
907 return true;
908 }
909
910 if(type.IsStruct()){
911 const CClass &objClass = type.GetClass();
912
913 int i = 0;
914 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
915 if(InitBuf[i]=='\0'){
916 SetError(41,0,cp);
917 return false;
918 }
919
920 i=GetOneParameter(InitBuf,i,temporary);
921
922 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
923
924 if(!InitLocalVar(offset+i3,
925 pMember->GetType(),
926 pMember->SubScripts,
927 temporary)) return false;
928
929 if(InitBuf[i]=='\0') break;
930 }
931 return true;
932 }
933
934 SetError(41,0,cp);
935 return false;
936 }
937
938
939 ///////////////////////////////////////
940 // 単発式([]で囲まれていない)
941 ///////////////////////////////////////
942
943 if(SubScripts[0]!=-1){
944 SetError(41,0,cp);
945 return false;
946 }
947
948 double dbl;
949 _int64 i64data;
950 Type calcType;
951
952 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
953 //動的データだった場合
954 return false;
955 }
956 if( calcType.IsReal() ){
957 memcpy(&dbl,&i64data,sizeof(double));
958 i64data=(_int64)dbl;
959 }
960 else dbl=(double)i64data;
961
962 //型チェック
963 CheckDifferentType(
964 type,
965 calcType,
966 0,0);
967
968 if( type.IsDouble() ){
969 memcpy(&i64data,&dbl,sizeof(double));
970
971 //mov rax,i64data
972 op_mov64_ToReg(REG_RAX,i64data);
973
974 //mov qword ptr[rsp+offset],rax
975 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
976 obp-=sizeof(long);
977 AddLocalVarAddrSchedule();
978 obp+=sizeof(long);
979 }
980 else if( type.IsSingle() ){
981 float flt;
982 flt=(float)dbl;
983
984 //mov dword ptr[rsp+offset],value
985 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,*(int *)&flt);
986 obp-=sizeof(long)+sizeof(long);
987 AddLocalVarAddrSchedule();
988 obp+=sizeof(long)+sizeof(long);
989 }
990 else if( type.Is64() || type.IsPointer() ){
991 if(type.GetBasicType()==typeOfPtrChar ){
992 //文字列定数のとき
993
994 char *temp;
995 temp=(char *)i64data;
996 i2=dataTable.AddString( temp );
997 HeapDefaultFree(temp);
998
999 //mov rax,i2
1000 op_mov_RV(sizeof(_int64),REG_RAX,i2);
1001 obp-=sizeof(long);
1002 pobj_DataTableSchedule->add();
1003 obp+=sizeof(long);
1004
1005 //mov qword ptr[rsp+offset],rax
1006 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1007 obp-=sizeof(long);
1008 AddLocalVarAddrSchedule();
1009 obp+=sizeof(long);
1010 }
1011 else{
1012 if(i64data&0xFFFFFFFF00000000){
1013 //mov rax,i64data
1014 op_mov64_ToReg(REG_RAX,i64data);
1015
1016 //mov qword ptr[rsp+offset],rax
1017 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1018 obp-=sizeof(long);
1019 AddLocalVarAddrSchedule();
1020 obp+=sizeof(long);
1021 }
1022 else{
1023 //mov qword ptr[rsp+offset],value
1024 op_mov_MV(sizeof(_int64),REG_RSP,offset,USE_OFFSET,(int)i64data);
1025 obp-=sizeof(long)+sizeof(long);
1026 AddLocalVarAddrSchedule();
1027 obp+=sizeof(long)+sizeof(long);
1028 }
1029 }
1030 }
1031 else if( type.IsDWord() || type.IsLong() ){
1032 //mov dword ptr[rsp+offset],value
1033 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,(int)i64data);
1034 obp-=sizeof(long)+sizeof(long);
1035 AddLocalVarAddrSchedule();
1036 obp+=sizeof(long)+sizeof(long);
1037 }
1038 else if( type.IsWord() || type.IsInteger() ){
1039 //mov word ptr[rsp+offset],value
1040 op_mov_MV(sizeof(short),REG_RSP,offset,USE_OFFSET,(int)i64data);
1041 obp-=sizeof(long)+sizeof(short);
1042 AddLocalVarAddrSchedule();
1043 obp+=sizeof(long)+sizeof(short);
1044 }
1045 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1046 //mov byte ptr[rsp+offset],value
1047 op_mov_MV(sizeof(char),REG_RSP,offset,USE_OFFSET,(int)i64data);
1048 obp-=sizeof(long)+sizeof(char);
1049 AddLocalVarAddrSchedule();
1050 obp+=sizeof(long)+sizeof(char);
1051 }
1052 return true;
1053}
1054
1055void dim( char *VarName,int *SubScripts,Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1056 if( UserProc::IsGlobalAreaCompiling() ){
1057 /////////////////////////
1058 // グローバル変数
1059 /////////////////////////
1060
1061 //OpcodeOthers( ( (string)"OutputDebugString(Ex\"" + VarName + "\r\n\")" ).c_str() );
1062 AddGlobalVariable(VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags);
1063 }
1064 else{
1065 /////////////////
1066 // ローカル変数
1067 /////////////////
1068
1069 if( UserProc::CompilingUserProc().localVars.DuplicateCheck( VarName ) ){
1070 //2重定義のエラー
1071 SetError(15,VarName,cp);
1072 return;
1073 }
1074
1075 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1076
1077 Variable *pVar = new Variable( VarName, type, isConst );
1078
1079 if( SubScripts[0] != -1 ){
1080 //配列あり
1081 pVar->SetArray( SubScripts );
1082 }
1083
1084 //コンストラクタ用パラメータ
1085 pVar->paramStrForConstructor = ConstractParameter;
1086
1087 //レキシカルスコープ
1088 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1089 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1090 pVar->bLiving=TRUE;
1091
1092 //エラー用
1093 pVar->source_code_address=cp;
1094
1095 // 変数を追加
1096 UserProc::CompilingUserProc().localVars.push_back( pVar );
1097
1098 //アラインメントを考慮
1099 if( pVar->IsStruct() ){
1100 int alignment = pVar->GetClass().iAlign;
1101
1102 if( alignment ){
1103 if( AllLocalVarSize % alignment ){
1104 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1105 }
1106 }
1107
1108 if( alignment == PTR_SIZE*2 ){
1109 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1110 // (例:CONTEXT構造体など)
1111 // 呼び出し側のオフセットズレを考慮する
1112
1113 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1114 AllLocalVarSize += PTR_SIZE;
1115 }
1116 }
1117 }
1118
1119 AllLocalVarSize += pVar->GetMemorySize();
1120 pVar->offset = AllLocalVarSize;
1121
1122 //レキシカルスコープ
1123 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1124 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1125 pVar->bLiving=TRUE;
1126
1127 if(InitBuf[0]){
1128 //初期代入時のみ、書き込みアクセスを許可する
1129 if( isConst ){
1130 pVar->ConstOff();
1131 }
1132
1133 int result = 0;
1134 if( !pVar->IsObject() ){
1135 result = InitLocalVar(-pVar->offset,
1136 *pVar,
1137 pVar->GetSubScriptsPtr(),
1138 InitBuf);
1139 }
1140
1141 if(!result){
1142 //動的な式だった場合は代入演算を行う
1143 char temporary[8192];
1144 sprintf(temporary,"%s=%s",VarName,InitBuf);
1145 OpcodeCalc(temporary);
1146 }
1147
1148 if( isConst ){
1149 pVar->ConstOn();
1150 }
1151 }
1152 else{
1153 //0初期化
1154
1155 //mov r8, 0
1156 op_zero_reg( REG_R8 );
1157
1158 //mov rdx, VarSize
1159 op_mov_RV( sizeof(_int64), REG_RDX, pVar->GetMemorySize() );
1160
1161 //mov rcx, rsp
1162 op_mov_RR( REG_RCX, REG_RSP );
1163
1164 //add rcx, offset
1165 op_add_RV( REG_RCX, -pVar->offset );
1166 obp-=sizeof(long);
1167 AddLocalVarAddrSchedule();
1168 obp+=sizeof(long);
1169
1170 //call FillMemory
1171 DllProc *pDllProc;
1172 pDllProc=GetDeclareHash("FillMemory");
1173 op_call( pDllProc );
1174 }
1175 }
1176
1177 //コンストラクタ呼び出し
1178 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1179 char objectSize[255];
1180 if( SubScripts[0] == -1 ){
1181 objectSize[0] = 0;
1182 }
1183 else{
1184 if( SubScripts[1] != -1 ){
1185 SetError(300,NULL,cp);
1186 }
1187 sprintf( objectSize, "%d", SubScripts[0] );
1188 }
1189 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1190
1191 Type tempType;
1192 RELATIVE_VAR RelativeVar;
1193 GetVarOffset( true, false, VarName, &RelativeVar, tempType );
1194 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1195 SetError();
1196 }
1197 SetVariableFromRax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1198 }
1199}
1200void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1201 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1202
1203 if(pRelativeVar->dwKind==VAR_GLOBAL){
1204 if(pRelativeVar->bOffsetOffset){
1205 //add r11,offset
1206 OpBuffer[obp++]=(char)0x49;
1207 OpBuffer[obp++]=(char)0x81;
1208 OpBuffer[obp++]=(char)0xC3;
1209 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1210 pobj_GlobalVarSchedule->add();
1211 obp+=sizeof(long);
1212
1213 //mov reg,r11
1214 op_mov_RR(reg,REG_R11);
1215 }
1216 else{
1217 //mov reg,offset
1218 op_mov64_ToReg(reg,(int)pRelativeVar->offset);
1219 obp-=sizeof(long);
1220 pobj_GlobalVarSchedule->add();
1221 obp+=sizeof(long);
1222 }
1223 }
1224 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
1225 if(pRelativeVar->bOffsetOffset){
1226 //add r11,qword ptr[offset]
1227 op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelativeVar->offset, MOD_DISP32 );
1228 obp-=sizeof(long);
1229 pobj_GlobalVarSchedule->add();
1230 obp+=sizeof(long);
1231 }
1232 else{
1233 //mov r11,qword ptr[offset]
1234 op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelativeVar->offset,MOD_DISP32);
1235 obp-=sizeof(long);
1236 pobj_GlobalVarSchedule->add();
1237 obp+=sizeof(long);
1238 }
1239
1240 goto directmem;
1241 }
1242 else if(pRelativeVar->dwKind==VAR_LOCAL){
1243 if(pRelativeVar->bOffsetOffset){
1244 //add r11,offset
1245 OpBuffer[obp++]=(char)0x49;
1246 OpBuffer[obp++]=(char)0x81;
1247 OpBuffer[obp++]=(char)0xC3;
1248 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1249 AddLocalVarAddrSchedule();
1250 obp+=sizeof(long);
1251
1252 //add r11,rsp
1253 op_add64_reg(REG_R11,REG_RSP);
1254
1255 //mov reg,r11
1256 op_mov_RR(reg,REG_R11);
1257 }
1258 else{
1259 //mov reg,rsp
1260 op_mov_RR(reg,REG_RSP);
1261
1262 //add reg,offset
1263 op_add_RV(reg,(int)pRelativeVar->offset);
1264 obp-=sizeof(long);
1265 AddLocalVarAddrSchedule();
1266 obp+=sizeof(long);
1267 }
1268 }
1269 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
1270 if(pRelativeVar->bOffsetOffset){
1271 //add r11,qword ptr[rsp+offset]
1272 OpBuffer[obp++]=(char)0x4C;
1273 OpBuffer[obp++]=(char)0x03;
1274 OpBuffer[obp++]=(char)0x9C;
1275 OpBuffer[obp++]=(char)0x24;
1276 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1277 AddLocalVarAddrSchedule();
1278 obp+=sizeof(long);
1279 }
1280 else{
1281 //mov r11,qword ptr[rsp+offset]
1282 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
1283 obp-=sizeof(long);
1284 AddLocalVarAddrSchedule();
1285 obp+=sizeof(long);
1286 }
1287
1288 goto directmem;
1289 }
1290 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1291directmem:
1292 //mov reg,r11
1293 op_mov_RR(reg,REG_R11);
1294 }
1295}
1296
1297bool Compile_AddGlobalRootsForGc(){
1298 UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1299 if( !pUserProc_AddGlobalRootPtr ){
1300 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1301 return false;
1302 }
1303
1304 BOOST_FOREACH( const Variable *pVar, globalVars ){
1305 if( pVar->IsObject() || pVar->IsPointer() || pVar->IsStruct() ){
1306 // オブジェクトまたはポインタだったとき
1307 // ※構造体も含む(暫定対応)
1308
1309 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1310 //mov r8,count
1311 op_mov_RV(sizeof(_int64), REG_R8,pVar->GetMemorySize()/PTR_SIZE);
1312
1313 // ルートポインタを引き渡す
1314 //mov rdx,offset
1315 op_mov_RV(sizeof(_int64), REG_RDX,(int)pVar->offset);
1316 obp-=sizeof(long);
1317 pobj_GlobalVarSchedule->add();
1318 obp+=sizeof(long);
1319
1320 // Thisポインタを引き渡す
1321 SetThisPtrToReg(REG_RCX);
1322
1323 // call AddGlobalRootPtr
1324 op_call( pUserProc_AddGlobalRootPtr );
1325
1326 ReallocNativeCodeBuffer();
1327 }
1328 }
1329
1330 return true;
1331}
Note: See TracBrowser for help on using the repository browser.