CLR_INT64* Library_corlib_native_System_TimeSpan::GetValuePtr( CLR_RT_HeapBlock& ref ) { NATIVE_PROFILE_CLR_CORE(); CLR_RT_HeapBlock* obj = &ref; CLR_DataType dt = obj->DataType(); if(dt == DATATYPE_OBJECT || dt == DATATYPE_BYREF) { obj = obj->Dereference(); if(!obj) return NULL; dt = obj->DataType(); } if(dt == DATATYPE_TIMESPAN) { return (CLR_INT64*)&obj->NumericByRef().s8; } if(dt == DATATYPE_I8) { return (CLR_INT64*)&obj->NumericByRef().s8; } if(dt == DATATYPE_VALUETYPE && obj->ObjectCls().m_data == g_CLR_RT_WellKnownTypes.m_TimeSpan.m_data) { return (CLR_INT64*)&obj[ FIELD__m_ticks ].NumericByRef().s8; } return NULL; }
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_spot_net_native_Microsoft_SPOT_Net_SocketNative::MarshalSockAddress( CLR_RT_HeapBlock& blkDst, const struct SOCK_sockaddr* addrSrc, CLR_UINT32 addrLenSrc ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* arr = NULL; CLR_RT_HeapBlock blkArr; blkArr.SetObjectReference( NULL ); CLR_RT_ProtectFromGC gc( blkArr ); SOCK_sockaddr_in* dst; SOCK_sockaddr_in* src = (SOCK_sockaddr_in*)addrSrc; TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( blkArr, addrLenSrc, g_CLR_RT_WellKnownTypes.m_UInt8 )); arr = blkArr.DereferenceArray(); _ASSERTE(arr); dst = (SOCK_sockaddr_in*)arr->GetFirstElement(); dst->sin_family = SwapEndianIfBEc16(src->sin_family); dst->sin_port = src->sin_port; dst->sin_addr.S_un.S_addr = src->sin_addr.S_un.S_addr; memcpy(dst->sin_zero, src->sin_zero, sizeof(dst->sin_zero)); _ASSERTE(blkDst.DataType() == DATATYPE_BYREF || blkDst.DataType() == DATATYPE_ARRAY_BYREF); TINYCLR_CHECK_HRESULT(blkArr.StoreToReference( blkDst, 0 )); TINYCLR_NOCLEANUP(); }
HRESULT CLR_RT_XmlState_InValue::ProcessEndWhitespace( CLR_RT_XmlState* st, CLR_UINT8*& buffer, bool& isDone ) { TINYCLR_HEADER(); _ASSERTE(isDone == true); CLR_RT_XmlState_InValue* state = &st->InValue; CLR_RT_HeapBlock* xmlSpace; CLR_RT_XmlSpace xmlSpaceValue; TINYCLR_CHECK_HRESULT(state->reader->GetXmlSpaces()->Peek( xmlSpace )); // note that xmlSpace is boxed _ASSERTE( xmlSpace->DataType() == DATATYPE_VALUETYPE ); xmlSpaceValue = (CLR_RT_XmlSpace)xmlSpace[ 1 ].NumericByRef().s4; if(xmlSpaceValue == XmlSpace_Preserve || !(state->settings & XmlSettings_IgnoreWhitespace)) { TINYCLR_SET_AND_LEAVE(PrepReturn( st, buffer, 0, (xmlSpaceValue == XmlSpace_Preserve) ? XmlNodeType_SignificantWhitespace : XmlNodeType_Whitespace )); } TINYCLR_CLEANUP(); // regardless of result, we'll set up the next state. note that it's not possible to get XML_E_NEED_MORE_DATA here CLR_RT_XmlState_NewTag::Setup( st ); TINYCLR_CLEANUP_END(); }
HRESULT Library_corlib_native_System_Reflection_RuntimeFieldInfo::GetValue___OBJECT__OBJECT( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock* argObj = &stack.Arg1(); CLR_RT_FieldDef_Instance instFD; CLR_RT_TypeDef_Instance instTD; const CLR_RECORD_FIELDDEF* fd; CLR_RT_HeapBlock* obj; CLR_RT_HeapBlock dst; 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); } { dst.Assign( *obj ); #if defined(TINYCLR_APPDOMAINS) //Marshal if necessary. if(argObj->IsTransparentProxy()) { _ASSERTE(argObj->DataType() == DATATYPE_OBJECT); argObj = argObj->Dereference(); _ASSERTE(argObj != NULL && argObj->DataType() == DATATYPE_TRANSPARENT_PROXY); TINYCLR_CHECK_HRESULT(argObj->TransparentProxyValidate()); TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.GetCurrentAppDomain()->MarshalObject( *obj, dst, argObj->TransparentProxyAppDomain() )); } #endif CLR_RT_HeapBlock& res = stack.PushValueAndAssign( dst ); TINYCLR_CHECK_HRESULT(res.PerformBoxingIfNeeded()); } TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_AppDomain::GetAppDomain( CLR_RT_HeapBlock& ref, CLR_RT_AppDomain*& appDomain, CLR_RT_AppDomain*& appDomainSav, bool fCheckForUnloadingAppDomain ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock* obj; CLR_RT_ObjectToEvent_Source* src; //Setting up appDomainSav is guaranteed to be initialized correctly by this function appDomainSav = g_CLR_RT_ExecutionEngine.GetCurrentAppDomain(); _ASSERTE(ref.DataType() == DATATYPE_OBJECT); obj = ref.Dereference(); FAULT_ON_NULL(obj); if(obj->DataType() == DATATYPE_TRANSPARENT_PROXY) { appDomain = obj->TransparentProxyAppDomain(); if(!appDomain) TINYCLR_SET_AND_LEAVE(CLR_E_APPDOMAIN_EXITED); obj = obj->TransparentProxyDereference(); FAULT_ON_NULL(obj); } _ASSERTE(obj->DataType() == DATATYPE_CLASS ); _ASSERTE(obj->ObjectCls().m_data == g_CLR_RT_WellKnownTypes.m_AppDomain.m_data); src = CLR_RT_ObjectToEvent_Source::ExtractInstance( obj[ FIELD__m_appDomain ] ); FAULT_ON_NULL(src); appDomain = (CLR_RT_AppDomain*)src->m_eventPtr ; FAULT_ON_NULL(appDomain); _ASSERTE(appDomain->DataType() == DATATYPE_APPDOMAIN_HEAD); if(fCheckForUnloadingAppDomain) { if(!appDomain->IsLoaded()) TINYCLR_SET_AND_LEAVE(CLR_E_APPDOMAIN_EXITED); } (void)g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( appDomain ); TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::MarshalSockAddress( CLR_RT_HeapBlock& blkDst, const struct SOCK_sockaddr* addrSrc, CLR_UINT32 addrLenSrc ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* arr = NULL; CLR_RT_HeapBlock blkArr; blkArr.SetObjectReference( NULL ); CLR_RT_ProtectFromGC gc( blkArr ); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( blkArr, addrLenSrc, g_CLR_RT_WellKnownTypes.m_UInt8 )); arr = blkArr.DereferenceArray(); _ASSERTE(arr); memcpy( arr->GetFirstElement(), addrSrc, addrLenSrc ); _ASSERTE(blkDst.DataType() == DATATYPE_BYREF || blkDst.DataType() == DATATYPE_ARRAY_BYREF); TINYCLR_CHECK_HRESULT(blkArr.StoreToReference( blkDst, 0 )); 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_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_HeapBlock_Array::Copy( CLR_RT_HeapBlock_Array* arraySrc, int indexSrc, CLR_RT_HeapBlock_Array* arrayDst, int indexDst, int length ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); if(length) { int numElemSrc = arraySrc->m_numOfElements; int numElemDst = arrayDst->m_numOfElements; if(length < 0 || indexSrc < 0 || indexDst < 0 || length + indexSrc > numElemSrc || length + indexDst > numElemDst ) { TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } // // Copy of an array on itself. // if(arraySrc == arrayDst && indexSrc == indexDst) TINYCLR_SET_AND_LEAVE(S_OK); if(arraySrc->SameHeader( *arrayDst )) { CLR_UINT8* dataSrc = arraySrc->GetFirstElement(); CLR_UINT8* dataDst = arrayDst->GetFirstElement(); CLR_UINT8 sizeElem = arraySrc->m_sizeOfElement; dataSrc += indexSrc * sizeElem; dataDst += indexDst * sizeElem; if(!arraySrc->m_fReference) { memmove( dataDst, dataSrc, length * sizeElem ); } else { CLR_RT_HeapBlock* ptrSrc = (CLR_RT_HeapBlock*)dataSrc; CLR_RT_HeapBlock* ptrDst = (CLR_RT_HeapBlock*)dataDst; int incr; if(arraySrc == arrayDst && ptrSrc < ptrDst) { incr = -1; ptrSrc += length-1; ptrDst += length-1; } else { incr = 1; } for(int i=0; i<length; i++, ptrSrc += incr, ptrDst += incr) { TINYCLR_CHECK_HRESULT(ptrDst->Reassign( *ptrSrc )); } } } else if(arraySrc->m_fReference && arrayDst->m_fReference) { CLR_RT_TypeDescriptor descSrc; CLR_RT_TypeDescriptor descDst; CLR_RT_HeapBlock* ptrSrc = (CLR_RT_HeapBlock*)arraySrc->GetElement( indexSrc ); CLR_RT_HeapBlock* ptrDst = (CLR_RT_HeapBlock*)arrayDst->GetElement( indexDst ); TINYCLR_CHECK_HRESULT(descDst.InitializeFromObject( *arrayDst )); descDst.GetElementType( descDst ); for(int i=0; i<length; i++, ptrSrc++, ptrDst++) { if(ptrSrc->DataType() == DATATYPE_OBJECT && ptrSrc->Dereference() == NULL) { ; } else { TINYCLR_CHECK_HRESULT(descSrc.InitializeFromObject( *ptrSrc )); if(CLR_RT_ExecutionEngine::IsInstanceOf( descSrc, descDst ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_CAST); } } TINYCLR_CHECK_HRESULT(ptrDst->Reassign( *ptrSrc )); } } else { CLR_RT_TypeDescriptor descSrc; CLR_RT_TypeDescriptor descDst; CLR_RT_HeapBlock ref; CLR_RT_HeapBlock elem; elem.SetObjectReference( NULL ); CLR_RT_ProtectFromGC gc( elem ); TINYCLR_CHECK_HRESULT(descDst.InitializeFromObject( *arrayDst )); descDst.GetElementType( descDst ); for(int i=0; i<length; i++) { ref.InitializeArrayReferenceDirect( *arraySrc, indexSrc++ ); TINYCLR_CHECK_HRESULT(elem.LoadFromReference( ref )); if(elem.DataType() == DATATYPE_OBJECT && elem.Dereference() == NULL) { ; } else { TINYCLR_CHECK_HRESULT(descSrc.InitializeFromObject( elem )); if(CLR_RT_ExecutionEngine::IsInstanceOf( descSrc, descDst ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_CAST); } } ref.InitializeArrayReferenceDirect( *arrayDst, indexDst++ ); TINYCLR_CHECK_HRESULT(elem.StoreToReference( ref, 0 )); } } } TINYCLR_NOCLEANUP(); }
/* This is not the same functionality as System.Array.IndexOf. CLR_RT_HeapBlock_Array::IndexOf does the search analogous to calling Object.ReferenceEquals, not Object.Equals, as System.Array.IndexOf demands. This function is used by TrySzIndexOf */ HRESULT CLR_RT_HeapBlock_Array::IndexOf( CLR_RT_HeapBlock_Array* array, CLR_RT_HeapBlock& match, int start, int stop, bool fForward, int& index ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); int numElem = array->m_numOfElements; int count; if(stop == -1) stop = numElem; count = stop - start; if(CheckRange( start, count, numElem ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); if(count > 0) { CLR_UINT8* data = array->GetFirstElement(); CLR_UINT8 sizeElem = array->m_sizeOfElement; int pos; int incr; if(fForward) { pos = start ; incr = 1; } else { pos = stop-1; incr = -1; } data += pos * sizeElem; if(!array->m_fReference) { CLR_RT_HeapBlock* matchPtr = match.FixBoxingReference(); FAULT_ON_NULL(matchPtr); if(matchPtr->DataType() <= DATATYPE_LAST_PRIMITIVE) { int incrElem = incr * sizeElem; while(true) { #if !defined(BIG_ENDIAN) if(memcmp( data, &matchPtr->NumericByRef(), sizeElem ) == 0) { index = pos; TINYCLR_SET_AND_LEAVE(S_OK); } #else CLR_UINT64 refNum; switch(sizeElem) { case 1: refNum = matchPtr->NumericByRef().u1; break; case 2: refNum = matchPtr->NumericByRef().u2; break; case 4: refNum = matchPtr->NumericByRef().u4; break; case 8: refNum = matchPtr->NumericByRef().u8; break; } if(memcmp( data, &refNum, sizeElem ) == 0) { index = pos; TINYCLR_SET_AND_LEAVE(S_OK); } #endif if(--count == 0) break; pos += incr; data += incrElem; } } } else { CLR_RT_HeapBlock* dataPtr = (CLR_RT_HeapBlock*)data; while(true) { if(CLR_RT_HeapBlock::Compare_Unsigned_Values( *dataPtr, match ) == 0) { index = pos; TINYCLR_SET_AND_LEAVE(S_OK); } if(--count == 0) break; pos += incr; dataPtr += incr; } } } index = -1; TINYCLR_NOCLEANUP(); }
HRESULT CLR_RT_HeapBlock_Delegate_List::Change( CLR_RT_HeapBlock& reference, CLR_RT_HeapBlock& delegateSrc, CLR_RT_HeapBlock& delegateTarget, bool fCombine, bool fWeak ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Delegate_List* dlgListSrc; CLR_RT_HeapBlock_Delegate_List* dlgListDst; CLR_RT_HeapBlock_Delegate* dlg; CLR_RT_HeapBlock* newDlgs; CLR_RT_HeapBlock* oldDlgs; CLR_UINT32 oldNum; CLR_UINT32 newNum; CLR_UINT32 num = 0; reference.SetObjectReference( NULL ); if(delegateSrc .DataType() != DATATYPE_OBJECT || delegateTarget.DataType() != DATATYPE_OBJECT ) { TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } dlg = delegateTarget.DereferenceDelegate(); if(dlg == NULL) { reference.SetObjectReference( delegateSrc.DereferenceDelegate() ); TINYCLR_SET_AND_LEAVE(S_OK); } if(dlg->DataType() == DATATYPE_DELEGATELIST_HEAD) { CLR_RT_HeapBlock intermediate; intermediate.Assign( delegateSrc ); CLR_RT_ProtectFromGC gc( intermediate ); dlgListDst = (CLR_RT_HeapBlock_Delegate_List*)dlg; newDlgs = dlgListDst->GetDelegates(); for(num=0; num<dlgListDst->m_length; num++, newDlgs++) { if(newDlgs->DataType() == DATATYPE_OBJECT && newDlgs->DereferenceDelegate() != NULL) // The delegate could have been GC'ed. { TINYCLR_CHECK_HRESULT(Change( reference, intermediate, *newDlgs, fCombine, fWeak )); intermediate.Assign( reference ); } } } else { dlgListSrc = delegateSrc.DereferenceDelegateList(); if(dlgListSrc == NULL) { oldDlgs = NULL; oldNum = 0; } else { switch(dlgListSrc->DataType()) { case DATATYPE_DELEGATE_HEAD: oldDlgs = &delegateSrc; oldNum = 1; break; case DATATYPE_DELEGATELIST_HEAD: oldDlgs = dlgListSrc->GetDelegates(); oldNum = dlgListSrc->m_length; break; default: TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } } if(fCombine) { if(oldNum == 0 && fWeak == false) { // // Empty input list, copy the delegate. // reference.Assign( delegateTarget ); TINYCLR_SET_AND_LEAVE(S_OK); } //--// newNum = oldNum + 1; } else { for(num=0, newDlgs=oldDlgs; num<oldNum; num++, newDlgs++) { CLR_RT_HeapBlock_Delegate* ptr = newDlgs->DereferenceDelegate(); if(ptr) { if( ptr->DelegateFtn().m_data == dlg->DelegateFtn().m_data && ptr->m_object.Dereference() == dlg->m_object.Dereference() ) { break; } } } if(num == oldNum) { reference.Assign( delegateSrc ); // Nothing to remove. TINYCLR_SET_AND_LEAVE(S_OK); } if(oldNum == 2 && (dlgListSrc->m_flags & CLR_RT_HeapBlock_Delegate_List::c_Weak) == 0) { reference.Assign( oldDlgs[ 1-num ] ); // Convert from a list to delegate. TINYCLR_SET_AND_LEAVE(S_OK); } if(oldNum == 1) { reference.SetObjectReference( NULL ); // Oops, empty delegate... TINYCLR_SET_AND_LEAVE(S_OK); } //--// newNum = oldNum - 1; } TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Delegate_List::CreateInstance( dlgListDst, newNum )); dlgListDst->m_cls = dlg->m_cls; newDlgs = dlgListDst->GetDelegates(); if(fCombine) { newDlgs = dlgListDst->CopyAndCompress( oldDlgs, newDlgs, oldNum ); newDlgs->Assign( delegateTarget ); } else { newDlgs = dlgListDst->CopyAndCompress( oldDlgs , newDlgs, num++ ); newDlgs = dlgListDst->CopyAndCompress( oldDlgs + num, newDlgs, oldNum - num ); } dlgListDst->m_flags = (dlgListSrc && oldNum > 1) ? dlgListSrc->m_flags : 0; if(fWeak) dlgListDst->m_flags |= CLR_RT_HeapBlock_Delegate_List::c_Weak; reference.SetObjectReference( dlgListDst ); } 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(); }