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

Last change on this file since 226 was 225, checked in by dai_9181, 17 years ago

CodeGeneratorクラスのベースを実装

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