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

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

ジェネリクスのベースを実装

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