source: dev/trunk/abdev/BasicCompiler64/Compile_Var.cpp@ 198

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