source: dev/trunk/abdev/BasicCompiler64/Compile_Var.cpp@ 242

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