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

Last change on this file since 330 was 301, checked in by dai_9181, 17 years ago
File size: 34.5 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 ResolveFormalGenericTypeParameter( resultType, classType );
227
228
229 //ポインタ変数の場合
230 if( resultType.IsPointer() ){
231 if( pMember->GetSubscripts().size() == 0 ){
232 lstrcpy(lpPtrOffset,array);
233 array[0]=0;
234 }
235 }
236 else{
237 if(lpPtrOffset[0]){
238 if(isErrorEnabled) SetError(16,member,cp);
239 return false;
240 }
241 }
242
243 if(offset){
244 //add ecx,offset
245 compiler.codeGenerator.op_add_RV( REG_ECX, offset );
246 }
247
248 if(array[0]){
249 //配列オフセット
250 if(!GetArrayOffset(pMember->GetSubscripts(),array,pMember->GetType())){
251 if(isErrorEnabled) SetError(14,member,cp);
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 // TODO: ベースオブジェクト(指定されていないときは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 bool isFound = false;
472 BOOST_FOREACH( CMember *pMember, compiler.pCompilingClass->GetDynamicMembers() ){
473 if( pMember->GetName() == VarName ){
474 isFound = true;
475 break;
476 }
477 }
478 if( !isFound ) goto NonClassMember;
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(), NULL );
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( type.IsObject() || type.IsStruct() ){
820 //オブジェクトまたは構造体の場合はありえない
821 SetError(300,NULL,cp);
822 return false;
823 }
824
825 if( subscripts.size() > 0 ){
826 SetError(41,0,cp);
827 return false;
828 }
829
830 double dbl;
831 _int64 i64data;
832 Type calcType;
833
834 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
835 //動的データだった場合
836 return false;
837 }
838 if( calcType.IsReal() ){
839 memcpy(&dbl,&i64data,sizeof(double));
840 i64data=(_int64)dbl;
841 }
842 else dbl=(double)i64data;
843
844 //型チェック
845 CheckDifferentType(
846 type,
847 calcType,
848 0,0);
849
850 if( type.IsDouble() ){
851 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
852 offset,
853 (const char *)&dbl,
854 sizeof(double)
855 );
856 }
857 else if( type.IsSingle() ){
858 float flt = (float)dbl;
859 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
860 offset,
861 (const char *)&flt,
862 sizeof(float)
863 );
864 }
865 else if( type.Is64() ){
866 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
867 offset,
868 (const char *)&i64data,
869 sizeof(_int64)
870 );
871 }
872 else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){
873 if(type.GetBasicType()==typeOfPtrChar){
874 //文字列定数のとき
875
876 char *temp;
877 temp=(char *)i64data;
878 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
879 HeapDefaultFree(temp);
880
881 //mov eax,DataPos
882 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
883
884 //mov dword ptr[offset],eax
885 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
886 }
887 else{
888 long l = (long)i64data;
889 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
890 offset,
891 (const char *)&l,
892 sizeof(long)
893 );
894 }
895 }
896 else if( type.IsWord() || type.IsInteger() ){
897 short s = (short)i64data;
898 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
899 offset,
900 (const char *)&s,
901 sizeof(short)
902 );
903 }
904 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
905 char c = (char)i64data;
906 compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
907 offset,
908 (const char *)&c,
909 sizeof(char)
910 );
911 }
912
913 return true;
914}
915bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
916 int i2,i3;
917 char temporary[VN_SIZE];
918 char InitBuf[VN_SIZE];
919 lstrcpy( InitBuf, lpszInitBuf );
920
921 if(InitBuf[0]=='['){
922 SlideString(InitBuf+1,-1);
923 InitBuf[lstrlen(InitBuf)-1]=0;
924
925 int typeSize = type.GetSize();
926
927 if( subscripts.size() > 0 ){
928 Subscripts nestSubscripts;
929 for( int i=1; i<(int)subscripts.size(); i++ )
930 {
931 nestSubscripts.push_back( subscripts[i] );
932 }
933
934 typeSize*=JumpSubScripts( nestSubscripts );
935 {
936 int i=0;
937 i2=0;
938 while(1){
939 if( subscripts[0] < i2 ){
940 SetError(41,0,cp);
941 return 0;
942 }
943 i=GetOneParameter(InitBuf,i,temporary);
944 if(!InitLocalVar(
945 offset+i2*typeSize,
946 type,
947 nestSubscripts,
948 temporary)) return false;
949 i2++;
950 if(InitBuf[i]=='\0') break;
951 }
952 }
953 return true;
954 }
955
956 if(type.IsStruct()){
957 const CClass &objClass = type.GetClass();
958
959 int i = 0;
960 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
961 if(InitBuf[i]=='\0'){
962 SetError(41,0,cp);
963 return false;
964 }
965
966 i=GetOneParameter(InitBuf,i,temporary);
967
968 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
969
970 if(!InitLocalVar(offset+i3,
971 pMember->GetType(),
972 pMember->GetSubscripts(),
973 temporary)) return false;
974
975 if(InitBuf[i]=='\0') break;
976 }
977 return true;
978 }
979
980 SetError(41,0,cp);
981 return false;
982 }
983
984
985 ///////////////////////////////////////
986 // 単発式([]で囲まれていない)
987 ///////////////////////////////////////
988
989 if( subscripts.size() > 0 ){
990 SetError(41,0,cp);
991 return false;
992 }
993
994 double dbl;
995 _int64 i64data;
996 Type calcType;
997
998 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
999 //動的データだった場合
1000 return false;
1001 }
1002 if( calcType.IsReal() ){
1003 memcpy(&dbl,&i64data,sizeof(double));
1004 i64data=(_int64)dbl;
1005 }
1006 else dbl=(double)i64data;
1007
1008 //型チェック
1009 CheckDifferentType(
1010 type,
1011 calcType,
1012 0,0);
1013
1014 if( type.IsDouble() ){
1015 //mov eax,HILONG(dbl)
1016 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
1017
1018 //mov dword ptr[ebp+offset+sizeof(long)],eax
1019 compiler.codeGenerator.localVarPertialSchedules.push_back(
1020 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1021 );
1022
1023 //mov eax,LOLONG(dbl)
1024 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
1025
1026 //mov dword ptr[ebp+offset],eax
1027 compiler.codeGenerator.localVarPertialSchedules.push_back(
1028 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1029 );
1030 }
1031 else if( type.IsSingle() ){
1032 float flt;
1033 flt=(float)dbl;
1034
1035 //mov eax,InitValue
1036 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
1037
1038 //mov dword ptr[ebp+offset],eax
1039 compiler.codeGenerator.localVarPertialSchedules.push_back(
1040 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1041 );
1042 }
1043 else if( type.Is64() ){
1044 //mov eax,HILONG(i64data)
1045 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
1046
1047 //mov dword ptr[ebp+offset+sizeof(long)],eax
1048 compiler.codeGenerator.localVarPertialSchedules.push_back(
1049 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1050 );
1051
1052 //mov eax,LOLONG(i64data)
1053 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
1054
1055 //mov dword ptr[ebp+offset],eax
1056 compiler.codeGenerator.localVarPertialSchedules.push_back(
1057 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1058 );
1059 }
1060 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1061 if(type.GetBasicType()==typeOfPtrChar){
1062 //文字列定数のとき
1063
1064 char *temp;
1065 temp=(char *)i64data;
1066 i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
1067 HeapDefaultFree(temp);
1068
1069 //mov eax,DataPos
1070 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
1071 }
1072 else{
1073 //mov eax,InitValue
1074 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
1075 }
1076
1077 //mov dword ptr[ebp+offset],eax
1078 compiler.codeGenerator.localVarPertialSchedules.push_back(
1079 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1080 );
1081 }
1082 else if( type.IsWord() || type.IsInteger() ){
1083 //mov word ptr[ebp+offset],InitValue
1084 compiler.codeGenerator.localVarPertialSchedules.push_back(
1085 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1086 );
1087 }
1088 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1089 //mov byte ptr[ebp+offset],InitValue
1090 compiler.codeGenerator.localVarPertialSchedules.push_back(
1091 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1092 );
1093 }
1094
1095 return true;
1096}
1097
1098void dim( char *VarName, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1099 if( UserProc::IsGlobalAreaCompiling() ){
1100 /////////////////////////
1101 // グローバル変数
1102 /////////////////////////
1103
1104 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1105 }
1106 else{
1107 /////////////////
1108 // ローカル変数
1109 /////////////////
1110
1111 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( Symbol( VarName ) ) ){
1112 //2重定義のエラー
1113 SetError(15,VarName,cp);
1114 return;
1115 }
1116
1117 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1118
1119 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter, false );
1120
1121 if( subscripts.size() > 0 ){
1122 //配列あり
1123 pVar->SetArray( subscripts );
1124 }
1125
1126 //レキシカルスコープ
1127 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1128 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1129 pVar->bLiving=TRUE;
1130
1131 //エラー用
1132 pVar->source_code_address=cp;
1133
1134 // 変数を追加
1135 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1136
1137 //アラインメントを考慮
1138 if( pVar->GetType().IsStruct() ){
1139 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1140
1141 if( alignment ){
1142 if( AllLocalVarSize % alignment ){
1143 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1144 }
1145 }
1146
1147 if( alignment == PTR_SIZE*2 ){
1148 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1149 // (例:CONTEXT構造体など)
1150 // 呼び出し側のオフセットズレを考慮する
1151
1152 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
1153 AllLocalVarSize += PTR_SIZE;
1154 }
1155 }
1156 }
1157
1158 AllLocalVarSize += pVar->GetMemorySize();
1159 pVar->SetOffsetAddress( AllLocalVarSize );
1160
1161 //レキシカルスコープ
1162 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1163 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1164 pVar->bLiving=TRUE;
1165
1166 if(InitBuf[0]){
1167 //初期代入時のみ、書き込みアクセスを許可する
1168 if( isConst ){
1169 pVar->ConstOff();
1170 }
1171
1172 int result = 0;
1173 if( !pVar->GetType().IsObject() ){
1174 result = InitLocalVar(-pVar->GetOffsetAddress(),
1175 pVar->GetType(),
1176 pVar->GetSubscripts(),
1177 InitBuf);
1178 }
1179
1180 if(!result){
1181 //動的な式だった場合は代入演算を行う
1182 char temporary[8192];
1183 sprintf(temporary,"%s=%s",VarName,InitBuf);
1184 OpcodeCalc(temporary);
1185 }
1186
1187 if( isConst ){
1188 pVar->ConstOn();
1189 }
1190 }
1191 else{
1192 //push 0
1193 compiler.codeGenerator.op_push_V(0);
1194
1195 //push VarSize
1196 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1197
1198 //mov eax,ebp
1199 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
1200
1201 //add eax,offset
1202 compiler.codeGenerator.localVarPertialSchedules.push_back(
1203 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1204 );
1205
1206 //push eax
1207 compiler.codeGenerator.op_push(REG_EAX);
1208
1209 //call FillMemory
1210 compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
1211 }
1212 }
1213
1214 //New呼び出し
1215 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
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.