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

Last change on this file since 767 was 767, checked in by dai, 15 years ago

配列の添え字が整数以外だった場合に、エラーとして処理するようにした。本件はx86のみの対応(x64は対応済み)。

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