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

Last change on this file since 260 was 257, checked in by dai_9181, 17 years ago
File size: 33.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 <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(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(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.objectModule.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.objectModule.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.objectModule.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.objectModule.meta.GetTypeDefs().GetIndex( VarName );
545 if( typeDefIndex != -1 ){
546 // TypeDef後の型名だったとき
547 lstrcpy( VarName, compiler.objectModule.meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
548 }
549
550 char temp2[VN_SIZE];
551 sprintf(temp2,"%s.%s",VarName,temporary);
552 pVar = compiler.objectModule.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.objectModule.meta.GetGlobalVars().Find( Symbol( temp2 ) );
565 if( pVar ){
566 goto GlobalOk;
567 }
568 }
569
570 /////////////////////
571 // グローバル変数
572 /////////////////////
573
574 pVar = compiler.objectModule.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 extern BYTE *initGlobalBuf;
745 int i2,i3;
746 char temporary[VN_SIZE];
747 char InitBuf[VN_SIZE];
748 lstrcpy( InitBuf, lpszInitBuf );
749
750 if(InitBuf[0]=='['){
751 SlideString(InitBuf+1,-1);
752 InitBuf[lstrlen(InitBuf)-1]=0;
753
754 int typeSize = type.GetSize();
755
756 if( subscripts.size() > 0 ){
757 Subscripts nestSubscripts;
758 for( int i=1; i<(int)subscripts.size(); i++ )
759 {
760 nestSubscripts.push_back( subscripts[i] );
761 }
762
763 typeSize*=JumpSubScripts( nestSubscripts );
764 {
765 int i=0;
766 i2=0;
767 while(1){
768 if( subscripts[0] < i2 ){
769 SetError(41,0,cp);
770 return 0;
771 }
772 i=GetOneParameter(InitBuf,i,temporary);
773 if(!SetInitGlobalData(
774 offset+i2*typeSize,
775 type,
776 nestSubscripts,
777 temporary)) return false;
778 i2++;
779 if(InitBuf[i]=='\0') break;
780 }
781 }
782 return true;
783 }
784
785 if(type.IsStruct()){
786 const CClass &objClass = type.GetClass();
787
788 int i = 0;
789 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
790 if(InitBuf[i]=='\0'){
791 SetError(41,0,cp);
792 return false;
793 }
794
795 i=GetOneParameter(InitBuf,i,temporary);
796
797 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
798
799 if(!SetInitGlobalData(offset+i3,
800 pMember->GetType(),
801 pMember->GetSubscripts(),
802 temporary)) return false;
803 }
804 return true;
805 }
806
807 SetError(41,0,cp);
808 return false;
809 }
810
811
812 ///////////////////////////////////////
813 // 単発式([]で囲まれていない)
814 ///////////////////////////////////////
815
816 if( type.IsObject() || type.IsStruct() ){
817 //オブジェクトまたは構造体の場合はありえない
818 SetError(300,NULL,cp);
819 return false;
820 }
821
822 if( subscripts.size() > 0 ){
823 SetError(41,0,cp);
824 return false;
825 }
826
827 double dbl;
828 _int64 i64data;
829 Type calcType;
830
831 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
832 //動的データだった場合
833 return false;
834 }
835 if( calcType.IsReal() ){
836 memcpy(&dbl,&i64data,sizeof(double));
837 i64data=(_int64)dbl;
838 }
839 else dbl=(double)i64data;
840
841 //型チェック
842 CheckDifferentType(
843 type,
844 calcType,
845 0,0);
846
847 if( type.IsDouble() ){
848 *(double *)(initGlobalBuf+offset)=(double)dbl;
849 }
850 else if( type.IsSingle() ){
851 *(float *)(initGlobalBuf+offset)=(float)dbl;
852 }
853 else if( type.Is64() || type.IsPointer() ){
854 if(type.GetBasicType()==typeOfPtrChar){
855 //文字列定数のとき
856
857 char *temp;
858 temp=(char *)i64data;
859 i2=compiler.objectModule.dataTable.AddString( temp );
860 HeapDefaultFree(temp);
861
862 //mov rax,DataPos
863 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,i2, Schedule::DataTable );
864
865 //mov qword ptr[offset],rax
866 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,0,offset,MOD_DISP32, Schedule::GlobalVar );
867 }
868 else{
869 *(_int64 *)(initGlobalBuf+offset)=i64data;
870 }
871 }
872 else if( type.IsDWord() || type.IsLong() ){
873 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
874 }
875 else if( type.IsWord() || type.IsInteger() ){
876 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
877 }
878 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
879 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
880 }
881
882 return true;
883}
884bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
885 int i2,i3;
886 char temporary[VN_SIZE];
887 char InitBuf[VN_SIZE];
888 lstrcpy( InitBuf, lpszInitBuf );
889
890 if(InitBuf[0]=='['){
891 SlideString(InitBuf+1,-1);
892 InitBuf[lstrlen(InitBuf)-1]=0;
893
894 int typeSize = type.GetSize();
895
896 if( subscripts.size() > 0 ){
897 Subscripts nestSubscripts;
898 for( int i=1; i<(int)subscripts.size(); i++ )
899 {
900 nestSubscripts.push_back( subscripts[i] );
901 }
902
903 typeSize*=JumpSubScripts( nestSubscripts );
904 {
905 int i=0;
906 i2=0;
907 while(1){
908 if( subscripts[0] < i2 ){
909 SetError(41,0,cp);
910 return 0;
911 }
912 i=GetOneParameter(InitBuf,i,temporary);
913 if(!InitLocalVar(
914 offset+i2*typeSize,
915 type,
916 nestSubscripts,
917 temporary)) return false;
918 i2++;
919 if(InitBuf[i]=='\0') break;
920 }
921 }
922 return true;
923 }
924
925 if(type.IsStruct()){
926 const CClass &objClass = type.GetClass();
927
928 int i = 0;
929 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
930 if(InitBuf[i]=='\0'){
931 SetError(41,0,cp);
932 return false;
933 }
934
935 i=GetOneParameter(InitBuf,i,temporary);
936
937 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
938
939 if(!InitLocalVar(offset+i3,
940 pMember->GetType(),
941 pMember->GetSubscripts(),
942 temporary)) return false;
943
944 if(InitBuf[i]=='\0') break;
945 }
946 return true;
947 }
948
949 SetError(41,0,cp);
950 return false;
951 }
952
953
954 ///////////////////////////////////////
955 // 単発式([]で囲まれていない)
956 ///////////////////////////////////////
957
958 if( subscripts.size() > 0 ){
959 SetError(41,0,cp);
960 return false;
961 }
962
963 double dbl;
964 _int64 i64data;
965 Type calcType;
966
967 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
968 //動的データだった場合
969 return false;
970 }
971 if( calcType.IsReal() ){
972 memcpy(&dbl,&i64data,sizeof(double));
973 i64data=(_int64)dbl;
974 }
975 else dbl=(double)i64data;
976
977 //型チェック
978 CheckDifferentType(
979 type,
980 calcType,
981 0,0);
982
983 if( type.IsDouble() ){
984 memcpy(&i64data,&dbl,sizeof(double));
985
986 //mov rax,i64data
987 compiler.codeGenerator.op_mov_RV64(REG_RAX,i64data);
988
989 //mov qword ptr[rsp+offset],rax
990 compiler.codeGenerator.localVarPertialSchedules.push_back(
991 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32, Schedule::None, true )
992 );
993 }
994 else if( type.IsSingle() ){
995 float flt;
996 flt=(float)dbl;
997
998 //mov dword ptr[rsp+offset],value
999 compiler.codeGenerator.localVarPertialSchedules.push_back(
1000 compiler.codeGenerator.op_mov_MV(sizeof(long),REG_RSP,offset, Schedule::None, true, USE_OFFSET,*(int *)&flt)
1001 );
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.objectModule.dataTable.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.localVarPertialSchedules.push_back(
1017 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32, Schedule::None, true )
1018 );
1019 }
1020 else{
1021 if(i64data&0xFFFFFFFF00000000){
1022 //mov rax,i64data
1023 compiler.codeGenerator.op_mov_RV64(REG_RAX,i64data);
1024
1025 //mov qword ptr[rsp+offset],rax
1026 compiler.codeGenerator.localVarPertialSchedules.push_back(
1027 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32, Schedule::None, true )
1028 );
1029 }
1030 else{
1031 //mov qword ptr[rsp+offset],value
1032 compiler.codeGenerator.localVarPertialSchedules.push_back(
1033 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RSP,offset, Schedule::None, true, USE_OFFSET,(int)i64data)
1034 );
1035 }
1036 }
1037 }
1038 else if( type.IsDWord() || type.IsLong() ){
1039 //mov dword ptr[rsp+offset],value
1040 compiler.codeGenerator.localVarPertialSchedules.push_back(
1041 compiler.codeGenerator.op_mov_MV(sizeof(long),REG_RSP,offset, Schedule::None, true, USE_OFFSET,(int)i64data)
1042 );
1043 }
1044 else if( type.IsWord() || type.IsInteger() ){
1045 //mov word ptr[rsp+offset],value
1046 compiler.codeGenerator.localVarPertialSchedules.push_back(
1047 compiler.codeGenerator.op_mov_MV(sizeof(short),REG_RSP,offset, Schedule::None, true, USE_OFFSET,(int)i64data)
1048 );
1049 }
1050 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1051 //mov byte ptr[rsp+offset],value
1052 compiler.codeGenerator.localVarPertialSchedules.push_back(
1053 compiler.codeGenerator.op_mov_MV(sizeof(char),REG_RSP,offset, Schedule::None, true, USE_OFFSET,(int)i64data)
1054 );
1055 }
1056 return true;
1057}
1058
1059void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1060 if( UserProc::IsGlobalAreaCompiling() ){
1061 /////////////////////////
1062 // グローバル変数
1063 /////////////////////////
1064
1065 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1066 }
1067 else{
1068 /////////////////
1069 // ローカル変数
1070 /////////////////
1071
1072 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( VarName ) ){
1073 //2重定義のエラー
1074 SetError(15,VarName,cp);
1075 return;
1076 }
1077
1078 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1079
1080 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter );
1081
1082 if( subscripts.size() > 0 ){
1083 //配列あり
1084 pVar->SetArray( subscripts );
1085 }
1086
1087 //レキシカルスコープ
1088 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1089 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1090 pVar->bLiving=TRUE;
1091
1092 //エラー用
1093 pVar->source_code_address=cp;
1094
1095 // 変数を追加
1096 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1097
1098 //アラインメントを考慮
1099 if( pVar->GetType().IsStruct() ){
1100 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1101
1102 if( alignment ){
1103 if( AllLocalVarSize % alignment ){
1104 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1105 }
1106 }
1107
1108 if( alignment == PTR_SIZE*2 ){
1109 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1110 // (例:CONTEXT構造体など)
1111 // 呼び出し側のオフセットズレを考慮する
1112
1113 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1114 AllLocalVarSize += PTR_SIZE;
1115 }
1116 }
1117 }
1118
1119 AllLocalVarSize += pVar->GetMemorySize();
1120 pVar->SetOffsetAddress( AllLocalVarSize );
1121
1122 //レキシカルスコープ
1123 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1124 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1125 pVar->bLiving=TRUE;
1126
1127 if(InitBuf[0]){
1128 //初期代入時のみ、書き込みアクセスを許可する
1129 if( isConst ){
1130 pVar->ConstOff();
1131 }
1132
1133 int result = 0;
1134 if( !pVar->GetType().IsObject() ){
1135 result = InitLocalVar(-pVar->GetOffsetAddress(),
1136 pVar->GetType(),
1137 pVar->GetSubscripts(),
1138 InitBuf);
1139 }
1140
1141 if(!result){
1142 //動的な式だった場合は代入演算を行う
1143 char temporary[8192];
1144 sprintf(temporary,"%s=%s",VarName,InitBuf);
1145 OpcodeCalc(temporary);
1146 }
1147
1148 if( isConst ){
1149 pVar->ConstOn();
1150 }
1151 }
1152 else{
1153 //0初期化
1154
1155 //mov r8, 0
1156 compiler.codeGenerator.op_zero_reg( REG_R8 );
1157
1158 //mov rdx, VarSize
1159 compiler.codeGenerator.op_mov_RV( sizeof(_int64), REG_RDX, pVar->GetMemorySize() );
1160
1161 //mov rcx, rsp
1162 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RSP );
1163
1164 //add rcx, offset
1165 compiler.codeGenerator.localVarPertialSchedules.push_back(
1166 compiler.codeGenerator.op_add_RV( REG_RCX, -pVar->GetOffsetAddress(), Schedule::None, true )
1167 );
1168
1169 //call FillMemory
1170 DllProc *pDllProc;
1171 pDllProc=GetDeclareHash("FillMemory");
1172 compiler.codeGenerator.op_call( pDllProc );
1173 }
1174 }
1175
1176 //コンストラクタ呼び出し
1177 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1178 char objectSize[255];
1179 if( subscripts.size() == 0 ){
1180 objectSize[0] = 0;
1181 }
1182 else{
1183 if( subscripts.size() > 1 ){
1184 SetError(300,NULL,cp);
1185 }
1186 sprintf( objectSize, "%d", subscripts[0] );
1187 }
1188 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1189
1190 Type tempType;
1191 RELATIVE_VAR RelativeVar;
1192 GetVarOffset( true, false, VarName, &RelativeVar, tempType );
1193 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1194 SetError();
1195 }
1196 SetVariableFromRax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1197 }
1198}
1199void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1200 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1201
1202 if(pRelativeVar->dwKind==VAR_GLOBAL){
1203 if(pRelativeVar->bOffsetOffset){
1204 //add r11,offset
1205 compiler.codeGenerator.op_add_RV( REG_R11, (long)pRelativeVar->offset, Schedule::GlobalVar );
1206
1207 //mov reg,r11
1208 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1209 }
1210 else{
1211 //mov reg,offset
1212 compiler.codeGenerator.op_mov_RV( sizeof(_int64), reg, (long)pRelativeVar->offset, Schedule::GlobalVar );
1213 }
1214 }
1215 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
1216 if(pRelativeVar->bOffsetOffset){
1217 //add r11,qword ptr[offset]
1218 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1219 }
1220 else{
1221 //mov r11,qword ptr[offset]
1222 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelativeVar->offset,MOD_DISP32, Schedule::GlobalVar );
1223 }
1224
1225 goto directmem;
1226 }
1227 else if(pRelativeVar->dwKind==VAR_LOCAL){
1228 if(pRelativeVar->bOffsetOffset){
1229 //add r11,offset
1230 compiler.codeGenerator.localVarPertialSchedules.push_back(
1231 compiler.codeGenerator.op_add_RV( REG_R11, (long)pRelativeVar->offset, Schedule::None, true )
1232 );
1233
1234 //add r11,rsp
1235 compiler.codeGenerator.op_add_RR(REG_R11,REG_RSP);
1236
1237 //mov reg,r11
1238 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1239 }
1240 else{
1241 //mov reg,rsp
1242 compiler.codeGenerator.op_mov_RR(reg,REG_RSP);
1243
1244 //add reg,offset
1245 compiler.codeGenerator.localVarPertialSchedules.push_back(
1246 compiler.codeGenerator.op_add_RV(reg,(long)pRelativeVar->offset, Schedule::None, true )
1247 );
1248 }
1249 }
1250 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
1251 if(pRelativeVar->bOffsetOffset){
1252 //add r11,qword ptr[rsp+offset]
1253 compiler.codeGenerator.localVarPertialSchedules.push_back(
1254 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (long)pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1255 );
1256 }
1257 else{
1258 //mov r11,qword ptr[rsp+offset]
1259 compiler.codeGenerator.localVarPertialSchedules.push_back(
1260 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32, Schedule::None, true )
1261 );
1262 }
1263
1264 goto directmem;
1265 }
1266 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1267directmem:
1268 //mov reg,r11
1269 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1270 }
1271}
1272
1273bool Compile_AddGlobalRootsForGc(){
1274 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1275 if( !pUserProc_AddGlobalRootPtr ){
1276 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1277 return false;
1278 }
1279
1280 BOOST_FOREACH( const Variable *pVar, compiler.objectModule.meta.GetGlobalVars() ){
1281 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1282 // オブジェクトまたはポインタだったとき
1283 // ※構造体も含む(暫定対応)
1284
1285 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1286 //mov r8,count
1287 compiler.codeGenerator.op_mov_RV(sizeof(_int64), REG_R8,pVar->GetMemorySize()/PTR_SIZE);
1288
1289 // ルートポインタを引き渡す
1290 //mov rdx,offset
1291 compiler.codeGenerator.op_mov_RV(sizeof(_int64), REG_RDX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1292
1293 // Thisポインタを引き渡す
1294 SetThisPtrToReg(REG_RCX);
1295
1296 // call AddGlobalRootPtr
1297 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1298
1299 ReallocNativeCodeBuffer();
1300 }
1301 }
1302
1303 return true;
1304}
Note: See TracBrowser for help on using the repository browser.