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

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

ジェネリクスのベースを実装

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