source: dev/BasicCompiler64/Compile_Var.cpp@ 123

Last change on this file since 123 was 120, checked in by dai_9181, 18 years ago

Parameter::Equals静的メソッドを廃止し、Parameters::Equalsメソッドを用意。
ポインタに要するサイズよりも一回り大きなアラインメントが指定されているときに、呼び出し側のオフセットズレを考慮するよう、修正

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