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(); }