source: dev/BasicCompiler32/Compile_Var.cpp@ 76

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

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

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