source: dev/BasicCompiler64/Compile_Var.cpp@ 36

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

Boolean型に対応。

File size: 31.9 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 && LocalVar[i].ScopeLevel <= obj_LexScopes.GetNowLevel() //現在のスコープレベルを超さないもの(Returnによる解放処理中を考慮)
412 ){
413 if(lstrcmp(VarName,LocalVar[i].name)==0) break;
414 }
415 }
416 if(i>=0){
417 //ポインタ変数の場合
418 if(IsPtrType(LocalVar[i].type)){
419 if(LocalVar[i].SubScripts[0]==-1){
420 lstrcpy(lpPtrOffset,array);
421 array[0]=0;
422 }
423 }
424 else{
425 if(lpPtrOffset[0]){
426 SetError(16,variable,cp);
427 pRelativeVar->dwKind=NON_VAR;
428 return 0;
429 }
430 }
431
432 pRelativeVar->offset=-LocalVar[i].offset;
433 pRelativeVar->bOffsetOffset=0;
434 if(LocalVar[i].fRef) pRelativeVar->dwKind=VAR_REFLOCAL;
435 else pRelativeVar->dwKind=VAR_LOCAL;
436 *pType=LocalVar[i].type;
437 lpIndex=LocalVar[i].u.index;
438 if(plpIndex) *plpIndex=lpIndex;
439 pSubScripts=LocalVar[i].SubScripts;
440 bConst = LocalVar[i].bConst;
441
442 goto ok;
443 }
444 }
445
446
447 if(pobj_CompilingClass){
448 //////////////////////
449 // クラスメンバの参照
450 //////////////////////
451
452 if(lstrcmpi(variable,"This")==0){
453 //自身のオブジェクトのThisポインタをr11にコピー
454 SetThisPtrToReg(REG_R11);
455
456 *pType=DEF_OBJECT;
457 pRelativeVar->dwKind=VAR_DIRECTMEM;
458
459 if(plpIndex) *plpIndex=(LONG_PTR)pobj_CompilingClass;
460 return 1;
461 }
462
463 if(memicmp(variable,"This.",5)==0){
464 //Thisオブジェクトのメンバを参照するとき
465 SlideString(variable+5,-5);
466 lstrcpy(VarName,variable);
467 }
468 else{
469 //クラス内メンバを参照するとき(通常)
470
471 for(i=0;i<pobj_CompilingClass->iMemberNum;i++){
472 if(lstrcmp(VarName,pobj_CompilingClass->ppobj_Member[i]->name)==0) break;
473 }
474 if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember;
475 }
476
477 //Const修飾子のメソッド内でメンバ書き込みアクセスが発生したとき
478 //(コンストラクタ、デストラクタ内を除く)
479 CMethod *pMethod = pobj_DBClass->GetNowCompilingMethodInfo();
480 if( isWriteAccess &&
481 pMethod->isConst &&
482 pobj_CompilingClass->IsCompilingConstructor() == false &&
483 pobj_CompilingClass->IsCompilingDestructor() == false
484 ){
485 SetError(131, NULL, cp );
486 }
487
488 //自身のオブジェクトのThisポインタをr11にコピー
489 SetThisPtrToReg(REG_R11);
490
491 pRelativeVar->dwKind=VAR_DIRECTMEM;
492 if(!GetMemberOffset(
493 isErrorEnabled,
494 isWriteAccess,
495 pobj_CompilingClass,
496 variable,
497 pType,
498 pRelativeVar,
499 &lpIndex,1)) return 0;
500 if(plpIndex) *plpIndex=lpIndex;
501 return 1;
502 }
503
504NonClassMember:
505
506 //////////////////////////
507 // 静的ローカル変数
508 // ※"Static.Object.Method.Variable"
509 //////////////////////////
510
511 char temporary[VN_SIZE];
512 extern SUBINFO *pCompilingSubInfo;
513 if(pCompilingSubInfo){
514 GetNowStaticVarFullName(VarName,temporary);
515
516 for(i=0;i<MaxGlobalVarNum;i++){
517 if(lstrcmp(temporary,GlobalVar[i].name)==0) break;
518 }
519 if(i!=MaxGlobalVarNum){
520 goto GlobalOk;
521 }
522 }
523
524
525 //////////////////////////
526 // クラスの静的メンバ
527 //////////////////////////
528
529 if(member[0]){
530 lstrcpy(temporary,member);
531
532 char tempMember[VN_SIZE];
533 char tempArray[VN_SIZE];
534 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,&i);
535
536 char temp2[VN_SIZE];
537 sprintf(temp2,"%s.%s",VarName,temporary);
538 for(i=0;i<MaxGlobalVarNum;i++){
539 if(lstrcmp(temp2,GlobalVar[i].name)==0) break;
540 }
541
542 if(i!=MaxGlobalVarNum){
543 lstrcpy(member,tempMember);
544 lstrcpy(array,tempArray);
545 goto GlobalOk;
546 }
547 }
548
549 if(pobj_CompilingClass){
550 //自身のクラスから静的メンバを参照する場合
551 char temp2[VN_SIZE];
552 sprintf(temp2,"%s.%s",pobj_CompilingClass->name,VarName);
553 for(i=0;i<MaxGlobalVarNum;i++){
554 if(lstrcmp(temp2,GlobalVar[i].name)==0) break;
555 }
556
557 if(i!=MaxGlobalVarNum){
558 goto GlobalOk;
559 }
560 }
561
562
563 /////////////////////
564 // グローバル変数
565 /////////////////////
566
567 for(i=MaxGlobalVarNum-1;i>=0;i--){ //レキシカルスコープを考慮してバックサーチ
568 if( GlobalVar[i].bLiving //現在のスコープで有効なもの
569 && GlobalVar[i].ScopeLevel <= obj_LexScopes.GetNowLevel() //現在のスコープレベルを超さないもの(Returnによる解放処理中を考慮)
570 ){
571 if(lstrcmp(VarName,GlobalVar[i].name)==0) break;
572 }
573 }
574 if(i>=0){
575 goto GlobalOk;
576 }
577
578 if(isErrorEnabled) SetError(3,variable,cp);
579 pRelativeVar->dwKind=NON_VAR;
580 return 0;
581
582
583
584GlobalOk:
585 //ポインタ変数の場合
586 if(IsPtrType(GlobalVar[i].type)){
587 if(GlobalVar[i].SubScripts[0]==-1){
588 lstrcpy(lpPtrOffset,array);
589 array[0]=0;
590 }
591 }
592 else{
593 if(lpPtrOffset[0]){
594 SetError(16,variable,cp);
595 pRelativeVar->dwKind=NON_VAR;
596 return 0;
597 }
598 }
599
600 pRelativeVar->offset=GlobalVar[i].offset;
601 pRelativeVar->bOffsetOffset=0;
602 pRelativeVar->dwKind=VAR_GLOBAL;
603 *pType=GlobalVar[i].type;
604 lpIndex=GlobalVar[i].u.index;
605 if(plpIndex) *plpIndex=lpIndex;
606 pSubScripts=GlobalVar[i].SubScripts;
607 bConst = GlobalVar[i].bConst;
608
609
610
611ok:
612
613 if( bConst && isWriteAccess ){
614 //Const定義の変数に書き込みアクセスをしようとした場合
615 if( *pType == DEF_OBJECT ){
616 //オブジェクト定数
617 SetError(130, VarName, cp );
618 }
619 else{
620 //一般のConst変数
621 SetError(61,VarName,cp);
622 }
623 }
624
625 if(array[0]==0&&pSubScripts[0]!=-1){
626 //配列の先頭ポインタを示す場合
627 *pType|=FLAG_PTR;
628 if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM);
629 return 1;
630 }
631
632 if(array[0]||member[0]){
633 //xor r11,r11(r11を0に初期化する)
634 //※r11は変数ベースアドレスからの相対オフセットを示す
635 op_zero_reg(REG_R11);
636
637 pRelativeVar->bOffsetOffset=1;
638 }
639 if(array[0]){
640 if(!GetArrayOffset(pSubScripts,array,*pType,lpIndex)){
641 SetError(14,variable,cp);
642 pRelativeVar->dwKind=NON_VAR;
643 return 0;
644 }
645 }
646 if(member[0]){
647 if(*pType==DEF_OBJECT){
648 //実態オブジェクトのメンバを参照(obj.member)
649 if(RefType!=DEF_OBJECT){
650 SetError(104,VarName,cp);
651 pRelativeVar->dwKind=NON_VAR;
652 return 0;
653 }
654 }
655 else if(*pType==DEF_PTR_OBJECT){
656 //ポインタオブジェクトが示すメンバを参照
657 if(lpPtrOffset[0]){
658 //pObj[n].member
659 if(RefType!=DEF_OBJECT){
660 SetError(104,VarName,cp);
661 pRelativeVar->dwKind=NON_VAR;
662 return 0;
663 }
664 SetRelativeOffset(pType,lpIndex,pRelativeVar,lpPtrOffset);
665 pRelativeVar->dwKind=VAR_DIRECTMEM;
666 }
667 else{
668 //pObj->member
669 if(RefType!=DEF_PTR_OBJECT){
670 SetError(104,VarName,cp);
671 pRelativeVar->dwKind=NON_VAR;
672 return 0;
673 }
674
675 SetVarPtrToReg(REG_R12,pRelativeVar);
676 pRelativeVar->dwKind=VAR_DIRECTMEM;
677
678 //mov r11,qword ptr[r12]
679 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
680 }
681 }
682 else if(*pType==MAKE_PTR_TYPE(DEF_OBJECT,2)){
683 //ポインタオブジェクトが示すメンバを参照
684 if(lpPtrOffset[0]){
685 //ppObj[n]->member
686 if(RefType!=DEF_PTR_OBJECT){
687 SetError(104,VarName,cp);
688 pRelativeVar->dwKind=NON_VAR;
689 return 0;
690 }
691
692 SetRelativeOffset(pType,lpIndex,pRelativeVar,lpPtrOffset);
693 pRelativeVar->dwKind=VAR_DIRECTMEM;
694
695
696 SetVarPtrToReg(REG_R12,pRelativeVar);
697
698 //mov r11,qword ptr[r12]
699 op_mov_RM(sizeof(_int64),REG_R11,REG_R12,0,MOD_BASE);
700 }
701 else{
702 SetError(104,VarName,cp);
703 pRelativeVar->dwKind=NON_VAR;
704 return 0;
705 }
706 }
707 else{
708 SetError(102,VarName,cp);
709 pRelativeVar->dwKind=NON_VAR;
710 return 0;
711 }
712
713 LONG_PTR lp2;
714 if(!GetMemberOffset(
715 isErrorEnabled,
716 isWriteAccess,
717 (CClass *)lpIndex,
718 member,pType,pRelativeVar,&lp2,0)) return 0;
719 if(plpIndex) *plpIndex=lp2;
720
721 return 1;
722 }
723
724 if(lpPtrOffset[0]){
725 SetRelativeOffset(pType,lpIndex,pRelativeVar,lpPtrOffset);
726 pRelativeVar->dwKind=VAR_DIRECTMEM;
727 }
728
729 return 1;
730}
731
732BOOL SetInitGlobalData(int offset,int type,LONG_PTR lpIndex,int *SubScripts,char *InitBuf){
733 extern BYTE *initGlobalBuf;
734 int i,i2,i3,TypeSize;
735 char temporary[VN_SIZE];
736
737 if(InitBuf[0]=='['){
738 SlideString(InitBuf+1,-1);
739 InitBuf[lstrlen(InitBuf)-1]=0;
740
741 TypeSize=GetTypeSize(type,lpIndex);
742
743 if(SubScripts[0]!=-1){
744 TypeSize*=JumpSubScripts(SubScripts+1);
745 i=0;
746 i2=0;
747 while(1){
748 if(SubScripts[0]<i2){
749 SetError(41,0,cp);
750 return 0;
751 }
752 i=GetOneParameter(InitBuf,i,temporary);
753 if(!SetInitGlobalData(
754 offset+i2*TypeSize,
755 type,
756 lpIndex,
757 SubScripts+1,
758 temporary)) return 0;
759 i2++;
760 if(InitBuf[i]=='\0') break;
761 }
762 return -1;
763 }
764
765 if(type==DEF_OBJECT){
766 CClass *pobj_c;
767 pobj_c=(CClass *)lpIndex;
768
769 for(i=0,i2=0;i2<pobj_c->iMemberNum;i2++){
770 i=GetOneParameter(InitBuf,i,temporary);
771
772 i3=GetSizeOfClassMember(pobj_c,pobj_c->ppobj_Member[i2]->name,NULL);
773
774 if(!SetInitGlobalData(offset+i3,
775 pobj_c->ppobj_Member[i2]->TypeInfo.type,
776 pobj_c->ppobj_Member[i2]->TypeInfo.u.lpIndex,
777 pobj_c->ppobj_Member[i2]->SubScripts,
778 temporary)) return 0;
779
780 if(InitBuf[i]=='\0') break;
781 }
782 if(i2+1!=pobj_c->iMemberNum){
783 SetError(41,0,cp);
784 return 0;
785 }
786 return 1;
787 }
788
789 SetError(41,0,cp);
790 return 0;
791 }
792
793
794 ///////////////////////////////////////
795 // 単発式([]で囲まれていない)
796 ///////////////////////////////////////
797
798 if( type == DEF_OBJECT){
799 //オブジェクトの場合はありえない
800 SetError(300,NULL,cp);
801 return 0;
802 }
803
804 if(SubScripts[0]!=-1){
805 SetError(41,0,cp);
806 return 0;
807 }
808
809 double dbl;
810 _int64 i64data;
811 int CalcType;
812 LONG_PTR lpCalcIndex;
813
814 CalcType=StaticCalculation(false, InitBuf,type,&i64data,&lpCalcIndex);
815 if(!CalcType){
816 //動的データだった場合
817 return 0;
818 }
819 if(IsRealNumberType(CalcType)){
820 memcpy(&dbl,&i64data,sizeof(double));
821 i64data=(_int64)dbl;
822 }
823 else dbl=(double)i64data;
824
825 //型チェック
826 CheckDifferentType(
827 type,
828 lpIndex,
829 CalcType,
830 lpCalcIndex,
831 0,0);
832
833 if(type==DEF_DOUBLE)
834 *(double *)(initGlobalBuf+offset)=(double)dbl;
835 else if(type==DEF_SINGLE)
836 *(float *)(initGlobalBuf+offset)=(float)dbl;
837 else if(type==DEF_INT64||type==DEF_QWORD||IsPtrType(type)){
838 if(type==DEF_PTR_BYTE&&lpCalcIndex==LITERAL_STRING){
839 //文字列定数のとき
840
841 char *temp;
842 temp=(char *)i64data;
843 i2=AddDataTable(temp,lstrlen(temp));
844 HeapDefaultFree(temp);
845
846 //mov rax,DataPos
847 op_mov_RV(sizeof(_int64),REG_RAX,i2);
848 obp-=sizeof(long);
849 pobj_DataTableSchedule->add();
850 obp+=sizeof(long);
851
852 //mov qword ptr[offset],rax
853 op_mov_MR(sizeof(_int64),REG_RAX,0,offset,MOD_DISP32);
854 obp-=sizeof(long);
855 pobj_GlobalVarSchedule->add();
856 obp+=sizeof(long);
857 }
858 else{
859 *(_int64 *)(initGlobalBuf+offset)=i64data;
860 }
861 }
862 else if(type==DEF_LONG||type==DEF_DWORD)
863 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
864 else if(type==DEF_INTEGER||type==DEF_WORD)
865 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
866 else if(type==DEF_CHAR||type==DEF_BYTE||type==DEF_BOOLEAN)
867 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
868
869 return 1;
870}
871BOOL InitLocalVar(int offset,int type,LONG_PTR lpIndex,int *SubScripts,char *InitBuf){
872 int i,i2,i3,TypeSize;
873 char temporary[VN_SIZE];
874
875 if(InitBuf[0]=='['){
876 SlideString(InitBuf+1,-1);
877 InitBuf[lstrlen(InitBuf)-1]=0;
878
879 TypeSize=GetTypeSize(type,lpIndex);
880
881 if(SubScripts[0]!=-1){
882 TypeSize*=JumpSubScripts(SubScripts+1);
883 i=0;
884 i2=0;
885 while(1){
886 if(SubScripts[0]<i2){
887 SetError(41,0,cp);
888 return 0;
889 }
890 i=GetOneParameter(InitBuf,i,temporary);
891 if(!InitLocalVar(
892 offset+i2*TypeSize,
893 type,
894 lpIndex,
895 SubScripts+1,
896 temporary)) return 0;
897 i2++;
898 if(InitBuf[i]=='\0') break;
899 }
900 return -1;
901 }
902
903 if(type==DEF_OBJECT){
904 CClass *pobj_c;
905 pobj_c=(CClass *)lpIndex;
906
907 for(i=0,i2=0;i2<pobj_c->iMemberNum;i2++){
908 i=GetOneParameter(InitBuf,i,temporary);
909
910 i3=GetSizeOfClassMember(pobj_c,pobj_c->ppobj_Member[i2]->name,NULL);
911
912 if(!InitLocalVar(offset+i3,
913 pobj_c->ppobj_Member[i2]->TypeInfo.type,
914 pobj_c->ppobj_Member[i2]->TypeInfo.u.lpIndex,
915 pobj_c->ppobj_Member[i2]->SubScripts,
916 temporary)) return 0;
917
918 if(InitBuf[i]=='\0') break;
919 }
920 if(i2+1!=pobj_c->iMemberNum){
921 SetError(41,0,cp);
922 return 0;
923 }
924 return 1;
925 }
926
927 SetError(41,0,cp);
928 return 0;
929 }
930
931 if(SubScripts[0]!=-1){
932 SetError(41,0,cp);
933 return 0;
934 }
935
936 double dbl;
937 _int64 i64data;
938 int CalcType;
939 LONG_PTR lpCalcIndex;
940 CalcType=StaticCalculation(false, InitBuf,type,&i64data,&lpCalcIndex);
941 if(!CalcType){
942 //動的データだった場合
943 return 0;
944 }
945 if(IsRealNumberType(CalcType)){
946 memcpy(&dbl,&i64data,sizeof(double));
947 i64data=(_int64)dbl;
948 }
949 else dbl=(double)i64data;
950
951 //型チェック
952 CheckDifferentType(
953 type,
954 lpIndex,
955 CalcType,
956 lpCalcIndex,
957 0,0);
958
959 if(type==DEF_DOUBLE){
960 memcpy(&i64data,&dbl,sizeof(double));
961
962 //mov rax,i64data
963 op_mov64_ToReg(REG_RAX,i64data);
964
965 //mov qword ptr[rsp+offset],rax
966 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
967 obp-=sizeof(long);
968 AddLocalVarAddrSchedule();
969 obp+=sizeof(long);
970 }
971 else if(type==DEF_SINGLE){
972 float flt;
973 flt=(float)dbl;
974
975 //mov dword ptr[rsp+offset],value
976 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,*(int *)&flt);
977 obp-=sizeof(long)+sizeof(long);
978 AddLocalVarAddrSchedule();
979 obp+=sizeof(long)+sizeof(long);
980 }
981 else if(type==DEF_INT64||type==DEF_QWORD||IsPtrType(type)){
982 if(type==DEF_PTR_BYTE&&lpCalcIndex==LITERAL_STRING){
983 //文字列定数のとき
984
985 char *temp;
986 temp=(char *)i64data;
987 i2=AddDataTable(temp,lstrlen(temp));
988 HeapDefaultFree(temp);
989
990 //mov rax,i2
991 op_mov_RV(sizeof(_int64),REG_RAX,i2);
992 obp-=sizeof(long);
993 pobj_DataTableSchedule->add();
994 obp+=sizeof(long);
995
996 //mov qword ptr[rsp+offset],rax
997 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{
1003 if(i64data&0xFFFFFFFF00000000){
1004 //mov rax,i64data
1005 op_mov64_ToReg(REG_RAX,i64data);
1006
1007 //mov qword ptr[rsp+offset],rax
1008 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,offset,MOD_BASE_DISP32);
1009 obp-=sizeof(long);
1010 AddLocalVarAddrSchedule();
1011 obp+=sizeof(long);
1012 }
1013 else{
1014 //mov qword ptr[rsp+offset],value
1015 op_mov_MV(sizeof(_int64),REG_RSP,offset,USE_OFFSET,(int)i64data);
1016 obp-=sizeof(long)+sizeof(long);
1017 AddLocalVarAddrSchedule();
1018 obp+=sizeof(long)+sizeof(long);
1019 }
1020 }
1021 }
1022 else if(type==DEF_LONG||type==DEF_DWORD){
1023 //mov dword ptr[rsp+offset],value
1024 op_mov_MV(sizeof(long),REG_RSP,offset,USE_OFFSET,(int)i64data);
1025 obp-=sizeof(long)+sizeof(long);
1026 AddLocalVarAddrSchedule();
1027 obp+=sizeof(long)+sizeof(long);
1028 }
1029 else if(type==DEF_INTEGER||type==DEF_WORD){
1030 //mov word ptr[rsp+offset],value
1031 op_mov_MV(sizeof(short),REG_RSP,offset,USE_OFFSET,(int)i64data);
1032 obp-=sizeof(long)+sizeof(short);
1033 AddLocalVarAddrSchedule();
1034 obp+=sizeof(long)+sizeof(short);
1035 }
1036 else if(type==DEF_CHAR||type==DEF_BYTE||type==DEF_BOOLEAN){
1037 //mov byte ptr[rsp+offset],value
1038 op_mov_MV(sizeof(char),REG_RSP,offset,USE_OFFSET,(int)i64data);
1039 obp-=sizeof(long)+sizeof(char);
1040 AddLocalVarAddrSchedule();
1041 obp+=sizeof(long)+sizeof(char);
1042 }
1043 return 1;
1044}
1045
1046
1047void dim(char *Parameter,DWORD dwFlag){
1048 extern BOOL bCompilingGlobal;
1049 extern HANDLE hHeap;
1050 int i2,i3,VarSize;
1051 char VarName[VN_SIZE];
1052
1053
1054 if(dwFlag & DIMFLAG_CONST){
1055 //////////////////////////////////
1056 // 定数変数の場合を考慮
1057 //////////////////////////////////
1058 for(i2=0;;i2++){
1059 if(Parameter[i2] == '=' ||
1060 Parameter[i2] == 1 && Parameter[i2] == ESC_AS ||
1061 Parameter[i2] =='('){
1062 VarName[i2] = 0;
1063 break;
1064 }
1065 VarName[i2] = Parameter[i2];
1066 }
1067
1068 //定数と2重定義されていないる場合は抜け出す
1069 if(CDBConst::obj.GetType(VarName)){
1070 return;
1071 }
1072
1073 //定数マクロとして定義されている場合は抜け出す
1074 if(GetConstHash(VarName)){
1075 return;
1076 }
1077 }
1078
1079
1080 //構文を解析
1081 int SubScripts[MAX_ARRAYDIM];
1082 TYPEINFO TypeInfo;
1083 char InitBuf[8192];
1084 char ConstractParameter[VN_SIZE];
1085 if(!GetDimentionFormat(Parameter,VarName,SubScripts,&TypeInfo,InitBuf,ConstractParameter))
1086 return;
1087
1088
1089 //定数と2重定義されていないかを調べる
1090 if(CDBConst::obj.GetType(VarName)){
1091 SetError(15,VarName,cp);
1092 return;
1093 }
1094
1095 //定数マクロとして定義されている場合
1096 if(GetConstHash(VarName)){
1097 SetError(15,VarName,cp);
1098 return;
1099 }
1100
1101
1102 //タイプサイズを取得
1103 int TypeSize;
1104 TypeSize=GetTypeSize(TypeInfo.type,TypeInfo.u.lpIndex);
1105
1106 if(dwFlag&DIMFLAG_STATIC){
1107 if(bCompilingGlobal){
1108 SetError(60,NULL,cp);
1109 return;
1110 }
1111
1112 /////////////////////
1113 // Static変数
1114 // ※"Static.Object.Method.Variable"
1115 /////////////////////
1116
1117 char temporary[VN_SIZE];
1118 GetNowStaticVarFullName(VarName,temporary);
1119
1120 AddGlobalVariable(temporary,SubScripts,&TypeInfo,TypeSize,InitBuf,ConstractParameter,dwFlag);
1121
1122 /*
1123 Note: 静的変数のコンストラクタ呼び出しは
1124 _System_InitStaticLocalVariables関数内で一括して行う
1125 */
1126 }
1127 else{
1128 if(bCompilingGlobal){
1129 /////////////////////////
1130 // グローバル変数
1131 /////////////////////////
1132
1133 AddGlobalVariable(VarName,SubScripts,&TypeInfo,TypeSize,InitBuf,ConstractParameter,dwFlag);
1134 }
1135 else{
1136 /////////////////
1137 // ローカル変数
1138 /////////////////
1139
1140 for(i2=0;i2<MaxLocalVarNum;i2++){
1141 if(LocalVar[i2].bLiving&&obj_LexScopes.GetNowLevel()==LocalVar[i2].ScopeLevel){
1142 if(lstrcmp(LocalVar[i2].name,VarName)==0){
1143 //2重定義のエラー
1144 SetError(15,VarName,cp);
1145 return;
1146 }
1147 }
1148 }
1149
1150 LocalVar=(VARIABLE *)HeapReAlloc(hHeap,0,LocalVar,(MaxLocalVarNum+1)*sizeof(VARIABLE));
1151
1152 for(i2=1,i3=0;i3<255;i3++){
1153 //配列要素数
1154 LocalVar[MaxLocalVarNum].SubScripts[i3]=SubScripts[i3];
1155
1156 if(SubScripts[i3]==-1) break;
1157 i2*=SubScripts[i3]+1;
1158 }
1159 VarSize=TypeSize*i2;
1160 if(VarSize%8) VarSize+=8-(VarSize%8);
1161
1162 VARIABLE *pVar = &LocalVar[MaxLocalVarNum];
1163
1164 MaxLocalVarNum++;
1165
1166 //変数データを追加
1167 lstrcpy(pVar->name,VarName);
1168 pVar->fRef=0;
1169 if(dwFlag & DIMFLAG_CONST) pVar->bConst = true;
1170 else pVar->bConst = false;
1171 if(SubScripts[0]==-1) pVar->bArray=0;
1172 else pVar->bArray=1;
1173 pVar->type=TypeInfo.type;
1174 pVar->u.index=TypeInfo.u.lpIndex;
1175 AllLocalVarSize+=VarSize;
1176 pVar->offset=AllLocalVarSize;
1177
1178 //レキシカルスコープ
1179 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1180 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1181 pVar->bLiving=TRUE;
1182
1183 if(InitBuf[0]){
1184 //初期代入時のみ、書き込みアクセスを許可する
1185 bool bConstBack = pVar->bConst;
1186 pVar->bConst = false;
1187
1188 int result = InitLocalVar(-pVar->offset,
1189 pVar->type,
1190 pVar->u.index,
1191 pVar->SubScripts,
1192 InitBuf);
1193
1194 if(!result){
1195 //動的な式だった場合は代入演算を行う
1196 char temporary[8192];
1197 sprintf(temporary,"%s=%s",VarName,InitBuf);
1198 OpcodeCalc(temporary);
1199 }
1200
1201 pVar->bConst = bConstBack;
1202 }
1203 else{
1204 //0初期化
1205
1206 //mov r8, 0
1207 op_zero_reg( REG_R8 );
1208
1209 //mov rdx, VarSize
1210 op_mov_RV( sizeof(_int64), REG_RDX, VarSize );
1211
1212 //mov rcx, rsp
1213 op_mov_RR( REG_RCX, REG_RSP );
1214
1215 //add rcx, offset
1216 op_add64_value( REG_RCX, -pVar->offset );
1217 obp-=sizeof(long);
1218 AddLocalVarAddrSchedule();
1219 obp+=sizeof(long);
1220
1221 //call FillMemory
1222 DECLAREINFO *pdi;
1223 pdi=GetDeclareHash("FillMemory");
1224 op_call( pdi );
1225 }
1226 }
1227
1228 //コンストラクタ呼び出し
1229 if(TypeInfo.type==DEF_OBJECT&&(dwFlag&DIMFLAG_NONCALL_CONSTRACTOR)==0){
1230 CallConstractor(VarName,SubScripts,TypeInfo,ConstractParameter);
1231 }
1232 }
1233
1234 if(TypeInfo.type==DEF_OBJECT){
1235 if(TypeInfo.u.pobj_Class->IsAbstract()){
1236 //抽象クラスだったとき
1237 SetError(125,TypeInfo.u.pobj_Class->name,cp);
1238 }
1239 }
1240}
1241void OpcodeDim(char *Parameter,DWORD dwFlag){
1242 int i,i2,i3,IsStr=0;
1243 char temporary[8192];
1244
1245 for(i=0,i2=0;;i++,i2++){
1246 if(Parameter[i]=='\"') IsStr^=1;
1247 if(Parameter[i]=='('&&IsStr==0){
1248 i3=GetStringInPare(temporary+i2,Parameter+i);
1249 i+=i3-1;
1250 i2+=i3-1;
1251 continue;
1252 }
1253 if(Parameter[i]=='['&&IsStr==0){
1254 i3=GetStringInBracket(temporary+i2,Parameter+i);
1255 i+=i3-1;
1256 i2+=i3-1;
1257 continue;
1258 }
1259 if((Parameter[i]==','&&IsStr==0)||
1260 Parameter[i]=='\0'){
1261 temporary[i2]=0;
1262
1263 dim(temporary,dwFlag);
1264
1265 if(Parameter[i]=='\0') break;
1266 i2=-1;
1267 continue;
1268 }
1269 temporary[i2]=Parameter[i];
1270 }
1271}
1272
1273void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1274 if(!IsGeneralReg(reg)) SetError(300,NULL,cp);
1275
1276 if(pRelativeVar->dwKind==VAR_GLOBAL){
1277 if(pRelativeVar->bOffsetOffset){
1278 //add r11,offset
1279 OpBuffer[obp++]=(char)0x49;
1280 OpBuffer[obp++]=(char)0x81;
1281 OpBuffer[obp++]=(char)0xC3;
1282 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1283 pobj_GlobalVarSchedule->add();
1284 obp+=sizeof(long);
1285
1286 //mov reg,r11
1287 op_mov64_ToReg_FromReg(reg,REG_R11);
1288 }
1289 else{
1290 //mov reg,offset
1291 op_mov64_ToReg(reg,(int)pRelativeVar->offset);
1292 obp-=sizeof(long);
1293 pobj_GlobalVarSchedule->add();
1294 obp+=sizeof(long);
1295 }
1296 }
1297 else if(pRelativeVar->dwKind==VAR_LOCAL){
1298 if(pRelativeVar->bOffsetOffset){
1299 //add r11,offset
1300 OpBuffer[obp++]=(char)0x49;
1301 OpBuffer[obp++]=(char)0x81;
1302 OpBuffer[obp++]=(char)0xC3;
1303 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1304 AddLocalVarAddrSchedule();
1305 obp+=sizeof(long);
1306
1307 //add r11,rsp
1308 op_add64_reg(REG_R11,REG_RSP);
1309
1310 //mov reg,r11
1311 op_mov64_ToReg_FromReg(reg,REG_R11);
1312 }
1313 else{
1314 //mov reg,rsp
1315 op_mov64_ToReg_FromReg(reg,REG_RSP);
1316
1317 //add reg,offset
1318 op_add64_value(reg,(int)pRelativeVar->offset);
1319 obp-=sizeof(long);
1320 AddLocalVarAddrSchedule();
1321 obp+=sizeof(long);
1322 }
1323 }
1324 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1325 if(pRelativeVar->bOffsetOffset){
1326 //add r11,qword ptr[rsp+offset]
1327 OpBuffer[obp++]=(char)0x4C;
1328 OpBuffer[obp++]=(char)0x03;
1329 OpBuffer[obp++]=(char)0x9C;
1330 OpBuffer[obp++]=(char)0x24;
1331 *((long *)(OpBuffer+obp))=(int)pRelativeVar->offset;
1332 AddLocalVarAddrSchedule();
1333 obp+=sizeof(long);
1334 }
1335 else{
1336 //mov r11,qword ptr[rsp+offset]
1337 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
1338 obp-=sizeof(long);
1339 AddLocalVarAddrSchedule();
1340 obp+=sizeof(long);
1341 }
1342
1343 goto directmem;
1344 }
1345 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1346directmem:
1347 //mov reg,r11
1348 op_mov64_ToReg_FromReg(reg,REG_R11);
1349 }
1350}
Note: See TracBrowser for help on using the repository browser.