Ignore:
Timestamp:
Oct 3, 2007, 3:42:05 AM (17 years ago)
Author:
dai_9181
Message:

64ビットコンパイラもデリゲートに対応させた

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler64/Compile_Func.cpp

    r331 r339  
    7070    return;
    7171}
    72 void Opcode_Func_AddressOf( const char *name, const Type &baseType ){
    73     extern int cp;
    74     const UserProc *pUserProc;
    75 
    76     if( baseType.IsProcPtr() )
    77     {
    78         //左辺の型にのっとり、オーバーロードを解決
    79 
    80         std::vector<const UserProc *> subs;
    81         GetOverloadSubHash( name, subs );
    82         if( subs.size() == 0 ){
    83             SetError(27,name,cp);
    84             return;
    85         }
    86 
    87         //オーバーロードを解決
    88         pUserProc=OverloadSolution(name,subs,compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()]->Params(), Type() );
    89 
    90         if(!pUserProc){
    91             SetError(27,name,cp);
    92             return;
    93         }
    94     }
    95     else{
    96         pUserProc=GetSubHash(name);
    97         if(!pUserProc){
    98             SetError(27,name,cp);
    99             return;
    100         }
    101     }
    102 
    103     if( pUserProc->IsVirtual() ){
     72
     73void _Opcode_Func_AddressOf( const char *methodInstanceName, const UserProc &userProc )
     74{
     75    if( userProc.IsVirtual() )
     76    {
    10477        ///////////////////////////////
    10578        // 仮想関数の場合
     
    11184        char ObjectName[VN_SIZE];
    11285        ReferenceKind referenceKind;
    113         SplitObjectName(name,ObjectName, referenceKind );
     86        SplitObjectName(methodInstanceName,ObjectName, referenceKind );
    11487
    11588        if(ObjectName[0]){
     
    151124        compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
    152125
    153         int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
     126        int i2 = pobj_c->GetFuncNumInVtbl( &userProc );
    154127
    155128        //mov rax,qword ptr[r11+func_index]
     
    165138
    166139        //mov rax,ProcAddr
    167         compiler.codeGenerator.op_addressof( REG_RAX, pUserProc );
    168     }
    169 
    170     pUserProc->Using();
     140        compiler.codeGenerator.op_addressof( REG_RAX, &userProc );
     141    }
     142
     143    userProc.Using();
     144}
     145void Opcode_CreateDelegate( const CClass &dgClass, const char *methodInstanceName, const UserProc &userProc )
     146{
     147    /////////////////////////////////////////////////////////////////
     148    // 関数ポインタをpush
     149    /////////////////////////////////////////////////////////////////
     150
     151    //mov rax,AddressOf
     152    _Opcode_Func_AddressOf( methodInstanceName, userProc );
     153
     154
     155    if( userProc.GetMethod().IsDynamic() )
     156    {
     157        //mov rdx,rax
     158        compiler.codeGenerator.op_mov_RR( REG_RDX, REG_RAX );
     159
     160        pobj_BlockReg->lock( REG_RDX );
     161
     162
     163        /////////////////////////////////////////////////////////////////
     164        // オブジェクト ポインタをpush
     165        /////////////////////////////////////////////////////////////////
     166
     167        // オブジェクト名を取得
     168        char objectName[VN_SIZE];
     169        char memberName[VN_SIZE];
     170        char *thisPtrName = "This";
     171        Type type;
     172        if( SplitMemberName( methodInstanceName, objectName, memberName ) )
     173        {
     174            if( GetVarType( objectName, type, false ) )
     175            {
     176                thisPtrName = objectName;
     177            }
     178        }
     179
     180        // オブジェクト ポインタを取得
     181        RELATIVE_VAR relativeVar;
     182        GetVarOffsetReadOnly( thisPtrName, &relativeVar, type );
     183        if( !type.IsObject() )
     184        {
     185            extern int cp;
     186            SetError(1,NULL,cp);
     187            return;
     188        }
     189
     190        SetVarPtrToReg( REG_RAX, &relativeVar );
     191
     192        //mov rcx,dword ptr[rax]
     193        compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RCX, REG_RAX, 0, MOD_BASE );
     194
     195        pobj_BlockReg->unlock( REG_RDX );
     196    }
     197    else
     198    {
     199        //mov rcx,rax
     200        compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
     201    }
     202
     203
     204    /////////////////////////////////////////////////////////////////
     205    // call _CreateDynamicDelegate/_CreateStaticDelegate
     206    /////////////////////////////////////////////////////////////////
     207
     208    std::vector<const UserProc *> subs;
     209    if( userProc.GetMethod().IsDynamic() )
     210    {
     211        dgClass.GetStaticMethods().Enum( "_CreateDynamicDelegate", subs );
     212    }
     213    else
     214    {
     215        dgClass.GetStaticMethods().Enum( "_CreateStaticDelegate", subs );
     216    }
     217
     218    // call _CreateDynamicDelegate
     219    compiler.codeGenerator.op_call( subs[0] );
     220}
     221void Opcode_Func_AddressOf( const char *name, const Type &baseType, bool isCallOn, Type &resultType )
     222{
     223    extern int cp;
     224    const UserProc *pUserProc;
     225
     226    const Parameters *pBaseParams = NULL;
     227    if( baseType.IsProcPtr() )
     228    {
     229        // 左辺で関数ポインタを要求されているとき
     230        pBaseParams = &compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()]->Params();
     231    }
     232    else if( baseType.IsDelegate() )
     233    {
     234        // 左辺でデリゲートを要求されているとき
     235        pBaseParams = &baseType.GetClass().GetDelegate().Params();
     236    }
     237
     238    if( pBaseParams )
     239    {
     240        //左辺の型にのっとり、オーバーロードを解決
     241
     242        std::vector<const UserProc *> subs;
     243        GetOverloadSubHash( name, subs );
     244        if( subs.size() == 0 ){
     245            SetError(27,name,cp);
     246            return;
     247        }
     248
     249        //オーバーロードを解決
     250        pUserProc=OverloadSolution( name, subs, *pBaseParams, Type() );
     251
     252        if( isCallOn && baseType.IsDelegate() )
     253        {
     254            // コード生成を伴う場合はエラーチェックを行う
     255            if( !pUserProc->Params().Equals( *pBaseParams )
     256                || !pUserProc->ReturnType().Equals( baseType.GetClass().GetDelegate().ReturnType() ) )
     257            {
     258                if( baseType.IsDelegate() )
     259                {
     260                    SetError(67, name, cp );
     261                }
     262                else
     263                {
     264                    SetError(66, name, cp );
     265                }
     266            }
     267        }
     268
     269        if(!pUserProc){
     270            SetError(27,name,cp);
     271            return;
     272        }
     273    }
     274    else{
     275        pUserProc=GetSubHash(name);
     276        if(!pUserProc){
     277            SetError(27,name,cp);
     278            return;
     279        }
     280    }
     281
     282    if( baseType.IsDelegate() )
     283    {
     284        if( isCallOn )
     285        {
     286            // デリゲートのとき
     287            Opcode_CreateDelegate( baseType.GetClass(), name, *pUserProc );
     288        }
     289        resultType = baseType;
     290    }
     291    else
     292    {
     293        if( isCallOn )
     294        {
     295            // 関数ポインタのとき
     296            _Opcode_Func_AddressOf( name, *pUserProc );
     297        }
     298        resultType.SetBasicType( DEF_PTR_VOID );
     299    }
    171300}
    172301void Opcode_Func_SizeOf( const string &typeName ){
     
    262391        i = GetOneParameter( paramsStr, i, methodPtrParamStr );
    263392
    264         char objPtrValueStr[VN_SIZE];
     393        char objPtrValueStr[VN_SIZE] = "";
    265394        if( isDynamicCall )
    266395        {
     
    307436            break;
    308437        case FUNC_ADDRESSOF:
    309             if( isCallOn ) Opcode_Func_AddressOf( Parameter, baseType );
    310             resultType.SetBasicType( DEF_PTR_VOID );
     438            Opcode_Func_AddressOf( Parameter, baseType, isCallOn, resultType );
    311439            break;
    312440        case FUNC_SIZEOF:
Note: See TracChangeset for help on using the changeset viewer.