source: dev/BasicCompiler64/Compile_Var.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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