source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_Var.cpp@ 514

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

[505][513]を64bit版にマージ。

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