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

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