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

Last change on this file since 242 was 242, checked in by dai_9181, 17 years ago
File size: 32.8 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,USE_OFFSET,*(int *)&flt);
1002 obp-=sizeof(long)+sizeof(long);
1003 AddLocalVarAddrSchedule();
1004 obp+=sizeof(long)+sizeof(long);
1005 }
1006 else if( type.Is64() || type.IsPointer() ){
1007 if(type.GetBasicType()==typeOfPtrChar ){
1008 //文字列定数のとき
1009
1010 char *temp;
1011 temp=(char *)i64data;
1012 i2=compiler.GetDataTable().AddString( temp );
1013 HeapDefaultFree(temp);
1014
1015 //mov rax,i2
1016 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,i2, Schedule::DataTable );
1017
1018 //mov qword ptr[rsp+offset],rax
1019 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32, Schedule::LocalVar );
1020 }
1021 else{
1022 if(i64data&0xFFFFFFFF00000000){
1023 //mov rax,i64data
1024 compiler.codeGenerator.op_mov_RV64(REG_RAX,i64data);
1025
1026 //mov qword ptr[rsp+offset],rax
1027 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32, Schedule::LocalVar );
1028 }
1029 else{
1030 //mov qword ptr[rsp+offset],value
1031 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RSP,offset,USE_OFFSET,(int)i64data);
1032 obp-=sizeof(long)+sizeof(long);
1033 AddLocalVarAddrSchedule();
1034 obp+=sizeof(long)+sizeof(long);
1035 }
1036 }
1037 }
1038 else if( type.IsDWord() || type.IsLong() ){
1039 //mov dword ptr[rsp+offset],value
1040 compiler.codeGenerator.op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,(int)i64data);
1041 obp-=sizeof(long)+sizeof(long);
1042 AddLocalVarAddrSchedule();
1043 obp+=sizeof(long)+sizeof(long);
1044 }
1045 else if( type.IsWord() || type.IsInteger() ){
1046 //mov word ptr[rsp+offset],value
1047 compiler.codeGenerator.op_mov_MV(sizeof(short),REG_RSP,offset,USE_OFFSET,(int)i64data);
1048 obp-=sizeof(long)+sizeof(short);
1049 AddLocalVarAddrSchedule();
1050 obp+=sizeof(long)+sizeof(short);
1051 }
1052 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1053 //mov byte ptr[rsp+offset],value
1054 compiler.codeGenerator.op_mov_MV(sizeof(char),REG_RSP,offset,USE_OFFSET,(int)i64data);
1055 obp-=sizeof(long)+sizeof(char);
1056 AddLocalVarAddrSchedule();
1057 obp+=sizeof(long)+sizeof(char);
1058 }
1059 return true;
1060}
1061
1062void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1063 if( UserProc::IsGlobalAreaCompiling() ){
1064 /////////////////////////
1065 // グローバル変数
1066 /////////////////////////
1067
1068 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1069 }
1070 else{
1071 /////////////////
1072 // ローカル変数
1073 /////////////////
1074
1075 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( VarName ) ){
1076 //2重定義のエラー
1077 SetError(15,VarName,cp);
1078 return;
1079 }
1080
1081 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1082
1083 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter );
1084
1085 if( subscripts.size() > 0 ){
1086 //配列あり
1087 pVar->SetArray( subscripts );
1088 }
1089
1090 //レキシカルスコープ
1091 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1092 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1093 pVar->bLiving=TRUE;
1094
1095 //エラー用
1096 pVar->source_code_address=cp;
1097
1098 // 変数を追加
1099 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1100
1101 //アラインメントを考慮
1102 if( pVar->GetType().IsStruct() ){
1103 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1104
1105 if( alignment ){
1106 if( AllLocalVarSize % alignment ){
1107 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1108 }
1109 }
1110
1111 if( alignment == PTR_SIZE*2 ){
1112 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1113 // (例:CONTEXT構造体など)
1114 // 呼び出し側のオフセットズレを考慮する
1115
1116 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1117 AllLocalVarSize += PTR_SIZE;
1118 }
1119 }
1120 }
1121
1122 AllLocalVarSize += pVar->GetMemorySize();
1123 pVar->SetOffsetAddress( AllLocalVarSize );
1124
1125 //レキシカルスコープ
1126 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1127 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1128 pVar->bLiving=TRUE;
1129
1130 if(InitBuf[0]){
1131 //初期代入時のみ、書き込みアクセスを許可する
1132 if( isConst ){
1133 pVar->ConstOff();
1134 }
1135
1136 int result = 0;
1137 if( !pVar->GetType().IsObject() ){
1138 result = InitLocalVar(-pVar->GetOffsetAddress(),
1139 pVar->GetType(),
1140 pVar->GetSubscripts(),
1141 InitBuf);
1142 }
1143
1144 if(!result){
1145 //動的な式だった場合は代入演算を行う
1146 char temporary[8192];
1147 sprintf(temporary,"%s=%s",VarName,InitBuf);
1148 OpcodeCalc(temporary);
1149 }
1150
1151 if( isConst ){
1152 pVar->ConstOn();
1153 }
1154 }
1155 else{
1156 //0初期化
1157
1158 //mov r8, 0
1159 compiler.codeGenerator.op_zero_reg( REG_R8 );
1160
1161 //mov rdx, VarSize
1162 compiler.codeGenerator.op_mov_RV( sizeof(_int64), REG_RDX, pVar->GetMemorySize() );
1163
1164 //mov rcx, rsp
1165 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RSP );
1166
1167 //add rcx, offset
1168 compiler.codeGenerator.op_add_RV( REG_RCX, -pVar->GetOffsetAddress() );
1169 obp-=sizeof(long);
1170 AddLocalVarAddrSchedule();
1171 obp+=sizeof(long);
1172
1173 //call FillMemory
1174 DllProc *pDllProc;
1175 pDllProc=GetDeclareHash("FillMemory");
1176 compiler.codeGenerator.op_call( pDllProc );
1177 }
1178 }
1179
1180 //コンストラクタ呼び出し
1181 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1182 char objectSize[255];
1183 if( subscripts.size() == 0 ){
1184 objectSize[0] = 0;
1185 }
1186 else{
1187 if( subscripts.size() > 1 ){
1188 SetError(300,NULL,cp);
1189 }
1190 sprintf( objectSize, "%d", subscripts[0] );
1191 }
1192 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1193
1194 Type tempType;
1195 RELATIVE_VAR RelativeVar;
1196 GetVarOffset( true, false, VarName, &RelativeVar, tempType );
1197 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1198 SetError();
1199 }
1200 SetVariableFromRax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1201 }
1202}
1203void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1204 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1205
1206 if(pRelativeVar->dwKind==VAR_GLOBAL){
1207 if(pRelativeVar->bOffsetOffset){
1208 //add r11,offset
1209 compiler.codeGenerator.op_add_RV( REG_R11, (long)pRelativeVar->offset, Schedule::GlobalVar );
1210
1211 //mov reg,r11
1212 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1213 }
1214 else{
1215 //mov reg,offset
1216 compiler.codeGenerator.op_mov_RV( sizeof(_int64), reg, (long)pRelativeVar->offset, Schedule::GlobalVar );
1217 }
1218 }
1219 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
1220 if(pRelativeVar->bOffsetOffset){
1221 //add r11,qword ptr[offset]
1222 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1223 }
1224 else{
1225 //mov r11,qword ptr[offset]
1226 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelativeVar->offset,MOD_DISP32, Schedule::GlobalVar );
1227 }
1228
1229 goto directmem;
1230 }
1231 else if(pRelativeVar->dwKind==VAR_LOCAL){
1232 if(pRelativeVar->bOffsetOffset){
1233 //add r11,offset
1234 compiler.codeGenerator.op_add_RV( REG_R11, (long)pRelativeVar->offset, Schedule::LocalVar );
1235
1236 //add r11,rsp
1237 compiler.codeGenerator.op_add_RR(REG_R11,REG_RSP);
1238
1239 //mov reg,r11
1240 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1241 }
1242 else{
1243 //mov reg,rsp
1244 compiler.codeGenerator.op_mov_RR(reg,REG_RSP);
1245
1246 //add reg,offset
1247 compiler.codeGenerator.op_add_RV(reg,(long)pRelativeVar->offset, Schedule::LocalVar );
1248 }
1249 }
1250 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
1251 if(pRelativeVar->bOffsetOffset){
1252 //add r11,qword ptr[rsp+offset]
1253 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (long)pRelativeVar->offset, MOD_BASE_DISP32, Schedule::LocalVar );
1254 }
1255 else{
1256 //mov r11,qword ptr[rsp+offset]
1257 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32, Schedule::LocalVar );
1258 }
1259
1260 goto directmem;
1261 }
1262 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1263directmem:
1264 //mov reg,r11
1265 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1266 }
1267}
1268
1269bool Compile_AddGlobalRootsForGc(){
1270 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1271 if( !pUserProc_AddGlobalRootPtr ){
1272 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1273 return false;
1274 }
1275
1276 BOOST_FOREACH( const Variable *pVar, compiler.GetMeta().GetGlobalVars() ){
1277 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1278 // オブジェクトまたはポインタだったとき
1279 // ※構造体も含む(暫定対応)
1280
1281 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1282 //mov r8,count
1283 compiler.codeGenerator.op_mov_RV(sizeof(_int64), REG_R8,pVar->GetMemorySize()/PTR_SIZE);
1284
1285 // ルートポインタを引き渡す
1286 //mov rdx,offset
1287 compiler.codeGenerator.op_mov_RV(sizeof(_int64), REG_RDX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1288
1289 // Thisポインタを引き渡す
1290 SetThisPtrToReg(REG_RCX);
1291
1292 // call AddGlobalRootPtr
1293 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1294
1295 ReallocNativeCodeBuffer();
1296 }
1297 }
1298
1299 return true;
1300}
Note: See TracBrowser for help on using the repository browser.