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

Last change on this file since 237 was 237, 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 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
848
849 //mov dword ptr[offset],eax
850 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
851 }
852 else{
853 *(DWORD *)(initGlobalBuf+offset)=(DWORD)i64data;
854 }
855 }
856 else if( type.IsWord() || type.IsInteger() ){
857 *(WORD *)(initGlobalBuf+offset)=(WORD)i64data;
858 }
859 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
860 *(BYTE *)(initGlobalBuf+offset)=(BYTE)i64data;
861 }
862
863 return true;
864}
865bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
866 int i2,i3;
867 char temporary[VN_SIZE];
868 char InitBuf[VN_SIZE];
869 lstrcpy( InitBuf, lpszInitBuf );
870
871 if(InitBuf[0]=='['){
872 SlideString(InitBuf+1,-1);
873 InitBuf[lstrlen(InitBuf)-1]=0;
874
875 int typeSize = type.GetSize();
876
877 if( subscripts.size() > 0 ){
878 Subscripts nestSubscripts;
879 for( int i=1; i<(int)subscripts.size(); i++ )
880 {
881 nestSubscripts.push_back( subscripts[i] );
882 }
883
884 typeSize*=JumpSubScripts( nestSubscripts );
885 {
886 int i=0;
887 i2=0;
888 while(1){
889 if( subscripts[0] < i2 ){
890 SetError(41,0,cp);
891 return 0;
892 }
893 i=GetOneParameter(InitBuf,i,temporary);
894 if(!InitLocalVar(
895 offset+i2*typeSize,
896 type,
897 nestSubscripts,
898 temporary)) return false;
899 i2++;
900 if(InitBuf[i]=='\0') break;
901 }
902 }
903 return true;
904 }
905
906 if(type.IsStruct()){
907 const CClass &objClass = type.GetClass();
908
909 int i = 0;
910 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
911 if(InitBuf[i]=='\0'){
912 SetError(41,0,cp);
913 return false;
914 }
915
916 i=GetOneParameter(InitBuf,i,temporary);
917
918 i3=objClass.GetMemberOffset( pMember->GetName().c_str(), NULL );
919
920 if(!InitLocalVar(offset+i3,
921 pMember->GetType(),
922 pMember->GetSubscripts(),
923 temporary)) return false;
924
925 if(InitBuf[i]=='\0') break;
926 }
927 return true;
928 }
929
930 SetError(41,0,cp);
931 return false;
932 }
933
934
935 ///////////////////////////////////////
936 // 単発式([]で囲まれていない)
937 ///////////////////////////////////////
938
939 if( subscripts.size() > 0 ){
940 SetError(41,0,cp);
941 return false;
942 }
943
944 double dbl;
945 _int64 i64data;
946 Type calcType;
947
948 if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
949 //動的データだった場合
950 return false;
951 }
952 if( calcType.IsReal() ){
953 memcpy(&dbl,&i64data,sizeof(double));
954 i64data=(_int64)dbl;
955 }
956 else dbl=(double)i64data;
957
958 //型チェック
959 CheckDifferentType(
960 type,
961 calcType,
962 0,0);
963
964 if( type.IsDouble() ){
965 //mov eax,HILONG(dbl)
966 OpBuffer[obp++]=(char)0xB8;
967 *((long *)(OpBuffer+obp))=(long)*(long *)(((char *)(&dbl))+4);
968 obp+=sizeof(long);
969
970 //mov dword ptr[ebp+offset+sizeof(long)],eax
971 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::LocalVar );
972
973 //mov eax,LOLONG(dbl)
974 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
975
976 //mov dword ptr[ebp+offset],eax
977 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::LocalVar );
978 }
979 else if( type.IsSingle() ){
980 float flt;
981 flt=(float)dbl;
982
983 //mov eax,InitValue
984 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
985
986 //mov dword ptr[ebp+offset],eax
987 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::LocalVar );
988 }
989 else if( type.Is64() ){
990 //mov eax,HILONG(i64data)
991 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
992
993 //mov dword ptr[ebp+offset+sizeof(long)],eax
994 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::LocalVar );
995
996 //mov eax,LOLONG(i64data)
997 compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
998
999 //mov dword ptr[ebp+offset],eax
1000 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::LocalVar );
1001 }
1002 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1003 if(type.GetBasicType()==typeOfPtrChar){
1004 //文字列定数のとき
1005
1006 char *temp;
1007 temp=(char *)i64data;
1008 i2=compiler.GetDataTable().AddString(temp,lstrlen(temp));
1009 HeapDefaultFree(temp);
1010
1011 //mov eax,DataPos
1012 compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
1013 }
1014 else{
1015 //mov eax,InitValue
1016 compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
1017 }
1018
1019 //mov dword ptr[ebp+offset],eax
1020 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::LocalVar );
1021 }
1022 else if( type.IsWord() || type.IsInteger() ){
1023 //mov word ptr[ebp+offset],InitValue
1024 compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::LocalVar, (long)i64data );
1025 }
1026 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1027 //mov byte ptr[ebp+offset],InitValue
1028 compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::LocalVar, (long)i64data );
1029 }
1030
1031 return true;
1032}
1033
1034void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1035 if( UserProc::IsGlobalAreaCompiling() ){
1036 /////////////////////////
1037 // グローバル変数
1038 /////////////////////////
1039
1040 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1041 }
1042 else{
1043 /////////////////
1044 // ローカル変数
1045 /////////////////
1046
1047 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( Symbol( VarName ) ) ){
1048 //2重定義のエラー
1049 SetError(15,VarName,cp);
1050 return;
1051 }
1052
1053 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1054
1055 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter );
1056
1057 if( subscripts.size() > 0 ){
1058 //配列あり
1059 pVar->SetArray( subscripts );
1060 }
1061
1062 //レキシカルスコープ
1063 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1064 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1065 pVar->bLiving=TRUE;
1066
1067 //エラー用
1068 pVar->source_code_address=cp;
1069
1070 // 変数を追加
1071 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1072
1073 //アラインメントを考慮
1074 if( pVar->GetType().IsStruct() ){
1075 int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1076
1077 if( alignment ){
1078 if( AllLocalVarSize % alignment ){
1079 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1080 }
1081 }
1082
1083 if( alignment == PTR_SIZE*2 ){
1084 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1085 // (例:CONTEXT構造体など)
1086 // 呼び出し側のオフセットズレを考慮する
1087
1088 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1089 AllLocalVarSize += PTR_SIZE;
1090 }
1091 }
1092 }
1093
1094 AllLocalVarSize += pVar->GetMemorySize();
1095 pVar->SetOffsetAddress( AllLocalVarSize );
1096
1097 //レキシカルスコープ
1098 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1099 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1100 pVar->bLiving=TRUE;
1101
1102 if(InitBuf[0]){
1103 //初期代入時のみ、書き込みアクセスを許可する
1104 if( isConst ){
1105 pVar->ConstOff();
1106 }
1107
1108 int result = 0;
1109 if( !pVar->GetType().IsObject() ){
1110 result = InitLocalVar(-pVar->GetOffsetAddress(),
1111 pVar->GetType(),
1112 pVar->GetSubscripts(),
1113 InitBuf);
1114 }
1115
1116 if(!result){
1117 //動的な式だった場合は代入演算を行う
1118 char temporary[8192];
1119 sprintf(temporary,"%s=%s",VarName,InitBuf);
1120 OpcodeCalc(temporary);
1121 }
1122
1123 if( isConst ){
1124 pVar->ConstOn();
1125 }
1126 }
1127 else{
1128 //push 0
1129 compiler.codeGenerator.op_push_V(0);
1130
1131 //push VarSize
1132 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1133
1134 //mov eax,ebp
1135 OpBuffer[obp++]=(char)0x8B;
1136 OpBuffer[obp++]=(char)0xC5;
1137
1138 //add eax,offset
1139 compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::LocalVar );
1140
1141 //push eax
1142 compiler.codeGenerator.op_push(REG_EAX);
1143
1144 //call FillMemory
1145 OpBuffer[obp++]=(char)0xFF;
1146 OpBuffer[obp++]=(char)0x15;
1147 DllProc *pDllProc = GetDeclareHash("FillMemory");
1148 pDllProc->Using();
1149 pobj_ImportAddrSchedule->add(pDllProc);
1150 obp+=sizeof(long);
1151 }
1152 }
1153
1154 //New呼び出し
1155 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1156 char objectSize[255];
1157 if( subscripts.size() == 0 ){
1158 objectSize[0] = 0;
1159 }
1160 else{
1161 if( subscripts.size() > 1 ){
1162 SetError(300,NULL,cp);
1163 }
1164 sprintf( objectSize, "%d", subscripts[0] );
1165 }
1166 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1167
1168 //pop eax
1169 compiler.codeGenerator.op_pop( REG_EAX );
1170
1171 RELATIVE_VAR RelativeVar;
1172 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
1173 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1174 SetError();
1175 }
1176 SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1177 }
1178}
1179
1180void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1181 if(pRelativeVar->dwKind==VAR_GLOBAL){
1182 if(pRelativeVar->bOffsetOffset){
1183 //lea eax,dword ptr[ecx+offset]
1184 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
1185 }
1186 else{
1187 //mov eax,offset
1188 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
1189 }
1190 }
1191 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1192 if(pRelativeVar->bOffsetOffset){
1193 //mov eax,ecx
1194 OpBuffer[obp++]=(char)0x8B;
1195 OpBuffer[obp++]=(char)0xC1;
1196
1197 //add eax,dword ptr[offset]
1198 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1199 }
1200 else{
1201 //mov eax,dword ptr[offset]
1202 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1203 }
1204 }
1205 else if(pRelativeVar->dwKind==VAR_LOCAL){
1206 if(pRelativeVar->bOffsetOffset){
1207 //add ecx,offset
1208 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::LocalVar );
1209
1210 //lea eax,dword ptr[ebp+ecx]
1211 OpBuffer[obp++]=(char)0x8D;
1212 OpBuffer[obp++]=(char)0x44;
1213 OpBuffer[obp++]=(char)0x0D;
1214 OpBuffer[obp++]=(char)0x00;
1215 }
1216 else{
1217 //lea eax,dword ptr[ecx+offset]
1218 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::LocalVar );
1219 }
1220 }
1221 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1222 if(pRelativeVar->bOffsetOffset){
1223 //mov eax,ecx
1224 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1225
1226 //add eax,dword ptr[ebp+offset]
1227 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::LocalVar );
1228 }
1229 else{
1230 //mov eax,dword ptr[ebp+offset]
1231 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::LocalVar );
1232 }
1233 }
1234 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1235 //mov eax,ecx
1236 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1237 }
1238}
1239void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1240 if( reg != REG_EAX ){
1241 SetError();
1242 //TODO: 未完成
1243 }
1244 SetVarPtrToEax( pRelativeVar );
1245}
1246
1247bool Compile_AddGlobalRootsForGc(){
1248 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1249 if( !pUserProc_AddGlobalRootPtr ){
1250 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1251 return false;
1252 }
1253
1254 BOOST_FOREACH( const Variable *pVar, compiler.GetMeta().GetGlobalVars() ){
1255 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1256 // オブジェクトまたはポインタだったとき
1257 // ※構造体も含む(暫定対応)
1258
1259 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1260 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
1261
1262
1263 /////////////////////////////
1264 // ルートポインタを引き渡す
1265
1266 //mov eax,offset
1267 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1268
1269 //push eax
1270 compiler.codeGenerator.op_push( REG_EAX );
1271
1272 //
1273 /////////////////////////////
1274
1275
1276 /////////////////////////////
1277 // Thisポインタを引き渡す
1278
1279 SetThisPtrToReg(REG_EAX);
1280
1281 //push eax
1282 compiler.codeGenerator.op_push( REG_EAX );
1283
1284 //
1285 /////////////////////////////
1286
1287
1288 // call AddGlobalRootPtr
1289 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1290
1291 ReallocNativeCodeBuffer();
1292 }
1293 }
1294
1295 return true;
1296}
Note: See TracBrowser for help on using the repository browser.