source: dev/BasicCompiler64/Compile_Var.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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