source: dev/BasicCompiler64/Compile_Var.cpp@ 11

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

Const変数の書き込み規制を有効化(グローバル/ローカル変数のみ)
定数オブジェクトと定数メンバは未実装。

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