source: dev/trunk/ab5.0/abdev/BasicCompiler32/Compile_Var.cpp@ 479

Last change on this file since 479 was 465, checked in by dai_9181, 17 years ago

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

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