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_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 CLR_RT_HeapBlock_Array::CreateInstance( CLR_RT_HeapBlock& reference, CLR_UINT32 length, const CLR_RT_ReflectionDef_Index& reflex ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* pArray; CLR_RT_TypeDef_Index cls; CLR_RT_TypeDef_Instance inst; reference.SetObjectReference( NULL ); if((CLR_INT32)length < 0) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); if(reflex.m_kind != REFLECTION_TYPE) { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } if(reflex.m_levels == 1) { cls = reflex.m_data.m_type; } else { cls = g_CLR_RT_WellKnownTypes.m_Array; } if(inst.InitializeFromIndex( cls ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } else { CLR_DataType dt = (CLR_DataType)inst.m_target->dataType; const CLR_RT_DataTypeLookup& dtl = c_CLR_RT_DataTypeLookup[ dt ]; if(dtl.m_sizeInBytes == CLR_RT_DataTypeLookup::c_NA) { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } pArray = (CLR_RT_HeapBlock_Array*)g_CLR_RT_ExecutionEngine.ExtractHeapBlocksForArray( inst, length, reflex ); CHECK_ALLOCATION(pArray); reference.SetObjectReference( pArray ); TINYCLR_SET_AND_LEAVE(pArray->ClearElements( 0, length )); } TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_Reflection_FieldInfo::Initialize( CLR_RT_StackFrame& stack, CLR_RT_FieldDef_Instance& instFD, CLR_RT_TypeDef_Instance& instTD, CLR_RT_HeapBlock*& obj ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock* hbField = stack.Arg0().Dereference(); if(CLR_RT_ReflectionDef_Index::Convert( *hbField, instFD ) == false || instTD.InitializeFromField ( instFD ) == false ) { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } if(instFD.m_target->flags & CLR_RECORD_FIELDDEF::FD_Static) { obj = CLR_RT_ExecutionEngine::AccessStaticField( instFD ); if(obj == NULL) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } else { TINYCLR_CHECK_HRESULT(stack.Arg1().EnsureObjectReference( obj )); if(CLR_RT_ExecutionEngine::IsInstanceOf( *obj, instTD ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } obj = &obj[ instFD.CrossReference().m_offset ]; } TINYCLR_NOCLEANUP(); }
void CLR_RT_DUMP::TYPE( const CLR_RT_ReflectionDef_Index& reflex ) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); CLR_RT_TypeDef_Instance inst; CLR_UINT32 levels; if(inst.InitializeFromReflection( reflex, &levels )) { CLR_RT_DUMP::TYPE( inst ); while(levels-- > 0) { CLR_Debug::Printf( "[]" ); } } }
HRESULT Library_corlib_native_System_RuntimeType::get_Assembly___SystemReflectionAssembly( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_TypeDef_Instance td; TINYCLR_CHECK_HRESULT(GetTypeDescriptor( stack.Arg0(), td, NULL )); { CLR_RT_Assembly_Index idx; idx.Set( td.Assembly() ); CLR_RT_HeapBlock& top = stack.PushValue(); top.SetReflection( idx ); } TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_Reflection_RuntimeFieldInfo::get_DeclaringType___SystemType( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_FieldDef_Instance fd; CLR_RT_TypeDef_Instance cls; if(GetFieldDescriptor( stack, stack.Arg0(), fd ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); if(cls.InitializeFromField( fd ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); { CLR_RT_HeapBlock& top = stack.PushValue(); top.SetReflection( cls ); } TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_RuntimeType::get_BaseType___SystemType( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_TypeDef_Instance td; CLR_UINT32 levels; CLR_RT_HeapBlock& top = stack.PushValueAndClear(); TINYCLR_CHECK_HRESULT(GetTypeDescriptor( stack.Arg0(), td, &levels )); if(levels > 0) { top.SetReflection( g_CLR_RT_WellKnownTypes.m_Array ); } else if(td.SwitchToParent()) { top.SetReflection( td ); } TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_RuntimeType::GetTypeDescriptor( CLR_RT_HeapBlock& arg, CLR_RT_TypeDef_Instance& inst ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_UINT32 levels; TINYCLR_CHECK_HRESULT(GetTypeDescriptor( arg, inst, &levels )); if(levels > 0) { inst.InitializeFromIndex( g_CLR_RT_WellKnownTypes.m_Array ); } TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_Reflection_FieldInfo::SetValue___VOID__OBJECT__OBJECT( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_FieldDef_Instance instFD; CLR_RT_TypeDef_Instance instTD; CLR_RT_TypeDescriptor instTDescObj; CLR_RT_TypeDef_Instance instTDField; const CLR_RECORD_FIELDDEF* fd; CLR_RT_HeapBlock* obj; bool fValueType; CLR_RT_HeapBlock& srcVal = stack.Arg2(); CLR_RT_HeapBlock& srcObj = stack.Arg1(); CLR_RT_HeapBlock val; val.Assign( srcVal ); CLR_RT_ProtectFromGC gc( val ); TINYCLR_CHECK_HRESULT(Library_corlib_native_System_Reflection_FieldInfo::Initialize( stack, instFD, instTD, obj )); fd = instFD.m_target; if(fd->flags & CLR_RECORD_FIELDDEF::FD_NoReflection) // don't allow reflection for fields with NoReflection attribute { TINYCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); } TINYCLR_CHECK_HRESULT(instTDescObj.InitializeFromFieldDefinition(instFD)); // make sure the right side object is of the same type as the left side if(NULL != val.Dereference() && !CLR_RT_ExecutionEngine::IsInstanceOf(val, instTDescObj.m_handlerCls)) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); fValueType = obj->IsAValueType(); if(fValueType || (c_CLR_RT_DataTypeLookup[ obj->DataType() ].m_flags & CLR_RT_DataTypeLookup::c_OptimizedValueType)) { if(val.Dereference() == NULL || !val.Dereference()->IsBoxed()) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); if(fValueType) { _ASSERTE(NULL != obj->Dereference()); if(NULL == obj->Dereference()) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); instTDField.InitializeFromIndex( obj->Dereference()->ObjectCls() ); } else { instTDField.InitializeFromIndex( *c_CLR_RT_DataTypeLookup[ obj->DataType() ].m_cls ); } TINYCLR_CHECK_HRESULT(val.PerformUnboxing( instTDField )); } else { #if defined(TINYCLR_APPDOMAINS) if(srcObj.IsTransparentProxy()) { _ASSERTE(srcObj.DataType() == DATATYPE_OBJECT); _ASSERTE(srcObj.Dereference() != NULL && srcObj.Dereference()->DataType() == DATATYPE_TRANSPARENT_PROXY); TINYCLR_CHECK_HRESULT(srcObj.Dereference()->TransparentProxyValidate()); TINYCLR_CHECK_HRESULT(srcObj.Dereference()->TransparentProxyAppDomain()->MarshalObject( val, val )); } #endif } switch(obj->DataType()) { case DATATYPE_DATETIME: // Special case. case DATATYPE_TIMESPAN: // Special case. obj->NumericByRef().s8 = val.NumericByRefConst().s8; break; default: obj->Assign( val ); break; } TINYCLR_NOCLEANUP(); }
HRESULT CLR_RT_StackFrame::FixCall() { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); const CLR_RECORD_METHODDEF* target = m_call.m_target; CLR_UINT8 numArgs = target->numArgs; // // The copy of ValueTypes is delayed as much as possible. // // If an argument is a ValueType, now it's a good time to clone it. // if(numArgs) { CLR_RT_SignatureParser parser; parser.Initialize_MethodSignature( m_call.m_assm, target ); CLR_RT_SignatureParser::Element res; CLR_RT_HeapBlock* args = m_arguments; if(parser.m_flags & PIMAGE_CEE_CS_CALLCONV_HASTHIS) { args++; } // // Skip return value. // TINYCLR_CHECK_HRESULT(parser.Advance( res )); for(; parser.Available() > 0; args++) { TINYCLR_CHECK_HRESULT(parser.Advance( res )); if(res.m_levels > 0) continue; // Array, no need to fix. if(args->DataType() == DATATYPE_OBJECT) { CLR_RT_TypeDef_Instance inst; inst.InitializeFromIndex( res.m_cls ); CLR_DataType dtT = (CLR_DataType)inst.m_target->dataType; const CLR_RT_DataTypeLookup& dtl = c_CLR_RT_DataTypeLookup[ dtT ]; if(dtl.m_flags & (CLR_RT_DataTypeLookup::c_OptimizedValueType | CLR_RT_DataTypeLookup::c_ValueType)) { CLR_RT_HeapBlock* value = args->FixBoxingReference(); FAULT_ON_NULL(value); if(value->DataType() == dtT) { // It's a boxed primitive/enum type. args->Assign( *value ); } else if(args->Dereference()->ObjectCls().m_data == res.m_cls.m_data) { TINYCLR_CHECK_HRESULT(args->PerformUnboxing( inst )); } else { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } } } if(res.m_dt == DATATYPE_VALUETYPE && res.m_fByRef == false) { if(args->IsAReferenceOfThisType( DATATYPE_VALUETYPE )) { TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.CloneObject( *args, *args )); } } } } TINYCLR_NOCLEANUP(); }
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" ); } } } }
static bool SerializeObject(CLR_RT_HeapBlock* pObj, CLR_UINT8* serData, CLR_INT32& serOffset, CLR_INT32& serSize ) { if(pObj == NULL) { return false; } switch(pObj->DataType()) { case DATATYPE_OBJECT: if(!SerializeObject(pObj->Dereference(), serData, serOffset, serSize)) return false; break; case DATATYPE_CLASS: case DATATYPE_VALUETYPE: { CLR_RT_TypeDef_Instance cls; cls.InitializeFromIndex( pObj->ObjectCls() ); int totFields = cls.CrossReference().m_totalFields; while(totFields-- > 0) { if(!SerializeObject( ++pObj, serData, serOffset, serSize )) return false; } } break; case DATATYPE_SZARRAY: { CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)pObj; int cnt = array->m_numOfElements; CLR_UINT8* pData; if(array->m_typeOfElement <= DATATYPE_LAST_NONPOINTER && cnt < 256) { pData = (CLR_UINT8*)array->GetFirstElement(); while(cnt--) { if(!SerializeIntrinsicType( (CLR_DataType)array->m_typeOfElement, pData, serData, serOffset, serSize )) return false; pData += array->m_sizeOfElement; } } else { return false; } } break; default: { CLR_UINT64 data = (CLR_UINT64)pObj->NumericByRef().u8; if(!SerializeIntrinsicType(pObj->DataType(), (CLR_UINT8*)&data, serData, serOffset, serSize)) return false; } break; } return true; }
static bool DeserializeObject(CLR_RT_HeapBlock* pObj, CLR_UINT8* serData, CLR_INT32& serOffset, const CLR_INT32 serSize ) { if(pObj == NULL) { return false; } switch(pObj->DataType()) { case DATATYPE_OBJECT: if(!DeserializeObject(pObj->Dereference(), serData, serOffset, serSize)) return false; break; case DATATYPE_CLASS: case DATATYPE_VALUETYPE: { CLR_RT_TypeDef_Instance cls; cls.InitializeFromIndex( pObj->ObjectCls() ); int totFields = cls.CrossReference().m_totalFields; while(totFields-- > 0) { if(!DeserializeObject( ++pObj, serData, serOffset, serSize )) return false; } } break; case DATATYPE_SZARRAY: { CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)pObj; int cnt = array->m_numOfElements; if(array->m_typeOfElement <= DATATYPE_LAST_NONPOINTER && cnt < 256) { CLR_UINT8* pData = (CLR_UINT8*)array->GetFirstElement(); int nativeSize = GetTypeSize((CLR_DataType)array->m_typeOfElement); if(nativeSize <= 0) return false; while(cnt--) { int size = nativeSize; int i = 0; while(size--) { #ifndef BIG_ENDIAN pData[i++ ] = serData[serOffset++]; #else pData[size] = serData[serOffset++]; #endif } pData += array->m_sizeOfElement; } } else { return false; } } break; default: { CLR_UINT64 data = (CLR_UINT64)pObj->NumericByRef().u8; if(!DeserializeIntrinsicType(pObj, serData, serOffset, serSize)) return false; } break; } return true; }