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

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

VariableクラスのLexicalAnalyzerクラスへの依存性をなくした。

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