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

Last change on this file since 228 was 228, checked in by dai_9181, 17 years ago
File size: 33.7 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
6#include <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);
871 obp-=sizeof(long);
872 pobj_GlobalVarSchedule->add();
873 obp+=sizeof(long);
874 }
875 else{
876 *(_int64 *)(initGlobalBuf+offset)=i64data;
877 }
878 }
879 else if( type.IsDWord() || type.IsLong() ){
880 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
881 }
882 else if( type.IsWord() || type.IsInteger() ){
883 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
884 }
885 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
886 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
887 }
888
889 return true;
890}
891bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
892 int i2,i3;
893 char temporary[VN_SIZE];
894 char InitBuf[VN_SIZE];
895 lstrcpy( InitBuf, lpszInitBuf );
896
897 if(InitBuf[0]=='['){
898 SlideString(InitBuf+1,-1);
899 InitBuf[lstrlen(InitBuf)-1]=0;
900
901 int typeSize = type.GetSize();
902
903 if( subscripts.size() > 0 ){
904 Subscripts nestSubscripts;
905 for( int i=1; i<(int)subscripts.size(); i++ )
906 {
907 nestSubscripts.push_back( subscripts[i] );
908 }
909
910 typeSize*=JumpSubScripts( nestSubscripts );
911 {
912 int i=0;
913 i2=0;
914 while(1){
915 if( subscripts[0] < i2 ){
916 SetError(41,0,cp);
917 return 0;
918 }
919 i=GetOneParameter(InitBuf,i,temporary);
920 if(!InitLocalVar(
921 offset+i2*typeSize,
922 type,
923 nestSubscripts,
924 temporary)) return false;
925 i2++;
926 if(InitBuf[i]=='\0') break;
927 }
928 }
929 return true;
930 }
931
932 if(type.IsStruct()){
933 const CClass &objClass = type.GetClass();
934
935 int i = 0;
936 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
937 if(InitBuf[i]=='\0'){
938 SetError(41,0,cp);
939 return false;
940 }
941
942 i=GetOneParameter(InitBuf,i,temporary);
943
944 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
945
946 if(!InitLocalVar(offset+i3,
947 pMember->GetType(),
948 pMember->GetSubscripts(),
949 temporary)) return false;
950
951 if(InitBuf[i]=='\0') break;
952 }
953 return true;
954 }
955
956 SetError(41,0,cp);
957 return false;
958 }
959
960
961 ///////////////////////////////////////
962 // 単発式([]で囲まれていない)
963 ///////////////////////////////////////
964
965 if( subscripts.size() > 0 ){
966 SetError(41,0,cp);
967 return false;
968 }
969
970 double dbl;
971 _int64 i64data;
972 Type calcType;
973
974 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
975 //動的データだった場合
976 return false;
977 }
978 if( calcType.IsReal() ){
979 memcpy(&dbl,&i64data,sizeof(double));
980 i64data=(_int64)dbl;
981 }
982 else dbl=(double)i64data;
983
984 //型チェック
985 CheckDifferentType(
986 type,
987 calcType,
988 0,0);
989
990 if( type.IsDouble() ){
991 memcpy(&i64data,&dbl,sizeof(double));
992
993 //mov rax,i64data
994 compiler.codeGenerator.op_mov64_ToReg(REG_RAX,i64data);
995
996 //mov qword ptr[rsp+offset],rax
997 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
998 obp-=sizeof(long);
999 AddLocalVarAddrSchedule();
1000 obp+=sizeof(long);
1001 }
1002 else if( type.IsSingle() ){
1003 float flt;
1004 flt=(float)dbl;
1005
1006 //mov dword ptr[rsp+offset],value
1007 compiler.codeGenerator.op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,*(int *)&flt);
1008 obp-=sizeof(long)+sizeof(long);
1009 AddLocalVarAddrSchedule();
1010 obp+=sizeof(long)+sizeof(long);
1011 }
1012 else if( type.Is64() || type.IsPointer() ){
1013 if(type.GetBasicType()==typeOfPtrChar ){
1014 //文字列定数のとき
1015
1016 char *temp;
1017 temp=(char *)i64data;
1018 i2=compiler.GetDataTable().AddString( temp );
1019 HeapDefaultFree(temp);
1020
1021 //mov rax,i2
1022 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RAX,i2);
1023 obp-=sizeof(long);
1024 pobj_DataTableSchedule->add();
1025 obp+=sizeof(long);
1026
1027 //mov qword ptr[rsp+offset],rax
1028 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1029 obp-=sizeof(long);
1030 AddLocalVarAddrSchedule();
1031 obp+=sizeof(long);
1032 }
1033 else{
1034 if(i64data&0xFFFFFFFF00000000){
1035 //mov rax,i64data
1036 compiler.codeGenerator.op_mov64_ToReg(REG_RAX,i64data);
1037
1038 //mov qword ptr[rsp+offset],rax
1039 compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1040 obp-=sizeof(long);
1041 AddLocalVarAddrSchedule();
1042 obp+=sizeof(long);
1043 }
1044 else{
1045 //mov qword ptr[rsp+offset],value
1046 compiler.codeGenerator.op_mov_MV(sizeof(_int64),REG_RSP,offset,USE_OFFSET,(int)i64data);
1047 obp-=sizeof(long)+sizeof(long);
1048 AddLocalVarAddrSchedule();
1049 obp+=sizeof(long)+sizeof(long);
1050 }
1051 }
1052 }
1053 else if( type.IsDWord() || type.IsLong() ){
1054 //mov dword ptr[rsp+offset],value
1055 compiler.codeGenerator.op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,(int)i64data);
1056 obp-=sizeof(long)+sizeof(long);
1057 AddLocalVarAddrSchedule();
1058 obp+=sizeof(long)+sizeof(long);
1059 }
1060 else if( type.IsWord() || type.IsInteger() ){
1061 //mov word ptr[rsp+offset],value
1062 compiler.codeGenerator.op_mov_MV(sizeof(short),REG_RSP,offset,USE_OFFSET,(int)i64data);
1063 obp-=sizeof(long)+sizeof(short);
1064 AddLocalVarAddrSchedule();
1065 obp+=sizeof(long)+sizeof(short);
1066 }
1067 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1068 //mov byte ptr[rsp+offset],value
1069 compiler.codeGenerator.op_mov_MV(sizeof(char),REG_RSP,offset,USE_OFFSET,(int)i64data);
1070 obp-=sizeof(long)+sizeof(char);
1071 AddLocalVarAddrSchedule();
1072 obp+=sizeof(long)+sizeof(char);
1073 }
1074 return true;
1075}
1076
1077void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1078 if( UserProc::IsGlobalAreaCompiling() ){
1079 /////////////////////////
1080 // グローバル変数
1081 /////////////////////////
1082
1083 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1084 }
1085 else{
1086 /////////////////
1087 // ローカル変数
1088 /////////////////
1089
1090 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( VarName ) ){
1091 //2重定義のエラー
1092 SetError(15,VarName,cp);
1093 return;
1094 }
1095
1096 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1097
1098 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter );
1099
1100 if( subscripts.size() > 0 ){
1101 //配列あり
1102 pVar->SetArray( subscripts );
1103 }
1104
1105 //レキシカルスコープ
1106 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1107 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1108 pVar->bLiving=TRUE;
1109
1110 //エラー用
1111 pVar->source_code_address=cp;
1112
1113 // 変数を追加
1114 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1115
1116 //アラインメントを考慮
1117 if( pVar->GetType().IsStruct() ){
1118 int alignment = pVar->GetType().GetClass().iAlign;
1119
1120 if( alignment ){
1121 if( AllLocalVarSize % alignment ){
1122 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1123 }
1124 }
1125
1126 if( alignment == PTR_SIZE*2 ){
1127 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1128 // (例:CONTEXT構造体など)
1129 // 呼び出し側のオフセットズレを考慮する
1130
1131 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1132 AllLocalVarSize += PTR_SIZE;
1133 }
1134 }
1135 }
1136
1137 AllLocalVarSize += pVar->GetMemorySize();
1138 pVar->SetOffsetAddress( AllLocalVarSize );
1139
1140 //レキシカルスコープ
1141 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1142 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1143 pVar->bLiving=TRUE;
1144
1145 if(InitBuf[0]){
1146 //初期代入時のみ、書き込みアクセスを許可する
1147 if( isConst ){
1148 pVar->ConstOff();
1149 }
1150
1151 int result = 0;
1152 if( !pVar->GetType().IsObject() ){
1153 result = InitLocalVar(-pVar->GetOffsetAddress(),
1154 pVar->GetType(),
1155 pVar->GetSubscripts(),
1156 InitBuf);
1157 }
1158
1159 if(!result){
1160 //動的な式だった場合は代入演算を行う
1161 char temporary[8192];
1162 sprintf(temporary,"%s=%s",VarName,InitBuf);
1163 OpcodeCalc(temporary);
1164 }
1165
1166 if( isConst ){
1167 pVar->ConstOn();
1168 }
1169 }
1170 else{
1171 //0初期化
1172
1173 //mov r8, 0
1174 compiler.codeGenerator.op_zero_reg( REG_R8 );
1175
1176 //mov rdx, VarSize
1177 compiler.codeGenerator.op_mov_RV( sizeof(_int64), REG_RDX, pVar->GetMemorySize() );
1178
1179 //mov rcx, rsp
1180 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RSP );
1181
1182 //add rcx, offset
1183 compiler.codeGenerator.op_add_RV( REG_RCX, -pVar->GetOffsetAddress() );
1184 obp-=sizeof(long);
1185 AddLocalVarAddrSchedule();
1186 obp+=sizeof(long);
1187
1188 //call FillMemory
1189 DllProc *pDllProc;
1190 pDllProc=GetDeclareHash("FillMemory");
1191 compiler.codeGenerator.op_call( pDllProc );
1192 }
1193 }
1194
1195 //コンストラクタ呼び出し
1196 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1197 char objectSize[255];
1198 if( subscripts.size() == 0 ){
1199 objectSize[0] = 0;
1200 }
1201 else{
1202 if( subscripts.size() > 1 ){
1203 SetError(300,NULL,cp);
1204 }
1205 sprintf( objectSize, "%d", subscripts[0] );
1206 }
1207 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1208
1209 Type tempType;
1210 RELATIVE_VAR RelativeVar;
1211 GetVarOffset( true, false, VarName, &RelativeVar, tempType );
1212 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1213 SetError();
1214 }
1215 SetVariableFromRax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1216 }
1217}
1218void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1219 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1220
1221 if(pRelativeVar->dwKind==VAR_GLOBAL){
1222 if(pRelativeVar->bOffsetOffset){
1223 //add r11,offset
1224 OpBuffer[obp++]=(char)0x49;
1225 OpBuffer[obp++]=(char)0x81;
1226 OpBuffer[obp++]=(char)0xC3;
1227 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1228 pobj_GlobalVarSchedule->add();
1229 obp+=sizeof(long);
1230
1231 //mov reg,r11
1232 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1233 }
1234 else{
1235 //mov reg,offset
1236 compiler.codeGenerator.op_mov64_ToReg(reg,(long)pRelativeVar->offset);
1237 obp-=sizeof(long);
1238 pobj_GlobalVarSchedule->add();
1239 obp+=sizeof(long);
1240 }
1241 }
1242 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
1243 if(pRelativeVar->bOffsetOffset){
1244 //add r11,qword ptr[offset]
1245 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelativeVar->offset, MOD_DISP32 );
1246 obp-=sizeof(long);
1247 pobj_GlobalVarSchedule->add();
1248 obp+=sizeof(long);
1249 }
1250 else{
1251 //mov r11,qword ptr[offset]
1252 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelativeVar->offset,MOD_DISP32);
1253 obp-=sizeof(long);
1254 pobj_GlobalVarSchedule->add();
1255 obp+=sizeof(long);
1256 }
1257
1258 goto directmem;
1259 }
1260 else if(pRelativeVar->dwKind==VAR_LOCAL){
1261 if(pRelativeVar->bOffsetOffset){
1262 //add r11,offset
1263 OpBuffer[obp++]=(char)0x49;
1264 OpBuffer[obp++]=(char)0x81;
1265 OpBuffer[obp++]=(char)0xC3;
1266 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1267 AddLocalVarAddrSchedule();
1268 obp+=sizeof(long);
1269
1270 //add r11,rsp
1271 compiler.codeGenerator.op_add_RR(REG_R11,REG_RSP);
1272
1273 //mov reg,r11
1274 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1275 }
1276 else{
1277 //mov reg,rsp
1278 compiler.codeGenerator.op_mov_RR(reg,REG_RSP);
1279
1280 //add reg,offset
1281 compiler.codeGenerator.op_add_RV(reg,(int)pRelativeVar->offset);
1282 obp-=sizeof(long);
1283 AddLocalVarAddrSchedule();
1284 obp+=sizeof(long);
1285 }
1286 }
1287 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
1288 if(pRelativeVar->bOffsetOffset){
1289 //add r11,qword ptr[rsp+offset]
1290 OpBuffer[obp++]=(char)0x4C;
1291 OpBuffer[obp++]=(char)0x03;
1292 OpBuffer[obp++]=(char)0x9C;
1293 OpBuffer[obp++]=(char)0x24;
1294 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1295 AddLocalVarAddrSchedule();
1296 obp+=sizeof(long);
1297 }
1298 else{
1299 //mov r11,qword ptr[rsp+offset]
1300 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
1301 obp-=sizeof(long);
1302 AddLocalVarAddrSchedule();
1303 obp+=sizeof(long);
1304 }
1305
1306 goto directmem;
1307 }
1308 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1309directmem:
1310 //mov reg,r11
1311 compiler.codeGenerator.op_mov_RR(reg,REG_R11);
1312 }
1313}
1314
1315bool Compile_AddGlobalRootsForGc(){
1316 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1317 if( !pUserProc_AddGlobalRootPtr ){
1318 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1319 return false;
1320 }
1321
1322 BOOST_FOREACH( const Variable *pVar, compiler.GetMeta().GetGlobalVars() ){
1323 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1324 // オブジェクトまたはポインタだったとき
1325 // ※構造体も含む(暫定対応)
1326
1327 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1328 //mov r8,count
1329 compiler.codeGenerator.op_mov_RV(sizeof(_int64), REG_R8,pVar->GetMemorySize()/PTR_SIZE);
1330
1331 // ルートポインタを引き渡す
1332 //mov rdx,offset
1333 compiler.codeGenerator.op_mov_RV(sizeof(_int64), REG_RDX,(int)pVar->GetOffsetAddress());
1334 obp-=sizeof(long);
1335 pobj_GlobalVarSchedule->add();
1336 obp+=sizeof(long);
1337
1338 // Thisポインタを引き渡す
1339 SetThisPtrToReg(REG_RCX);
1340
1341 // call AddGlobalRootPtr
1342 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1343
1344 ReallocNativeCodeBuffer();
1345 }
1346 }
1347
1348 return true;
1349}
Note: See TracBrowser for help on using the repository browser.