source: dev/BasicCompiler64/Compile_Var.cpp@ 91

Last change on this file since 91 was 89, checked in by dai_9181, 18 years ago

実行時型情報の生成に対応。
関数の戻り値の型に抽象クラスを指定できるようにした。

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