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

Last change on this file since 750 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 35.5 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;
[677]411 if( pVar->IsRef() || pVar->IsByValStructParameter() ){
[75]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;
[750]794 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;
[745]875 i2 = compiler.AddStringToDataTable( temp );
[3]876 HeapDefaultFree(temp);
877
878 //mov eax,DataPos
[237]879 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
[3]880
881 //mov dword ptr[offset],eax
[230]882 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
[3]883 }
884 else{
[288]885 long l = (long)i64data;
886 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
887 offset,
888 (const char *)&l,
889 sizeof(long)
890 );
[3]891 }
892 }
[75]893 else if( type.IsWord() || type.IsInteger() ){
[288]894 short s = (short)i64data;
895 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
896 offset,
897 (const char *)&s,
898 sizeof(short)
899 );
[75]900 }
901 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[288]902 char c = (char)i64data;
903 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
904 offset,
905 (const char *)&c,
906 sizeof(char)
907 );
[75]908 }
909
910 return true;
[3]911}
[206]912bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
913 int i2,i3;
[3]914 char temporary[VN_SIZE];
[138]915 char InitBuf[VN_SIZE];
916 lstrcpy( InitBuf, lpszInitBuf );
[3]917
918 if(InitBuf[0]=='['){
919 SlideString(InitBuf+1,-1);
920 InitBuf[lstrlen(InitBuf)-1]=0;
921
[75]922 int typeSize = type.GetSize();
[3]923
[206]924 if( subscripts.size() > 0 ){
925 Subscripts nestSubscripts;
926 for( int i=1; i<(int)subscripts.size(); i++ )
927 {
928 nestSubscripts.push_back( subscripts[i] );
929 }
930
931 typeSize*=JumpSubScripts( nestSubscripts );
932 {
933 int i=0;
934 i2=0;
935 while(1){
936 if( subscripts[0] < i2 ){
[465]937 compiler.errorMessenger.Output(41,0,cp);
[206]938 return 0;
939 }
940 i=GetOneParameter(InitBuf,i,temporary);
941 if(!InitLocalVar(
942 offset+i2*typeSize,
943 type,
944 nestSubscripts,
945 temporary)) return false;
946 i2++;
947 if(InitBuf[i]=='\0') break;
[3]948 }
949 }
[75]950 return true;
[3]951 }
952
[75]953 if(type.IsStruct()){
954 const CClass &objClass = type.GetClass();
[3]955
[140]956 int i = 0;
[750]957 foreach( Member *pMember, objClass.GetDynamicMembers() ){
[140]958 if(InitBuf[i]=='\0'){
[465]959 compiler.errorMessenger.Output(41,0,cp);
[140]960 return false;
961 }
962
[3]963 i=GetOneParameter(InitBuf,i,temporary);
964
[409]965 i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
[3]966
967 if(!InitLocalVar(offset+i3,
[140]968 pMember->GetType(),
[206]969 pMember->GetSubscripts(),
[75]970 temporary)) return false;
[3]971
972 if(InitBuf[i]=='\0') break;
973 }
[75]974 return true;
[3]975 }
976
[465]977 compiler.errorMessenger.Output(41,0,cp);
[75]978 return false;
[3]979 }
980
[20]981
982 ///////////////////////////////////////
983 // 単発式([]で囲まれていない)
984 ///////////////////////////////////////
985
[206]986 if( subscripts.size() > 0 ){
[465]987 compiler.errorMessenger.Output(41,0,cp);
[75]988 return false;
[3]989 }
990
991 double dbl;
992 _int64 i64data;
[75]993 Type calcType;
994
995 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
[8]996 //動的データだった場合
[75]997 return false;
[8]998 }
[75]999 if( calcType.IsReal() ){
[3]1000 memcpy(&dbl,&i64data,sizeof(double));
1001 i64data=(_int64)dbl;
1002 }
1003 else dbl=(double)i64data;
1004
1005 //型チェック
1006 CheckDifferentType(
1007 type,
[75]1008 calcType,
[3]1009 0,0);
1010
[75]1011 if( type.IsDouble() ){
[3]1012 //mov eax,HILONG(dbl)
[241]1013 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
[3]1014
1015 //mov dword ptr[ebp+offset+sizeof(long)],eax
[253]1016 compiler.codeGenerator.localVarPertialSchedules.push_back(
1017 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1018 );
[3]1019
1020 //mov eax,LOLONG(dbl)
[231]1021 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
[3]1022
1023 //mov dword ptr[ebp+offset],eax
[253]1024 compiler.codeGenerator.localVarPertialSchedules.push_back(
1025 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1026 );
[3]1027 }
[75]1028 else if( type.IsSingle() ){
[3]1029 float flt;
1030 flt=(float)dbl;
[231]1031
[3]1032 //mov eax,InitValue
[231]1033 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
[3]1034
1035 //mov dword ptr[ebp+offset],eax
[253]1036 compiler.codeGenerator.localVarPertialSchedules.push_back(
1037 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1038 );
[3]1039 }
[75]1040 else if( type.Is64() ){
[3]1041 //mov eax,HILONG(i64data)
[231]1042 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
[3]1043
1044 //mov dword ptr[ebp+offset+sizeof(long)],eax
[253]1045 compiler.codeGenerator.localVarPertialSchedules.push_back(
1046 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1047 );
[3]1048
1049 //mov eax,LOLONG(i64data)
[231]1050 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
[3]1051
1052 //mov dword ptr[ebp+offset],eax
[253]1053 compiler.codeGenerator.localVarPertialSchedules.push_back(
1054 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1055 );
[3]1056 }
[75]1057 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
[453]1058 if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
1059 {
[3]1060 //文字列定数のとき
1061
1062 char *temp;
1063 temp=(char *)i64data;
[745]1064 i2 = compiler.AddStringToDataTable( temp );
[3]1065 HeapDefaultFree(temp);
1066
1067 //mov eax,DataPos
[237]1068 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
[3]1069 }
1070 else{
1071 //mov eax,InitValue
[231]1072 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
[3]1073 }
1074
1075 //mov dword ptr[ebp+offset],eax
[253]1076 compiler.codeGenerator.localVarPertialSchedules.push_back(
1077 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1078 );
[3]1079 }
[75]1080 else if( type.IsWord() || type.IsInteger() ){
[234]1081 //mov word ptr[ebp+offset],InitValue
[253]1082 compiler.codeGenerator.localVarPertialSchedules.push_back(
1083 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1084 );
[3]1085 }
[75]1086 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[3]1087 //mov byte ptr[ebp+offset],InitValue
[253]1088 compiler.codeGenerator.localVarPertialSchedules.push_back(
1089 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1090 );
[3]1091 }
[75]1092
1093 return true;
[3]1094}
1095
[299]1096void dim( char *VarName, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
[537]1097 if( compiler.IsGlobalAreaCompiling() ){
[64]1098 /////////////////////////
1099 // グローバル変数
1100 /////////////////////////
1101
[206]1102 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
[64]1103 }
1104 else{
1105 /////////////////
1106 // ローカル変数
1107 /////////////////
1108
[570]1109 if( compiler.GetCompilingUserProc().GetLocalVars().DuplicateCheck( LexicalAnalyzer::FullNameToSymbol( VarName ), compiler.codeGenerator.lexicalScopes.GetNowLevel() ) ){
[75]1110 //2重定義のエラー
[465]1111 compiler.errorMessenger.Output(15,VarName,cp);
[75]1112 return;
[64]1113 }
1114
[75]1115 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
[64]1116
[580]1117 Variable *pVar = new Variable(
1118 ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( VarName ),
1119 type,
1120 isConst,
1121 false,
1122 ConstractParameter,
1123 false
1124 );
[75]1125
[206]1126 if( subscripts.size() > 0 ){
[75]1127 //配列あり
[206]1128 pVar->SetArray( subscripts );
[64]1129 }
1130
[75]1131 //レキシカルスコープ
[248]1132 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1133 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[392]1134 pVar->isLiving = true;
[75]1135
1136 //エラー用
1137 pVar->source_code_address=cp;
1138
1139 // 変数を追加
[537]1140 compiler.GetCompilingUserProc().GetLocalVars().push_back( pVar );
[75]1141
1142 //アラインメントを考慮
[206]1143 if( pVar->GetType().IsStruct() ){
[233]1144 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
[120]1145
[75]1146 if( alignment ){
1147 if( AllLocalVarSize % alignment ){
1148 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1149 }
1150 }
[120]1151
1152 if( alignment == PTR_SIZE*2 ){
1153 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1154 // (例:CONTEXT構造体など)
1155 // 呼び出し側のオフセットズレを考慮する
1156
[537]1157 if( 0 == ( compiler.GetCompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
[120]1158 AllLocalVarSize += PTR_SIZE;
1159 }
1160 }
[64]1161 }
1162
[75]1163 AllLocalVarSize += pVar->GetMemorySize();
[206]1164 pVar->SetOffsetAddress( AllLocalVarSize );
[64]1165
1166 //レキシカルスコープ
[248]1167 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1168 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[392]1169 pVar->isLiving = true;
[64]1170
1171 if(InitBuf[0]){
1172 //初期代入時のみ、書き込みアクセスを許可する
[75]1173 if( isConst ){
1174 pVar->ConstOff();
1175 }
[64]1176
1177 int result = 0;
[206]1178 if( !pVar->GetType().IsObject() ){
1179 result = InitLocalVar(-pVar->GetOffsetAddress(),
1180 pVar->GetType(),
1181 pVar->GetSubscripts(),
[64]1182 InitBuf);
1183 }
1184
1185 if(!result){
1186 //動的な式だった場合は代入演算を行う
1187 char temporary[8192];
1188 sprintf(temporary,"%s=%s",VarName,InitBuf);
1189 OpcodeCalc(temporary);
1190 }
1191
[75]1192 if( isConst ){
1193 pVar->ConstOn();
1194 }
[64]1195 }
1196 else{
1197 //push 0
[225]1198 compiler.codeGenerator.op_push_V(0);
[64]1199
1200 //push VarSize
[225]1201 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
[64]1202
1203 //mov eax,ebp
[241]1204 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
[64]1205
1206 //add eax,offset
[253]1207 compiler.codeGenerator.localVarPertialSchedules.push_back(
1208 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1209 );
[64]1210
1211 //push eax
[225]1212 compiler.codeGenerator.op_push(REG_EAX);
[64]1213
1214 //call FillMemory
[250]1215 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
[64]1216 }
1217 }
1218
1219 //New呼び出し
[350]1220 if( type.IsObject()
[370]1221 && !type.IsInterface() && !type.IsComInterface()
[350]1222 &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0
1223 &&InitBuf[0]=='\0')
1224 {
[64]1225 char objectSize[255];
[206]1226 if( subscripts.size() == 0 ){
[64]1227 objectSize[0] = 0;
1228 }
1229 else{
[206]1230 if( subscripts.size() > 1 ){
[465]1231 compiler.errorMessenger.Output(300,NULL,cp);
[64]1232 }
[206]1233 sprintf( objectSize, "%d", subscripts[0] );
[64]1234 }
[75]1235 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
[64]1236
1237 //pop eax
[225]1238 compiler.codeGenerator.op_pop( REG_EAX );
[64]1239
1240 RELATIVE_VAR RelativeVar;
[75]1241 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
[64]1242 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
[465]1243 compiler.errorMessenger.OutputFatalError();
[64]1244 }
[290]1245 SetVariableFromEax( Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr() ), DEF_OBJECT, &RelativeVar );
[64]1246 }
1247}
[3]1248
1249void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1250 if(pRelativeVar->dwKind==VAR_GLOBAL){
1251 if(pRelativeVar->bOffsetOffset){
1252 //lea eax,dword ptr[ecx+offset]
[230]1253 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
[3]1254 }
1255 else{
1256 //mov eax,offset
[230]1257 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
[3]1258 }
1259 }
[62]1260 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1261 if(pRelativeVar->bOffsetOffset){
1262 //mov eax,ecx
[241]1263 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[62]1264
1265 //add eax,dword ptr[offset]
[230]1266 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
[62]1267 }
1268 else{
1269 //mov eax,dword ptr[offset]
[230]1270 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
[62]1271 }
1272 }
[3]1273 else if(pRelativeVar->dwKind==VAR_LOCAL){
1274 if(pRelativeVar->bOffsetOffset){
1275 //add ecx,offset
[253]1276 compiler.codeGenerator.localVarPertialSchedules.push_back(
1277 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1278 );
[3]1279
1280 //lea eax,dword ptr[ebp+ecx]
[241]1281 compiler.codeGenerator.PutOld(
1282 (char)0x8D,
1283 (char)0x44,
1284 (char)0x0D,
1285 (char)0x00
1286 );
[3]1287 }
1288 else{
[230]1289 //lea eax,dword ptr[ecx+offset]
[253]1290 compiler.codeGenerator.localVarPertialSchedules.push_back(
1291 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1292 );
[3]1293 }
1294 }
1295 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1296 if(pRelativeVar->bOffsetOffset){
1297 //mov eax,ecx
[231]1298 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[3]1299
1300 //add eax,dword ptr[ebp+offset]
[253]1301 compiler.codeGenerator.localVarPertialSchedules.push_back(
1302 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1303 );
[3]1304 }
1305 else{
1306 //mov eax,dword ptr[ebp+offset]
[253]1307 compiler.codeGenerator.localVarPertialSchedules.push_back(
1308 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1309 );
[3]1310 }
1311 }
1312 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1313 //mov eax,ecx
[231]1314 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[3]1315 }
1316}
[641]1317void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar)
1318{
[97]1319 if( reg != REG_EAX ){
[465]1320 compiler.errorMessenger.OutputFatalError();
[97]1321 //TODO: 未完成
1322 }
1323 SetVarPtrToEax( pRelativeVar );
1324}
[95]1325
[641]1326bool Compile_AddGlobalRootsForGc()
1327{
[206]1328 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
[641]1329 if( !pUserProc_AddGlobalRootPtr )
1330 {
[465]1331 compiler.errorMessenger.Output(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
[95]1332 return false;
1333 }
1334
[750]1335 foreach( const Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
[206]1336 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
[95]1337 // オブジェクトまたはポインタだったとき
1338 // ※構造体も含む(暫定対応)
1339
1340 // 変数領域に要するLONG_PTR単位の個数を引き渡す
[225]1341 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
[95]1342
1343
1344 /////////////////////////////
1345 // ルートポインタを引き渡す
1346
1347 //mov eax,offset
[231]1348 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
[95]1349
1350 //push eax
[225]1351 compiler.codeGenerator.op_push( REG_EAX );
[95]1352
1353 //
1354 /////////////////////////////
1355
1356
1357 /////////////////////////////
1358 // Thisポインタを引き渡す
1359
1360 SetThisPtrToReg(REG_EAX);
1361
1362 //push eax
[225]1363 compiler.codeGenerator.op_push( REG_EAX );
[95]1364
1365 //
1366 /////////////////////////////
1367
1368
1369 // call AddGlobalRootPtr
[225]1370 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
[95]1371 }
1372 }
1373
1374 return true;
1375}
Note: See TracBrowser for help on using the repository browser.