source: dev/trunk/abdev/BasicCompiler32/Compile_Var.cpp@ 273

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