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

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