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

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