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

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