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

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