Changeset 20 in dev for BasicCompiler32/CParameter.cpp


Ignore:
Timestamp:
Dec 28, 2006, 5:24:48 AM (17 years ago)
Author:
dai_9181
Message:

参照型パラメータに関数の戻り値オブジェクトを指定した場合などの、一時オブジェクトの扱いを可能にした。
Dimで指定される初期値を見分けることで、As指定を省略できるようにした。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • BasicCompiler32/CParameter.cpp

    r11 r20  
    331331}
    332332
     333void CParameter::NewTempParameters( char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum ){
     334    ///////////////////////////////////////////////////////
     335    // 一時オブジェクトをあらかじめスタックに積んでおく
     336    ///////////////////////////////////////////////////////
     337    //TODO: 64ビットコードのままなので、32ビット用に書き換える
     338
     339    useTempObject = false;
     340
     341    //一時オブジェクトの数
     342    nCountOfTempObjects = 0;
     343
     344    BOOL bEllipse;
     345    if(pi_num){
     346        if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
     347        else bEllipse=0;
     348    }
     349    else bEllipse=0;
     350
     351    for(int i2=ParmsNum-1;i2>=0;i2--){
     352        useTempParameters[i2] = false;
     353
     354        if(bEllipse&&i2<=pi_num-2) bEllipse=0;
     355
     356        if(i2==0&&ppi[i2].name){
     357            if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
     358                //オブジェクトメンバの第一パラメータのThisポインタ
     359                continue;
     360            }
     361        }
     362        if((i2==0||i2==1)&&ppi[i2].name){
     363            if(lstrcmp(ppi[i2].name,FuncName)==0){
     364                //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
     365                continue;
     366            }
     367        }
     368
     369        TYPEINFO DummyTypeInfo;
     370        BOOL bByVal;
     371        if(bEllipse){
     372            DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
     373            bByVal=1;
     374        }
     375        else{
     376            DummyTypeInfo.type=ppi[i2].type;
     377            DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
     378            bByVal=ppi[i2].bByVal;
     379        }
     380
     381
     382        if( !bByVal ){
     383            //ポインタ参照
     384            if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
     385                //ポインタ指定
     386                continue;
     387            }
     388
     389            LONG_PTR lpVarIndex;
     390            if( GetVarType( Parms[i2], &lpVarIndex, FALSE ) == -1 ){
     391                //変数ではないとき
     392                int reg = REG_RAX;
     393                int type = NumOpe( Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
     394                //↑ここでスタックに積む
     395
     396                useTempParameters[i2] = true;
     397                useTempObject = true;
     398
     399                types[i2].type = type;
     400                types[i2].u.lpIndex = lpVarIndex;
     401
     402                nCountOfTempObjects++;
     403            }
     404        }
     405    }
     406}
     407void CParameter::DeleteTempParameters(){
     408    ///////////////////////////////////////////////////////
     409    // 一時オブジェクトを破棄
     410    ///////////////////////////////////////////////////////
     411    //TODO: 64ビットコードのままなので、32ビット用に書き換える
     412
     413    if( !useTempObject ) return;
     414
     415    for(int i2=ParmsNum-1;i2>=0;i2--){
     416        if( useTempParameters[i2] ){
     417            //スタックフレームから取得
     418            // ※関数呼び出し時も値が普遍のebxを利用する
     419            op_pop(REG_EBX);
     420
     421
     422            ///////////////////////////
     423            // デストラクタを呼び出す
     424            ///////////////////////////
     425
     426            //push ebx
     427            op_push(REG_EBX);
     428
     429            //call destructor
     430            int i5 = types[i2].u.pobj_Class->DestructorMemberSubIndex;
     431            op_call( types[i2].u.pobj_Class->ppobj_Method[i5]->psi );
     432
     433
     434            /////////////////////////
     435            // メモリを解放する
     436            /////////////////////////
     437
     438            //push ebx
     439            op_push(REG_EBX);
     440
     441            //call free
     442            extern SUBINFO *pSub_free;
     443            op_call(pSub_free);
     444        }
     445    }
     446}
     447
    333448void CParameter::SetObjectParameter(CClass *pobj_Class,LPSTR Parameter){
    334449    int object_size;
     
    441556    int ParmSize=0;
    442557    RELATIVE_VAR RelativeVar;
     558    int nCountOfNowTempObjects = 0;
    443559    for(i2=ParmsNum-1;i2>=0;i2--){
    444560        if(bEllipse&&i2<=pi_num-2) bEllipse=0;
     
    556672                int VarType;
    557673                LONG_PTR lpVarIndex;
    558                 if(!GetVarOffsetReadOnly(Parms[i2],&VarType,&RelativeVar,&lpVarIndex)) continue;
    559 
    560                 if(DummyTypeInfo.type!=DEF_ANY){
    561                     //型チェックを行う
    562                     if(DummyTypeInfo.type==VarType){
    563                         if(DummyTypeInfo.type==DEF_OBJECT){
    564                             if(DummyTypeInfo.u.lpIndex!=lpVarIndex){
     674                if(GetVarOffset(
     675                    false,
     676                    false,
     677                    Parms[i2],
     678                    &VarType,
     679                    &RelativeVar,
     680                    &lpVarIndex)){
     681                        if(DummyTypeInfo.type!=DEF_ANY){
     682                            //型チェックを行う
     683                            if(DummyTypeInfo.type==VarType){
     684                                if(DummyTypeInfo.type==DEF_OBJECT){
     685                                    if(DummyTypeInfo.u.lpIndex!=lpVarIndex){
     686                                        SetError(11,Parms[i2],cp);
     687                                    }
     688                                }
     689                            }
     690                            else if((VarType&FLAG_PTR)&&((int)(VarType^FLAG_PTR)==DummyTypeInfo.type)){
     691                                //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
     692                            }
     693                            else{
    565694                                SetError(11,Parms[i2],cp);
    566695                            }
    567696                        }
    568                     }
    569                     else if((VarType&FLAG_PTR)&&((int)(VarType^FLAG_PTR)==DummyTypeInfo.type)){
    570                         //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
    571                     }
    572                     else{
    573                         SetError(11,Parms[i2],cp);
    574                     }
     697
     698                        //変数アドレスをレジスタにセット
     699                        SetVarPtrToEax(&RelativeVar);
     700
     701                        //push eax
     702                        op_push(REG_EAX);
    575703                }
    576 
    577                 //変数アドレスをレジスタにセット
    578                 SetVarPtrToEax(&RelativeVar);
    579 
    580                 //push eax
    581                 op_push(REG_EAX);
     704                else{
     705                    //一時オブジェクトをコピー
     706
     707                    //mov eax, dword ptr[esp+offset]
     708                    op_mov_RM(
     709                        sizeof(long),
     710                        REG_EAX,
     711                        REG_ESP,
     712                        ( ( ParmsNum - i2 - 1 ) + ( nCountOfTempObjects - nCountOfNowTempObjects - 1 ) ) * PTR_SIZE,
     713                        MOD_BASE_DISP32 );
     714
     715                    nCountOfNowTempObjects++;
     716
     717                    //push eax
     718                    op_push(REG_EAX);
     719
     720                    //VarType = NumOpe( Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
     721                }
    582722            }
    583723
Note: See TracChangeset for help on using the changeset viewer.