source: dev/trunk/ab5.0/abdev/BasicCompiler64/Compile_Var.cpp@ 454

Last change on this file since 454 was 454, checked in by dai_9181, 16 years ago

[453]を64bit版にマージ。

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