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

Last change on this file since 253 was 253, checked in by dai_9181, 17 years ago
File size: 33.1 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
6#include <LexicalScope.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.localVarPertialSchedules.push_back(
966 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
967 );
968
969 //mov eax,LOLONG(dbl)
970 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
971
972 //mov dword ptr[ebp+offset],eax
973 compiler.codeGenerator.localVarPertialSchedules.push_back(
974 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
975 );
976 }
977 else if( type.IsSingle() ){
978 float flt;
979 flt=(float)dbl;
980
981 //mov eax,InitValue
982 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
983
984 //mov dword ptr[ebp+offset],eax
985 compiler.codeGenerator.localVarPertialSchedules.push_back(
986 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
987 );
988 }
989 else if( type.Is64() ){
990 //mov eax,HILONG(i64data)
991 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
992
993 //mov dword ptr[ebp+offset+sizeof(long)],eax
994 compiler.codeGenerator.localVarPertialSchedules.push_back(
995 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
996 );
997
998 //mov eax,LOLONG(i64data)
999 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
1000
1001 //mov dword ptr[ebp+offset],eax
1002 compiler.codeGenerator.localVarPertialSchedules.push_back(
1003 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1004 );
1005 }
1006 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1007 if(type.GetBasicType()==typeOfPtrChar){
1008 //文字列定数のとき
1009
1010 char *temp;
1011 temp=(char *)i64data;
1012 i2=compiler.GetDataTable().AddString(temp,lstrlen(temp));
1013 HeapDefaultFree(temp);
1014
1015 //mov eax,DataPos
1016 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
1017 }
1018 else{
1019 //mov eax,InitValue
1020 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
1021 }
1022
1023 //mov dword ptr[ebp+offset],eax
1024 compiler.codeGenerator.localVarPertialSchedules.push_back(
1025 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1026 );
1027 }
1028 else if( type.IsWord() || type.IsInteger() ){
1029 //mov word ptr[ebp+offset],InitValue
1030 compiler.codeGenerator.localVarPertialSchedules.push_back(
1031 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1032 );
1033 }
1034 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1035 //mov byte ptr[ebp+offset],InitValue
1036 compiler.codeGenerator.localVarPertialSchedules.push_back(
1037 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1038 );
1039 }
1040
1041 return true;
1042}
1043
1044void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1045 if( UserProc::IsGlobalAreaCompiling() ){
1046 /////////////////////////
1047 // グローバル変数
1048 /////////////////////////
1049
1050 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1051 }
1052 else{
1053 /////////////////
1054 // ローカル変数
1055 /////////////////
1056
1057 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( Symbol( VarName ) ) ){
1058 //2重定義のエラー
1059 SetError(15,VarName,cp);
1060 return;
1061 }
1062
1063 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1064
1065 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter );
1066
1067 if( subscripts.size() > 0 ){
1068 //配列あり
1069 pVar->SetArray( subscripts );
1070 }
1071
1072 //レキシカルスコープ
1073 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1074 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1075 pVar->bLiving=TRUE;
1076
1077 //エラー用
1078 pVar->source_code_address=cp;
1079
1080 // 変数を追加
1081 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1082
1083 //アラインメントを考慮
1084 if( pVar->GetType().IsStruct() ){
1085 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1086
1087 if( alignment ){
1088 if( AllLocalVarSize % alignment ){
1089 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1090 }
1091 }
1092
1093 if( alignment == PTR_SIZE*2 ){
1094 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1095 // (例:CONTEXT構造体など)
1096 // 呼び出し側のオフセットズレを考慮する
1097
1098 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1099 AllLocalVarSize += PTR_SIZE;
1100 }
1101 }
1102 }
1103
1104 AllLocalVarSize += pVar->GetMemorySize();
1105 pVar->SetOffsetAddress( AllLocalVarSize );
1106
1107 //レキシカルスコープ
1108 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1109 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1110 pVar->bLiving=TRUE;
1111
1112 if(InitBuf[0]){
1113 //初期代入時のみ、書き込みアクセスを許可する
1114 if( isConst ){
1115 pVar->ConstOff();
1116 }
1117
1118 int result = 0;
1119 if( !pVar->GetType().IsObject() ){
1120 result = InitLocalVar(-pVar->GetOffsetAddress(),
1121 pVar->GetType(),
1122 pVar->GetSubscripts(),
1123 InitBuf);
1124 }
1125
1126 if(!result){
1127 //動的な式だった場合は代入演算を行う
1128 char temporary[8192];
1129 sprintf(temporary,"%s=%s",VarName,InitBuf);
1130 OpcodeCalc(temporary);
1131 }
1132
1133 if( isConst ){
1134 pVar->ConstOn();
1135 }
1136 }
1137 else{
1138 //push 0
1139 compiler.codeGenerator.op_push_V(0);
1140
1141 //push VarSize
1142 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1143
1144 //mov eax,ebp
1145 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
1146
1147 //add eax,offset
1148 compiler.codeGenerator.localVarPertialSchedules.push_back(
1149 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1150 );
1151
1152 //push eax
1153 compiler.codeGenerator.op_push(REG_EAX);
1154
1155 //call FillMemory
1156 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
1157 }
1158 }
1159
1160 //New呼び出し
1161 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1162 char objectSize[255];
1163 if( subscripts.size() == 0 ){
1164 objectSize[0] = 0;
1165 }
1166 else{
1167 if( subscripts.size() > 1 ){
1168 SetError(300,NULL,cp);
1169 }
1170 sprintf( objectSize, "%d", subscripts[0] );
1171 }
1172 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1173
1174 //pop eax
1175 compiler.codeGenerator.op_pop( REG_EAX );
1176
1177 RELATIVE_VAR RelativeVar;
1178 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
1179 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1180 SetError();
1181 }
1182 SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1183 }
1184}
1185
1186void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1187 if(pRelativeVar->dwKind==VAR_GLOBAL){
1188 if(pRelativeVar->bOffsetOffset){
1189 //lea eax,dword ptr[ecx+offset]
1190 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
1191 }
1192 else{
1193 //mov eax,offset
1194 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
1195 }
1196 }
1197 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1198 if(pRelativeVar->bOffsetOffset){
1199 //mov eax,ecx
1200 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1201
1202 //add eax,dword ptr[offset]
1203 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1204 }
1205 else{
1206 //mov eax,dword ptr[offset]
1207 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1208 }
1209 }
1210 else if(pRelativeVar->dwKind==VAR_LOCAL){
1211 if(pRelativeVar->bOffsetOffset){
1212 //add ecx,offset
1213 compiler.codeGenerator.localVarPertialSchedules.push_back(
1214 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1215 );
1216
1217 //lea eax,dword ptr[ebp+ecx]
1218 compiler.codeGenerator.PutOld(
1219 (char)0x8D,
1220 (char)0x44,
1221 (char)0x0D,
1222 (char)0x00
1223 );
1224 }
1225 else{
1226 //lea eax,dword ptr[ecx+offset]
1227 compiler.codeGenerator.localVarPertialSchedules.push_back(
1228 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1229 );
1230 }
1231 }
1232 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1233 if(pRelativeVar->bOffsetOffset){
1234 //mov eax,ecx
1235 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1236
1237 //add eax,dword ptr[ebp+offset]
1238 compiler.codeGenerator.localVarPertialSchedules.push_back(
1239 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1240 );
1241 }
1242 else{
1243 //mov eax,dword ptr[ebp+offset]
1244 compiler.codeGenerator.localVarPertialSchedules.push_back(
1245 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1246 );
1247 }
1248 }
1249 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1250 //mov eax,ecx
1251 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1252 }
1253}
1254void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1255 if( reg != REG_EAX ){
1256 SetError();
1257 //TODO: 未完成
1258 }
1259 SetVarPtrToEax( pRelativeVar );
1260}
1261
1262bool Compile_AddGlobalRootsForGc(){
1263 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1264 if( !pUserProc_AddGlobalRootPtr ){
1265 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1266 return false;
1267 }
1268
1269 BOOST_FOREACH( const Variable *pVar, compiler.GetMeta().GetGlobalVars() ){
1270 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1271 // オブジェクトまたはポインタだったとき
1272 // ※構造体も含む(暫定対応)
1273
1274 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1275 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
1276
1277
1278 /////////////////////////////
1279 // ルートポインタを引き渡す
1280
1281 //mov eax,offset
1282 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1283
1284 //push eax
1285 compiler.codeGenerator.op_push( REG_EAX );
1286
1287 //
1288 /////////////////////////////
1289
1290
1291 /////////////////////////////
1292 // Thisポインタを引き渡す
1293
1294 SetThisPtrToReg(REG_EAX);
1295
1296 //push eax
1297 compiler.codeGenerator.op_push( REG_EAX );
1298
1299 //
1300 /////////////////////////////
1301
1302
1303 // call AddGlobalRootPtr
1304 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1305
1306 ReallocNativeCodeBuffer();
1307 }
1308 }
1309
1310 return true;
1311}
Note: See TracBrowser for help on using the repository browser.