HRESULT Library_corlib_native_System_Resources_ResourceManager::GetObject___STATIC__OBJECT__SystemResourcesResourceManager__SystemEnum( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock& blkResourceManager = stack.Arg0();
    CLR_RT_HeapBlock& blkEnumObj         = stack.Arg1();    
    CLR_RT_HeapBlock* blkVT              = blkEnumObj.Dereference();
    CLR_RT_HeapBlock* blkEnum            = blkVT + 1;
    CLR_RT_MethodDef_Instance md;

    if(stack.m_customState == 0)
    {
        stack.m_customState = 1;

        FAULT_ON_NULL(blkVT);
        
        if(blkEnum->DataType() != DATATYPE_I2 && blkEnum->DataType() != DATATYPE_U2) TINYCLR_SET_AND_LEAVE( CLR_E_INVALID_PARAMETER );
        
        //call back into ResourceManager.GetObjectFromId(short id);

        _SIDE_ASSERTE(md.InitializeFromIndex( g_CLR_RT_WellKnownMethods.m_ResourceManager_GetObjectFromId ));

        TINYCLR_CHECK_HRESULT( stack.MakeCall( md, &blkResourceManager, blkEnum, 1 ));
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_ConstructorInfo::Invoke___OBJECT__SZARRAY_OBJECT( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*           thisRef = stack.ThisRef().Dereference();
    CLR_RT_MethodDef_Instance   md;
    CLR_RT_HeapBlock_Array*     pArray  = stack.Arg1().DereferenceArray();
    CLR_RT_HeapBlock*           args    = NULL;
    int                         numArgs = 0;

    if(md.InitializeFromIndex( thisRef->ReflectionDataConst().m_data.m_method ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE);

    if(stack.m_customState == 0)
    {
        stack.m_customState = 1;

        if(pArray)
        {
            args = (CLR_RT_HeapBlock*)pArray->GetFirstElement();
            numArgs = pArray->m_numOfElements;
        }

        TINYCLR_CHECK_HRESULT(stack.MakeCall( md, NULL, args, numArgs ));
    }   

    TINYCLR_NOCLEANUP();
}
void CLR_RT_Assembly::DumpOpcode( CLR_RT_StackFrame* stack, CLR_PMETADATA ip )
{
    NATIVE_PROFILE_CLR_DIAGNOSTICS();
    if(s_CLR_RT_fTrace_Instructions < c_CLR_RT_Trace_Info) return;

    CLR_RT_MethodDef_Instance inst;

    if(s_CLR_RT_fTrace_Instructions >= c_CLR_RT_Trace_Verbose)
    {
        inst = stack->m_call;
    }
    else
    {
        inst.Clear();
    }

    DumpOpcodeDirect( inst, ip, stack->m_IPstart, stack->m_owningThread->m_pid );
}
HRESULT Library_corlib_native_System_Resources_ResourceManager::GetObject___STATIC__OBJECT__SystemResourcesResourceManager__SystemEnum__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock& blkResourceManager = stack.Arg0();
    CLR_RT_MethodDef_Instance md;

    if(stack.m_customState == 0)
    {
        stack.m_customState = 1;

        //call back into ResourceManager.GetObjectFromId(short id, int offset, int length);

        _SIDE_ASSERTE(md.InitializeFromIndex( g_CLR_RT_WellKnownMethods.m_ResourceManager_GetObjectChunkFromId ));

        TINYCLR_CHECK_HRESULT( stack.MakeCall( md, &blkResourceManager, &stack.Arg1(), 3 ));
    }

    TINYCLR_NOCLEANUP();
}
Example #5
0
HRESULT CLR_RT_StackFrame::MakeCall( CLR_RT_MethodDef_Instance md, CLR_RT_HeapBlock* obj, CLR_RT_HeapBlock* args, int nArgs )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    const CLR_RECORD_METHODDEF* mdR        = md.m_target;
    bool                        fStatic    =(mdR->flags & CLR_RECORD_METHODDEF::MD_Static) != 0;
    int                         numArgs    = mdR->numArgs;
    int                         argsOffset = 0;
    CLR_RT_StackFrame*          stackSub;
    CLR_RT_HeapBlock            tmp;
    tmp.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC        gc(tmp);

    if(mdR->flags & CLR_RECORD_METHODDEF::MD_Constructor)
    {
        CLR_RT_TypeDef_Instance owner;
        owner.InitializeFromMethod( md );

        _ASSERTE(obj == NULL);

        _SIDE_ASSERTE(owner.InitializeFromMethod( md ));

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObject( tmp, owner ));

        obj = &tmp;

        //
        // Make a copy of the object pointer.
        //
        PushValueAndAssign( tmp );
    }

    if(!fStatic)
    {
        FAULT_ON_NULL(obj);
        numArgs--;
        argsOffset = 1;
    }

    if(numArgs != nArgs) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    //
    // In case the invoked method is abstract or virtual, resolve it to the correct method implementation.
    //
    if(mdR->flags & (CLR_RECORD_METHODDEF::MD_Abstract | CLR_RECORD_METHODDEF::MD_Virtual))
    {
        CLR_RT_TypeDef_Index   cls;
        CLR_RT_MethodDef_Index mdReal;

        _ASSERTE(obj);
        _ASSERTE(!fStatic);

        TINYCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractTypeIndexFromObject( *obj, cls ));

        if(g_CLR_RT_EventCache.FindVirtualMethod( cls, md, mdReal ) == false)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
        }

        md.InitializeFromIndex( mdReal );

        mdR = md.m_target;
    }

#if defined(TINYCLR_APPDOMAINS)

    if(!fStatic && obj->IsTransparentProxy())
    {
        TINYCLR_CHECK_HRESULT(CLR_RT_StackFrame::PushAppDomainTransition( m_owningThread, md, obj, args ));

        stackSub = m_owningThread->CurrentFrame();

        stackSub->m_flags |= CLR_RT_StackFrame::c_AppDomainMethodInvoke;
    }
    else
#endif
    {
        TINYCLR_CHECK_HRESULT(CLR_RT_StackFrame::Push( m_owningThread, md, md.m_target->numArgs ));

        stackSub = m_owningThread->CurrentFrame();

        if(!fStatic)
        {
            stackSub->m_arguments[ 0 ].Assign( *obj );
        }

        if(numArgs)
        {
            memcpy( &stackSub->m_arguments[ argsOffset ], args, sizeof(CLR_RT_HeapBlock) * numArgs );
        }
    }

    TINYCLR_CHECK_HRESULT(stackSub->FixCall());

    TINYCLR_SET_AND_LEAVE(CLR_E_RESTART_EXECUTION);

    TINYCLR_NOCLEANUP();
}
void CLR_RT_EventCache::VirtualMethodTable::DumpTree()
{
    TreeDiagram_Vector vec;
    TreeDiagram*       tdChild;
    size_t             tot;
    size_t             col;
    int                row;
    int                depth = 0;

    BuildLevel( vec, (LookupEntry*)m_tree.m_root, depth, 0, tdChild );

    tot = vec.size();

    if(tot)
    {
        std::string nameCLS;
        std::string nameMD;

        printf( "Tree:\n\n" );

        for(row=0; row<=depth; row++)
        {
            TreeDiagram tdActive;

            for(int j=0; j<4; j++)
            {
                for(col=0; col<tot; col++)
                {
                    TreeDiagram& td = vec[ col ];
                    LPCSTR       sz = " ";

                    if(td.depth == row)
                    {
                        switch(j)
                        {
                        case 0:
                            tdActive = td;
                            sz       = "*";

                            {
                                LookupEntry* other;
                                int          res;

                                other = (LookupEntry*)td.node->m_left;
                                if(other)
                                {
                                    res = td.node->m_payload.Compare( other->m_payload );

                                    if(res != 1) sz = "#";
                                }

                                other = (LookupEntry*)td.node->m_right;
                                if(other)
                                {
                                    res = td.node->m_payload.Compare( other->m_payload );

                                    if(res != -1) sz = "#";
                                }
                            }
                            break;

                        case 1: if(td.HasChildren()) sz = "|"; break;
                        case 2: if(td.HasChildren()) sz = "+"; break;
                        }
                    }
                    else if(td.parent != -1 && vec[ td.parent ].depth == row)
                    {
                        switch(j)
                        {
                        case 2: sz = td.parent < col ? "\\" : "/"; break;
                        case 3: sz = "|";                          break;
                        }
                    }
                    else if(tdActive.DrawHorizontalBar( col ))
                    {
                        switch(j)
                        {
                        case 2: sz = "-"; break;
                        }
                    }
                    else if(td.parent != -1 && vec[ td.parent ].depth < row && row < td.depth)
                    {
                        sz = "|";
                    }

                    printf( sz );
                }

                if(j == 0 && tdActive.node)
                {
                    Payload&         pl = tdActive.node->m_payload;
                    CLR_RT_StringMap map;

                    printf( " %08x %4d %4d [%08x %08x] ", (size_t)tdActive.node, tdActive.depthOfLeftChildren, tdActive.depthOfRightChildren, pl.m_mdVirtual.m_data, pl.m_cls.m_data );

                    CLR_RT_TypeDef_Instance   instCLS; instCLS.InitializeFromIndex( pl.m_cls       );
                    CLR_RT_MethodDef_Instance instMD ; instMD .InitializeFromIndex( pl.m_mdVirtual );

                    if(instCLS.InitializeFromIndex( pl.m_cls       ) &&
                       instMD .InitializeFromIndex( pl.m_mdVirtual )  )
                    {
                        instCLS.m_assm->BuildClassName ( instCLS.m_target, nameCLS, false );
                        instMD .m_assm->BuildMethodName( instMD .m_target, nameMD , map   );

                        printf( " {%4d %s %s}", instMD.Hits(), nameCLS.c_str(), nameMD.c_str() );
                    }
                }

                printf( "\n" );
            }
        }
    }
}
bool CLR_RT_StackFrame::PushInline( CLR_PMETADATA& ip, CLR_RT_Assembly*& assm, CLR_RT_HeapBlock*& evalPos, CLR_RT_MethodDef_Instance& calleeInst, CLR_RT_HeapBlock* pThis)
{
    const CLR_RECORD_METHODDEF* md =  calleeInst.m_target;

    if( (m_inlineFrame != NULL) ||                                                                                      // We can only support one inline at a time per stack call
        (m_evalStackEnd - evalPos) <= (md->numArgs + md->numLocals + md->lengthEvalStack + 2) ||                       // We must have enough space on the current stack for the inline method
        (m_nativeMethod != (CLR_RT_MethodHandler)CLR_RT_Thread::Execute_IL) ||                                          // We only support IL inlining
        (md->flags & ~CLR_RECORD_METHODDEF::MD_HasExceptionHandlers) >= CLR_RECORD_METHODDEF::MD_Constructor ||         // Do not try to inline constructors, etc because they require special processing
        (0 != (md->flags & CLR_RECORD_METHODDEF::MD_Static)) ||                                                         // Static methods also requires special processing
        (calleeInst.m_assm->m_nativeCode != NULL && (calleeInst.m_assm->m_nativeCode[ calleeInst.Method() ] != NULL)) || // Make sure the callee is not an internal method
        (md->RVA == CLR_EmptyIndex) ||                                                                                   // Make sure we have a valid IP address for the method
        !g_CLR_RT_EventCache.GetInlineFrameBuffer(&m_inlineFrame))                                                       // Make sure we have an extra slot in the inline cache
    {
        return false;
    }
    
    CLR_PMETADATA ipTmp = calleeInst.m_assm->GetByteCode( md->RVA );

#if defined(PLATFORM_WINDOWS)
        if(s_CLR_RT_fTrace_SimulateSpeed > c_CLR_RT_Trace_None)
        {
            CLR_PROF_Handler::SuspendTime();
    
            HAL_Windows_FastSleep( g_HAL_Configuration_Windows.TicksPerMethodCall );
    
            CLR_PROF_Handler::ResumeTime();
        }
#endif

    // make backup
    m_inlineFrame->m_frame.m_IP        = ip;
    m_inlineFrame->m_frame.m_IPStart   = m_IPstart;
    m_inlineFrame->m_frame.m_locals    = m_locals;
    m_inlineFrame->m_frame.m_args      = m_arguments;
    m_inlineFrame->m_frame.m_call      = m_call;
    m_inlineFrame->m_frame.m_evalStack = m_evalStack;
    m_inlineFrame->m_frame.m_evalPos   = pThis;

    // increment the evalPos pointer so that we don't corrupt the real stack
    evalPos++;
    assm           = calleeInst.m_assm;
    ip             = ipTmp;
    
    m_arguments    = pThis;     
    m_locals       = &m_evalStackEnd[-md->numLocals];
    m_call         = calleeInst;
    m_evalStackEnd = m_locals;
    m_evalStack    = evalPos;
    m_evalStackPos = evalPos + 1;
    m_IPstart      = ip;
    m_IP           = ip;

    if(md->numLocals)
    {        
        g_CLR_RT_ExecutionEngine.InitializeLocals( m_locals, calleeInst.m_assm, md );
    }

    m_flags |= CLR_RT_StackFrame::c_MethodKind_Inlined;

    if(md->retVal != DATATYPE_VOID)
    {
        m_flags |= CLR_RT_StackFrame::c_InlineMethodHasReturnValue;
    }

#if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING)
    m_depth++;

    if(g_CLR_RT_ExecutionEngine.m_breakpointsNum)
    {
        if(m_call.DebuggingInfo().HasBreakpoint())
        {
            m_flags |= CLR_RT_StackFrame::c_HasBreakpoint;
        }

        if(m_owningThread->m_fHasJMCStepper || (m_flags & CLR_RT_StackFrame::c_HasBreakpoint))
        {
            g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Push( this, CLR_DBG_Commands::Debugging_Execution_BreakpointDef::c_DEPTH_STEP_CALL );
        }
    }
#endif

    return true;
}