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

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

SplitMemberNameの依存関係を排除。

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