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

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

[409]をマージした。

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