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

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

SplitMemberNameの依存関係を排除。

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