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

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