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

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