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

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