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

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