source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Var.cpp@ 641

Last change on this file since 641 was 641, checked in by dai_9181, 16 years ago

・デバッグトレース時、グローバル領域の終端行でステップインまたはステップアウトしたときにデバッグ情報の取得に失敗して強制終了してしまう不具合を修正。
・グローバル領域のデバッグ実行ができなくなっている不具合を修正。

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