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

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