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

Last change on this file since 426 was 424, checked in by dai_9181, 17 years ago

・ジェネリックな型をパラメータに持つメソッドのオーバーロード解決に対応した。
・型パラメータの制約クラス指定に対応した。

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