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

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