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

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