HRESULT CLR_RT_HeapBlock_Array::CreateInstance( CLR_RT_HeapBlock& reference, CLR_UINT32 length, CLR_RT_Assembly* assm, CLR_UINT32 tk )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock         ref;
    CLR_RT_TypeDef_Instance  cls;
    CLR_RT_TypeSpec_Instance def;

    if(cls.ResolveToken( tk, assm ))
    {
        ref.SetReflection( cls );
    }
    else if(def.ResolveToken( tk, assm ))
    {
        TINYCLR_CHECK_HRESULT(ref.SetReflection( def ));
    }
    else
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
    }

    ref.ReflectionData().m_levels++;

    TINYCLR_SET_AND_LEAVE(CreateInstance( reference, length, ref.ReflectionData() ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_RuntimeType::GetInterfaces___SZARRAY_SystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_TypeDef_Instance td;    
    CLR_RT_HeapBlock& top = stack.PushValueAndClear();
    CLR_RT_HeapBlock* ptr;
    
    TINYCLR_CHECK_HRESULT(GetTypeDescriptor( stack.Arg0(), td ));

    //
    // Scan the list of interfaces.
    //
    CLR_RT_SignatureParser          parser; parser.Initialize_Interfaces( td.m_assm, td.m_target );
    CLR_RT_SignatureParser::Element res;
    
    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, parser.Available(), g_CLR_RT_WellKnownTypes.m_Type ));
    
    ptr = (CLR_RT_HeapBlock*)top.DereferenceArray()->GetFirstElement();

    while(parser.Available() > 0)
    {
        TINYCLR_CHECK_HRESULT(parser.Advance( res ));        

        ptr->SetReflection( res.m_cls );

        ptr++;
    }    

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_MethodBase::get_DeclaringType___SystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_MethodDef_Instance md;
    CLR_RT_TypeDef_Instance   cls;
    CLR_RT_HeapBlock* hbMeth  = stack.Arg0().Dereference();

    TINYCLR_CHECK_HRESULT(GetMethodDescriptor( stack, *hbMeth, md ));

    if(cls.InitializeFromMethod( md ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);

    {
        CLR_RT_HeapBlock& top = stack.PushValue();
        CLR_RT_HeapBlock* hbObj;

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_TypeStatic));
        
        hbObj = top.Dereference();
        hbObj->SetReflection( cls );
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::GetType___SystemType__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();
    
    CLR_RT_Assembly_Instance assm;
    CLR_RT_TypeDef_Index     td;
    CLR_RT_HeapBlock*        hbRef;
    CLR_RT_HeapBlock*        hbObj;
    LPCSTR                   szClass = stack.Arg1().RecoverString(); 
    CLR_RT_HeapBlock*        hbAsm = stack.Arg0().Dereference();

    FAULT_ON_NULL(szClass);
    FAULT_ON_NULL(hbAsm);

    TINYCLR_CHECK_HRESULT(GetTypeDescriptor( *hbAsm, assm ));

    hbRef = &stack.PushValueAndClear();
    
    if(g_CLR_RT_TypeSystem.FindTypeDef( szClass, assm.m_assm, td ))
    {
        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*hbRef, g_CLR_RT_WellKnownTypes.m_TypeStatic));
        
        hbObj = hbRef->Dereference();
        hbObj->SetReflection( td );
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Reflection::GetAssemblyFromHash___STATIC__mscorlibSystemReflectionAssembly__U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock& top  = stack.PushValueAndClear();
    CLR_UINT32        hash = stack.Arg0().NumericByRefConst().u4;

    TINYCLR_FOREACH_ASSEMBLY_IN_CURRENT_APPDOMAIN(g_CLR_RT_TypeSystem)
    {
        if(pASSM->ComputeAssemblyHash() == hash)
        {
            CLR_RT_HeapBlock* hbObj;
            CLR_RT_Assembly_Index idx; idx.Set( pASSM->m_idx );
            
            TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_Assembly));
            hbObj = top.Dereference();
            
            hbObj->SetReflection( idx ); 

            TINYCLR_SET_AND_LEAVE(S_OK);
        }
    }
    TINYCLR_FOREACH_ASSEMBLY_IN_CURRENT_APPDOMAIN_END();

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_RuntimeMethodInfo::get_ReturnType___SystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_MethodDef_Instance md;
    CLR_RT_SignatureParser    parser;
    CLR_RT_TypeDescriptor     desc;
    CLR_RT_HeapBlock*         hbMeth = stack.Arg0().Dereference();

    TINYCLR_CHECK_HRESULT(Library_corlib_native_System_Reflection_MethodBase::GetMethodDescriptor( stack, *hbMeth, md ));

    parser.Initialize_MethodSignature( md.m_assm, md.m_target );

    TINYCLR_CHECK_HRESULT(desc.InitializeFromSignatureParser( parser ));

    {
        CLR_RT_HeapBlock& top = stack.PushValue();
        CLR_RT_HeapBlock* hbObj;
        
        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_TypeStatic));
        hbObj = top.Dereference();
        hbObj->SetReflection( desc.m_reflex );
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::GetTypes___SZARRAY_SystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_Assembly_Instance assm;

    TINYCLR_CHECK_HRESULT(GetTypeDescriptor( stack.Arg0(), assm ));

    {
        CLR_RT_Assembly*  pASSM = assm.m_assm;
        CLR_UINT32        num   = pASSM->m_pTablesSize[ TBL_TypeDef ];
        CLR_RT_HeapBlock& top   = stack.PushValue();

        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, num, g_CLR_RT_WellKnownTypes.m_Type ));

        if(num)
        {
            CLR_RT_HeapBlock* pArray = (CLR_RT_HeapBlock*)top.DereferenceArray()->GetFirstElement();

            for(CLR_UINT32 i=0; i<num; i++, pArray++)
            {
                CLR_RT_TypeDef_Index idx; idx.Set( pASSM->m_idx, i );

                pArray->SetReflection( idx );
            }
        }
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::Load___STATIC__SystemReflectionAssembly__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* array = NULL;
    CLR_RT_Assembly*        assm  = NULL;
    CLR_RT_HeapBlock&       top   = stack.PushValueAndClear();
    CLR_RT_HeapBlock*       hbObj;
    CLR_RECORD_ASSEMBLY*    header;

    array = stack.Arg0().DereferenceArray(); FAULT_ON_NULL(array);

    header = (CLR_RECORD_ASSEMBLY*)array->GetFirstElement();
    
    TINYCLR_CHECK_HRESULT(CLR_RT_Assembly::VerifyEndian(header));

    if(header->GoodAssembly())
    {
        //
        // Sorry, you'll have to reboot to load this assembly.
        //
        if(header->flags & CLR_RECORD_ASSEMBLY::c_Flags_NeedReboot)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_BUSY);
        }

        TINYCLR_CHECK_HRESULT(CLR_RT_Assembly::CreateInstance( header, assm ));

        assm->m_pFile = array;

        g_CLR_RT_TypeSystem.Link( assm );

        TINYCLR_CHECK_HRESULT(g_CLR_RT_TypeSystem.ResolveAll         ());
        TINYCLR_CHECK_HRESULT(g_CLR_RT_TypeSystem.PrepareForExecution());
    }

    if(assm)
    {
        CLR_RT_Assembly_Index idx; idx.Set( assm->m_idx );

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_Assembly));
        
        hbObj = top.Dereference();
        hbObj->SetReflection( idx );
    }

    TINYCLR_CLEANUP();

    if(FAILED(hr))
    {
        if(assm)
        {
            assm->DestroyInstance();
        }
    }

    TINYCLR_CLEANUP_END();
}
HRESULT Library_spot_native_Microsoft_SPOT_Reflection::GetAssemblies___STATIC__SZARRAY_mscorlibSystemReflectionAssembly( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock& top    = stack.PushValueAndClear();

#if defined(TINYCLR_APPDOMAINS)
    TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.GetCurrentAppDomain()->GetAssemblies( top ));
#else
    int               count  = 0;
    CLR_RT_HeapBlock* pArray = NULL;

    for(int pass=0; pass<2; pass++)
    {
        TINYCLR_FOREACH_ASSEMBLY(g_CLR_RT_TypeSystem)
        {
            if(pASSM->m_header->flags & CLR_RECORD_ASSEMBLY::c_Flags_Patch) continue;

            if(pass == 0)
            {
                count++;
            }
            else
            {
                CLR_RT_HeapBlock* hbObj;
                CLR_RT_Assembly_Index idx; idx.Set( pASSM->m_idx );

                TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*pArray, g_CLR_RT_WellKnownTypes.m_Assembly));
                hbObj = pArray->Dereference();
                
                hbObj->SetReflection( idx ); 

                pArray++;
            }
        }
        TINYCLR_FOREACH_ASSEMBLY_END();

        if(pass == 0)
        {
            TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, count, g_CLR_RT_WellKnownTypes.m_Assembly ));

            pArray = (CLR_RT_HeapBlock*)top.DereferenceArray()->GetFirstElement();
        }
    }
#endif //TINYCLR_APPDOMAINS

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Reflection::GetTypeFromHash___STATIC__mscorlibSystemType__U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock&    top = stack.PushValueAndClear();
    CLR_RT_TypeDef_Index res;

    if(g_CLR_RT_TypeSystem.FindTypeDef( stack.Arg0().NumericByRefConst().u4, res ))
    {
        CLR_RT_HeapBlock* hbObj;

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_TypeStatic));
        hbObj = top.Dereference();
        
        hbObj->SetReflection( res ); 
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::GetExecutingAssembly___STATIC__SystemReflectionAssembly( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock& top = stack.PushValueAndClear();
    CLR_RT_HeapBlock* hbObj;

    CLR_RT_StackFrame* caller = stack.Caller(); if(caller == NULL) TINYCLR_SET_AND_LEAVE(S_OK);

    {
        CLR_RT_Assembly_Index idx; idx.Set( caller->MethodCall().m_assm->m_idx );

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_Assembly));
        
        hbObj = top.Dereference();
        hbObj->SetReflection( idx );
    }
    
    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Delegate::get_Method___SystemReflectionMethodInfo( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Delegate* dlg = stack.Arg0().DereferenceDelegate();

    dlg = GetLastDelegate( dlg ); if(!dlg) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);

    {
        CLR_RT_HeapBlock& top = stack.PushValue();
        CLR_RT_HeapBlock* hbObj;
        
        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_MethodInfo));
        hbObj = top.Dereference();
        
        hbObj->SetReflection( dlg->DelegateFtn() ); 
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Object::GetType___SystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_TypeDescriptor desc;
    CLR_RT_ReflectionDef_Index idx;
    CLR_RT_HeapBlock& arg0 = stack.Arg0();
    CLR_RT_HeapBlock* pObj;

    TINYCLR_CHECK_HRESULT(desc.InitializeFromObject( arg0 ));

    pObj = arg0.Dereference();

    if(pObj && pObj->DataType() == DATATYPE_REFLECTION)
    {
        idx.m_kind               = REFLECTION_TYPE;
        idx.m_levels             = 0;
        idx.m_data.m_type.m_data = desc.m_handlerCls.m_data;
    }
    else
    {
        idx = desc.m_reflex;
    }

    {
        CLR_RT_HeapBlock& top = stack.PushValue();
        CLR_RT_HeapBlock* hbObj;

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_TypeStatic));
        
        hbObj = top.Dereference();
        hbObj->SetReflection( idx );
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Reflection::GetTypesImplementingInterface___STATIC__SZARRAY_mscorlibSystemType__mscorlibSystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock&       top    = stack.PushValueAndClear();
    int                     tot    = 0;
    CLR_RT_HeapBlock*       pArray = NULL;
    CLR_RT_TypeDef_Instance tdMatch;
    CLR_RT_HeapBlock*       hbType = stack.Arg0().Dereference();

    TINYCLR_CHECK_HRESULT(Library_corlib_native_System_RuntimeType::GetTypeDescriptor( *hbType, tdMatch ));

    if((tdMatch.m_target->flags & CLR_RECORD_TYPEDEF::TD_Semantics_Mask) != CLR_RECORD_TYPEDEF::TD_Semantics_Interface)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }

    for(int pass=0; pass<2; pass++)
    {
        int              count = 0;

        TINYCLR_FOREACH_ASSEMBLY_IN_CURRENT_APPDOMAIN(g_CLR_RT_TypeSystem)
        {
            const CLR_RECORD_TYPEDEF* td      = pASSM->GetTypeDef( 0 );
            int                       tblSize = pASSM->m_pTablesSize[ TBL_TypeDef ];

            for(int i=0; i<tblSize; i++, td++)
            {
                if(td->flags & CLR_RECORD_TYPEDEF::TD_Abstract) continue;

                CLR_RT_TypeDef_Index idx; idx.Set( pASSM->m_idx, i );

                if(CLR_RT_ExecutionEngine::IsInstanceOf( idx, tdMatch ))
                {
                    if(pass == 0)
                    {
                        tot++;
                    }
                    else
                    {
                        CLR_RT_HeapBlock* hbObj;
                        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(pArray[count], g_CLR_RT_WellKnownTypes.m_TypeStatic));
                        hbObj = pArray[count].Dereference();
                        hbObj->SetReflection( idx );
                    }

                    count++;
                }
            }
        }
        TINYCLR_FOREACH_ASSEMBLY_IN_CURRENT_APPDOMAIN_END();

        if(pass == 0)
        {
            if(tot == 0) break;

            TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, tot, g_CLR_RT_WellKnownTypes.m_TypeStatic ));

            CLR_RT_HeapBlock_Array* array = top.DereferenceArray();

            pArray = (CLR_RT_HeapBlock*)array->GetFirstElement();
        }
    }


    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::LoadInternal___STATIC__SystemReflectionAssembly__STRING__BOOLEAN__I4__I4__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

#if defined(TINYCLR_APPDOMAINS)
    CLR_RT_AppDomain*     appDomain = g_CLR_RT_ExecutionEngine.GetCurrentAppDomain();
#endif
    CLR_RT_HeapBlock*     pArgs     = &stack.Arg0();
    CLR_RT_HeapBlock*     hbObj;
    CLR_RT_Assembly*      assembly;
    LPCSTR                szAssembly;
    CLR_RT_Assembly_Index idx; 
    bool                  fVersion;
    CLR_INT16             maj, min, build, rev;
    CLR_RT_HeapBlock&     top = stack.PushValueAndClear();
    
    szAssembly = pArgs[ 0 ].RecoverString(); FAULT_ON_NULL(szAssembly );
    fVersion   = pArgs[ 1 ].NumericByRef().u1 != 0;    
    maj        = pArgs[ 2 ].NumericByRef().s4;    
    min        = pArgs[ 3 ].NumericByRef().s4;
    build      = pArgs[ 4 ].NumericByRef().s4;
    rev        = pArgs[ 5 ].NumericByRef().s4;

    if(fVersion && (maj == -1 || min == -1 || build == -1 || rev == -1))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }

    if(fVersion)
    {
        CLR_RECORD_VERSION ver;

        ver.iMajorVersion   = (CLR_UINT16)maj;
        ver.iMinorVersion   = (CLR_UINT16)min;
        ver.iBuildNumber    = (CLR_UINT16)build;
        ver.iRevisionNumber = (CLR_UINT16)rev;
        
        assembly = g_CLR_RT_TypeSystem.FindAssembly( szAssembly, &ver, true ); FAULT_ON_NULL_HR(assembly, CLR_E_INVALID_PARAMETER);
    }
    else
    {
        assembly = g_CLR_RT_TypeSystem.FindAssembly( szAssembly, NULL, false ); FAULT_ON_NULL_HR(assembly, CLR_E_INVALID_PARAMETER);
    }
    
#if defined(TINYCLR_APPDOMAINS)
    TINYCLR_CHECK_HRESULT(appDomain->LoadAssembly( assembly ));
#endif
    idx.Set( assembly->m_idx );

    TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_Assembly));

    hbObj = top.Dereference();
    hbObj->SetReflection( idx );

    TINYCLR_CLEANUP();

    //Avoid exception handling in common case.  Just return NULL on failure.
    //Managed code decides to throw the exception or not.  
    hr = S_OK;

    TINYCLR_CLEANUP_END();
}
Example #16
0
HRESULT CLR_RT_StackFrame::HandleSynchronized( bool fAcquire, bool fGlobal )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock   refType;
    CLR_RT_HeapBlock*  obj;
    CLR_RT_HeapBlock   ref;
    CLR_RT_HeapBlock** ppGlobalLock;
    CLR_RT_HeapBlock*  pGlobalLock;

    if(fGlobal)
    {
        obj = &ref;

#if defined(TINYCLR_APPDOMAINS)
        //With AppDomains enabled, the global lock is no longer global.  It is only global wrt the AppDomain/
        //Do we need a GlobalGlobalLock? (an attribute on GloballySynchronized (GlobalAcrossAppDomain?)
        ppGlobalLock = &g_CLR_RT_ExecutionEngine.GetCurrentAppDomain()->m_globalLock;
#else
        ppGlobalLock = &g_CLR_RT_ExecutionEngine.m_globalLock;
#endif

        pGlobalLock = *ppGlobalLock;

        if(pGlobalLock)
        {
            obj->SetObjectReference( pGlobalLock );
        }
        else
        {
            //
            // Create an private object to implement global locks.
            //
            TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( *obj, g_CLR_RT_WellKnownTypes.m_Object ));

            *ppGlobalLock = obj->Dereference();
        }
    }
    else if(m_call.m_target->flags & CLR_RECORD_METHODDEF::MD_Static)
    {
        CLR_RT_TypeDef_Index idx;

        idx.Set( m_call.Assembly(), m_call.CrossReference().GetOwner() );

        refType.SetReflection( idx );

        obj = &refType;
    }
    else
    {
        obj = &Arg0();
    }

    if(fAcquire)
    {
        TINYCLR_SET_AND_LEAVE(g_CLR_RT_ExecutionEngine.LockObject( *obj, m_owningSubThread, TIMEOUT_INFINITE, false ));
    }
    else
    {
        TINYCLR_SET_AND_LEAVE(g_CLR_RT_ExecutionEngine.UnlockObject( *obj, m_owningSubThread ));
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_AppDomain::LoadInternal___SystemReflectionAssembly__STRING__BOOLEAN__I4__I4__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*     pArgs        = &(stack.Arg1());
    CLR_RT_AppDomain*     appDomainSav;
    CLR_RT_AppDomain*     appDomain;
    CLR_RT_Assembly*      assembly;
    CLR_RT_Assembly_Index idx; 
    bool                  fVersion;
    CLR_INT16             maj, min, build, rev;
    LPCSTR                szAssembly;

    TINYCLR_CHECK_HRESULT(GetAppDomain( stack.ThisRef(), appDomain, appDomainSav, true ));

    szAssembly = pArgs[ 0 ].RecoverString(); FAULT_ON_NULL(szAssembly);    
    fVersion   = pArgs[ 1 ].NumericByRef().u8 != 0;
    maj        = pArgs[ 2 ].NumericByRef().s4;    
    min        = pArgs[ 3 ].NumericByRef().s4;
    build      = pArgs[ 4 ].NumericByRef().s4;
    rev        = pArgs[ 5 ].NumericByRef().s4;

    if(fVersion && (maj == -1 || min == -1 || build == -1 || rev == -1))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }

    if(fVersion)
    {
        CLR_RECORD_VERSION ver;

        ver.iMajorVersion   = (CLR_UINT16) maj;
        ver.iMinorVersion   = (CLR_UINT16) min;
        ver.iBuildNumber    = (CLR_UINT16) build;
        ver.iRevisionNumber = (CLR_UINT16) rev;
        
        assembly = g_CLR_RT_TypeSystem.FindAssembly( szAssembly, &ver, true ); FAULT_ON_NULL_HR(assembly, CLR_E_INVALID_PARAMETER);
    }
    else
    {    
        assembly = g_CLR_RT_TypeSystem.FindAssembly( szAssembly, NULL, false ); FAULT_ON_NULL_HR(assembly, CLR_E_INVALID_PARAMETER);
    }
    
    TINYCLR_CHECK_HRESULT(appDomain->LoadAssembly( assembly ));

    {
        CLR_RT_HeapBlock&     top = stack.PushValue();
        CLR_RT_HeapBlock*     hbObj;

        idx.Set( assembly->m_idx );

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_Assembly));

        hbObj = top.Dereference();
        hbObj->SetReflection( idx );
    }

    TINYCLR_CLEANUP();

    g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( appDomainSav );

    TINYCLR_CLEANUP_END();
}