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

Last change on this file since 288 was 288, checked in by dai_9181, 17 years ago
File size: 33.8 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){
[140]718 int i2,i3;
[3]719 char temporary[VN_SIZE];
[138]720 char InitBuf[VN_SIZE];
721 lstrcpy( InitBuf, lpszInitBuf );
[3]722
723 if(InitBuf[0]=='['){
724 SlideString(InitBuf+1,-1);
725 InitBuf[lstrlen(InitBuf)-1]=0;
726
[75]727 int typeSize = type.GetSize();
[3]728
[206]729 if( subscripts.size() > 0 ){
730 Subscripts nestSubscripts;
731 for( int i=1; i<(int)subscripts.size(); i++ )
732 {
733 nestSubscripts.push_back( subscripts[i] );
734 }
735
736 typeSize*=JumpSubScripts( nestSubscripts );
737 {
738 int i=0;
739 i2=0;
740 while(1){
741 if( subscripts[0] < i2 ){
742 SetError(41,0,cp);
743 return 0;
744 }
745 i=GetOneParameter(InitBuf,i,temporary);
746 if(!SetInitGlobalData(
747 offset+i2*typeSize,
748 type,
749 nestSubscripts,
750 temporary)) return false;
751 i2++;
752 if(InitBuf[i]=='\0') break;
[3]753 }
754 }
[75]755 return true;
[3]756 }
757
[75]758 if(type.IsStruct()){
759 const CClass &objClass = type.GetClass();
[3]760
[140]761 int i = 0;
762 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
763 if(InitBuf[i]=='\0'){
764 SetError(41,0,cp);
765 return false;
766 }
767
[3]768 i=GetOneParameter(InitBuf,i,temporary);
769
[140]770 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
[3]771
772 if(!SetInitGlobalData(offset+i3,
[140]773 pMember->GetType(),
[206]774 pMember->GetSubscripts(),
[75]775 temporary)) return false;
[3]776 }
[75]777 return true;
[3]778 }
779
780 SetError(41,0,cp);
[75]781 return false;
[3]782 }
783
[20]784
785 ///////////////////////////////////////
786 // 単発式([]で囲まれていない)
787 ///////////////////////////////////////
788
[75]789 if( type.IsObject() || type.IsStruct() ){
[64]790 //オブジェクトまたは構造体の場合はありえない
[20]791 SetError(300,NULL,cp);
[75]792 return false;
[20]793 }
794
[206]795 if( subscripts.size() > 0 ){
[3]796 SetError(41,0,cp);
[75]797 return false;
[3]798 }
799
800 double dbl;
801 _int64 i64data;
[75]802 Type calcType;
803
804 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
805 //動的データだった場合
806 return false;
807 }
808 if( calcType.IsReal() ){
[3]809 memcpy(&dbl,&i64data,sizeof(double));
810 i64data=(_int64)dbl;
811 }
812 else dbl=(double)i64data;
813
814 //型チェック
815 CheckDifferentType(
816 type,
[75]817 calcType,
[3]818 0,0);
819
[75]820 if( type.IsDouble() ){
[288]821 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
822 offset,
823 (const char *)&dbl,
824 sizeof(double)
825 );
[75]826 }
827 else if( type.IsSingle() ){
[288]828 float flt = (float)dbl;
829 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
830 offset,
831 (const char *)&flt,
832 sizeof(float)
833 );
[75]834 }
835 else if( type.Is64() ){
[288]836 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
837 offset,
838 (const char *)&i64data,
839 sizeof(_int64)
840 );
[75]841 }
842 else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){
[97]843 if(type.GetBasicType()==typeOfPtrChar){
[3]844 //文字列定数のとき
845
846 char *temp;
847 temp=(char *)i64data;
[265]848 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
[3]849 HeapDefaultFree(temp);
850
851 //mov eax,DataPos
[237]852 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
[3]853
854 //mov dword ptr[offset],eax
[230]855 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
[3]856 }
857 else{
[288]858 long l = (long)i64data;
859 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
860 offset,
861 (const char *)&l,
862 sizeof(long)
863 );
[3]864 }
865 }
[75]866 else if( type.IsWord() || type.IsInteger() ){
[288]867 short s = (short)i64data;
868 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
869 offset,
870 (const char *)&s,
871 sizeof(short)
872 );
[75]873 }
874 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[288]875 char c = (char)i64data;
876 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
877 offset,
878 (const char *)&c,
879 sizeof(char)
880 );
[75]881 }
882
883 return true;
[3]884}
[206]885bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
886 int i2,i3;
[3]887 char temporary[VN_SIZE];
[138]888 char InitBuf[VN_SIZE];
889 lstrcpy( InitBuf, lpszInitBuf );
[3]890
891 if(InitBuf[0]=='['){
892 SlideString(InitBuf+1,-1);
893 InitBuf[lstrlen(InitBuf)-1]=0;
894
[75]895 int typeSize = type.GetSize();
[3]896
[206]897 if( subscripts.size() > 0 ){
898 Subscripts nestSubscripts;
899 for( int i=1; i<(int)subscripts.size(); i++ )
900 {
901 nestSubscripts.push_back( subscripts[i] );
902 }
903
904 typeSize*=JumpSubScripts( nestSubscripts );
905 {
906 int i=0;
907 i2=0;
908 while(1){
909 if( subscripts[0] < i2 ){
910 SetError(41,0,cp);
911 return 0;
912 }
913 i=GetOneParameter(InitBuf,i,temporary);
914 if(!InitLocalVar(
915 offset+i2*typeSize,
916 type,
917 nestSubscripts,
918 temporary)) return false;
919 i2++;
920 if(InitBuf[i]=='\0') break;
[3]921 }
922 }
[75]923 return true;
[3]924 }
925
[75]926 if(type.IsStruct()){
927 const CClass &objClass = type.GetClass();
[3]928
[140]929 int i = 0;
930 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
931 if(InitBuf[i]=='\0'){
932 SetError(41,0,cp);
933 return false;
934 }
935
[3]936 i=GetOneParameter(InitBuf,i,temporary);
937
[140]938 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
[3]939
940 if(!InitLocalVar(offset+i3,
[140]941 pMember->GetType(),
[206]942 pMember->GetSubscripts(),
[75]943 temporary)) return false;
[3]944
945 if(InitBuf[i]=='\0') break;
946 }
[75]947 return true;
[3]948 }
949
950 SetError(41,0,cp);
[75]951 return false;
[3]952 }
953
[20]954
955 ///////////////////////////////////////
956 // 単発式([]で囲まれていない)
957 ///////////////////////////////////////
958
[206]959 if( subscripts.size() > 0 ){
[3]960 SetError(41,0,cp);
[75]961 return false;
[3]962 }
963
964 double dbl;
965 _int64 i64data;
[75]966 Type calcType;
967
968 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
[8]969 //動的データだった場合
[75]970 return false;
[8]971 }
[75]972 if( calcType.IsReal() ){
[3]973 memcpy(&dbl,&i64data,sizeof(double));
974 i64data=(_int64)dbl;
975 }
976 else dbl=(double)i64data;
977
978 //型チェック
979 CheckDifferentType(
980 type,
[75]981 calcType,
[3]982 0,0);
983
[75]984 if( type.IsDouble() ){
[3]985 //mov eax,HILONG(dbl)
[241]986 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
[3]987
988 //mov dword ptr[ebp+offset+sizeof(long)],eax
[253]989 compiler.codeGenerator.localVarPertialSchedules.push_back(
990 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
991 );
[3]992
993 //mov eax,LOLONG(dbl)
[231]994 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
[3]995
996 //mov dword ptr[ebp+offset],eax
[253]997 compiler.codeGenerator.localVarPertialSchedules.push_back(
998 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
999 );
[3]1000 }
[75]1001 else if( type.IsSingle() ){
[3]1002 float flt;
1003 flt=(float)dbl;
[231]1004
[3]1005 //mov eax,InitValue
[231]1006 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
[3]1007
1008 //mov dword ptr[ebp+offset],eax
[253]1009 compiler.codeGenerator.localVarPertialSchedules.push_back(
1010 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1011 );
[3]1012 }
[75]1013 else if( type.Is64() ){
[3]1014 //mov eax,HILONG(i64data)
[231]1015 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
[3]1016
1017 //mov dword ptr[ebp+offset+sizeof(long)],eax
[253]1018 compiler.codeGenerator.localVarPertialSchedules.push_back(
1019 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1020 );
[3]1021
1022 //mov eax,LOLONG(i64data)
[231]1023 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
[3]1024
1025 //mov dword ptr[ebp+offset],eax
[253]1026 compiler.codeGenerator.localVarPertialSchedules.push_back(
1027 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1028 );
[3]1029 }
[75]1030 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
[97]1031 if(type.GetBasicType()==typeOfPtrChar){
[3]1032 //文字列定数のとき
1033
1034 char *temp;
1035 temp=(char *)i64data;
[265]1036 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
[3]1037 HeapDefaultFree(temp);
1038
1039 //mov eax,DataPos
[237]1040 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
[3]1041 }
1042 else{
1043 //mov eax,InitValue
[231]1044 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
[3]1045 }
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.IsWord() || type.IsInteger() ){
[234]1053 //mov word ptr[ebp+offset],InitValue
[253]1054 compiler.codeGenerator.localVarPertialSchedules.push_back(
1055 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1056 );
[3]1057 }
[75]1058 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
[3]1059 //mov byte ptr[ebp+offset],InitValue
[253]1060 compiler.codeGenerator.localVarPertialSchedules.push_back(
1061 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1062 );
[3]1063 }
[75]1064
1065 return true;
[3]1066}
1067
[206]1068void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
[75]1069 if( UserProc::IsGlobalAreaCompiling() ){
[64]1070 /////////////////////////
1071 // グローバル変数
1072 /////////////////////////
1073
[206]1074 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
[64]1075 }
1076 else{
1077 /////////////////
1078 // ローカル変数
1079 /////////////////
1080
[206]1081 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( Symbol( VarName ) ) ){
[75]1082 //2重定義のエラー
1083 SetError(15,VarName,cp);
1084 return;
[64]1085 }
1086
[75]1087 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
[64]1088
[275]1089 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter, false );
[75]1090
[206]1091 if( subscripts.size() > 0 ){
[75]1092 //配列あり
[206]1093 pVar->SetArray( subscripts );
[64]1094 }
1095
[75]1096 //レキシカルスコープ
[248]1097 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1098 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[75]1099 pVar->bLiving=TRUE;
1100
1101 //エラー用
1102 pVar->source_code_address=cp;
1103
1104 // 変数を追加
[206]1105 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
[75]1106
1107 //アラインメントを考慮
[206]1108 if( pVar->GetType().IsStruct() ){
[233]1109 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
[120]1110
[75]1111 if( alignment ){
1112 if( AllLocalVarSize % alignment ){
1113 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1114 }
1115 }
[120]1116
1117 if( alignment == PTR_SIZE*2 ){
1118 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1119 // (例:CONTEXT構造体など)
1120 // 呼び出し側のオフセットズレを考慮する
1121
[288]1122 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
[120]1123 AllLocalVarSize += PTR_SIZE;
1124 }
1125 }
[64]1126 }
1127
[75]1128 AllLocalVarSize += pVar->GetMemorySize();
[206]1129 pVar->SetOffsetAddress( AllLocalVarSize );
[64]1130
1131 //レキシカルスコープ
[248]1132 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1133 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
[64]1134 pVar->bLiving=TRUE;
1135
1136 if(InitBuf[0]){
1137 //初期代入時のみ、書き込みアクセスを許可する
[75]1138 if( isConst ){
1139 pVar->ConstOff();
1140 }
[64]1141
1142 int result = 0;
[206]1143 if( !pVar->GetType().IsObject() ){
1144 result = InitLocalVar(-pVar->GetOffsetAddress(),
1145 pVar->GetType(),
1146 pVar->GetSubscripts(),
[64]1147 InitBuf);
1148 }
1149
1150 if(!result){
1151 //動的な式だった場合は代入演算を行う
1152 char temporary[8192];
1153 sprintf(temporary,"%s=%s",VarName,InitBuf);
1154 OpcodeCalc(temporary);
1155 }
1156
[75]1157 if( isConst ){
1158 pVar->ConstOn();
1159 }
[64]1160 }
1161 else{
1162 //push 0
[225]1163 compiler.codeGenerator.op_push_V(0);
[64]1164
1165 //push VarSize
[225]1166 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
[64]1167
1168 //mov eax,ebp
[241]1169 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
[64]1170
1171 //add eax,offset
[253]1172 compiler.codeGenerator.localVarPertialSchedules.push_back(
1173 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1174 );
[64]1175
1176 //push eax
[225]1177 compiler.codeGenerator.op_push(REG_EAX);
[64]1178
1179 //call FillMemory
[250]1180 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
[64]1181 }
1182 }
1183
1184 //New呼び出し
[75]1185 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
[64]1186 char objectSize[255];
[206]1187 if( subscripts.size() == 0 ){
[64]1188 objectSize[0] = 0;
1189 }
1190 else{
[206]1191 if( subscripts.size() > 1 ){
[64]1192 SetError(300,NULL,cp);
1193 }
[206]1194 sprintf( objectSize, "%d", subscripts[0] );
[64]1195 }
[75]1196 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
[64]1197
1198 //pop eax
[225]1199 compiler.codeGenerator.op_pop( REG_EAX );
[64]1200
1201 RELATIVE_VAR RelativeVar;
[75]1202 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
[64]1203 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1204 SetError();
1205 }
1206 SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1207 }
1208}
[3]1209
1210void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1211 if(pRelativeVar->dwKind==VAR_GLOBAL){
1212 if(pRelativeVar->bOffsetOffset){
1213 //lea eax,dword ptr[ecx+offset]
[230]1214 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
[3]1215 }
1216 else{
1217 //mov eax,offset
[230]1218 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
[3]1219 }
1220 }
[62]1221 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1222 if(pRelativeVar->bOffsetOffset){
1223 //mov eax,ecx
[241]1224 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[62]1225
1226 //add eax,dword ptr[offset]
[230]1227 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
[62]1228 }
1229 else{
1230 //mov eax,dword ptr[offset]
[230]1231 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
[62]1232 }
1233 }
[3]1234 else if(pRelativeVar->dwKind==VAR_LOCAL){
1235 if(pRelativeVar->bOffsetOffset){
1236 //add ecx,offset
[253]1237 compiler.codeGenerator.localVarPertialSchedules.push_back(
1238 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1239 );
[3]1240
1241 //lea eax,dword ptr[ebp+ecx]
[241]1242 compiler.codeGenerator.PutOld(
1243 (char)0x8D,
1244 (char)0x44,
1245 (char)0x0D,
1246 (char)0x00
1247 );
[3]1248 }
1249 else{
[230]1250 //lea eax,dword ptr[ecx+offset]
[253]1251 compiler.codeGenerator.localVarPertialSchedules.push_back(
1252 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1253 );
[3]1254 }
1255 }
1256 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1257 if(pRelativeVar->bOffsetOffset){
1258 //mov eax,ecx
[231]1259 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[3]1260
1261 //add eax,dword ptr[ebp+offset]
[253]1262 compiler.codeGenerator.localVarPertialSchedules.push_back(
1263 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1264 );
[3]1265 }
1266 else{
1267 //mov eax,dword ptr[ebp+offset]
[253]1268 compiler.codeGenerator.localVarPertialSchedules.push_back(
1269 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1270 );
[3]1271 }
1272 }
1273 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1274 //mov eax,ecx
[231]1275 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
[3]1276 }
1277}
[97]1278void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1279 if( reg != REG_EAX ){
1280 SetError();
1281 //TODO: 未完成
1282 }
1283 SetVarPtrToEax( pRelativeVar );
1284}
[95]1285
1286bool Compile_AddGlobalRootsForGc(){
[206]1287 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
[95]1288 if( !pUserProc_AddGlobalRootPtr ){
1289 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1290 return false;
1291 }
1292
[265]1293 BOOST_FOREACH( const Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
[206]1294 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
[95]1295 // オブジェクトまたはポインタだったとき
1296 // ※構造体も含む(暫定対応)
1297
1298 // 変数領域に要するLONG_PTR単位の個数を引き渡す
[225]1299 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
[95]1300
1301
1302 /////////////////////////////
1303 // ルートポインタを引き渡す
1304
1305 //mov eax,offset
[231]1306 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
[95]1307
1308 //push eax
[225]1309 compiler.codeGenerator.op_push( REG_EAX );
[95]1310
1311 //
1312 /////////////////////////////
1313
1314
1315 /////////////////////////////
1316 // Thisポインタを引き渡す
1317
1318 SetThisPtrToReg(REG_EAX);
1319
1320 //push eax
[225]1321 compiler.codeGenerator.op_push( REG_EAX );
[95]1322
1323 //
1324 /////////////////////////////
1325
1326
1327 // call AddGlobalRootPtr
[225]1328 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
[95]1329 }
1330 }
1331
1332 return true;
1333}
Note: See TracBrowser for help on using the repository browser.