source: dev/trunk/ab5.0/abdev/BasicCompiler64/Compile_Var.cpp @ 463

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

[461]を64bit版にマージ。

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