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

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

COM修飾子に対応。COMインターフェイスを呼び出せるようにした

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