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

Last change on this file since 308 was 308, checked in by dai_9181, 17 years ago

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

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