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

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