source: dev/BasicCompiler32/Compile_Var.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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