source: dev/trunk/abdev/BasicCompiler32/Compile_Var.cpp@ 159

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

プロジェクト内を整理。jengaライブラリのベースを作成。

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