source: dev/trunk/abdev/BasicCompiler64/NumOpe.cpp @ 436

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

関数の戻り値の構造体など、一時メモリに保持された構造体のメンバに直接アクセスした場合、その一時メモリの解放が正常に行われないバグを修正(64bit版も修正した)。

File size: 36.1 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4
5#include <Compiler.h>
6
7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
10void NewStringObject(int reg, const char *str){
11    ///////////////////////////////////////////////////////
12    // lpszTextを元にStringオブジェクトを生成し、
13    // オブジェクトポインタをregに格納する
14    ///////////////////////////////////////////////////////
15
16
17    //////////////////////////////////////////////////////
18    /////    レジスタ資源のバックアップ
19    {   BACKUP_REGISTER_RESOURCE
20    //////////////////////////////////////////////////////
21
22        char *parameter = (char *)malloc( lstrlen( str ) + 32 );
23        sprintf( parameter, "%s%c%c*Char", str, 1, ESC_AS );
24
25        Operator_New( *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ) );
26
27        free( parameter );
28
29        //mov reg,rax
30        compiler.codeGenerator.op_mov_RR( reg, REG_RAX );
31
32    /////////////////////////////////////////////
33    //////   レジスタ資源を復元
34        RESTORE_REGISTER_RESOURCE
35    }////////////////////////////////////////////
36}
37
38void SetUseRegFromRax(int type,int UseReg,int XmmReg){
39    if(IsRealNumberType(type)){
40        //実数型
41        if(XmmReg==REG_XMM4){
42            if(type==DEF_DOUBLE){
43                //movsd qword ptr[rsp+offset],xmm0  ※スタックフレームを利用
44                pobj_sf->push(REG_XMM0,sizeof(double));
45            }
46            if(type==DEF_SINGLE){
47                //movss dword ptr[rsp+offset],xmm0  ※スタックフレームを利用
48                pobj_sf->push(REG_XMM0,sizeof(float));
49            }
50        }
51        else{
52            if(type==DEF_DOUBLE){
53                //movsd xmm_reg,xmm0
54                compiler.codeGenerator.op_movsd_RR(XmmReg,REG_XMM0);
55            }
56            else if(type==DEF_SINGLE){
57                //movss xmm_reg,xmm0
58                compiler.codeGenerator.op_movss_RR(XmmReg,REG_XMM0);
59            }
60        }
61    }
62    else{
63        //整数型
64        if(UseReg==REG_R14){
65            //mov qword ptr[rsp+offset],rax     ※スタックフレームを利用
66            pobj_sf->push(REG_RAX);
67        }
68        else{
69            //mov reg,rax
70            compiler.codeGenerator.op_mov_RR(UseReg,REG_RAX);
71        }
72    }
73}
74
75void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
76    switch( Type::GetBasicSize( bigBasicType ) ){
77        case sizeof(_int64):
78            ExtendTypeTo64(baseBasicType,reg);
79            break;
80        case sizeof(long):
81            ExtendTypeTo32(baseBasicType,reg);
82            break;
83        case sizeof(short):
84            ExtendTypeTo16(baseBasicType,reg);
85            break;
86    }
87}
88
89
90bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){
91    int UseReg=pobj_reg->GetNextReg();
92    int XmmReg=pobj_reg->GetNextXmmReg();
93
94    //大きな型への暗黙の変換
95    int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
96
97    if(resultType.GetBasicType()&FLAG_PTR){
98        //配列ポインタ
99        resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) );
100
101        SetVarPtrToReg(UseReg,&relativeVar);
102    }
103    else if(resultType.IsReal()){
104        //実数型
105        if( resultType.IsDouble() )
106            SetXmmReg_DoubleVariable(&relativeVar,XmmReg);
107        if( resultType.IsSingle() )
108            SetXmmReg_SingleVariable(&relativeVar,XmmReg);
109    }
110    else if( resultType.IsWhole() || resultType.IsObject()){
111        //整数型
112        SetReg_WholeVariable(resultType,&relativeVar,UseReg);
113    }
114    else if( resultType.IsStruct() ){
115        //構造体ポインタをUseRegへ格納(構造体は値型)
116        SetVarPtrToReg(UseReg,&relativeVar);
117    }
118    else{
119        return false;
120    }
121
122    if( resultType.GetBasicType() != bigType ){
123        // 大きな型へ変換された場合
124        // ※レジスタの値をキャストする
125        ExtendRegToBigType( UseReg, bigType, resultType.GetBasicType() );
126
127        resultType.SetBasicType( bigType );
128    }
129
130    return true;
131}
132bool TermMemberOpe( const Type &leftType, bool &isNeedHeapFreeStructure, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool &isVariable, RELATIVE_VAR &relativeVar )
133{
134    const CClass &objClass = leftType.GetClass();
135
136    const int useReg=pobj_reg->GetNextReg();
137    const int xmmReg=pobj_reg->GetNextXmmReg();
138
139
140    ////////////////////////////////
141    // インデクサ(getアクセサ)
142    ////////////////////////////////
143    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
144    GetArrayElement(member,VarName,ArrayElements);
145    if(ArrayElements[0]){
146        Type classType;
147        if( VarName[0] == '\0' )
148        {
149            classType = leftType;
150
151            if( classType.IsObject() )
152            {
153                // 既にuseRegにオブジェクトポインタが格納されており、それに対するインデクサを呼び出す場合
154                // ※「プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す」場合にここにくる
155
156                // オブジェクトメンバのポインタは既にraxに入っている
157            }
158        }
159        else
160        {
161            GetMemberType( leftType, VarName, classType, 0, false );
162
163            if( classType.IsObject() )
164            {
165                //オブジェクトポインタをr11にコピー
166                compiler.codeGenerator.op_mov_RR( REG_R11, useReg );
167
168                RELATIVE_VAR tempRelativeVar;
169                tempRelativeVar.dwKind=VAR_DIRECTMEM;
170
171                if( !_member_offset(
172                    true,   //エラー表示あり
173                    false,  //読み込み専用
174                    leftType,
175                    VarName,&tempRelativeVar,classType,0)){
176                        return false;
177                }
178
179                // オブジェクトメンバのポインタをraxにコピー
180                if( !VarToReg( tempRelativeVar, baseType, resultType ) ){
181                    SetError(11,termFull,cp);
182                }
183            }
184        }
185
186        if( classType.IsObject() )
187        {
188            //////////////////////////////////////////////////////
189            /////    レジスタ資源のバックアップ
190            {   BACKUP_REGISTER_RESOURCE
191            //////////////////////////////////////////////////////
192
193                //オブジェクトポインタをスタックに入れておく
194                //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
195                pobj_sf->push( useReg );
196
197                char objectFullName[VN_SIZE], dummyArrayElements[VN_SIZE];
198                GetArrayElement(termFull,objectFullName,dummyArrayElements);
199
200                CallIndexerGetterProc(useReg,classType,objectFullName, ArrayElements,resultType, PROCFLAG_NEW );
201
202                pobj_sf->pop();
203
204            /////////////////////////////////////////////
205            //////   レジスタ資源を復元
206                RESTORE_REGISTER_RESOURCE
207            }////////////////////////////////////////////
208
209            return true;
210        }
211    }
212
213
214    ///////////////////////////////////////////////////////////////////
215    // メンバを検索
216    ///////////////////////////////////////////////////////////////////
217    if( GetMemberType( leftType, member, resultType, 0, false ) ){
218        // メンバが見つかったとき
219
220        if( isNeedHeapFreeStructure )
221        {
222            if( !leftType.IsStruct() )
223            {
224                SetError();
225            }
226
227            pobj_reg->LockReg();
228
229            // 親となる構造体が一時メモリに存在していた場合、後ほど解放する必要がある
230            compiler.codeGenerator.op_AddNeedFreeTempStructure( useReg );
231            isNeedHeapFreeStructure = false;
232
233            pobj_reg->UnlockReg();
234        }
235
236        //オブジェクトポインタをr11にコピー
237        compiler.codeGenerator.op_mov_RR( REG_R11, useReg );
238
239        relativeVar.dwKind=VAR_DIRECTMEM;
240
241        if( !_member_offset(
242            true,   //エラー表示あり
243            false,  //読み込み専用
244            leftType,
245            member,&relativeVar,resultType,0)){
246                return false;
247        }
248
249        // 変数として扱う
250        isVariable = true;
251
252        return true;
253    }
254
255
256    ///////////////////////////////////////////////////////////////////
257    // 動的メソッドを検索
258    ///////////////////////////////////////////////////////////////////
259    vector<const UserProc *> userProcs;
260
261    char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
262    ReferenceKind refType;
263    PareOrBracket pareOrBracket = None;
264    lstrcpy( methodName, member );
265    GetVarFormatString( methodName, parameter, lpPtrOffset, dummy, refType, &pareOrBracket );
266
267    objClass.EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
268    if(userProcs.size()){
269        //オーバーロードを解決
270        const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
271
272        if( pUserProc )
273        {
274            if(
275                pUserProc->Params().size() == 0             // 仮引数の個数は0
276                && parameter[0]                             // 実引数は1つ以上
277                && pUserProc->ReturnType().IsObject()       // 戻り値がクラス型の場合
278                && pareOrBracket == Bracket )               // 実引数は[]で囲まれている
279            {
280                // プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す
281
282                // まずはプロパティ値を取得
283                bool dummyIsVariable;
284                RELATIVE_VAR dummyRelativeVar;
285                TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, methodName, dummyIsVariable, dummyRelativeVar );
286
287                // 戻り値のオブジェクトインスタンスのインデクサを呼び出す
288                char temporary[VN_SIZE], temp2[VN_SIZE];
289                sprintf( temporary, "[%s]", parameter );
290                sprintf( temp2, "%s.%s", termLeft, methodName );
291                Type classType = resultType;
292                return TermMemberOpe( classType, isNeedHeapFreeStructure, baseType, resultType, termFull, temp2, temporary, isVariable, relativeVar );
293            }
294
295            resultType = pUserProc->ReturnType();
296
297
298            //////////////////////////////////////////////////////
299            /////    レジスタ資源のバックアップ
300            {   BACKUP_REGISTER_RESOURCE
301            //////////////////////////////////////////////////////
302
303                //オブジェクトポインタをスタックに入れておく
304                //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
305                pobj_sf->push( useReg );
306
307                if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft ) ){
308                    //レジスタ資源を復元
309                    RESTORE_REGISTER_RESOURCE
310
311                    return false;
312                }
313
314                pobj_sf->pop();
315
316                /////////////////////
317                // 戻り値の処理
318                /////////////////////
319
320                //大きな型への暗黙の変換
321                int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
322
323                if( resultType.GetBasicType() != bigType ){
324                    // 大きな型へ変換された場合
325                    // ※レジスタの値をキャストする
326                    ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
327
328                    resultType.SetBasicType( bigType );
329                }
330
331                SetUseRegFromRax(resultType.GetBasicType(),useReg,xmmReg);
332
333                // 型パラメータを解決
334                ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
335
336
337            /////////////////////////////////////////////
338            //////   レジスタ資源を復元
339                RESTORE_REGISTER_RESOURCE
340            }////////////////////////////////////////////
341           
342            return true;
343        }
344    }
345    else if( pareOrBracket == Pare )
346    {
347        // 関数ポインタ
348        SetError();
349
350        ///////////////////////////////////////////////////////////////////
351        // メンバを検索
352        ///////////////////////////////////////////////////////////////////
353        if( GetMemberType( leftType, methodName, resultType, 0, false ) ){
354            // メンバが見つかったとき
355        }
356    }
357
358    SetError();
359
360    return false;
361}
362bool _TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool &isVariable, RELATIVE_VAR &relativeVar, bool isWriteAccess )
363{
364    char parameter[VN_SIZE];
365
366    // Withを解決
367    char termFull[VN_SIZE];
368    if(term[0]=='.'){
369        GetWithName(termFull);
370        lstrcat(termFull,term);
371    }
372    else lstrcpy(termFull,term);
373
374    char termLeft[VN_SIZE];
375    lstrcpy(termLeft,termFull);
376
377    // パース
378    char member[VN_SIZE];
379    ReferenceKind refType;
380    if( SplitMemberName( termFull, termLeft, member, refType ) ){
381        ///////////////////////////////////////////////////////////////////
382        // オブジェクトとメンバに分解できるとき
383        // termLeft.member
384        ///////////////////////////////////////////////////////////////////
385
386        isLiteral = false;
387
388        // オブジェクト側の型を取得
389        bool isClassName = false;
390        Type leftType;
391        if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
392            if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
393                // 左側のオブジェクト部分がBlittable型のとき
394
395                char temporary[VN_SIZE];
396                lstrcpy( temporary, termLeft );
397                sprintf( termLeft, "%s(%s)",
398                    compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
399                    temporary );
400            }
401        }
402
403        if( !TermOpe( termLeft, baseType, leftType, isLiteral, isNeedHeapFreeStructure, &isClassName ) ){
404            goto globalArea;
405        }
406
407        if( isClassName ){
408            // 静的メンバ/メソッドの場合
409            goto globalArea;
410        }
411
412        if( !leftType.HasMember() ){
413            // メンバを持たない型の場合
414            if( isProcedureCallOnly )
415            {
416                SetError(1,NULL,cp);
417            }
418            return false;
419        }
420
421        return TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, member, isVariable, relativeVar );
422    }
423globalArea:
424
425    //////////////////////////////////////////////
426    // クラス名かどうかをチェック(静的メンバ用)
427    //////////////////////////////////////////////
428
429    if( pIsClassName ){
430        if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
431            *pIsClassName = true;
432            return true;
433        }
434    }
435
436
437    /////////////////////////////////////////////////////////////////
438    // グローバル属性エリア
439    /////////////////////////////////////////////////////////////////
440
441    int UseReg=pobj_reg->GetNextReg();
442    int XmmReg=pobj_reg->GetNextXmmReg();
443
444
445    if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
446        if( compiler.pCompilingClass == NULL )
447        {
448            SetError(142,NULL,cp);
449            return false;
450        }
451
452        //Thisオブジェクト
453        resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
454
455        SetThisPtrToReg( UseReg );
456
457        isLiteral = false;
458
459        return true;
460    }
461
462
463    //////////////////////////////////////
464    // 関数(DLL、ユーザー定義、組み込み)
465    //////////////////////////////////////
466    char procName[VN_SIZE];
467    char temporary[8192];
468
469    int i2=GetCallProcName(termFull,procName);
470    if(termFull[i2]=='('){
471        int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
472
473        void *pInfo;
474        int idProc=GetProc(procName,(void **)&pInfo);
475
476        if(idProc){
477            //閉じカッコ")"に続く文字がNULLでないとき
478            if(termFull[i2+1+i4+1]!='\0'){
479                SetError(42,NULL,cp);
480            }
481
482
483            //////////////////////////////////////////////////////
484            /////    レジスタ資源のバックアップ
485            {   BACKUP_REGISTER_RESOURCE
486            //////////////////////////////////////////////////////
487
488
489                ////////////////
490                // 呼び出し
491                ////////////////
492
493                CallProc(idProc,pInfo,procName,parameter, baseType,resultType);
494
495
496                /////////////////////
497                // 戻り値の処理
498                /////////////////////
499
500                //大きな型への暗黙の変換
501                int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
502
503                if( resultType.GetBasicType() != bigType ){
504                    // 大きな型へ変換された場合
505                    // ※レジスタの値をキャストする
506                    ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
507
508                    resultType.SetBasicType( bigType );
509                }
510
511                SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
512
513            /////////////////////////////////////////////
514            //////   レジスタ資源を復元
515                RESTORE_REGISTER_RESOURCE
516            }////////////////////////////////////////////
517
518            if(resultType.IsStruct())
519            {
520                //構造体が戻ったときはヒープ領域にインスタンスが格納されている
521                //※後にfreeする必要あり
522                // TODO: 解放はGCに任せる
523                isNeedHeapFreeStructure = true;
524            }
525
526            isLiteral = false;
527
528            return true;
529        }
530
531        ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
532        if( pConstMacro )
533        {
534            if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
535            {
536                /////////////////////////
537                // マクロ関数
538                /////////////////////////
539
540                //閉じカッコ")"に続く文字がNULLでないときはエラーにする
541                if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
542
543                //マクロ関数の場合
544                NumOpe(&UseReg, temporary,Type(),resultType);
545
546                if(!IS_LITERAL(resultType.GetIndex())){
547                    //リテラル値ではなかったとき
548                    isLiteral = false;
549                }
550
551                return true;
552            }
553        }
554    }
555    else if( isProcedureCallOnly ){
556        // 関数呼び出し以外は受け付けない
557        return false;
558    }
559
560
561    ////////////////////////////////
562    // インデクサ(getアクセサ)
563    ////////////////////////////////
564
565    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
566    GetArrayElement(termFull,VarName,ArrayElements);
567    if(ArrayElements[0]){
568        Type classType;
569        GetVarType(VarName,classType,false);
570        if( classType.IsObject() )
571        {
572            CallIndexerGetterProc(UseReg,classType,VarName,ArrayElements,resultType);
573
574            isLiteral = false;
575
576            return true;
577        }
578    }
579
580
581    ////////////////////////////////
582    // 変数
583    ////////////////////////////////
584
585    if(GetVarOffset(
586        false,  //エラー表示なし
587        isWriteAccess,
588        termFull,
589        &relativeVar,resultType)){
590        //////////
591        // 変数
592        //////////
593
594        // 変数として扱う
595        isVariable = true;
596
597        isLiteral = false;
598
599        return true;
600    }
601
602/*
603    ////////////////////////////////
604    // 型名
605    ////////////////////////////////
606
607    if( compiler.StringToType( termFull, resultType ) ){
608        resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
609        return true;
610    }*/
611
612
613    /////////////////////////////////
614    // プロパティ用のメソッド
615    /////////////////////////////////
616
617    //配列要素を排除
618    GetArrayElement(termFull,VarName,ArrayElements);
619
620    if(GetSubHash(VarName,0)){
621
622        //////////////////////////////////////////////////////
623        /////    レジスタ資源のバックアップ
624        {   BACKUP_REGISTER_RESOURCE
625        //////////////////////////////////////////////////////
626
627            CallPropertyMethod(termFull,NULL,resultType);
628
629            //大きな型への暗黙の変換
630            int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
631
632            if( resultType.GetBasicType() != bigType ){
633                // 大きな型へ変換された場合
634                // ※レジスタの値をキャストする
635                ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
636
637                resultType.SetBasicType( bigType );
638            }
639
640            SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
641
642        /////////////////////////////////////////////
643        //////   レジスタ資源を復元
644            RESTORE_REGISTER_RESOURCE
645        }////////////////////////////////////////////
646
647        if(resultType.IsStruct())
648        {
649            //構造体が戻ったときはヒープ領域にインスタンスが格納されている
650            //※後にfreeする必要あり
651            // TODO: 解放はGCに任せる
652            isNeedHeapFreeStructure = true;
653        }
654
655        isLiteral = false;
656
657        return true;
658    }
659
660    if( isProcedureCallOnly )
661    {
662        SetError(3, termLeft, cp );
663    }
664
665    return false;
666}
667
668bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool isWriteAccess )
669{
670    bool isInitRegSwitch = false;
671    if( !pobj_reg )
672    {
673        isInitRegSwitch = true;
674
675        //作業用レジスタを取得
676        pobj_reg = new CRegister( REG_RAX );
677    }
678
679    //エラー時の復旧用
680    CRegister objReg_Backup = *pobj_reg;
681
682
683    RELATIVE_VAR relativeVar;
684    bool isVariable = false;
685    bool result = _TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructure, pIsClassName, isProcedureCallOnly, isVariable, relativeVar, isWriteAccess );
686
687    if( isVariable )
688    {
689        // 変数の場合はeaxに変数ポインタを格納する
690        if( !VarToReg( relativeVar, baseType, resultType ) ){
691            SetError(11,term,cp);
692        }
693    }
694
695
696    if( !result )
697    {
698        *pobj_reg = objReg_Backup;
699    }
700
701    if( isInitRegSwitch ){
702        //整合性をチェック(バグ回避)
703        if( result )
704        {
705            pobj_reg->bug_check();
706        }
707
708        //作業レジスタを解放
709        delete pobj_reg;
710        pobj_reg = NULL;
711    }
712
713    return result;
714}
715bool TermOpeOnlyVariable( const char *term, Type &resultType, RELATIVE_VAR &relativeVar, bool isWriteAccess )
716{
717    if( pobj_reg )
718    {
719        SetError();
720    }
721
722    //作業用レジスタを取得
723    pobj_reg = new CRegister( REG_NON );
724
725    bool isLiteral, isVariable = false, isNeedHeapFreeStructure = false;
726    bool result = _TermOpe( term, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, false, isVariable, relativeVar, isWriteAccess );
727
728    if( !isVariable )
729    {
730        SetError();
731    }
732
733    //整合性をチェック(バグ回避)
734    if( result )
735    {
736        pobj_reg->bug_check();
737    }
738
739    //作業レジスタを解放
740    delete pobj_reg;
741    pobj_reg=0;
742
743    return result;
744}
745
746
747bool _numope( int *pReg,
748            const char *expression,
749            const Type &baseType,
750            Type &resultType,
751            bool *pbIsNeedHeapFreeStructure )
752{
753    int i,i2,i3;
754    char temporary[1024],temp2[1024];
755
756    if(expression[0]=='\0'){
757        SetError(1,NULL,cp);
758        return false;
759    }
760
761    if( !baseType.IsNull() && expression[0] == '[' ){
762        // リテラル配列の場合
763
764        int dataTableOffset;
765        if( !compiler.GetObjectModule().dataTable.MakeLiteralArrayBuffer( expression, baseType, dataTableOffset ) )
766        {
767            return false;
768        }
769
770        //mov reg,i2
771        compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable );
772
773        resultType = baseType;
774
775        return true;
776    }
777
778    bool isLiteralCalculation;
779    if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
780    {
781        if( isLiteralCalculation )
782        {
783            //右辺値が数値の定数式の場合
784            _int64 i64data;
785            StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
786
787            if(resultType.IsReal()){
788                if(baseType.IsReal()) resultType=baseType;
789
790                int xmmReg = pobj_reg->GetNextXmmReg();
791                *pReg = xmmReg;
792
793                if(resultType.IsDouble()){
794                    i3 = compiler.GetObjectModule().dataTable.Add( i64data );
795
796                    //movlpd xmm_reg,qword ptr[data table offset]
797                    compiler.codeGenerator.op_movlpd_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
798                }
799                if(resultType.IsSingle()){
800                    double dbl;
801                    memcpy(&dbl,&i64data,sizeof(_int64));
802
803                    float flt;
804                    int i32data;
805                    flt=(float)dbl;
806                    memcpy(&i32data,&flt,sizeof(long));
807
808                    i3 = compiler.GetObjectModule().dataTable.Add( i32data );
809
810                    //movss xmm_reg,dword ptr[data table offset]
811                    compiler.codeGenerator.op_movss_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
812                }
813            }
814            else{
815                if(!resultType.Is64()){
816                    //整数(符号有り/無し)
817
818                    i3=(long)i64data;
819
820                    if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
821                    if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
822
823                    i64data=(_int64)i3;
824                }
825
826                //mov reg,i64data
827                compiler.codeGenerator.op_mov_RV64(*pReg,i64data);
828            }
829            return true;
830        }
831    }
832
833    if( expression[0] == 1 )
834    {
835        if( expression[1]==ESC_NEW )
836        {
837            //New演算子(オブジェクト生成)
838
839            if( pobj_BlockReg->check(REG_RAX) ){
840                SetError();
841            }
842
843            //////////////////////////////////////////////////////
844            /////    レジスタ資源のバックアップ
845            {   BACKUP_REGISTER_RESOURCE
846            //////////////////////////////////////////////////////
847
848                if( !Operator_New( expression+2, baseType, resultType ) ){
849                    return false;
850                }
851
852            /////////////////////////////////////////////
853            //////   レジスタ資源を復元
854                RESTORE_REGISTER_RESOURCE
855            }////////////////////////////////////////////
856
857            //mov reg,rax
858            compiler.codeGenerator.op_mov_RR( *pReg, REG_RAX );
859
860            return true;
861        }
862        else if( expression[1] == ESC_SYSTEM_STATIC_NEW )
863        {
864            // 静的領域にオブジェクトを作る
865
866            // 静的領域にオブジェクトを生成
867            int dataTableOffset;
868            if( !compiler.GetObjectModule().dataTable.MakeConstObjectToProcessStaticBuffer( expression + 2, resultType, dataTableOffset ) )
869            {
870                return false;
871            }
872
873            //mov reg,i2
874            compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable);
875
876            return true;
877        }
878    }
879
880
881    /////////////////////////////////
882    // 式要素を逆ポーランド式で取得
883    /////////////////////////////////
884
885    char *values[255];
886    long calc[255];
887    long stack[255];
888    int pnum;
889    if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
890        for(i=0;i<pnum;i++){
891            if(values[i]) HeapDefaultFree(values[i]);
892        }
893        return 0;
894    }
895
896
897    ////////////////////////////////
898    // 演算部分のコード生成を開始
899    ////////////////////////////////
900
901    BOOL bError;
902    bError=0;
903
904    //リテラル値のみの計算かどうかを判別するためのフラグ
905    BOOL bLiteralCalculation=1;
906
907    double dbl;
908    int sp;
909    int type_stack[255];
910    LONG_PTR index_stack[255];
911    bool isNothing_stack[255];
912    bool isNeedHeapFreeStructureStack[255];
913    _int64 i64data;
914    int UseReg,XmmReg;
915    BOOL bXmm;
916    for(i=0,sp=0;i<pnum;i++){
917        int idCalc;
918        idCalc=calc[i]%100;
919
920        if(idCalc){
921            if(type_stack[sp-2]==DEF_OBJECT){
922                if( idCalc == CALC_AS
923                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
924                    && index_stack[sp-1] == index_stack[sp-2]
925                    || isNothing_stack[sp-2] ){
926                        // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
927                }
928                else if( idCalc == CALC_AS
929                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
930                    && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
931                    )){
932                        // ダウンキャストを許可する
933                }
934                else{
935                    //オーバーロードされたオペレータを呼び出す
936                    i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,isNeedHeapFreeStructureStack,sp);
937                    if(i2==0){
938                        if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
939                        else GetCalcName(idCalc,temp2);
940                        sprintf(temporary,"Operator %s",temp2);
941                        SetError(27,temporary,cp);
942                        goto error;
943                    }
944                    else if(i2==-1) goto error;
945
946                    continue;
947                }
948            }
949
950            if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
951        }
952
953        switch(idCalc){
954            //数値
955            case 0:
956                index_stack[sp]=-1;
957                isNothing_stack[sp] = false;
958                isNeedHeapFreeStructureStack[sp] = false;
959
960                UseReg=pobj_reg->GetNextReg();
961                XmmReg=pobj_reg->GetNextXmmReg();
962
963                bXmm=0;
964
965                char *term;
966                term=values[i];
967
968                if( calc[i+1]%100 == CALC_AS ){
969                    // As演算子の右辺値
970                    //型名
971                    if( compiler.StringToType( term, resultType ) ){
972                        resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
973                    }
974                    else{
975                        SetError(3, term, cp );
976                        goto error;
977                    }
978
979                    type_stack[sp] = resultType.GetBasicType();
980                    index_stack[sp] = resultType.GetIndex();
981                    sp++;
982
983                    break;
984                }
985
986                if( (term[0]=='e'||term[0]=='E')
987                    && (term[1]=='x'||term[1]=='X')
988                    && term[2]=='\"'
989                    || term[0] == '\"' )
990                {
991                    bool isEx = true;
992                    if( term[0] == '\"' )
993                    {
994                        isEx = false;
995                    }
996
997                    if( isEx )
998                    {
999                        // 拡張版リテラル文字列(エスケープシーケンス可能)
1000                        if(!RemoveStringQuotes(term+2)){
1001                            SetError(43,NULL,cp);
1002                            goto error;
1003                        }
1004                        i3=FormatString_EscapeSequence(term+2);
1005                        term+=2;
1006                    }
1007                    else
1008                    {
1009                        // 通常文字列
1010                        if(!RemoveStringQuotes(term)){
1011                            SetError(43,NULL,cp);
1012                            goto error;
1013                        }
1014                        i3=lstrlen(term);
1015                    }
1016
1017                    if( !baseType.IsPointer() )
1018                    {
1019                        //要求タイプがオブジェクト、または未定のとき
1020
1021                        //String型オブジェクトを生成
1022                        i2 = compiler.GetObjectModule().dataTable.MakeConstStringObjectToProcessStaticBuffer( term );
1023
1024                        //mov reg,i2
1025                        compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
1026
1027                        type_stack[sp]=DEF_OBJECT;
1028                        index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1029                        bLiteralCalculation=0;
1030
1031                        if(bXmm) pobj_reg->LockXmmReg();
1032                        else pobj_reg->LockReg();
1033
1034                        sp++;
1035                        break;
1036                    }
1037
1038StrLiteral:
1039
1040                    type_stack[sp]=typeOfPtrChar;
1041                    bLiteralCalculation=0;
1042
1043                    i2 = compiler.GetObjectModule().dataTable.AddString( term, i3 );
1044
1045                    //mov reg,i2
1046                    compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
1047
1048                    if(UseReg==REG_R14){
1049                        //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
1050                        pobj_sf->push(REG_R14);
1051                    }
1052                }
1053                else if(IsVariableTopChar(term[0])||
1054                    term[0]=='*'||
1055                    (term[0]=='.'&&IsVariableTopChar(term[1])))
1056                {
1057                    //////////////////
1058                    // 何らかの識別子
1059
1060                    bool isLiteral;
1061                    if( TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructureStack[sp] ) ){
1062                        if(resultType.IsNull()){
1063                            //戻り値が存在しないとき
1064                            for(i2=0;;i2++){
1065                                if(term[i2]=='('||term[i2]=='\0'){
1066                                    term[i2]=0;
1067                                    break;
1068                                }
1069                            }
1070                            SetError(38,term,cp);
1071
1072                            goto error;
1073                        }
1074
1075                        type_stack[sp] = resultType.GetBasicType();
1076                        index_stack[sp] = resultType.GetIndex();
1077
1078                        if( !isLiteral ){
1079                            bLiteralCalculation=0;
1080                        }
1081
1082                        if( resultType.GetBasicType() & FLAG_CAST ){
1083                            // 型名のみ
1084                            SetError();
1085                        }
1086                        else{
1087                            if( resultType.IsReal() == false && UseReg==REG_R14 ){
1088                                //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
1089                                pobj_sf->push(REG_R14);
1090                            }
1091                            if( resultType.IsReal() && XmmReg==REG_XMM4 ){
1092                                if(resultType.IsDouble()){
1093                                    //movsd qword ptr[rsp+offset],xmm4  ※スタックフレームを利用
1094                                    pobj_sf->push(REG_XMM4,sizeof(double));
1095                                }
1096                                if(resultType.IsSingle()){
1097                                    //movss dword ptr[rsp+offset],xmm4  ※スタックフレームを利用
1098                                    pobj_sf->push(REG_XMM4,sizeof(float));
1099                                }
1100                            }
1101
1102                            if( resultType.IsReal() ){
1103                                pobj_reg->LockXmmReg();
1104                            }
1105                            else{
1106                                pobj_reg->LockReg();
1107                            }
1108                        }
1109
1110                        sp++;
1111                        break;
1112                    }
1113
1114
1115                    // Nothing
1116                    if( lstrcmp( term, "Nothing" ) == 0 ){
1117                        isNothing_stack[sp] = true;
1118
1119                        type_stack[sp] = DEF_OBJECT;
1120                        if( baseType.IsObject() ){
1121                            index_stack[sp] = baseType.GetIndex();
1122                        }
1123                        else{
1124                            index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
1125                        }
1126
1127                        bLiteralCalculation = 0;
1128
1129                        //xor reg,reg
1130                        compiler.codeGenerator.op_zero_reg( UseReg );
1131
1132                        if(UseReg==REG_R14){
1133                            //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
1134                            pobj_sf->push(REG_R14);
1135                        }
1136
1137                        pobj_reg->LockReg();
1138                        sp++;
1139                        break;
1140                    }
1141
1142
1143                    //////////////
1144                    // 定数の場合
1145                    //////////////
1146
1147                    i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
1148                    if(i3){
1149                        if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
1150                            //リテラル文字列
1151
1152                            if( baseType.IsObject() || baseType.IsNull() )
1153                            {
1154                                //要求タイプがオブジェクト、または未定のとき
1155
1156                                //String型オブジェクトを生成
1157                                NewStringObject(UseReg,term);
1158
1159                                type_stack[sp]=DEF_OBJECT;
1160                                index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1161                                bLiteralCalculation=0;
1162
1163                                if(bXmm) pobj_reg->LockXmmReg();
1164                                else pobj_reg->LockReg();
1165
1166                                sp++;
1167                                break;
1168                            }
1169
1170                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1171                            memcpy(&i64data,&dbl,sizeof(double));
1172
1173                            //バイト数
1174                            i3=lstrlen((char *)i64data);
1175
1176                            memcpy(term,(char *)i64data,i3);
1177                            term[i3]=0;
1178                            goto StrLiteral;
1179                        }
1180
1181                        type_stack[sp] = i3;
1182                        if(IsRealNumberType(i3)){
1183                            //実数
1184                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1185                            memcpy(&i64data,&dbl,sizeof(double));
1186                            goto Literal;
1187                        }
1188                        else if(IsWholeNumberType(i3)){
1189                            //整数
1190                            i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
1191                            goto Literal;
1192                        }
1193                        else{
1194                            SetError(1,NULL,0);
1195                            goto error;
1196                        }
1197                    }
1198
1199
1200                    //該当する識別子が見当たらないときはエラー扱いにする
1201                    bError=1;
1202                    SetError(3,term,cp);
1203                    type_stack[sp]=DEF_DOUBLE;
1204                }
1205                else{
1206                    //リテラル値
1207                    type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1208Literal:
1209                    if(type_stack[sp]==DEF_DOUBLE){
1210                        //64ビット浮動小数型
1211                        bXmm=1;
1212
1213                        if(XmmReg==REG_XMM4){
1214                            //mov r14,i64data
1215                            compiler.codeGenerator.op_mov_RV64(REG_R14,i64data);
1216
1217
1218                            //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
1219                            pobj_sf->push(REG_R14);
1220                        }
1221                        else{
1222                            i3 = compiler.GetObjectModule().dataTable.Add( i64data );
1223
1224                            //movlpd xmm_reg,qword ptr[data table offset]
1225                            compiler.codeGenerator.op_movlpd_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1226                        }
1227                    }
1228                    else if(type_stack[sp]==DEF_SINGLE){
1229                        //32ビット浮動小数型
1230                        bXmm=1;
1231
1232                        float flt;
1233                        int i32data;
1234                        memcpy(&dbl,&i64data,sizeof(double));
1235                        flt=(float)dbl;
1236                        memcpy(&i32data,&flt,sizeof(long));
1237
1238                        if(XmmReg==REG_XMM4){
1239                            SetError();     // TODO: 未実装
1240                            //push term
1241                            //compiler.codeGenerator.op_push_value(i32data);
1242                        }
1243                        else{
1244                            i3=compiler.GetObjectModule().dataTable.Add( i32data );
1245
1246                            //movss xmm_reg,dword ptr[data table offset]
1247                            compiler.codeGenerator.op_movss_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1248                        }
1249                    }
1250                    else{
1251                        //整数
1252
1253                        index_stack[sp]=GetLiteralIndex(i64data);
1254
1255                        //mov reg,i64data
1256                        compiler.codeGenerator.op_mov_RV64(UseReg,i64data);
1257
1258                        if(UseReg==REG_R14){
1259                            //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
1260                            pobj_sf->push(REG_R14);
1261                        }
1262                    }
1263                }
1264
1265                if(bXmm) pobj_reg->LockXmmReg();
1266                else pobj_reg->LockReg();
1267
1268                sp++;
1269                break;
1270
1271            //論理演算子
1272            case CALC_XOR:
1273            case CALC_OR:
1274            case CALC_AND:
1275                if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
1276                break;
1277            case CALC_NOT:
1278                //value[sp-1]=Not value[sp-1]
1279                //NOT演算子
1280                if(!Calc_Not(type_stack,sp)) goto error;
1281                break;
1282
1283            //比較演算子
1284            case CALC_PE:       //value[sp-2] <= value[sp-1]
1285            case CALC_QE:       //value[sp-2] >= value[sp-1]
1286            case CALC_P:        //value[sp-2] <  value[sp-1]
1287            case CALC_Q:        //value[sp-2] >  value[sp-1]
1288            case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1289            case CALC_EQUAL:    //value[sp-2] =  value[sp-1]               
1290                if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
1291                break;
1292
1293            //ビットシフト
1294            case CALC_SHL:  //value[sp-2] << value[sp-1]
1295            case CALC_SHR:  //value[sp-2] >> value[sp-1]
1296                if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
1297                break;
1298
1299            //算術演算
1300            case CALC_ADDITION:
1301            case CALC_SUBTRACTION:
1302            case CALC_PRODUCT:
1303                if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1304                break;
1305            case CALC_MOD:
1306                //value[sp-2]%=value[sp-1]
1307                //剰余演算
1308                if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
1309                break;
1310            case CALC_QUOTIENT:
1311                //value[sp-2]/=value[sp-1];
1312                //除算
1313                if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1314                break;
1315            case CALC_INTQUOTIENT:
1316                //value[sp-2]/=value[sp-1]
1317                //整数除算
1318                if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1319                break;
1320            case CALC_MINUSMARK:
1321                //value[sp-1]=-value[sp-1]
1322                //符号反転
1323                if(!Calc_MinusMark(type_stack,sp)) goto error;
1324                break;
1325            case CALC_POWER:
1326                //べき乗演算(浮動小数点演算のみ)
1327                if(!Calc_Power(type_stack,&sp)) goto error;
1328                break;
1329            case CALC_AS:
1330                //キャスト
1331                if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1332                break;
1333            case CALC_BYVAL:
1334                //ポインタ型→参照型
1335                if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1336                    //ポインタ型ではないとき
1337                    SetError( 3, NULL, cp );
1338                    goto error;
1339                }
1340
1341                type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1342
1343                break;
1344
1345            default:
1346                SetError(300,NULL,cp);
1347                goto error;
1348        }
1349    }
1350
1351    if(bError) goto error;
1352
1353    if(sp!=1){
1354        SetError(1,NULL,cp);
1355        goto error;
1356    }
1357
1358    if(bLiteralCalculation){
1359        SetError();
1360    }
1361    else{
1362        //右辺値が数値の定数式ではないとき
1363        if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1364    }
1365
1366    if( pbIsNeedHeapFreeStructure )
1367    {
1368        *pbIsNeedHeapFreeStructure = isNeedHeapFreeStructureStack[0];
1369    }
1370
1371    if(IsRealNumberType(type_stack[0]))
1372        *pReg=pobj_reg->UnlockXmmReg();
1373    else
1374        *pReg=pobj_reg->UnlockReg();
1375
1376
1377    resultType.SetType( type_stack[0], index_stack[0] );
1378
1379    bool isSuccessful = true;
1380    goto finish;
1381
1382
1383
1384    //////////////////
1385    // エラー処理
1386    //////////////////
1387
1388error:
1389
1390    isSuccessful = false;
1391    goto finish;
1392
1393
1394
1395
1396finish:
1397
1398    for(i=0;i<pnum;i++){
1399        if(values[i]) HeapDefaultFree(values[i]);
1400    }
1401
1402    return isSuccessful;
1403}
1404
1405bool NumOpe( int *pReg,
1406            const char *expression,
1407            const Type &baseType,
1408            Type &resultType,
1409            bool *pbIsNeedHeapFreeStructure )
1410{
1411    bool isInitRegSwitch = false;
1412    if( !pobj_reg )
1413    {
1414        isInitRegSwitch = true;
1415
1416        //作業用レジスタを取得
1417        pobj_reg = new CRegister( *pReg );
1418    }
1419
1420    //エラー時の復旧用
1421    CRegister objReg_Backup = *pobj_reg;
1422
1423    *pReg = pobj_reg->GetNextReg();
1424
1425
1426    bool result = _numope( pReg, expression, baseType, resultType, pbIsNeedHeapFreeStructure );
1427
1428
1429    if( !result )
1430    {
1431        *pobj_reg = objReg_Backup;
1432    }
1433
1434    if( isInitRegSwitch ){
1435        //整合性をチェック(バグ回避)
1436        if( result )
1437        {
1438            pobj_reg->bug_check();
1439        }
1440
1441        //作業レジスタを解放
1442        delete pobj_reg;
1443        pobj_reg = NULL;
1444    }
1445
1446    return result;
1447}
Note: See TracBrowser for help on using the repository browser.