source: dev/BasicCompiler64/Compile_Var.cpp @ 131

Last change on this file since 131 was 131, checked in by dai_9181, 16 years ago

Prototypeクラスを用意した。

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