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

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

Symbolコンストラクタを少なくし、LexicalAnalyzer::FullNameToSymbolメソッドを実装。

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