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

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