source: dev/BasicCompiler64/Compile_Var.cpp@ 106

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

名前空間機能をクラスの静的メンバに適用。

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