source: dev/BasicCompiler64/Compile_Var.cpp@ 79

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

バージョンをβ17にした。
#strictをデフォルトの状態で適用するようにした(#90)。
Dimステートメントにおいて、初期値式とAsが同時に指定されていたとき、As以降も初期値式の一部として捉えるよう、変更(#91)。
GetTypeDef関数を完全廃止。

File size: 31.0 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}
368void GetWithName(char *buffer){
369 extern WITHINFO WithInfo;
370 int i;
371
372 buffer[0]=0;
373 for(i=0;i<WithInfo.num;i++)
374 lstrcat(buffer,WithInfo.ppName[i]);
375}
376
377int LocalVar_ThisPtrOffset;
378void SetThisPtrToReg(int reg){
379 //自身のオブジェクトのThisポインタをregにコピー
380
381 RELATIVE_VAR RelativeVar;
382 RelativeVar.dwKind=VAR_LOCAL;
383 RelativeVar.bOffsetOffset=0;
384 RelativeVar.offset=-LocalVar_ThisPtrOffset;
385
386 SetReg_WholeVariable(DEF_PTR_VOID,&RelativeVar,reg);
387}
[75]388bool GetVarOffset(bool isErrorEnabled,bool isWriteAccess,const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss){
[64]389 int i;
[3]390 char variable[VN_SIZE],member[VN_SIZE],VarName[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
391
392 if(NameBuffer[0]=='.'){
393 GetWithName(variable);
394 lstrcat(variable,NameBuffer);
395 }
396 else lstrcpy(variable,NameBuffer);
397
[64]398 CClass::RefType refType;
399 if( FormatUseProcReturnObject( variable, VarName, array, refType, member ) ){
[49]400 // 戻り値オブジェクトのメンバを直接参照しているとき
401 //例: func().member
402
403 void *pInfo;
[75]404 int idProc=GetProc(VarName,(void **)&pInfo);
[49]405
406 if(idProc){
407 pRelativeVar->dwKind=VAR_DIRECTMEM;
408
[75]409 Type type;
410
[49]411 //////////////////////////////////////////////////////
412 ///// レジスタ資源のバックアップ
413 { BACKUP_REGISTER_RESOURCE
414 //////////////////////////////////////////////////////
415
416 ////////////////
417 // 呼び出し
418 ////////////////
419
[75]420 CallProc(idProc,pInfo,VarName,array,type);
[49]421
422 //戻り値をr11にコピー
423 op_mov_RR( REG_R11, REG_RAX );
424
425 /////////////////////////////////////////////
426 ////// レジスタ資源を復元
427 RESTORE_REGISTER_RESOURCE
428 }////////////////////////////////////////////
429
[75]430 if(!_member_offset(
[49]431 isErrorEnabled,
432 isWriteAccess,
[75]433 type.GetClass(),
434 member,pRelativeVar,resultType,0)) return false;
[49]435
[75]436 return true;
[49]437 }
438 }
439
440
441
[3]442 lstrcpy(VarName,variable);
[64]443 GetVarFormatString(VarName,array,lpPtrOffset,member,refType);
[3]444
[75]445 const int *pSubScripts;
[11]446 bool bConst = false;
[3]447
448
[75]449 if( UserProc::IsLocalAreaCompiling() ){
[3]450 //////////////////
451 // ローカル変数
452 //////////////////
453
[75]454 const Variable *pVar = UserProc::CompilingUserProc().localVars.BackSearch( VarName );
455 if( pVar ){
[3]456 //ポインタ変数の場合
[75]457 if( pVar->IsPointer() ){
458 if( !pVar->IsArray() ){
[3]459 lstrcpy(lpPtrOffset,array);
460 array[0]=0;
461 }
462 }
463 else{
464 if(lpPtrOffset[0]){
465 SetError(16,variable,cp);
466 pRelativeVar->dwKind=NON_VAR;
[75]467 return false;
[3]468 }
469 }
470
[75]471 pRelativeVar->offset=-pVar->offset;
[3]472 pRelativeVar->bOffsetOffset=0;
[75]473 if( pVar->IsRef() ){
[40]474 // 参照型
475 pRelativeVar->dwKind = VAR_REFLOCAL;
476 }
[3]477 else pRelativeVar->dwKind=VAR_LOCAL;
[75]478 resultType = *pVar;
479 pSubScripts=pVar->GetSubScriptsPtr();
480 bConst = pVar->IsConst();
[3]481
482 goto ok;
483 }
484 }
485
486
487 if(pobj_CompilingClass){
488 //////////////////////
489 // クラスメンバの参照
490 //////////////////////
491
492 if(lstrcmpi(variable,"This")==0){
493 //自身のオブジェクトのThisポインタをr11にコピー
494 SetThisPtrToReg(REG_R11);
495
496 pRelativeVar->dwKind=VAR_DIRECTMEM;
497
[75]498 resultType.SetType( DEF_OBJECT, pobj_CompilingClass );
499 return true;
[3]500 }
501
502 if(memicmp(variable,"This.",5)==0){
503 //Thisオブジェクトのメンバを参照するとき
504 SlideString(variable+5,-5);
505 lstrcpy(VarName,variable);
506 }
507 else{
508 //クラス内メンバを参照するとき(通常)
509
510 for(i=0;i<pobj_CompilingClass->iMemberNum;i++){
511 if(lstrcmp(VarName,pobj_CompilingClass->ppobj_Member[i]->name)==0) break;
512 }
513 if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember;
514 }
515
[18]516 //Const修飾子のメソッド内でメンバ書き込みアクセスが発生したとき
517 //(コンストラクタ、デストラクタ内を除く)
518 CMethod *pMethod = pobj_DBClass->GetNowCompilingMethodInfo();
519 if( isWriteAccess &&
520 pMethod->isConst &&
521 pobj_CompilingClass->IsCompilingConstructor() == false &&
522 pobj_CompilingClass->IsCompilingDestructor() == false
523 ){
524 SetError(131, NULL, cp );
525 }
526
[3]527 //自身のオブジェクトのThisポインタをr11にコピー
528 SetThisPtrToReg(REG_R11);
529
530 pRelativeVar->dwKind=VAR_DIRECTMEM;
[75]531 if(!_member_offset(
[17]532 isErrorEnabled,
533 isWriteAccess,
[75]534 *pobj_CompilingClass,
[17]535 variable,
536 pRelativeVar,
[75]537 resultType,1)) return false;
538 return true;
[3]539 }
540
541NonClassMember:
542
[75]543 {
544 const Variable *pVar;
[3]545
[75]546 //////////////////////////
547 // 静的ローカル変数
548 // ※"Static.Object.Method.Variable"
549 //////////////////////////
[3]550
[75]551 char temporary[VN_SIZE];
552 if( UserProc::IsLocalAreaCompiling() ){
553 GetNowStaticVarFullName(VarName,temporary);
554
555 pVar = globalVars.Find( temporary );
556 if( pVar ){
557 goto GlobalOk;
558 }
[3]559 }
560
561
[75]562 //////////////////////////
563 // クラスの静的メンバ
564 //////////////////////////
[3]565
[75]566 if(member[0]){
567 lstrcpy(temporary,member);
[3]568
[75]569 char tempMember[VN_SIZE];
570 char tempArray[VN_SIZE];
571 {
572 CClass::RefType refType;
573 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember, refType );
574 }
[27]575
[75]576 char temp2[VN_SIZE];
577 sprintf(temp2,"%s.%s",VarName,temporary);
578 pVar = globalVars.Find( temp2 );
579 if( pVar ){
580 lstrcpy(member,tempMember);
581 lstrcpy(array,tempArray);
582 goto GlobalOk;
583 }
[3]584 }
585
[75]586 if(pobj_CompilingClass){
587 //自身のクラスから静的メンバを参照する場合
588 char temp2[VN_SIZE];
589 sprintf(temp2,"%s.%s",pobj_CompilingClass->name,VarName);
590 pVar = globalVars.Find( temp2 );
591 if( pVar ){
592 goto GlobalOk;
593 }
[3]594 }
595
[75]596 /////////////////////
597 // グローバル変数
598 /////////////////////
[3]599
[75]600 pVar = globalVars.BackSearch( VarName );
601 if( pVar ){
[3]602 goto GlobalOk;
603 }
604
[75]605 if(isErrorEnabled) SetError(3,variable,cp);
606 pRelativeVar->dwKind=NON_VAR;
607 return false;
[27]608
609
[3]610
611GlobalOk:
[75]612 //ポインタ変数の場合
613 if( pVar->IsPointer() ){
614 if( !pVar->IsArray() ){
615 lstrcpy(lpPtrOffset,array);
616 array[0]=0;
617 }
[3]618 }
[75]619 else{
620 if(lpPtrOffset[0]){
621 SetError(16,variable,cp);
622 pRelativeVar->dwKind=NON_VAR;
623 return false;
624 }
[3]625 }
626
[75]627 pRelativeVar->offset=pVar->offset;
628 pRelativeVar->bOffsetOffset=0;
629 if( pVar->IsRef() ){
630 // 参照型
631 pRelativeVar->dwKind = VAR_REFGLOBAL;
632 }
633 else pRelativeVar->dwKind=VAR_GLOBAL;
634 resultType = *pVar;
635 pSubScripts=pVar->GetSubScriptsPtr();
636 bConst = pVar->IsConst();
[62]637 }
[3]638
639
640
641ok:
642
[18]643 if( bConst && isWriteAccess ){
[11]644 //Const定義の変数に書き込みアクセスをしようとした場合
[75]645 if( resultType.IsObject() ){
[18]646 //オブジェクト定数
647 SetError(130, VarName, cp );
648 }
649 else{
650 //一般のConst変数
651 SetError(61,VarName,cp);
652 }
[11]653 }
[3]654
655 if(array[0]==0&&pSubScripts[0]!=-1){
656 //配列の先頭ポインタを示す場合
[75]657 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
[3]658 if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM);
[75]659 return true;
[3]660 }
661
[49]662 if( array[0] || member[0] ){
[3]663 //xor r11,r11(r11を0に初期化する)
664 //※r11は変数ベースアドレスからの相対オフセットを示す
665 op_zero_reg(REG_R11);
666
667 pRelativeVar->bOffsetOffset=1;
668 }
669 if(array[0]){
[75]670 if(!GetArrayOffset(pSubScripts,array,resultType)){
[3]671 SetError(14,variable,cp);
672 pRelativeVar->dwKind=NON_VAR;
[75]673 return false;
[3]674 }
675 }
676 if(member[0]){
[75]677 if( resultType.IsObject() || resultType.IsStruct() ){
[3]678 //実態オブジェクトのメンバを参照(obj.member)
[64]679 if( refType != CClass::Dot ){
[3]680 SetError(104,VarName,cp);
681 pRelativeVar->dwKind=NON_VAR;
[75]682 return false;
[3]683 }
[64]684
[75]685 if( resultType.IsObject() ){
[64]686 // 参照内容へのポインタを抽出
687 SetRelativeOffset( *pRelativeVar );
688 }
[3]689 }
[75]690 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
[3]691 //ポインタオブジェクトが示すメンバを参照
692 if(lpPtrOffset[0]){
693 //pObj[n].member
[64]694 if( refType != CClass::Dot ){
[3]695 SetError(104,VarName,cp);
696 pRelativeVar->dwKind=NON_VAR;
[75]697 return false;
[3]698 }
[75]699 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
[3]700 pRelativeVar->dwKind=VAR_DIRECTMEM;
701 }
702 else{
703 //pObj->member
[64]704 if( refType != CClass::Pointer ){
[3]705 SetError(104,VarName,cp);
706 pRelativeVar->dwKind=NON_VAR;
[75]707 return false;
[3]708 }
709
710 SetVarPtrToReg(REG_R12,pRelativeVar);
711 pRelativeVar->dwKind=VAR_DIRECTMEM;
712
713 //mov r11,qword ptr[r12]
714 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
715 }
716 }
[75]717 else if( resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_STRUCT,2)){
[3]718 //ポインタオブジェクトが示すメンバを参照
719 if(lpPtrOffset[0]){
720 //ppObj[n]->member
[64]721 if( refType != CClass::Pointer ){
[3]722 SetError(104,VarName,cp);
723 pRelativeVar->dwKind=NON_VAR;
[75]724 return false;
[3]725 }
726
[75]727 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
[3]728 pRelativeVar->dwKind=VAR_DIRECTMEM;
729
730
731 SetVarPtrToReg(REG_R12,pRelativeVar);
732
733 //mov r11,qword ptr[r12]
734 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
735 }
736 else{
737 SetError(104,VarName,cp);
738 pRelativeVar->dwKind=NON_VAR;
[75]739 return false;
[3]740 }
741 }
742 else{
743 SetError(102,VarName,cp);
744 pRelativeVar->dwKind=NON_VAR;
[75]745 return false;
[3]746 }
[17]747
[75]748 if(!_member_offset(
[17]749 isErrorEnabled,
750 isWriteAccess,
[75]751 resultType.GetClass(),
752 member,pRelativeVar,resultType,0)) return false;
[17]753
[75]754 return true;
[3]755 }
756
757 if(lpPtrOffset[0]){
[75]758 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
[3]759 pRelativeVar->dwKind=VAR_DIRECTMEM;
760 }
761
[75]762 return true;
[3]763}
764
[75]765bool SetInitGlobalData(int offset,const Type &type,const int *SubScripts,char *InitBuf){
[3]766 extern BYTE *initGlobalBuf;
[75]767 int i,i2,i3;
[3]768 char temporary[VN_SIZE];
769
770 if(InitBuf[0]=='['){
771 SlideString(InitBuf+1,-1);
772 InitBuf[lstrlen(InitBuf)-1]=0;
773
[75]774 int typeSize = type.GetSize();
[3]775
776 if(SubScripts[0]!=-1){
[75]777 typeSize*=JumpSubScripts(SubScripts+1);
[3]778 i=0;
779 i2=0;
780 while(1){
781 if(SubScripts[0]<i2){
782 SetError(41,0,cp);
783 return 0;
784 }
785 i=GetOneParameter(InitBuf,i,temporary);
786 if(!SetInitGlobalData(
[75]787 offset+i2*typeSize,
[3]788 type,
789 SubScripts+1,
[75]790 temporary)) return false;
[3]791 i2++;
792 if(InitBuf[i]=='\0') break;
793 }
[75]794 return true;
[3]795 }
796
[75]797 if(type.IsStruct()){
798 const CClass &objClass = type.GetClass();
[3]799
[75]800 for(i=0,i2=0;i2<objClass.iMemberNum;i2++){
[3]801 i=GetOneParameter(InitBuf,i,temporary);
802
[75]803 i3=objClass.GetMemberOffset( objClass.ppobj_Member[i2]->name, NULL );
[3]804
805 if(!SetInitGlobalData(offset+i3,
[75]806 *objClass.ppobj_Member[i2],
807 objClass.ppobj_Member[i2]->SubScripts,
808 temporary)) return false;
[3]809
810 if(InitBuf[i]=='\0') break;
811 }
[75]812 if(i2+1!=objClass.iMemberNum){
[3]813 SetError(41,0,cp);
[75]814 return false;
[3]815 }
[75]816 return true;
[3]817 }
818
819 SetError(41,0,cp);
[75]820 return false;
[3]821 }
822
[20]823
824 ///////////////////////////////////////
825 // 単発式([]で囲まれていない)
826 ///////////////////////////////////////
827
[75]828 if( type.IsObject() || type.IsStruct() ){
[64]829 //オブジェクトまたは構造体の場合はありえない
[20]830 SetError(300,NULL,cp);
[75]831 return false;
[20]832 }
833
[3]834 if(SubScripts[0]!=-1){
835 SetError(41,0,cp);
[75]836 return false;
[3]837 }
838
839 double dbl;
840 _int64 i64data;
[75]841 Type calcType;
[3]842
[75]843 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
[9]844 //動的データだった場合
[75]845 return false;
[9]846 }
[75]847 if( calcType.IsReal() ){
[3]848 memcpy(&dbl,&i64data,sizeof(double));
849 i64data=(_int64)dbl;
850 }
851 else dbl=(double)i64data;
852
853 //型チェック
854 CheckDifferentType(
855 type,
[75]856 calcType,
[3]857 0,0);
858
[75]859 if( type.IsDouble() ){
[3]860 *(double *)(initGlobalBuf+offset)=(double)dbl;
[75]861 }
862 else if( type.IsSingle() ){
863 *(float *)(initGlobalBuf+offset)=(float)dbl;
864 }
865 else if( type.Is64() || type.IsPointer() ){
866 if(type.GetBasicType()==typeOfPtrChar && type.GetIndex()==LITERAL_STRING){
[3]867 //文字列定数のとき
868
869 char *temp;
870 temp=(char *)i64data;
[56]871 i2=dataTable.AddString( temp );
[3]872 HeapDefaultFree(temp);
873
874 //mov rax,DataPos
875 op_mov_RV(sizeof(_int64),REG_RAX,i2);
876 obp-=sizeof(long);
877 pobj_DataTableSchedule->add();
878 obp+=sizeof(long);
879
880 //mov qword ptr[offset],rax
881 op_mov_MR(sizeof(_int64),REG_RAX,0,offset,MOD_DISP32);
882 obp-=sizeof(long);
883 pobj_GlobalVarSchedule->add();
884 obp+=sizeof(long);
885 }
886 else{
887 *(_int64 *)(initGlobalBuf+offset)=i64data;
888 }
889 }
[75]890 else if( type.IsDWord() || type.IsLong() ){
[3]891 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
[75]892 }
893 else if( type.IsWord() || type.IsInteger() ){
[3]894 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
[75]895 }
896 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[3]897 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
[75]898 }
[3]899
[75]900 return true;
[3]901}
[75]902bool InitLocalVar(int offset,const Type &type,const int *SubScripts,char *InitBuf){
903 int i,i2,i3;
[3]904 char temporary[VN_SIZE];
905
906 if(InitBuf[0]=='['){
907 SlideString(InitBuf+1,-1);
908 InitBuf[lstrlen(InitBuf)-1]=0;
909
[75]910 int typeSize = type.GetSize();
[3]911
912 if(SubScripts[0]!=-1){
[75]913 typeSize*=JumpSubScripts(SubScripts+1);
[3]914 i=0;
915 i2=0;
916 while(1){
917 if(SubScripts[0]<i2){
918 SetError(41,0,cp);
[75]919 return false;
[3]920 }
921 i=GetOneParameter(InitBuf,i,temporary);
922 if(!InitLocalVar(
[75]923 offset+i2*typeSize,
[3]924 type,
925 SubScripts+1,
[75]926 temporary)) return false;
[3]927 i2++;
928 if(InitBuf[i]=='\0') break;
929 }
[75]930 return true;
[3]931 }
932
[75]933 if(type.IsStruct()){
934 const CClass &objClass = type.GetClass();
[3]935
[75]936 for(i=0,i2=0;i2<objClass.iMemberNum;i2++){
[3]937 i=GetOneParameter(InitBuf,i,temporary);
938
[75]939 i3=objClass.GetMemberOffset( objClass.ppobj_Member[i2]->name, NULL );
[3]940
941 if(!InitLocalVar(offset+i3,
[75]942 *objClass.ppobj_Member[i2],
943 objClass.ppobj_Member[i2]->SubScripts,
944 temporary)) return false;
[3]945
946 if(InitBuf[i]=='\0') break;
947 }
[75]948 if(i2+1!=objClass.iMemberNum){
[3]949 SetError(41,0,cp);
950 return 0;
951 }
[75]952 return true;
[3]953 }
954
955 SetError(41,0,cp);
[75]956 return false;
[3]957 }
958
[41]959
960 ///////////////////////////////////////
961 // 単発式([]で囲まれていない)
962 ///////////////////////////////////////
963
[3]964 if(SubScripts[0]!=-1){
965 SetError(41,0,cp);
[75]966 return false;
[3]967 }
968
969 double dbl;
970 _int64 i64data;
[75]971 Type calcType;
972
973 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
[9]974 //動的データだった場合
[75]975 return false;
[9]976 }
[75]977 if( calcType.IsReal() ){
[3]978 memcpy(&dbl,&i64data,sizeof(double));
979 i64data=(_int64)dbl;
980 }
981 else dbl=(double)i64data;
982
983 //型チェック
984 CheckDifferentType(
985 type,
[75]986 calcType,
[3]987 0,0);
988
[75]989 if( type.IsDouble() ){
[3]990 memcpy(&i64data,&dbl,sizeof(double));
991
992 //mov rax,i64data
993 op_mov64_ToReg(REG_RAX,i64data);
994
995 //mov qword ptr[rsp+offset],rax
996 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
997 obp-=sizeof(long);
998 AddLocalVarAddrSchedule();
999 obp+=sizeof(long);
1000 }
[75]1001 else if( type.IsSingle() ){
[3]1002 float flt;
1003 flt=(float)dbl;
1004
1005 //mov dword ptr[rsp+offset],value
1006 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,*(int *)&flt);
1007 obp-=sizeof(long)+sizeof(long);
1008 AddLocalVarAddrSchedule();
1009 obp+=sizeof(long)+sizeof(long);
1010 }
[75]1011 else if( type.Is64() || type.IsPointer() ){
1012 if(type.GetBasicType()==typeOfPtrChar && type.GetIndex()==LITERAL_STRING){
[3]1013 //文字列定数のとき
1014
1015 char *temp;
1016 temp=(char *)i64data;
[56]1017 i2=dataTable.AddString( temp );
[3]1018 HeapDefaultFree(temp);
1019
1020 //mov rax,i2
1021 op_mov_RV(sizeof(_int64),REG_RAX,i2);
1022 obp-=sizeof(long);
1023 pobj_DataTableSchedule->add();
1024 obp+=sizeof(long);
1025
1026 //mov qword ptr[rsp+offset],rax
1027 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1028 obp-=sizeof(long);
1029 AddLocalVarAddrSchedule();
1030 obp+=sizeof(long);
1031 }
1032 else{
1033 if(i64data&0xFFFFFFFF00000000){
1034 //mov rax,i64data
1035 op_mov64_ToReg(REG_RAX,i64data);
1036
1037 //mov qword ptr[rsp+offset],rax
1038 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1039 obp-=sizeof(long);
1040 AddLocalVarAddrSchedule();
1041 obp+=sizeof(long);
1042 }
1043 else{
1044 //mov qword ptr[rsp+offset],value
1045 op_mov_MV(sizeof(_int64),REG_RSP,offset,USE_OFFSET,(int)i64data);
1046 obp-=sizeof(long)+sizeof(long);
1047 AddLocalVarAddrSchedule();
1048 obp+=sizeof(long)+sizeof(long);
1049 }
1050 }
1051 }
[75]1052 else if( type.IsDWord() || type.IsLong() ){
[3]1053 //mov dword ptr[rsp+offset],value
1054 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,(int)i64data);
1055 obp-=sizeof(long)+sizeof(long);
1056 AddLocalVarAddrSchedule();
1057 obp+=sizeof(long)+sizeof(long);
1058 }
[75]1059 else if( type.IsWord() || type.IsInteger() ){
[3]1060 //mov word ptr[rsp+offset],value
1061 op_mov_MV(sizeof(short),REG_RSP,offset,USE_OFFSET,(int)i64data);
1062 obp-=sizeof(long)+sizeof(short);
1063 AddLocalVarAddrSchedule();
1064 obp+=sizeof(long)+sizeof(short);
1065 }
[75]1066 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[3]1067 //mov byte ptr[rsp+offset],value
1068 op_mov_MV(sizeof(char),REG_RSP,offset,USE_OFFSET,(int)i64data);
1069 obp-=sizeof(long)+sizeof(char);
1070 AddLocalVarAddrSchedule();
1071 obp+=sizeof(long)+sizeof(char);
1072 }
[75]1073 return true;
[3]1074}
1075
[79]1076void dim( char *VarName,int *SubScripts,Type &type,char *InitBuf,char *ConstractParameter,DWORD dwFlags){
[75]1077 if( UserProc::IsGlobalAreaCompiling() ){
[64]1078 /////////////////////////
1079 // グローバル変数
1080 /////////////////////////
[3]1081
[79]1082 AddGlobalVariable(VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags);
[64]1083 }
1084 else{
1085 /////////////////
1086 // ローカル変数
1087 /////////////////
1088
[75]1089 if( UserProc::CompilingUserProc().localVars.DuplicateCheck( VarName ) ){
1090 //2重定義のエラー
1091 SetError(15,VarName,cp);
1092 return;
[64]1093 }
1094
[75]1095 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
[64]1096
[79]1097 Variable *pVar = new Variable( VarName, type, isConst );
[75]1098
1099 if( SubScripts[0] != -1 ){
1100 //配列あり
1101 pVar->SetArray( SubScripts );
[64]1102 }
1103
[75]1104 //コンストラクタ用パラメータ
1105 pVar->paramStrForConstructor = ConstractParameter;
[64]1106
[75]1107 //レキシカルスコープ
1108 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1109 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1110 pVar->bLiving=TRUE;
[64]1111
[75]1112 //エラー用
1113 pVar->source_code_address=cp;
[64]1114
[75]1115 // 変数を追加
1116 UserProc::CompilingUserProc().localVars.push_back( pVar );
1117
[64]1118 //アラインメントを考慮
[75]1119 if( pVar->IsStruct() ){
1120 int alignment = pVar->GetClass().iAlign;
[64]1121 if( alignment ){
1122 if( AllLocalVarSize % alignment ){
1123 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1124 }
1125 }
1126 }
1127
[75]1128 AllLocalVarSize += pVar->GetMemorySize();
1129 pVar->offset = AllLocalVarSize;
[64]1130
1131 //レキシカルスコープ
1132 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1133 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1134 pVar->bLiving=TRUE;
1135
1136 if(InitBuf[0]){
1137 //初期代入時のみ、書き込みアクセスを許可する
[75]1138 if( isConst ){
1139 pVar->ConstOff();
1140 }
[64]1141
1142 int result = 0;
[75]1143 if( !pVar->IsObject() ){
[64]1144 result = InitLocalVar(-pVar->offset,
[75]1145 *pVar,
1146 pVar->GetSubScriptsPtr(),
[64]1147 InitBuf);
1148 }
1149
1150 if(!result){
1151 //動的な式だった場合は代入演算を行う
1152 char temporary[8192];
1153 sprintf(temporary,"%s=%s",VarName,InitBuf);
1154 OpcodeCalc(temporary);
1155 }
1156
[75]1157 if( isConst ){
1158 pVar->ConstOn();
1159 }
[64]1160 }
1161 else{
1162 //0初期化
1163
1164 //mov r8, 0
1165 op_zero_reg( REG_R8 );
1166
1167 //mov rdx, VarSize
[75]1168 op_mov_RV( sizeof(_int64), REG_RDX, pVar->GetMemorySize() );
[64]1169
1170 //mov rcx, rsp
1171 op_mov_RR( REG_RCX, REG_RSP );
1172
1173 //add rcx, offset
1174 op_add_RV( REG_RCX, -pVar->offset );
1175 obp-=sizeof(long);
1176 AddLocalVarAddrSchedule();
1177 obp+=sizeof(long);
1178
1179 //call FillMemory
[75]1180 DllProc *pDllProc;
1181 pDllProc=GetDeclareHash("FillMemory");
1182 op_call( pDllProc );
[64]1183 }
1184 }
1185
1186 //コンストラクタ呼び出し
[75]1187 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
[64]1188 char objectSize[255];
1189 if( SubScripts[0] == -1 ){
1190 objectSize[0] = 0;
1191 }
1192 else{
1193 if( SubScripts[1] != -1 ){
1194 SetError(300,NULL,cp);
1195 }
1196 sprintf( objectSize, "%d", SubScripts[0] );
1197 }
[75]1198 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
[64]1199
[75]1200 Type tempType;
[64]1201 RELATIVE_VAR RelativeVar;
[75]1202 GetVarOffset( true, false, VarName, &RelativeVar, tempType );
[64]1203 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1204 SetError();
1205 }
1206 SetVariableFromRax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1207 }
1208
[75]1209 if( type.IsObject() ){
1210 if( type.GetClass().IsAbstract() ){
[64]1211 //抽象クラスだったとき
[75]1212 SetError(125,type.GetClass().name,cp);
[64]1213 }
1214 }
1215}
[3]1216void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1217 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1218
1219 if(pRelativeVar->dwKind==VAR_GLOBAL){
1220 if(pRelativeVar->bOffsetOffset){
1221 //add r11,offset
1222 OpBuffer[obp++]=(char)0x49;
1223 OpBuffer[obp++]=(char)0x81;
1224 OpBuffer[obp++]=(char)0xC3;
1225 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1226 pobj_GlobalVarSchedule->add();
1227 obp+=sizeof(long);
1228
1229 //mov reg,r11
[64]1230 op_mov_RR(reg,REG_R11);
[3]1231 }
1232 else{
1233 //mov reg,offset
1234 op_mov64_ToReg(reg,(int)pRelativeVar->offset);
1235 obp-=sizeof(long);
1236 pobj_GlobalVarSchedule->add();
1237 obp+=sizeof(long);
1238 }
1239 }
[62]1240 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
1241 if(pRelativeVar->bOffsetOffset){
1242 //add r11,qword ptr[offset]
1243 op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelativeVar->offset, MOD_DISP32 );
1244 obp-=sizeof(long);
1245 pobj_GlobalVarSchedule->add();
1246 obp+=sizeof(long);
1247 }
1248 else{
1249 //mov r11,qword ptr[offset]
1250 op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelativeVar->offset,MOD_DISP32);
1251 obp-=sizeof(long);
1252 pobj_GlobalVarSchedule->add();
1253 obp+=sizeof(long);
1254 }
1255
1256 goto directmem;
1257 }
[3]1258 else if(pRelativeVar->dwKind==VAR_LOCAL){
1259 if(pRelativeVar->bOffsetOffset){
1260 //add r11,offset
1261 OpBuffer[obp++]=(char)0x49;
1262 OpBuffer[obp++]=(char)0x81;
1263 OpBuffer[obp++]=(char)0xC3;
1264 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1265 AddLocalVarAddrSchedule();
1266 obp+=sizeof(long);
1267
1268 //add r11,rsp
1269 op_add64_reg(REG_R11,REG_RSP);
1270
1271 //mov reg,r11
[64]1272 op_mov_RR(reg,REG_R11);
[3]1273 }
1274 else{
1275 //mov reg,rsp
[64]1276 op_mov_RR(reg,REG_RSP);
[3]1277
1278 //add reg,offset
[64]1279 op_add_RV(reg,(int)pRelativeVar->offset);
[3]1280 obp-=sizeof(long);
1281 AddLocalVarAddrSchedule();
1282 obp+=sizeof(long);
1283 }
1284 }
[40]1285 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
[3]1286 if(pRelativeVar->bOffsetOffset){
1287 //add r11,qword ptr[rsp+offset]
1288 OpBuffer[obp++]=(char)0x4C;
1289 OpBuffer[obp++]=(char)0x03;
1290 OpBuffer[obp++]=(char)0x9C;
1291 OpBuffer[obp++]=(char)0x24;
1292 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1293 AddLocalVarAddrSchedule();
1294 obp+=sizeof(long);
1295 }
1296 else{
1297 //mov r11,qword ptr[rsp+offset]
1298 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
1299 obp-=sizeof(long);
1300 AddLocalVarAddrSchedule();
1301 obp+=sizeof(long);
1302 }
1303
1304 goto directmem;
1305 }
1306 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1307directmem:
1308 //mov reg,r11
[64]1309 op_mov_RR(reg,REG_R11);
[3]1310 }
1311}
Note: See TracBrowser for help on using the repository browser.