source: dev/BasicCompiler64/Compile_Var.cpp@ 28

Last change on this file since 28 was 28, checked in by dai_9181, 17 years ago

・【32ビットコンパイラ】戻り値に実態オブジェクトを持つインデクサを呼び出すと強制終了してしまうバグを修正。
・仮想関数のオーバーロードが正常に動作しないバグを修正。
・純仮想関数(抽象メソッド)が仮想関数でオーバーロードされていると、クラスのインスタンスが生成できてしまうバグを修正。

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