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

Last change on this file since 288 was 288, checked in by dai_9181, 17 years ago
File size: 33.8 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 int i2,i3;
719 char temporary[VN_SIZE];
720 char InitBuf[VN_SIZE];
721 lstrcpy( InitBuf, lpszInitBuf );
722
723 if(InitBuf[0]=='['){
724 SlideString(InitBuf+1,-1);
725 InitBuf[lstrlen(InitBuf)-1]=0;
726
727 int typeSize = type.GetSize();
728
729 if( subscripts.size() > 0 ){
730 Subscripts nestSubscripts;
731 for( int i=1; i<(int)subscripts.size(); i++ )
732 {
733 nestSubscripts.push_back( subscripts[i] );
734 }
735
736 typeSize*=JumpSubScripts( nestSubscripts );
737 {
738 int i=0;
739 i2=0;
740 while(1){
741 if( subscripts[0] < i2 ){
742 SetError(41,0,cp);
743 return 0;
744 }
745 i=GetOneParameter(InitBuf,i,temporary);
746 if(!SetInitGlobalData(
747 offset+i2*typeSize,
748 type,
749 nestSubscripts,
750 temporary)) return false;
751 i2++;
752 if(InitBuf[i]=='\0') break;
753 }
754 }
755 return true;
756 }
757
758 if(type.IsStruct()){
759 const CClass &objClass = type.GetClass();
760
761 int i = 0;
762 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
763 if(InitBuf[i]=='\0'){
764 SetError(41,0,cp);
765 return false;
766 }
767
768 i=GetOneParameter(InitBuf,i,temporary);
769
770 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
771
772 if(!SetInitGlobalData(offset+i3,
773 pMember->GetType(),
774 pMember->GetSubscripts(),
775 temporary)) return false;
776 }
777 return true;
778 }
779
780 SetError(41,0,cp);
781 return false;
782 }
783
784
785 ///////////////////////////////////////
786 // 単発式([]で囲まれていない)
787 ///////////////////////////////////////
788
789 if( type.IsObject() || type.IsStruct() ){
790 //オブジェクトまたは構造体の場合はありえない
791 SetError(300,NULL,cp);
792 return false;
793 }
794
795 if( subscripts.size() > 0 ){
796 SetError(41,0,cp);
797 return false;
798 }
799
800 double dbl;
801 _int64 i64data;
802 Type calcType;
803
804 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
805 //動的データだった場合
806 return false;
807 }
808 if( calcType.IsReal() ){
809 memcpy(&dbl,&i64data,sizeof(double));
810 i64data=(_int64)dbl;
811 }
812 else dbl=(double)i64data;
813
814 //型チェック
815 CheckDifferentType(
816 type,
817 calcType,
818 0,0);
819
820 if( type.IsDouble() ){
821 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
822 offset,
823 (const char *)&dbl,
824 sizeof(double)
825 );
826 }
827 else if( type.IsSingle() ){
828 float flt = (float)dbl;
829 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
830 offset,
831 (const char *)&flt,
832 sizeof(float)
833 );
834 }
835 else if( type.Is64() ){
836 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
837 offset,
838 (const char *)&i64data,
839 sizeof(_int64)
840 );
841 }
842 else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){
843 if(type.GetBasicType()==typeOfPtrChar){
844 //文字列定数のとき
845
846 char *temp;
847 temp=(char *)i64data;
848 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
849 HeapDefaultFree(temp);
850
851 //mov eax,DataPos
852 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
853
854 //mov dword ptr[offset],eax
855 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
856 }
857 else{
858 long l = (long)i64data;
859 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
860 offset,
861 (const char *)&l,
862 sizeof(long)
863 );
864 }
865 }
866 else if( type.IsWord() || type.IsInteger() ){
867 short s = (short)i64data;
868 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
869 offset,
870 (const char *)&s,
871 sizeof(short)
872 );
873 }
874 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
875 char c = (char)i64data;
876 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
877 offset,
878 (const char *)&c,
879 sizeof(char)
880 );
881 }
882
883 return true;
884}
885bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
886 int i2,i3;
887 char temporary[VN_SIZE];
888 char InitBuf[VN_SIZE];
889 lstrcpy( InitBuf, lpszInitBuf );
890
891 if(InitBuf[0]=='['){
892 SlideString(InitBuf+1,-1);
893 InitBuf[lstrlen(InitBuf)-1]=0;
894
895 int typeSize = type.GetSize();
896
897 if( subscripts.size() > 0 ){
898 Subscripts nestSubscripts;
899 for( int i=1; i<(int)subscripts.size(); i++ )
900 {
901 nestSubscripts.push_back( subscripts[i] );
902 }
903
904 typeSize*=JumpSubScripts( nestSubscripts );
905 {
906 int i=0;
907 i2=0;
908 while(1){
909 if( subscripts[0] < i2 ){
910 SetError(41,0,cp);
911 return 0;
912 }
913 i=GetOneParameter(InitBuf,i,temporary);
914 if(!InitLocalVar(
915 offset+i2*typeSize,
916 type,
917 nestSubscripts,
918 temporary)) return false;
919 i2++;
920 if(InitBuf[i]=='\0') break;
921 }
922 }
923 return true;
924 }
925
926 if(type.IsStruct()){
927 const CClass &objClass = type.GetClass();
928
929 int i = 0;
930 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
931 if(InitBuf[i]=='\0'){
932 SetError(41,0,cp);
933 return false;
934 }
935
936 i=GetOneParameter(InitBuf,i,temporary);
937
938 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
939
940 if(!InitLocalVar(offset+i3,
941 pMember->GetType(),
942 pMember->GetSubscripts(),
943 temporary)) return false;
944
945 if(InitBuf[i]=='\0') break;
946 }
947 return true;
948 }
949
950 SetError(41,0,cp);
951 return false;
952 }
953
954
955 ///////////////////////////////////////
956 // 単発式([]で囲まれていない)
957 ///////////////////////////////////////
958
959 if( subscripts.size() > 0 ){
960 SetError(41,0,cp);
961 return false;
962 }
963
964 double dbl;
965 _int64 i64data;
966 Type calcType;
967
968 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
969 //動的データだった場合
970 return false;
971 }
972 if( calcType.IsReal() ){
973 memcpy(&dbl,&i64data,sizeof(double));
974 i64data=(_int64)dbl;
975 }
976 else dbl=(double)i64data;
977
978 //型チェック
979 CheckDifferentType(
980 type,
981 calcType,
982 0,0);
983
984 if( type.IsDouble() ){
985 //mov eax,HILONG(dbl)
986 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
987
988 //mov dword ptr[ebp+offset+sizeof(long)],eax
989 compiler.codeGenerator.localVarPertialSchedules.push_back(
990 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
991 );
992
993 //mov eax,LOLONG(dbl)
994 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
995
996 //mov dword ptr[ebp+offset],eax
997 compiler.codeGenerator.localVarPertialSchedules.push_back(
998 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
999 );
1000 }
1001 else if( type.IsSingle() ){
1002 float flt;
1003 flt=(float)dbl;
1004
1005 //mov eax,InitValue
1006 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
1007
1008 //mov dword ptr[ebp+offset],eax
1009 compiler.codeGenerator.localVarPertialSchedules.push_back(
1010 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1011 );
1012 }
1013 else if( type.Is64() ){
1014 //mov eax,HILONG(i64data)
1015 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
1016
1017 //mov dword ptr[ebp+offset+sizeof(long)],eax
1018 compiler.codeGenerator.localVarPertialSchedules.push_back(
1019 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1020 );
1021
1022 //mov eax,LOLONG(i64data)
1023 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
1024
1025 //mov dword ptr[ebp+offset],eax
1026 compiler.codeGenerator.localVarPertialSchedules.push_back(
1027 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1028 );
1029 }
1030 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1031 if(type.GetBasicType()==typeOfPtrChar){
1032 //文字列定数のとき
1033
1034 char *temp;
1035 temp=(char *)i64data;
1036 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
1037 HeapDefaultFree(temp);
1038
1039 //mov eax,DataPos
1040 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
1041 }
1042 else{
1043 //mov eax,InitValue
1044 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
1045 }
1046
1047 //mov dword ptr[ebp+offset],eax
1048 compiler.codeGenerator.localVarPertialSchedules.push_back(
1049 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1050 );
1051 }
1052 else if( type.IsWord() || type.IsInteger() ){
1053 //mov word ptr[ebp+offset],InitValue
1054 compiler.codeGenerator.localVarPertialSchedules.push_back(
1055 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1056 );
1057 }
1058 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1059 //mov byte ptr[ebp+offset],InitValue
1060 compiler.codeGenerator.localVarPertialSchedules.push_back(
1061 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1062 );
1063 }
1064
1065 return true;
1066}
1067
1068void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1069 if( UserProc::IsGlobalAreaCompiling() ){
1070 /////////////////////////
1071 // グローバル変数
1072 /////////////////////////
1073
1074 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1075 }
1076 else{
1077 /////////////////
1078 // ローカル変数
1079 /////////////////
1080
1081 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( Symbol( VarName ) ) ){
1082 //2重定義のエラー
1083 SetError(15,VarName,cp);
1084 return;
1085 }
1086
1087 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1088
1089 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter, false );
1090
1091 if( subscripts.size() > 0 ){
1092 //配列あり
1093 pVar->SetArray( subscripts );
1094 }
1095
1096 //レキシカルスコープ
1097 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1098 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1099 pVar->bLiving=TRUE;
1100
1101 //エラー用
1102 pVar->source_code_address=cp;
1103
1104 // 変数を追加
1105 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1106
1107 //アラインメントを考慮
1108 if( pVar->GetType().IsStruct() ){
1109 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1110
1111 if( alignment ){
1112 if( AllLocalVarSize % alignment ){
1113 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1114 }
1115 }
1116
1117 if( alignment == PTR_SIZE*2 ){
1118 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1119 // (例:CONTEXT構造体など)
1120 // 呼び出し側のオフセットズレを考慮する
1121
1122 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
1123 AllLocalVarSize += PTR_SIZE;
1124 }
1125 }
1126 }
1127
1128 AllLocalVarSize += pVar->GetMemorySize();
1129 pVar->SetOffsetAddress( AllLocalVarSize );
1130
1131 //レキシカルスコープ
1132 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1133 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1134 pVar->bLiving=TRUE;
1135
1136 if(InitBuf[0]){
1137 //初期代入時のみ、書き込みアクセスを許可する
1138 if( isConst ){
1139 pVar->ConstOff();
1140 }
1141
1142 int result = 0;
1143 if( !pVar->GetType().IsObject() ){
1144 result = InitLocalVar(-pVar->GetOffsetAddress(),
1145 pVar->GetType(),
1146 pVar->GetSubscripts(),
1147 InitBuf);
1148 }
1149
1150 if(!result){
1151 //動的な式だった場合は代入演算を行う
1152 char temporary[8192];
1153 sprintf(temporary,"%s=%s",VarName,InitBuf);
1154 OpcodeCalc(temporary);
1155 }
1156
1157 if( isConst ){
1158 pVar->ConstOn();
1159 }
1160 }
1161 else{
1162 //push 0
1163 compiler.codeGenerator.op_push_V(0);
1164
1165 //push VarSize
1166 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1167
1168 //mov eax,ebp
1169 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
1170
1171 //add eax,offset
1172 compiler.codeGenerator.localVarPertialSchedules.push_back(
1173 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1174 );
1175
1176 //push eax
1177 compiler.codeGenerator.op_push(REG_EAX);
1178
1179 //call FillMemory
1180 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
1181 }
1182 }
1183
1184 //New呼び出し
1185 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1186 char objectSize[255];
1187 if( subscripts.size() == 0 ){
1188 objectSize[0] = 0;
1189 }
1190 else{
1191 if( subscripts.size() > 1 ){
1192 SetError(300,NULL,cp);
1193 }
1194 sprintf( objectSize, "%d", subscripts[0] );
1195 }
1196 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1197
1198 //pop eax
1199 compiler.codeGenerator.op_pop( REG_EAX );
1200
1201 RELATIVE_VAR RelativeVar;
1202 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
1203 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1204 SetError();
1205 }
1206 SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1207 }
1208}
1209
1210void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1211 if(pRelativeVar->dwKind==VAR_GLOBAL){
1212 if(pRelativeVar->bOffsetOffset){
1213 //lea eax,dword ptr[ecx+offset]
1214 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
1215 }
1216 else{
1217 //mov eax,offset
1218 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
1219 }
1220 }
1221 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1222 if(pRelativeVar->bOffsetOffset){
1223 //mov eax,ecx
1224 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1225
1226 //add eax,dword ptr[offset]
1227 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1228 }
1229 else{
1230 //mov eax,dword ptr[offset]
1231 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1232 }
1233 }
1234 else if(pRelativeVar->dwKind==VAR_LOCAL){
1235 if(pRelativeVar->bOffsetOffset){
1236 //add ecx,offset
1237 compiler.codeGenerator.localVarPertialSchedules.push_back(
1238 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1239 );
1240
1241 //lea eax,dword ptr[ebp+ecx]
1242 compiler.codeGenerator.PutOld(
1243 (char)0x8D,
1244 (char)0x44,
1245 (char)0x0D,
1246 (char)0x00
1247 );
1248 }
1249 else{
1250 //lea eax,dword ptr[ecx+offset]
1251 compiler.codeGenerator.localVarPertialSchedules.push_back(
1252 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1253 );
1254 }
1255 }
1256 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1257 if(pRelativeVar->bOffsetOffset){
1258 //mov eax,ecx
1259 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1260
1261 //add eax,dword ptr[ebp+offset]
1262 compiler.codeGenerator.localVarPertialSchedules.push_back(
1263 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1264 );
1265 }
1266 else{
1267 //mov eax,dword ptr[ebp+offset]
1268 compiler.codeGenerator.localVarPertialSchedules.push_back(
1269 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1270 );
1271 }
1272 }
1273 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1274 //mov eax,ecx
1275 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1276 }
1277}
1278void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1279 if( reg != REG_EAX ){
1280 SetError();
1281 //TODO: 未完成
1282 }
1283 SetVarPtrToEax( pRelativeVar );
1284}
1285
1286bool Compile_AddGlobalRootsForGc(){
1287 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1288 if( !pUserProc_AddGlobalRootPtr ){
1289 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1290 return false;
1291 }
1292
1293 BOOST_FOREACH( const Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
1294 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1295 // オブジェクトまたはポインタだったとき
1296 // ※構造体も含む(暫定対応)
1297
1298 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1299 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
1300
1301
1302 /////////////////////////////
1303 // ルートポインタを引き渡す
1304
1305 //mov eax,offset
1306 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1307
1308 //push eax
1309 compiler.codeGenerator.op_push( REG_EAX );
1310
1311 //
1312 /////////////////////////////
1313
1314
1315 /////////////////////////////
1316 // Thisポインタを引き渡す
1317
1318 SetThisPtrToReg(REG_EAX);
1319
1320 //push eax
1321 compiler.codeGenerator.op_push( REG_EAX );
1322
1323 //
1324 /////////////////////////////
1325
1326
1327 // call AddGlobalRootPtr
1328 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1329 }
1330 }
1331
1332 return true;
1333}
Note: See TracBrowser for help on using the repository browser.