source: dev/BasicCompiler64/Compile_Var.cpp@ 135

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

Method/Memberのリファクタリング

File size: 31.7 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 int i;
190
191
192 //////////////////////////////////////
193 // クラス、配列の構成要素を解析する
194 //////////////////////////////////////
195
196 char VarName[VN_SIZE]; //変数名
197 char array[VN_SIZE]; //第1次配列
198 char lpPtrOffset[VN_SIZE]; //第2次配列
199 char NestMember[VN_SIZE]; //入れ子メンバ
200 CClass::RefType refType;
201 lstrcpy(VarName,member);
202 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false;
203
204
205 ////////////////////////////
206 // メンバオフセットを取得
207 ////////////////////////////
208
209 int offset = objClass.GetMemberOffset( VarName, &i );
210 if(i==objClass.iMemberNum){
211 if(isErrorEnabled) SetError(103,VarName,cp);
212 return false;
213 }
214
215 CMember *pMember=objClass.ppobj_Member[i];
216
217
218 //アクセシビリティをチェック
219 if(&objClass==pobj_CompilingClass){
220 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
221 if(pMember->dwAccess==ACCESS_NON){
222 if(isErrorEnabled) SetError(107,VarName,cp);
223 return false;
224 }
225 }
226 else{
227 if((bPrivateAccess==0&&pMember->dwAccess==ACCESS_PRIVATE)||
228 pMember->dwAccess==ACCESS_NON){
229 if(isErrorEnabled) SetError(107,VarName,cp);
230 return false;
231 }
232 else if(bPrivateAccess==0&&pMember->dwAccess==ACCESS_PROTECTED){
233 if(isErrorEnabled) SetError(108,VarName,cp);
234 return false;
235 }
236 }
237
238 //Const定義の場合は書き込みアクセスを制限する
239 //※コンストラクタをコンパイル中の場合は例外的に許可する
240 if( pMember->IsConst() && //定数メンバである
241 isWriteAccess && //書き込みアクセスを要求されている
242 objClass.IsCompilingConstructor() == false //コンストラクタ コンパイル中を除く
243 ){
244 //Const定義の変数に書き込みアクセスをしようとした場合
245 SetError(61,VarName,cp);
246 }
247
248 resultType = *pMember;
249
250 //ポインタ変数の場合
251 if( resultType.IsPointer() ){
252 if(pMember->SubScripts[0]==-1){
253 lstrcpy(lpPtrOffset,array);
254 array[0]=0;
255 }
256 }
257 else{
258 if(lpPtrOffset[0]){
259 if(isErrorEnabled) SetError(16,member,cp);
260 return false;
261 }
262 }
263
264 if(offset){
265 //add r11,offset
266 OpBuffer[obp++]=(char)0x49;
267 OpBuffer[obp++]=(char)0x81;
268 OpBuffer[obp++]=(char)0xC3;
269 *((long *)(OpBuffer+obp))=offset;
270 obp+=sizeof(long);
271 }
272
273 if(array[0]){
274 //配列オフセット
275 if(!GetArrayOffset(pMember->SubScripts,array,*pMember)){
276 if(isErrorEnabled) SetError(14,member,cp);
277 }
278 }
279 else if(pMember->SubScripts[0]!=-1){
280 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
281 }
282
283 if(NestMember[0]){
284 //入れ子構造の場合
285
286 if( resultType.IsObject() || resultType.IsStruct() ){
287 if( refType != CClass::Dot ){
288 if(isErrorEnabled) SetError(104,member,cp);
289 return false;
290 }
291
292 if( resultType.IsObject() ){
293 // 参照内容へのポインタを抽出
294 SetRelativeOffset( *pRelativeVar );
295 }
296 }
297 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
298 //構造体ポインタ型メンバ変数
299
300 if(lpPtrOffset[0]){
301 //pObj[n].member
302 if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() )
303 && refType != CClass::Dot ){
304 if(isErrorEnabled) SetError(104,member,cp);
305 return false;
306 }
307
308 //直接参照に切り替え
309 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
310 pRelativeVar->dwKind=VAR_DIRECTMEM;
311
312 lpPtrOffset[0]=0;
313 }
314 else{
315 //pObj->member
316 if( (resultType.IsObjectPtr() || resultType.IsStructPtr() )
317 && refType != CClass::Pointer ){
318 if(isErrorEnabled) SetError(104,member,cp);
319 return false;
320 }
321
322 SetRelativeOffset( *pRelativeVar );
323 }
324 }
325 else if( resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_OBJECT,2)
326 || resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_STRUCT,2)){
327 //構造体ポインタのポインタ型メンバ変数
328
329 if(lpPtrOffset[0]){
330 //ppObj[n]->member
331 if( refType != CClass::Pointer ){
332 if(isErrorEnabled) SetError(104,member,cp);
333 return false;
334 }
335
336 //直接参照に切り替え
337 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
338 pRelativeVar->dwKind=VAR_DIRECTMEM;
339
340 lpPtrOffset[0]=0;
341
342 //mov r11,qword ptr[r11]
343 op_mov_RM(sizeof(_int64),REG_R11,REG_R11,0,MOD_BASE);
344 }
345 else{
346 if(isErrorEnabled) SetError(104,member,cp);
347 return false;
348 }
349 }
350
351 if(!_member_offset(
352 isErrorEnabled,
353 isWriteAccess,
354 pMember->GetClass(),
355 NestMember,
356 pRelativeVar,
357 resultType,
358 0)) return false;
359 }
360
361 if(lpPtrOffset[0]){
362 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
363 pRelativeVar->dwKind=VAR_DIRECTMEM;
364 }
365
366 return true;
367}
368
369int LocalVar_ThisPtrOffset;
370void SetThisPtrToReg(int reg){
371 //自身のオブジェクトのThisポインタをregにコピー
372
373 RELATIVE_VAR RelativeVar;
374 RelativeVar.dwKind=VAR_LOCAL;
375 RelativeVar.bOffsetOffset=0;
376 RelativeVar.offset=-LocalVar_ThisPtrOffset;
377
378 SetReg_WholeVariable(DEF_PTR_VOID,&RelativeVar,reg);
379}
380bool GetVarOffset(bool isErrorEnabled,bool isWriteAccess,const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss){
381 int i;
382 char variable[VN_SIZE];
383
384 if(NameBuffer[0]=='.'){
385 GetWithName(variable);
386 lstrcat(variable,NameBuffer);
387 }
388 else lstrcpy(variable,NameBuffer);
389
390 // 名前空間を分離
391 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
392 Smoothie::Meta::namespaceScopesCollection.SplitNamespace( variable, namespaceStr, simpleName );
393
394 // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
395 CClass::RefType refType;
396 char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
397 GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
398
399 // 名前空間を分離していた場合は結合
400 char VarName[VN_SIZE];
401 if( namespaceStr[0] ){
402 sprintf( VarName, "%s.%s", namespaceStr, simpleName );
403 }
404 else{
405 lstrcpy( VarName, simpleName );
406 }
407
408 const int *pSubScripts;
409 bool bConst = false;
410
411
412 if( UserProc::IsLocalAreaCompiling() ){
413 //////////////////
414 // ローカル変数
415 //////////////////
416
417 const Variable *pVar = UserProc::CompilingUserProc().localVars.BackSearch( VarName );
418 if( pVar ){
419 //ポインタ変数の場合
420 if( pVar->IsPointer() ){
421 if( !pVar->IsArray() ){
422 lstrcpy(lpPtrOffset,array);
423 array[0]=0;
424 }
425 }
426 else{
427 if(lpPtrOffset[0]){
428 SetError(16,variable,cp);
429 pRelativeVar->dwKind=NON_VAR;
430 return false;
431 }
432 }
433
434 pRelativeVar->offset=-pVar->offset;
435 pRelativeVar->bOffsetOffset=0;
436 if( pVar->IsRef() ){
437 // 参照型
438 pRelativeVar->dwKind = VAR_REFLOCAL;
439 }
440 else pRelativeVar->dwKind=VAR_LOCAL;
441 resultType = *pVar;
442 pSubScripts=pVar->GetSubScriptsPtr();
443 bConst = pVar->IsConst();
444
445 goto ok;
446 }
447 }
448
449
450 if(pobj_CompilingClass){
451 //////////////////////
452 // クラスメンバの参照
453 //////////////////////
454
455 if(lstrcmpi(variable,"This")==0){
456 //自身のオブジェクトのThisポインタをr11にコピー
457 SetThisPtrToReg(REG_R11);
458
459 pRelativeVar->dwKind=VAR_DIRECTMEM;
460
461 resultType.SetType( DEF_OBJECT, pobj_CompilingClass );
462 return true;
463 }
464
465 if(memicmp(variable,"This.",5)==0){
466 //Thisオブジェクトのメンバを参照するとき
467 SlideString(variable+5,-5);
468 lstrcpy(VarName,variable);
469 }
470 else{
471 //クラス内メンバを参照するとき(通常)
472
473 for(i=0;i<pobj_CompilingClass->iMemberNum;i++){
474 if( pobj_CompilingClass->ppobj_Member[i]->GetName() == VarName ){
475 break;
476 }
477 }
478 if(i==pobj_CompilingClass->iMemberNum) 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,char *InitBuf){
739 extern BYTE *initGlobalBuf;
740 int i,i2,i3;
741 char temporary[VN_SIZE];
742
743 if(InitBuf[0]=='['){
744 SlideString(InitBuf+1,-1);
745 InitBuf[lstrlen(InitBuf)-1]=0;
746
747 int typeSize = type.GetSize();
748
749 if(SubScripts[0]!=-1){
750 typeSize*=JumpSubScripts(SubScripts+1);
751 i=0;
752 i2=0;
753 while(1){
754 if(SubScripts[0]<i2){
755 SetError(41,0,cp);
756 return 0;
757 }
758 i=GetOneParameter(InitBuf,i,temporary);
759 if(!SetInitGlobalData(
760 offset+i2*typeSize,
761 type,
762 SubScripts+1,
763 temporary)) return false;
764 i2++;
765 if(InitBuf[i]=='\0') break;
766 }
767 return true;
768 }
769
770 if(type.IsStruct()){
771 const CClass &objClass = type.GetClass();
772
773 for(i=0,i2=0;i2<objClass.iMemberNum;i2++){
774 i=GetOneParameter(InitBuf,i,temporary);
775
776 i3=objClass.GetMemberOffset( objClass.ppobj_Member[i2]->GetName().c_str(), NULL );
777
778 if(!SetInitGlobalData(offset+i3,
779 *objClass.ppobj_Member[i2],
780 objClass.ppobj_Member[i2]->SubScripts,
781 temporary)) return false;
782
783 if(InitBuf[i]=='\0') break;
784 }
785 if(i2+1!=objClass.iMemberNum){
786 SetError(41,0,cp);
787 return false;
788 }
789 return true;
790 }
791
792 SetError(41,0,cp);
793 return false;
794 }
795
796
797 ///////////////////////////////////////
798 // 単発式([]で囲まれていない)
799 ///////////////////////////////////////
800
801 if( type.IsObject() || type.IsStruct() ){
802 //オブジェクトまたは構造体の場合はありえない
803 SetError(300,NULL,cp);
804 return false;
805 }
806
807 if(SubScripts[0]!=-1){
808 SetError(41,0,cp);
809 return false;
810 }
811
812 double dbl;
813 _int64 i64data;
814 Type calcType;
815
816 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
817 //動的データだった場合
818 return false;
819 }
820 if( calcType.IsReal() ){
821 memcpy(&dbl,&i64data,sizeof(double));
822 i64data=(_int64)dbl;
823 }
824 else dbl=(double)i64data;
825
826 //型チェック
827 CheckDifferentType(
828 type,
829 calcType,
830 0,0);
831
832 if( type.IsDouble() ){
833 *(double *)(initGlobalBuf+offset)=(double)dbl;
834 }
835 else if( type.IsSingle() ){
836 *(float *)(initGlobalBuf+offset)=(float)dbl;
837 }
838 else if( type.Is64() || type.IsPointer() ){
839 if(type.GetBasicType()==typeOfPtrChar){
840 //文字列定数のとき
841
842 char *temp;
843 temp=(char *)i64data;
844 i2=dataTable.AddString( temp );
845 HeapDefaultFree(temp);
846
847 //mov rax,DataPos
848 op_mov_RV(sizeof(_int64),REG_RAX,i2);
849 obp-=sizeof(long);
850 pobj_DataTableSchedule->add();
851 obp+=sizeof(long);
852
853 //mov qword ptr[offset],rax
854 op_mov_MR(sizeof(_int64),REG_RAX,0,offset,MOD_DISP32);
855 obp-=sizeof(long);
856 pobj_GlobalVarSchedule->add();
857 obp+=sizeof(long);
858 }
859 else{
860 *(_int64 *)(initGlobalBuf+offset)=i64data;
861 }
862 }
863 else if( type.IsDWord() || type.IsLong() ){
864 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
865 }
866 else if( type.IsWord() || type.IsInteger() ){
867 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
868 }
869 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
870 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
871 }
872
873 return true;
874}
875bool InitLocalVar(int offset,const Type &type,const int *SubScripts,char *InitBuf){
876 int i,i2,i3;
877 char temporary[VN_SIZE];
878
879 if(InitBuf[0]=='['){
880 SlideString(InitBuf+1,-1);
881 InitBuf[lstrlen(InitBuf)-1]=0;
882
883 int typeSize = type.GetSize();
884
885 if(SubScripts[0]!=-1){
886 typeSize*=JumpSubScripts(SubScripts+1);
887 i=0;
888 i2=0;
889 while(1){
890 if(SubScripts[0]<i2){
891 SetError(41,0,cp);
892 return false;
893 }
894 i=GetOneParameter(InitBuf,i,temporary);
895 if(!InitLocalVar(
896 offset+i2*typeSize,
897 type,
898 SubScripts+1,
899 temporary)) return false;
900 i2++;
901 if(InitBuf[i]=='\0') break;
902 }
903 return true;
904 }
905
906 if(type.IsStruct()){
907 const CClass &objClass = type.GetClass();
908
909 for(i=0,i2=0;i2<objClass.iMemberNum;i2++){
910 i=GetOneParameter(InitBuf,i,temporary);
911
912 i3=objClass.GetMemberOffset( objClass.ppobj_Member[i2]->GetName().c_str(), NULL );
913
914 if(!InitLocalVar(offset+i3,
915 *objClass.ppobj_Member[i2],
916 objClass.ppobj_Member[i2]->SubScripts,
917 temporary)) return false;
918
919 if(InitBuf[i]=='\0') break;
920 }
921 if(i2+1!=objClass.iMemberNum){
922 SetError(41,0,cp);
923 return 0;
924 }
925 return true;
926 }
927
928 SetError(41,0,cp);
929 return false;
930 }
931
932
933 ///////////////////////////////////////
934 // 単発式([]で囲まれていない)
935 ///////////////////////////////////////
936
937 if(SubScripts[0]!=-1){
938 SetError(41,0,cp);
939 return false;
940 }
941
942 double dbl;
943 _int64 i64data;
944 Type calcType;
945
946 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
947 //動的データだった場合
948 return false;
949 }
950 if( calcType.IsReal() ){
951 memcpy(&dbl,&i64data,sizeof(double));
952 i64data=(_int64)dbl;
953 }
954 else dbl=(double)i64data;
955
956 //型チェック
957 CheckDifferentType(
958 type,
959 calcType,
960 0,0);
961
962 if( type.IsDouble() ){
963 memcpy(&i64data,&dbl,sizeof(double));
964
965 //mov rax,i64data
966 op_mov64_ToReg(REG_RAX,i64data);
967
968 //mov qword ptr[rsp+offset],rax
969 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
970 obp-=sizeof(long);
971 AddLocalVarAddrSchedule();
972 obp+=sizeof(long);
973 }
974 else if( type.IsSingle() ){
975 float flt;
976 flt=(float)dbl;
977
978 //mov dword ptr[rsp+offset],value
979 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,*(int *)&flt);
980 obp-=sizeof(long)+sizeof(long);
981 AddLocalVarAddrSchedule();
982 obp+=sizeof(long)+sizeof(long);
983 }
984 else if( type.Is64() || type.IsPointer() ){
985 if(type.GetBasicType()==typeOfPtrChar ){
986 //文字列定数のとき
987
988 char *temp;
989 temp=(char *)i64data;
990 i2=dataTable.AddString( temp );
991 HeapDefaultFree(temp);
992
993 //mov rax,i2
994 op_mov_RV(sizeof(_int64),REG_RAX,i2);
995 obp-=sizeof(long);
996 pobj_DataTableSchedule->add();
997 obp+=sizeof(long);
998
999 //mov qword ptr[rsp+offset],rax
1000 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1001 obp-=sizeof(long);
1002 AddLocalVarAddrSchedule();
1003 obp+=sizeof(long);
1004 }
1005 else{
1006 if(i64data&0xFFFFFFFF00000000){
1007 //mov rax,i64data
1008 op_mov64_ToReg(REG_RAX,i64data);
1009
1010 //mov qword ptr[rsp+offset],rax
1011 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1012 obp-=sizeof(long);
1013 AddLocalVarAddrSchedule();
1014 obp+=sizeof(long);
1015 }
1016 else{
1017 //mov qword ptr[rsp+offset],value
1018 op_mov_MV(sizeof(_int64),REG_RSP,offset,USE_OFFSET,(int)i64data);
1019 obp-=sizeof(long)+sizeof(long);
1020 AddLocalVarAddrSchedule();
1021 obp+=sizeof(long)+sizeof(long);
1022 }
1023 }
1024 }
1025 else if( type.IsDWord() || type.IsLong() ){
1026 //mov dword ptr[rsp+offset],value
1027 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,(int)i64data);
1028 obp-=sizeof(long)+sizeof(long);
1029 AddLocalVarAddrSchedule();
1030 obp+=sizeof(long)+sizeof(long);
1031 }
1032 else if( type.IsWord() || type.IsInteger() ){
1033 //mov word ptr[rsp+offset],value
1034 op_mov_MV(sizeof(short),REG_RSP,offset,USE_OFFSET,(int)i64data);
1035 obp-=sizeof(long)+sizeof(short);
1036 AddLocalVarAddrSchedule();
1037 obp+=sizeof(long)+sizeof(short);
1038 }
1039 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1040 //mov byte ptr[rsp+offset],value
1041 op_mov_MV(sizeof(char),REG_RSP,offset,USE_OFFSET,(int)i64data);
1042 obp-=sizeof(long)+sizeof(char);
1043 AddLocalVarAddrSchedule();
1044 obp+=sizeof(long)+sizeof(char);
1045 }
1046 return true;
1047}
1048
1049void dim( char *VarName,int *SubScripts,Type &type,char *InitBuf,char *ConstractParameter,DWORD dwFlags){
1050 if( UserProc::IsGlobalAreaCompiling() ){
1051 /////////////////////////
1052 // グローバル変数
1053 /////////////////////////
1054
1055 //OpcodeOthers( ( (string)"OutputDebugString(Ex\"" + VarName + "\r\n\")" ).c_str() );
1056 AddGlobalVariable(VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags);
1057 }
1058 else{
1059 /////////////////
1060 // ローカル変数
1061 /////////////////
1062
1063 if( UserProc::CompilingUserProc().localVars.DuplicateCheck( VarName ) ){
1064 //2重定義のエラー
1065 SetError(15,VarName,cp);
1066 return;
1067 }
1068
1069 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1070
1071 Variable *pVar = new Variable( VarName, type, isConst );
1072
1073 if( SubScripts[0] != -1 ){
1074 //配列あり
1075 pVar->SetArray( SubScripts );
1076 }
1077
1078 //コンストラクタ用パラメータ
1079 pVar->paramStrForConstructor = ConstractParameter;
1080
1081 //レキシカルスコープ
1082 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1083 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1084 pVar->bLiving=TRUE;
1085
1086 //エラー用
1087 pVar->source_code_address=cp;
1088
1089 // 変数を追加
1090 UserProc::CompilingUserProc().localVars.push_back( pVar );
1091
1092 //アラインメントを考慮
1093 if( pVar->IsStruct() ){
1094 int alignment = pVar->GetClass().iAlign;
1095
1096 if( alignment ){
1097 if( AllLocalVarSize % alignment ){
1098 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1099 }
1100 }
1101
1102 if( alignment == PTR_SIZE*2 ){
1103 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1104 // (例:CONTEXT構造体など)
1105 // 呼び出し側のオフセットズレを考慮する
1106
1107 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1108 AllLocalVarSize += PTR_SIZE;
1109 }
1110 }
1111 }
1112
1113 AllLocalVarSize += pVar->GetMemorySize();
1114 pVar->offset = AllLocalVarSize;
1115
1116 //レキシカルスコープ
1117 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1118 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1119 pVar->bLiving=TRUE;
1120
1121 if(InitBuf[0]){
1122 //初期代入時のみ、書き込みアクセスを許可する
1123 if( isConst ){
1124 pVar->ConstOff();
1125 }
1126
1127 int result = 0;
1128 if( !pVar->IsObject() ){
1129 result = InitLocalVar(-pVar->offset,
1130 *pVar,
1131 pVar->GetSubScriptsPtr(),
1132 InitBuf);
1133 }
1134
1135 if(!result){
1136 //動的な式だった場合は代入演算を行う
1137 char temporary[8192];
1138 sprintf(temporary,"%s=%s",VarName,InitBuf);
1139 OpcodeCalc(temporary);
1140 }
1141
1142 if( isConst ){
1143 pVar->ConstOn();
1144 }
1145 }
1146 else{
1147 //0初期化
1148
1149 //mov r8, 0
1150 op_zero_reg( REG_R8 );
1151
1152 //mov rdx, VarSize
1153 op_mov_RV( sizeof(_int64), REG_RDX, pVar->GetMemorySize() );
1154
1155 //mov rcx, rsp
1156 op_mov_RR( REG_RCX, REG_RSP );
1157
1158 //add rcx, offset
1159 op_add_RV( REG_RCX, -pVar->offset );
1160 obp-=sizeof(long);
1161 AddLocalVarAddrSchedule();
1162 obp+=sizeof(long);
1163
1164 //call FillMemory
1165 DllProc *pDllProc;
1166 pDllProc=GetDeclareHash("FillMemory");
1167 op_call( pDllProc );
1168 }
1169 }
1170
1171 //コンストラクタ呼び出し
1172 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1173 char objectSize[255];
1174 if( SubScripts[0] == -1 ){
1175 objectSize[0] = 0;
1176 }
1177 else{
1178 if( SubScripts[1] != -1 ){
1179 SetError(300,NULL,cp);
1180 }
1181 sprintf( objectSize, "%d", SubScripts[0] );
1182 }
1183 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1184
1185 Type tempType;
1186 RELATIVE_VAR RelativeVar;
1187 GetVarOffset( true, false, VarName, &RelativeVar, tempType );
1188 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1189 SetError();
1190 }
1191 SetVariableFromRax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1192 }
1193}
1194void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1195 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1196
1197 if(pRelativeVar->dwKind==VAR_GLOBAL){
1198 if(pRelativeVar->bOffsetOffset){
1199 //add r11,offset
1200 OpBuffer[obp++]=(char)0x49;
1201 OpBuffer[obp++]=(char)0x81;
1202 OpBuffer[obp++]=(char)0xC3;
1203 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1204 pobj_GlobalVarSchedule->add();
1205 obp+=sizeof(long);
1206
1207 //mov reg,r11
1208 op_mov_RR(reg,REG_R11);
1209 }
1210 else{
1211 //mov reg,offset
1212 op_mov64_ToReg(reg,(int)pRelativeVar->offset);
1213 obp-=sizeof(long);
1214 pobj_GlobalVarSchedule->add();
1215 obp+=sizeof(long);
1216 }
1217 }
1218 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
1219 if(pRelativeVar->bOffsetOffset){
1220 //add r11,qword ptr[offset]
1221 op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelativeVar->offset, MOD_DISP32 );
1222 obp-=sizeof(long);
1223 pobj_GlobalVarSchedule->add();
1224 obp+=sizeof(long);
1225 }
1226 else{
1227 //mov r11,qword ptr[offset]
1228 op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelativeVar->offset,MOD_DISP32);
1229 obp-=sizeof(long);
1230 pobj_GlobalVarSchedule->add();
1231 obp+=sizeof(long);
1232 }
1233
1234 goto directmem;
1235 }
1236 else if(pRelativeVar->dwKind==VAR_LOCAL){
1237 if(pRelativeVar->bOffsetOffset){
1238 //add r11,offset
1239 OpBuffer[obp++]=(char)0x49;
1240 OpBuffer[obp++]=(char)0x81;
1241 OpBuffer[obp++]=(char)0xC3;
1242 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1243 AddLocalVarAddrSchedule();
1244 obp+=sizeof(long);
1245
1246 //add r11,rsp
1247 op_add64_reg(REG_R11,REG_RSP);
1248
1249 //mov reg,r11
1250 op_mov_RR(reg,REG_R11);
1251 }
1252 else{
1253 //mov reg,rsp
1254 op_mov_RR(reg,REG_RSP);
1255
1256 //add reg,offset
1257 op_add_RV(reg,(int)pRelativeVar->offset);
1258 obp-=sizeof(long);
1259 AddLocalVarAddrSchedule();
1260 obp+=sizeof(long);
1261 }
1262 }
1263 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
1264 if(pRelativeVar->bOffsetOffset){
1265 //add r11,qword ptr[rsp+offset]
1266 OpBuffer[obp++]=(char)0x4C;
1267 OpBuffer[obp++]=(char)0x03;
1268 OpBuffer[obp++]=(char)0x9C;
1269 OpBuffer[obp++]=(char)0x24;
1270 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1271 AddLocalVarAddrSchedule();
1272 obp+=sizeof(long);
1273 }
1274 else{
1275 //mov r11,qword ptr[rsp+offset]
1276 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
1277 obp-=sizeof(long);
1278 AddLocalVarAddrSchedule();
1279 obp+=sizeof(long);
1280 }
1281
1282 goto directmem;
1283 }
1284 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1285directmem:
1286 //mov reg,r11
1287 op_mov_RR(reg,REG_R11);
1288 }
1289}
1290
1291bool Compile_AddGlobalRootsForGc(){
1292 UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1293 if( !pUserProc_AddGlobalRootPtr ){
1294 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1295 return false;
1296 }
1297
1298 BOOST_FOREACH( const Variable *pVar, globalVars ){
1299 if( pVar->IsObject() || pVar->IsPointer() || pVar->IsStruct() ){
1300 // オブジェクトまたはポインタだったとき
1301 // ※構造体も含む(暫定対応)
1302
1303 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1304 //mov r8,count
1305 op_mov_RV(sizeof(_int64), REG_R8,pVar->GetMemorySize()/PTR_SIZE);
1306
1307 // ルートポインタを引き渡す
1308 //mov rdx,offset
1309 op_mov_RV(sizeof(_int64), REG_RDX,(int)pVar->offset);
1310 obp-=sizeof(long);
1311 pobj_GlobalVarSchedule->add();
1312 obp+=sizeof(long);
1313
1314 // Thisポインタを引き渡す
1315 SetThisPtrToReg(REG_RCX);
1316
1317 // call AddGlobalRootPtr
1318 op_call( pUserProc_AddGlobalRootPtr );
1319
1320 ReallocNativeCodeBuffer();
1321 }
1322 }
1323
1324 return true;
1325}
Note: See TracBrowser for help on using the repository browser.