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

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

DataTable::AddWStringメソッドを追加。

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