source: dev/BasicCompiler32/Compile_Var.cpp@ 104

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

TODOコメントを追加。

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