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

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