source: dev/BasicCompiler32/Compile_Var.cpp@ 106

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

名前空間機能をクラスの静的メンバに適用。

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