source: dev/trunk/ab5.0/abdev/BasicCompiler32/Compile_Var.cpp@ 457

Last change on this file since 457 was 453, checked in by dai_9181, 17 years ago

"Dim a = 0 As *Char" など、Charポインタ型変数の初期値にリテラル数値を指定すると強制終了してしまうバグを修正。

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