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

Last change on this file since 409 was 409, checked in by dai_9181, 16 years ago

クラス継承を行う際、dynamicMembersの中身をコピーする方式をやめ、基底クラスのものを参照するように修正した。

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