source: dev/BasicCompiler64/Compile_Var.cpp@ 97

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

関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

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