source: dev/BasicCompiler32/Compile_Var.cpp@ 135

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

Method/Memberのリファクタリング

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