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