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

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

ObjectModuleに関連するクラス一式をab_commonプロジェクトに移動した。

File size: 35.9 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
[598]542 int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex(
543 LexicalAnalyzer::FullNameToSymbol( VarName )
544 );
[116]545 if( typeDefIndex != -1 ){
546 // TypeDef後の型名だったとき
[265]547 lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
[116]548 }
549
[75]550 char temp2[VN_SIZE];
551 sprintf(temp2,"%s.%s",VarName,temporary);
[508]552 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
[75]553 if( pVar ){
554 lstrcpy(member,tempMember);
555 lstrcpy(array,tempArray);
556 goto GlobalOk;
557 }
[3]558 }
559
[536]560 if( compiler.IsCompilingClass() ){
[75]561 //自身のクラスから静的メンバを参照する場合
562 char temp2[VN_SIZE];
[536]563 sprintf(temp2,"%s.%s",compiler.GetCompilingClass().GetName().c_str(),VarName);
[508]564 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
[75]565 if( pVar ){
566 goto GlobalOk;
567 }
[3]568 }
569
[75]570 /////////////////////
571 // グローバル変数
572 /////////////////////
[3]573
[570]574 pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch(
575 LexicalAnalyzer::FullNameToSymbol( VarName ),
576 compiler.codeGenerator.lexicalScopes.GetNowLevel()
577 );
[75]578 if( pVar ){
[3]579 goto GlobalOk;
580 }
581
[465]582 if(isErrorEnabled) compiler.errorMessenger.Output(3,variable,cp);
[75]583 pRelativeVar->dwKind=NON_VAR;
584 return false;
[27]585
586
587
[3]588GlobalOk:
[75]589 //ポインタ変数の場合
[206]590 if( pVar->GetType().IsPointer() ){
[75]591 if( !pVar->IsArray() ){
592 lstrcpy(lpPtrOffset,array);
593 array[0]=0;
594 }
[3]595 }
[75]596 else{
597 if(lpPtrOffset[0]){
[465]598 compiler.errorMessenger.Output(16,variable,cp);
[75]599 pRelativeVar->dwKind=NON_VAR;
600 return false;
601 }
[3]602 }
603
[206]604 pRelativeVar->offset=pVar->GetOffsetAddress();
[75]605 pRelativeVar->bOffsetOffset=0;
606 if( pVar->IsRef() ){
607 // 参照型
608 pRelativeVar->dwKind = VAR_REFGLOBAL;
609 }
610 else pRelativeVar->dwKind=VAR_GLOBAL;
[206]611 resultType = pVar->GetType();
612 pSubscripts=&pVar->GetSubscripts();
[75]613 bConst = pVar->IsConst();
[62]614 }
[3]615
616
[75]617
[3]618ok:
619
[18]620 if( bConst && isWriteAccess ){
[11]621 //Const定義の変数に書き込みアクセスをしようとした場合
[75]622 if( resultType.IsObject() ){
[18]623 //オブジェクト定数
[465]624 compiler.errorMessenger.Output(130, VarName, cp );
[18]625 }
626 else{
627 //一般のConst変数
[465]628 compiler.errorMessenger.Output(61,VarName,cp);
[18]629 }
[11]630 }
[3]631
[206]632 if( array[0] == 0 && pSubscripts->size() > 0 ){
[3]633 //配列の先頭ポインタを示す場合
[75]634 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
[206]635
636 if( pResultSubscripts )
637 {
638 (*pResultSubscripts) = *pSubscripts;
639 }
[75]640 return true;
[3]641 }
642
643 if(array[0]||member[0]){
644 //xor ecx,ecx(ecxを0に初期化する)
645 //※ecxは変数ベースアドレスからの相対オフセットを示す
[225]646 compiler.codeGenerator.op_zero_reg(REG_ECX);
[3]647
648 pRelativeVar->bOffsetOffset=1;
649 }
650 if(array[0]){
[206]651 if(!GetArrayOffset(*pSubscripts,array,resultType)){
[465]652 compiler.errorMessenger.Output(14,variable,cp);
[3]653 pRelativeVar->dwKind=NON_VAR;
[75]654 return false;
[3]655 }
656 }
657 if(member[0]){
[75]658 if( resultType.IsObject() || resultType.IsStruct() ){
[3]659 //実態オブジェクトのメンバを参照(obj.member)
[206]660 if( refType != RefDot ){
[465]661 compiler.errorMessenger.Output(104,VarName,cp);
[3]662 pRelativeVar->dwKind=NON_VAR;
[75]663 return false;
[3]664 }
[64]665
[75]666 if( resultType.IsObject() ){
[64]667 // 参照内容へのポインタを抽出
668 SetRelativeOffset( *pRelativeVar );
669 }
[3]670 }
[75]671 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
[3]672 //ポインタオブジェクトが示すメンバを参照
673 if(lpPtrOffset[0]){
674 //pObj[n].member
[206]675 if( refType != RefDot ){
[465]676 compiler.errorMessenger.Output(104,VarName,cp);
[3]677 pRelativeVar->dwKind=NON_VAR;
[75]678 return false;
[3]679 }
[75]680 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
[3]681 pRelativeVar->dwKind=VAR_DIRECTMEM;
682 }
683 else{
684 //pObj->member
[206]685 if( refType != RefPointer ){
[465]686 compiler.errorMessenger.Output(104,VarName,cp);
[3]687 pRelativeVar->dwKind=NON_VAR;
[75]688 return false;
[3]689 }
690
691 SetVarPtrToEax(pRelativeVar);
692 pRelativeVar->dwKind=VAR_DIRECTMEM;
693
694 //mov ecx,dword ptr[eax]
[241]695 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
[3]696 }
697 }
[75]698 else if( resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_STRUCT,2)){
[3]699 //ポインタオブジェクトが示すメンバを参照
700 if(lpPtrOffset[0]){
701 //ppObj[n]->member
[206]702 if( refType != RefPointer ){
[465]703 compiler.errorMessenger.Output(104,VarName,cp);
[3]704 pRelativeVar->dwKind=NON_VAR;
[75]705 return false;
[3]706 }
707
[75]708 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
[3]709 pRelativeVar->dwKind=VAR_DIRECTMEM;
710
711
712 SetVarPtrToEax(pRelativeVar);
713
714 //mov ecx,dword ptr[eax]
[241]715 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
[3]716 }
717 else{
[465]718 compiler.errorMessenger.Output(104,VarName,cp);
[3]719 pRelativeVar->dwKind=NON_VAR;
[75]720 return false;
[3]721 }
722 }
723 else{
[465]724 compiler.errorMessenger.Output(102,VarName,cp);
[3]725 pRelativeVar->dwKind=NON_VAR;
[75]726 return false;
[3]727 }
[17]728
[301]729 Type classType( resultType );
730
[75]731 if(!_member_offset(
[17]732 isErrorEnabled,
733 isWriteAccess,
[301]734 classType,
[75]735 member,pRelativeVar,resultType,0)) return false;
[17]736
[75]737 return true;
[3]738 }
739
740 if(lpPtrOffset[0]){
[75]741 SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
[3]742 pRelativeVar->dwKind=VAR_DIRECTMEM;
743 }
744
[75]745 return true;
[3]746}
747
[206]748bool SetInitGlobalData(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
[140]749 int i2,i3;
[3]750 char temporary[VN_SIZE];
[138]751 char InitBuf[VN_SIZE];
752 lstrcpy( InitBuf, lpszInitBuf );
[3]753
754 if(InitBuf[0]=='['){
755 SlideString(InitBuf+1,-1);
756 InitBuf[lstrlen(InitBuf)-1]=0;
757
[75]758 int typeSize = type.GetSize();
[3]759
[206]760 if( subscripts.size() > 0 ){
761 Subscripts nestSubscripts;
762 for( int i=1; i<(int)subscripts.size(); i++ )
763 {
764 nestSubscripts.push_back( subscripts[i] );
765 }
766
767 typeSize*=JumpSubScripts( nestSubscripts );
768 {
769 int i=0;
770 i2=0;
771 while(1){
772 if( subscripts[0] < i2 ){
[465]773 compiler.errorMessenger.Output(41,0,cp);
[206]774 return 0;
775 }
776 i=GetOneParameter(InitBuf,i,temporary);
777 if(!SetInitGlobalData(
778 offset+i2*typeSize,
779 type,
780 nestSubscripts,
781 temporary)) return false;
782 i2++;
783 if(InitBuf[i]=='\0') break;
[3]784 }
785 }
[75]786 return true;
[3]787 }
788
[75]789 if(type.IsStruct()){
790 const CClass &objClass = type.GetClass();
[3]791
[140]792 int i = 0;
[561]793 BOOST_FOREACH( Member *pMember, objClass.GetDynamicMembers() ){
[140]794 if(InitBuf[i]=='\0'){
[465]795 compiler.errorMessenger.Output(41,0,cp);
[140]796 return false;
797 }
798
[3]799 i=GetOneParameter(InitBuf,i,temporary);
800
[409]801 i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
[3]802
803 if(!SetInitGlobalData(offset+i3,
[140]804 pMember->GetType(),
[206]805 pMember->GetSubscripts(),
[75]806 temporary)) return false;
[3]807 }
[75]808 return true;
[3]809 }
810
[465]811 compiler.errorMessenger.Output(41,0,cp);
[75]812 return false;
[3]813 }
814
[20]815
816 ///////////////////////////////////////
817 // 単発式([]で囲まれていない)
818 ///////////////////////////////////////
819
[206]820 if( subscripts.size() > 0 ){
[465]821 compiler.errorMessenger.Output(41,0,cp);
[75]822 return false;
[3]823 }
824
825 double dbl;
826 _int64 i64data;
[75]827 Type calcType;
828
829 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
830 //動的データだった場合
831 return false;
832 }
833 if( calcType.IsReal() ){
[3]834 memcpy(&dbl,&i64data,sizeof(double));
835 i64data=(_int64)dbl;
836 }
837 else dbl=(double)i64data;
838
839 //型チェック
840 CheckDifferentType(
841 type,
[75]842 calcType,
[3]843 0,0);
844
[75]845 if( type.IsDouble() ){
[288]846 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
847 offset,
848 (const char *)&dbl,
849 sizeof(double)
850 );
[75]851 }
852 else if( type.IsSingle() ){
[288]853 float flt = (float)dbl;
854 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
855 offset,
856 (const char *)&flt,
857 sizeof(float)
858 );
[75]859 }
860 else if( type.Is64() ){
[288]861 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
862 offset,
863 (const char *)&i64data,
864 sizeof(_int64)
865 );
[75]866 }
867 else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){
[453]868 if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
869 {
[3]870 //文字列定数のとき
871
872 char *temp;
873 temp=(char *)i64data;
[591]874 if( compiler.IsUnicode() )
875 {
876 i2 = compiler.GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( temp ) );
877 }
878 else
879 {
880 i2 = compiler.GetObjectModule().dataTable.AddString( temp );
881 }
[3]882 HeapDefaultFree(temp);
883
884 //mov eax,DataPos
[237]885 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
[3]886
887 //mov dword ptr[offset],eax
[230]888 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
[3]889 }
890 else{
[288]891 long l = (long)i64data;
892 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
893 offset,
894 (const char *)&l,
895 sizeof(long)
896 );
[3]897 }
898 }
[75]899 else if( type.IsWord() || type.IsInteger() ){
[288]900 short s = (short)i64data;
901 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
902 offset,
903 (const char *)&s,
904 sizeof(short)
905 );
[75]906 }
907 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[288]908 char c = (char)i64data;
909 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
910 offset,
911 (const char *)&c,
912 sizeof(char)
913 );
[75]914 }
915
916 return true;
[3]917}
[206]918bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
919 int i2,i3;
[3]920 char temporary[VN_SIZE];
[138]921 char InitBuf[VN_SIZE];
922 lstrcpy( InitBuf, lpszInitBuf );
[3]923
924 if(InitBuf[0]=='['){
925 SlideString(InitBuf+1,-1);
926 InitBuf[lstrlen(InitBuf)-1]=0;
927
[75]928 int typeSize = type.GetSize();
[3]929
[206]930 if( subscripts.size() > 0 ){
931 Subscripts nestSubscripts;
932 for( int i=1; i<(int)subscripts.size(); i++ )
933 {
934 nestSubscripts.push_back( subscripts[i] );
935 }
936
937 typeSize*=JumpSubScripts( nestSubscripts );
938 {
939 int i=0;
940 i2=0;
941 while(1){
942 if( subscripts[0] < i2 ){
[465]943 compiler.errorMessenger.Output(41,0,cp);
[206]944 return 0;
945 }
946 i=GetOneParameter(InitBuf,i,temporary);
947 if(!InitLocalVar(
948 offset+i2*typeSize,
949 type,
950 nestSubscripts,
951 temporary)) return false;
952 i2++;
953 if(InitBuf[i]=='\0') break;
[3]954 }
955 }
[75]956 return true;
[3]957 }
958
[75]959 if(type.IsStruct()){
960 const CClass &objClass = type.GetClass();
[3]961
[140]962 int i = 0;
[561]963 BOOST_FOREACH( Member *pMember, objClass.GetDynamicMembers() ){
[140]964 if(InitBuf[i]=='\0'){
[465]965 compiler.errorMessenger.Output(41,0,cp);
[140]966 return false;
967 }
968
[3]969 i=GetOneParameter(InitBuf,i,temporary);
970
[409]971 i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
[3]972
973 if(!InitLocalVar(offset+i3,
[140]974 pMember->GetType(),
[206]975 pMember->GetSubscripts(),
[75]976 temporary)) return false;
[3]977
978 if(InitBuf[i]=='\0') break;
979 }
[75]980 return true;
[3]981 }
982
[465]983 compiler.errorMessenger.Output(41,0,cp);
[75]984 return false;
[3]985 }
986
[20]987
988 ///////////////////////////////////////
989 // 単発式([]で囲まれていない)
990 ///////////////////////////////////////
991
[206]992 if( subscripts.size() > 0 ){
[465]993 compiler.errorMessenger.Output(41,0,cp);
[75]994 return false;
[3]995 }
996
997 double dbl;
998 _int64 i64data;
[75]999 Type calcType;
1000
1001 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
[8]1002 //動的データだった場合
[75]1003 return false;
[8]1004 }
[75]1005 if( calcType.IsReal() ){
[3]1006 memcpy(&dbl,&i64data,sizeof(double));
1007 i64data=(_int64)dbl;
1008 }
1009 else dbl=(double)i64data;
1010
1011 //型チェック
1012 CheckDifferentType(
1013 type,
[75]1014 calcType,
[3]1015 0,0);
1016
[75]1017 if( type.IsDouble() ){
[3]1018 //mov eax,HILONG(dbl)
[241]1019 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
[3]1020
1021 //mov dword ptr[ebp+offset+sizeof(long)],eax
[253]1022 compiler.codeGenerator.localVarPertialSchedules.push_back(
1023 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1024 );
[3]1025
1026 //mov eax,LOLONG(dbl)
[231]1027 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
[3]1028
1029 //mov dword ptr[ebp+offset],eax
[253]1030 compiler.codeGenerator.localVarPertialSchedules.push_back(
1031 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1032 );
[3]1033 }
[75]1034 else if( type.IsSingle() ){
[3]1035 float flt;
1036 flt=(float)dbl;
[231]1037
[3]1038 //mov eax,InitValue
[231]1039 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
[3]1040
1041 //mov dword ptr[ebp+offset],eax
[253]1042 compiler.codeGenerator.localVarPertialSchedules.push_back(
1043 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1044 );
[3]1045 }
[75]1046 else if( type.Is64() ){
[3]1047 //mov eax,HILONG(i64data)
[231]1048 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
[3]1049
1050 //mov dword ptr[ebp+offset+sizeof(long)],eax
[253]1051 compiler.codeGenerator.localVarPertialSchedules.push_back(
1052 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1053 );
[3]1054
1055 //mov eax,LOLONG(i64data)
[231]1056 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
[3]1057
1058 //mov dword ptr[ebp+offset],eax
[253]1059 compiler.codeGenerator.localVarPertialSchedules.push_back(
1060 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1061 );
[3]1062 }
[75]1063 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
[453]1064 if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
1065 {
[3]1066 //文字列定数のとき
1067
1068 char *temp;
1069 temp=(char *)i64data;
[591]1070 if( compiler.IsUnicode() )
1071 {
1072 i2 = compiler.GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( temp ) );
1073 }
1074 else
1075 {
1076 i2 = compiler.GetObjectModule().dataTable.AddString( temp );
1077 }
[3]1078 HeapDefaultFree(temp);
1079
1080 //mov eax,DataPos
[237]1081 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
[3]1082 }
1083 else{
1084 //mov eax,InitValue
[231]1085 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
[3]1086 }
1087
1088 //mov dword ptr[ebp+offset],eax
[253]1089 compiler.codeGenerator.localVarPertialSchedules.push_back(
1090 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1091 );
[3]1092 }
[75]1093 else if( type.IsWord() || type.IsInteger() ){
[234]1094 //mov word ptr[ebp+offset],InitValue
[253]1095 compiler.codeGenerator.localVarPertialSchedules.push_back(
1096 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1097 );
[3]1098 }
[75]1099 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[3]1100 //mov byte ptr[ebp+offset],InitValue
[253]1101 compiler.codeGenerator.localVarPertialSchedules.push_back(
1102 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1103 );
[3]1104 }
[75]1105
1106 return true;
[3]1107}
1108
[299]1109void dim( char *VarName, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
[537]1110 if( compiler.IsGlobalAreaCompiling() ){
[64]1111 /////////////////////////
1112 // グローバル変数
1113 /////////////////////////
1114
[206]1115 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
[64]1116 }
1117 else{
1118 /////////////////
1119 // ローカル変数
1120 /////////////////
1121
[570]1122 if( compiler.GetCompilingUserProc().GetLocalVars().DuplicateCheck( LexicalAnalyzer::FullNameToSymbol( VarName ), compiler.codeGenerator.lexicalScopes.GetNowLevel() ) ){
[75]1123 //2重定義のエラー
[465]1124 compiler.errorMessenger.Output(15,VarName,cp);
[75]1125 return;
[64]1126 }
1127
[75]1128 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
[64]1129
[580]1130 Variable *pVar = new Variable(
1131 ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( VarName ),
1132 type,
1133 isConst,
1134 false,
1135 ConstractParameter,
1136 false
1137 );
[75]1138
[206]1139 if( subscripts.size() > 0 ){
[75]1140 //配列あり
[206]1141 pVar->SetArray( subscripts );
[64]1142 }
1143
[75]1144 //レキシカルスコープ
[248]1145 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1146 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[392]1147 pVar->isLiving = true;
[75]1148
1149 //エラー用
1150 pVar->source_code_address=cp;
1151
1152 // 変数を追加
[537]1153 compiler.GetCompilingUserProc().GetLocalVars().push_back( pVar );
[75]1154
1155 //アラインメントを考慮
[206]1156 if( pVar->GetType().IsStruct() ){
[233]1157 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
[120]1158
[75]1159 if( alignment ){
1160 if( AllLocalVarSize % alignment ){
1161 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1162 }
1163 }
[120]1164
1165 if( alignment == PTR_SIZE*2 ){
1166 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1167 // (例:CONTEXT構造体など)
1168 // 呼び出し側のオフセットズレを考慮する
1169
[537]1170 if( 0 == ( compiler.GetCompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
[120]1171 AllLocalVarSize += PTR_SIZE;
1172 }
1173 }
[64]1174 }
1175
[75]1176 AllLocalVarSize += pVar->GetMemorySize();
[206]1177 pVar->SetOffsetAddress( AllLocalVarSize );
[64]1178
1179 //レキシカルスコープ
[248]1180 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1181 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[392]1182 pVar->isLiving = true;
[64]1183
1184 if(InitBuf[0]){
1185 //初期代入時のみ、書き込みアクセスを許可する
[75]1186 if( isConst ){
1187 pVar->ConstOff();
1188 }
[64]1189
1190 int result = 0;
[206]1191 if( !pVar->GetType().IsObject() ){
1192 result = InitLocalVar(-pVar->GetOffsetAddress(),
1193 pVar->GetType(),
1194 pVar->GetSubscripts(),
[64]1195 InitBuf);
1196 }
1197
1198 if(!result){
1199 //動的な式だった場合は代入演算を行う
1200 char temporary[8192];
1201 sprintf(temporary,"%s=%s",VarName,InitBuf);
1202 OpcodeCalc(temporary);
1203 }
1204
[75]1205 if( isConst ){
1206 pVar->ConstOn();
1207 }
[64]1208 }
1209 else{
1210 //push 0
[225]1211 compiler.codeGenerator.op_push_V(0);
[64]1212
1213 //push VarSize
[225]1214 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
[64]1215
1216 //mov eax,ebp
[241]1217 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
[64]1218
1219 //add eax,offset
[253]1220 compiler.codeGenerator.localVarPertialSchedules.push_back(
1221 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1222 );
[64]1223
1224 //push eax
[225]1225 compiler.codeGenerator.op_push(REG_EAX);
[64]1226
1227 //call FillMemory
[250]1228 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
[64]1229 }
1230 }
1231
1232 //New呼び出し
[350]1233 if( type.IsObject()
[370]1234 && !type.IsInterface() && !type.IsComInterface()
[350]1235 &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0
1236 &&InitBuf[0]=='\0')
1237 {
[64]1238 char objectSize[255];
[206]1239 if( subscripts.size() == 0 ){
[64]1240 objectSize[0] = 0;
1241 }
1242 else{
[206]1243 if( subscripts.size() > 1 ){
[465]1244 compiler.errorMessenger.Output(300,NULL,cp);
[64]1245 }
[206]1246 sprintf( objectSize, "%d", subscripts[0] );
[64]1247 }
[75]1248 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
[64]1249
1250 //pop eax
[225]1251 compiler.codeGenerator.op_pop( REG_EAX );
[64]1252
1253 RELATIVE_VAR RelativeVar;
[75]1254 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
[64]1255 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
[465]1256 compiler.errorMessenger.OutputFatalError();
[64]1257 }
[290]1258 SetVariableFromEax( Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr() ), DEF_OBJECT, &RelativeVar );
[64]1259 }
1260}
[3]1261
1262void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1263 if(pRelativeVar->dwKind==VAR_GLOBAL){
1264 if(pRelativeVar->bOffsetOffset){
1265 //lea eax,dword ptr[ecx+offset]
[230]1266 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
[3]1267 }
1268 else{
1269 //mov eax,offset
[230]1270 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
[3]1271 }
1272 }
[62]1273 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1274 if(pRelativeVar->bOffsetOffset){
1275 //mov eax,ecx
[241]1276 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[62]1277
1278 //add eax,dword ptr[offset]
[230]1279 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
[62]1280 }
1281 else{
1282 //mov eax,dword ptr[offset]
[230]1283 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
[62]1284 }
1285 }
[3]1286 else if(pRelativeVar->dwKind==VAR_LOCAL){
1287 if(pRelativeVar->bOffsetOffset){
1288 //add ecx,offset
[253]1289 compiler.codeGenerator.localVarPertialSchedules.push_back(
1290 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1291 );
[3]1292
1293 //lea eax,dword ptr[ebp+ecx]
[241]1294 compiler.codeGenerator.PutOld(
1295 (char)0x8D,
1296 (char)0x44,
1297 (char)0x0D,
1298 (char)0x00
1299 );
[3]1300 }
1301 else{
[230]1302 //lea eax,dword ptr[ecx+offset]
[253]1303 compiler.codeGenerator.localVarPertialSchedules.push_back(
1304 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1305 );
[3]1306 }
1307 }
1308 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1309 if(pRelativeVar->bOffsetOffset){
1310 //mov eax,ecx
[231]1311 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[3]1312
1313 //add eax,dword ptr[ebp+offset]
[253]1314 compiler.codeGenerator.localVarPertialSchedules.push_back(
1315 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1316 );
[3]1317 }
1318 else{
1319 //mov eax,dword ptr[ebp+offset]
[253]1320 compiler.codeGenerator.localVarPertialSchedules.push_back(
1321 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1322 );
[3]1323 }
1324 }
1325 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1326 //mov eax,ecx
[231]1327 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[3]1328 }
1329}
[97]1330void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1331 if( reg != REG_EAX ){
[465]1332 compiler.errorMessenger.OutputFatalError();
[97]1333 //TODO: 未完成
1334 }
1335 SetVarPtrToEax( pRelativeVar );
1336}
[95]1337
1338bool Compile_AddGlobalRootsForGc(){
[206]1339 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
[95]1340 if( !pUserProc_AddGlobalRootPtr ){
[465]1341 compiler.errorMessenger.Output(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
[95]1342 return false;
1343 }
1344
[265]1345 BOOST_FOREACH( const Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
[206]1346 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
[95]1347 // オブジェクトまたはポインタだったとき
1348 // ※構造体も含む(暫定対応)
1349
1350 // 変数領域に要するLONG_PTR単位の個数を引き渡す
[225]1351 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
[95]1352
1353
1354 /////////////////////////////
1355 // ルートポインタを引き渡す
1356
1357 //mov eax,offset
[231]1358 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
[95]1359
1360 //push eax
[225]1361 compiler.codeGenerator.op_push( REG_EAX );
[95]1362
1363 //
1364 /////////////////////////////
1365
1366
1367 /////////////////////////////
1368 // Thisポインタを引き渡す
1369
1370 SetThisPtrToReg(REG_EAX);
1371
1372 //push eax
[225]1373 compiler.codeGenerator.op_push( REG_EAX );
[95]1374
1375 //
1376 /////////////////////////////
1377
1378
1379 // call AddGlobalRootPtr
[225]1380 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
[95]1381 }
1382 }
1383
1384 return true;
1385}
Note: See TracBrowser for help on using the repository browser.