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

Last change on this file since 230 was 230, checked in by dai_9181, 17 years ago
File size: 33.5 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
6#include <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 OpBuffer[obp++]=(char)0x89;
981 OpBuffer[obp++]=(char)0x85;
982 *((long *)(OpBuffer+obp))=offset+sizeof(long);
983 AddLocalVarAddrSchedule();
984 obp+=sizeof(long);
985
986 //mov eax,LOLONG(dbl)
987 OpBuffer[obp++]=(char)0xB8;
988 *((long *)(OpBuffer+obp))=*(long *)(&dbl);
989 obp+=sizeof(long);
990
991 //mov dword ptr[ebp+offset],eax
992 OpBuffer[obp++]=(char)0x89;
993 OpBuffer[obp++]=(char)0x85;
994 *((long *)(OpBuffer+obp))=offset;
995 AddLocalVarAddrSchedule();
996 obp+=sizeof(long);
997 }
998 else if( type.IsSingle() ){
999 float flt;
1000 flt=(float)dbl;
1001 //mov eax,InitValue
1002 OpBuffer[obp++]=(char)0xB8;
1003 *((long *)(OpBuffer+obp))=*(long *)&flt;
1004 obp+=sizeof(long);
1005
1006 //mov dword ptr[ebp+offset],eax
1007 OpBuffer[obp++]=(char)0x89;
1008 OpBuffer[obp++]=(char)0x85;
1009 *((long *)(OpBuffer+obp))=offset;
1010 AddLocalVarAddrSchedule();
1011 obp+=sizeof(long);
1012 }
1013 else if( type.Is64() ){
1014 //mov eax,HILONG(i64data)
1015 OpBuffer[obp++]=(char)0xB8;
1016 *((long *)(OpBuffer+obp))=(long)*(long *)(((char *)(&i64data))+4);
1017 obp+=sizeof(long);
1018
1019 //mov dword ptr[ebp+offset+sizeof(long)],eax
1020 OpBuffer[obp++]=(char)0x89;
1021 OpBuffer[obp++]=(char)0x85;
1022 *((long *)(OpBuffer+obp))=offset+sizeof(long);
1023 AddLocalVarAddrSchedule();
1024 obp+=sizeof(long);
1025
1026 //mov eax,LOLONG(i64data)
1027 OpBuffer[obp++]=(char)0xB8;
1028 *((long *)(OpBuffer+obp))=*(long *)(&i64data);
1029 obp+=sizeof(long);
1030
1031 //mov dword ptr[ebp+offset],eax
1032 OpBuffer[obp++]=(char)0x89;
1033 OpBuffer[obp++]=(char)0x85;
1034 *((long *)(OpBuffer+obp))=offset;
1035 AddLocalVarAddrSchedule();
1036 obp+=sizeof(long);
1037 }
1038 else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1039 if(type.GetBasicType()==typeOfPtrChar){
1040 //文字列定数のとき
1041
1042 char *temp;
1043 temp=(char *)i64data;
1044 i2=compiler.GetDataTable().AddString(temp,lstrlen(temp));
1045 HeapDefaultFree(temp);
1046
1047 //mov eax,DataPos
1048 OpBuffer[obp++]=(char)0xB8;
1049 *((long *)(OpBuffer+obp))=(long)i2;
1050 pobj_DataTableSchedule->add();
1051 obp+=sizeof(long);
1052 }
1053 else{
1054 //mov eax,InitValue
1055 OpBuffer[obp++]=(char)0xB8;
1056 *((long *)(OpBuffer+obp))=(long)i64data;
1057 obp+=sizeof(long);
1058 }
1059
1060 //mov dword ptr[ebp+offset],eax
1061 OpBuffer[obp++]=(char)0x89;
1062 OpBuffer[obp++]=(char)0x85;
1063 *((long *)(OpBuffer+obp))=offset;
1064 AddLocalVarAddrSchedule();
1065 obp+=sizeof(long);
1066 }
1067 else if( type.IsWord() || type.IsInteger() ){
1068 //mov ax,InitValue
1069 OpBuffer[obp++]=(char)0x66;
1070 OpBuffer[obp++]=(char)0xB8;
1071 *((WORD *)(OpBuffer+obp))=(WORD)i64data;
1072 obp+=sizeof(WORD);
1073
1074 //mov word ptr[ebp+offset],ax
1075 OpBuffer[obp++]=(char)0x66;
1076 OpBuffer[obp++]=(char)0x89;
1077 OpBuffer[obp++]=(char)0x85;
1078 *((long *)(OpBuffer+obp))=offset;
1079 AddLocalVarAddrSchedule();
1080 obp+=sizeof(long);
1081 }
1082 else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1083 //mov byte ptr[ebp+offset],InitValue
1084 OpBuffer[obp++]=(char)0xC6;
1085 OpBuffer[obp++]=(char)0x85;
1086 *((long *)(OpBuffer+obp))=offset;
1087 AddLocalVarAddrSchedule();
1088 obp+=sizeof(long);
1089 *((BYTE *)(OpBuffer+obp))=(BYTE)i64data;
1090 obp+=sizeof(BYTE);
1091 }
1092
1093 return true;
1094}
1095
1096void dim( char *VarName, const Subscripts &subscripts, Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1097 if( UserProc::IsGlobalAreaCompiling() ){
1098 /////////////////////////
1099 // グローバル変数
1100 /////////////////////////
1101
1102 AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1103 }
1104 else{
1105 /////////////////
1106 // ローカル変数
1107 /////////////////
1108
1109 if( UserProc::CompilingUserProc().GetLocalVars().DuplicateCheck( Symbol( VarName ) ) ){
1110 //2重定義のエラー
1111 SetError(15,VarName,cp);
1112 return;
1113 }
1114
1115 bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1116
1117 Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter );
1118
1119 if( subscripts.size() > 0 ){
1120 //配列あり
1121 pVar->SetArray( subscripts );
1122 }
1123
1124 //レキシカルスコープ
1125 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1126 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1127 pVar->bLiving=TRUE;
1128
1129 //エラー用
1130 pVar->source_code_address=cp;
1131
1132 // 変数を追加
1133 UserProc::CompilingUserProc().GetLocalVars().push_back( pVar );
1134
1135 //アラインメントを考慮
1136 if( pVar->GetType().IsStruct() ){
1137 int alignment = pVar->GetType().GetClass().iAlign;
1138
1139 if( alignment ){
1140 if( AllLocalVarSize % alignment ){
1141 AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1142 }
1143 }
1144
1145 if( alignment == PTR_SIZE*2 ){
1146 // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1147 // (例:CONTEXT構造体など)
1148 // 呼び出し側のオフセットズレを考慮する
1149
1150 if( 0 == ( UserProc::CompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE/*ret分*/ ) % alignment ){
1151 AllLocalVarSize += PTR_SIZE;
1152 }
1153 }
1154 }
1155
1156 AllLocalVarSize += pVar->GetMemorySize();
1157 pVar->SetOffsetAddress( AllLocalVarSize );
1158
1159 //レキシカルスコープ
1160 pVar->SetScopeLevel( GetLexicalScopes().GetNowLevel() );
1161 pVar->SetScopeStartAddress( GetLexicalScopes().GetStartAddress() );
1162 pVar->bLiving=TRUE;
1163
1164 if(InitBuf[0]){
1165 //初期代入時のみ、書き込みアクセスを許可する
1166 if( isConst ){
1167 pVar->ConstOff();
1168 }
1169
1170 int result = 0;
1171 if( !pVar->GetType().IsObject() ){
1172 result = InitLocalVar(-pVar->GetOffsetAddress(),
1173 pVar->GetType(),
1174 pVar->GetSubscripts(),
1175 InitBuf);
1176 }
1177
1178 if(!result){
1179 //動的な式だった場合は代入演算を行う
1180 char temporary[8192];
1181 sprintf(temporary,"%s=%s",VarName,InitBuf);
1182 OpcodeCalc(temporary);
1183 }
1184
1185 if( isConst ){
1186 pVar->ConstOn();
1187 }
1188 }
1189 else{
1190 //push 0
1191 compiler.codeGenerator.op_push_V(0);
1192
1193 //push VarSize
1194 compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1195
1196 //mov eax,ebp
1197 OpBuffer[obp++]=(char)0x8B;
1198 OpBuffer[obp++]=(char)0xC5;
1199
1200 //add eax,offset
1201 OpBuffer[obp++]=(char)0x05;
1202 *((long *)(OpBuffer+obp))=-pVar->GetOffsetAddress();
1203 AddLocalVarAddrSchedule();
1204 obp+=sizeof(long);
1205
1206 //push eax
1207 compiler.codeGenerator.op_push(REG_EAX);
1208
1209 //call FillMemory
1210 OpBuffer[obp++]=(char)0xFF;
1211 OpBuffer[obp++]=(char)0x15;
1212 DllProc *pDllProc = GetDeclareHash("FillMemory");
1213 pDllProc->Using();
1214 pobj_ImportAddrSchedule->add(pDllProc);
1215 obp+=sizeof(long);
1216 }
1217 }
1218
1219 //New呼び出し
1220 if( type.IsObject() &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0&&InitBuf[0]=='\0'){
1221 char objectSize[255];
1222 if( subscripts.size() == 0 ){
1223 objectSize[0] = 0;
1224 }
1225 else{
1226 if( subscripts.size() > 1 ){
1227 SetError(300,NULL,cp);
1228 }
1229 sprintf( objectSize, "%d", subscripts[0] );
1230 }
1231 Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1232
1233 //pop eax
1234 compiler.codeGenerator.op_pop( REG_EAX );
1235
1236 RELATIVE_VAR RelativeVar;
1237 GetVarOffset( true, false, VarName, &RelativeVar, Type() );
1238 if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1239 SetError();
1240 }
1241 SetVariableFromEax( DEF_OBJECT, DEF_OBJECT, &RelativeVar );
1242 }
1243}
1244
1245void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1246 if(pRelativeVar->dwKind==VAR_GLOBAL){
1247 if(pRelativeVar->bOffsetOffset){
1248 //lea eax,dword ptr[ecx+offset]
1249 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
1250 }
1251 else{
1252 //mov eax,offset
1253 compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
1254 }
1255 }
1256 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1257 if(pRelativeVar->bOffsetOffset){
1258 //mov eax,ecx
1259 OpBuffer[obp++]=(char)0x8B;
1260 OpBuffer[obp++]=(char)0xC1;
1261
1262 //add eax,dword ptr[offset]
1263 compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1264 }
1265 else{
1266 //mov eax,dword ptr[offset]
1267 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1268 }
1269 }
1270 else if(pRelativeVar->dwKind==VAR_LOCAL){
1271 if(pRelativeVar->bOffsetOffset){
1272 //add ecx,offset
1273 compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::LocalVar );
1274
1275 //lea eax,dword ptr[ebp+ecx]
1276 OpBuffer[obp++]=(char)0x8D;
1277 OpBuffer[obp++]=(char)0x44;
1278 OpBuffer[obp++]=(char)0x0D;
1279 OpBuffer[obp++]=(char)0x00;
1280 }
1281 else{
1282 //lea eax,dword ptr[ecx+offset]
1283 compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::LocalVar );
1284 }
1285 }
1286 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1287 if(pRelativeVar->bOffsetOffset){
1288 //mov eax,ecx
1289 OpBuffer[obp++]=(char)0x8B;
1290 OpBuffer[obp++]=(char)0xC1;
1291
1292 //add eax,dword ptr[ebp+offset]
1293 OpBuffer[obp++]=(char)0x03;
1294 OpBuffer[obp++]=(char)0x85;
1295 *((long *)(OpBuffer+obp))=pRelativeVar->offset;
1296 AddLocalVarAddrSchedule();
1297 obp+=sizeof(long);
1298 }
1299 else{
1300 //mov eax,dword ptr[ebp+offset]
1301 OpBuffer[obp++]=(char)0x8B;
1302 OpBuffer[obp++]=(char)0x85;
1303 *((long *)(OpBuffer+obp))=pRelativeVar->offset;
1304 AddLocalVarAddrSchedule();
1305 obp+=sizeof(long);
1306 }
1307 }
1308 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1309 //mov eax,ecx
1310 OpBuffer[obp++]=(char)0x8B;
1311 OpBuffer[obp++]=(char)0xC1;
1312 }
1313}
1314void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1315 if( reg != REG_EAX ){
1316 SetError();
1317 //TODO: 未完成
1318 }
1319 SetVarPtrToEax( pRelativeVar );
1320}
1321
1322bool Compile_AddGlobalRootsForGc(){
1323 const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1324 if( !pUserProc_AddGlobalRootPtr ){
1325 SetError(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1326 return false;
1327 }
1328
1329 BOOST_FOREACH( const Variable *pVar, compiler.GetMeta().GetGlobalVars() ){
1330 if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1331 // オブジェクトまたはポインタだったとき
1332 // ※構造体も含む(暫定対応)
1333
1334 // 変数領域に要するLONG_PTR単位の個数を引き渡す
1335 compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
1336
1337
1338 /////////////////////////////
1339 // ルートポインタを引き渡す
1340
1341 //mov eax,offset
1342 compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress());
1343 obp-=sizeof(long);
1344 pobj_GlobalVarSchedule->add();
1345 obp+=sizeof(long);
1346
1347 //push eax
1348 compiler.codeGenerator.op_push( REG_EAX );
1349
1350 //
1351 /////////////////////////////
1352
1353
1354 /////////////////////////////
1355 // Thisポインタを引き渡す
1356
1357 SetThisPtrToReg(REG_EAX);
1358
1359 //push eax
1360 compiler.codeGenerator.op_push( REG_EAX );
1361
1362 //
1363 /////////////////////////////
1364
1365
1366 // call AddGlobalRootPtr
1367 compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1368
1369 ReallocNativeCodeBuffer();
1370 }
1371 }
1372
1373 return true;
1374}
Note: See TracBrowser for help on using the repository browser.