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

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

値渡しの構造体パラメータが正常に引き渡されない不具合を修正。

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