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_RuntimeFieldInfo::get_FieldType___SystemType( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_TypeDescriptor desc; CLR_RT_FieldDef_Instance fd; if(GetFieldDescriptor( stack, stack.Arg0(), fd ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); TINYCLR_CHECK_HRESULT(desc.InitializeFromFieldDefinition( fd )); stack.PushValue().SetReflection( desc.m_handlerCls ); TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_RuntimeType::GetElementType___SystemType( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_TypeDescriptor desc; CLR_RT_TypeDescriptor descSub; CLR_RT_HeapBlock& top = stack.PushValueAndClear(); TINYCLR_CHECK_HRESULT(desc.InitializeFromReflection( stack.Arg0().ReflectionDataConst() )); if(desc.GetElementType( descSub )) { top.SetReflection( descSub.m_reflex ); } 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; TINYCLR_CHECK_HRESULT(Library_corlib_native_System_Reflection_MethodBase::GetMethodDescriptor( stack, stack.Arg0(), md )); parser.Initialize_MethodSignature( md.m_assm, md.m_target ); TINYCLR_CHECK_HRESULT(desc.InitializeFromSignatureParser( parser )); stack.PushValue().SetReflection( desc.m_reflex ); 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 MethodCompiler::Opcode::Initialize( MethodCompiler* mc, CLR_OFFSET offset, CLR_OFFSET* targets ) { TINYCLR_HEADER(); CLR_PMETADATA ip = mc->m_ipStart + offset; //--// memset( this, 0, sizeof(*this) ); m_op = CLR_ReadNextOpcodeCompressed( ip ); m_ol = &c_CLR_RT_OpcodeLookup[ m_op ]; m_ipOffset = offset; m_stackPop = m_ol->StackPop (); m_stackPush = m_ol->StackPush(); m_token = CLR_EmptyToken; m_value.SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FIRST_INVALID, 0, 1) ); //--// switch(m_ol->m_opParam) { case CLR_OpcodeParam_Field: { FETCH_ARG_COMPRESSED_FIELDTOKEN(arg,ip); m_token = arg; } break; case CLR_OpcodeParam_Method: { FETCH_ARG_COMPRESSED_METHODTOKEN(arg,ip); m_token = arg; } break; case CLR_OpcodeParam_Type: { FETCH_ARG_COMPRESSED_TYPETOKEN(arg,ip); m_token = arg; } break; case CLR_OpcodeParam_String: { FETCH_ARG_COMPRESSED_STRINGTOKEN(arg,ip); m_token = arg; } break; case CLR_OpcodeParam_Tok: { FETCH_ARG_TOKEN(arg,ip); m_token = arg; } break; case CLR_OpcodeParam_Sig: TINYCLR_SET_AND_LEAVE(CLR_E_JITTER_OPCODE_UNSUPPORTED); case CLR_OpcodeParam_BrTarget: { FETCH_ARG_INT16(arg,ip); m_numTargets = 1; if(targets) { *targets++ = (CLR_OFFSET)(ip - mc->m_ipStart + arg); } } break; case CLR_OpcodeParam_ShortBrTarget: { FETCH_ARG_INT8(arg,ip); m_numTargets = 1; if(targets) { *targets++ = (CLR_OFFSET)(ip - mc->m_ipStart + arg); } } break; case CLR_OpcodeParam_I: { FETCH_ARG_INT32(arg,ip); m_value.SetInteger( arg ); } break; case CLR_OpcodeParam_I8: { FETCH_ARG_INT64(arg,ip); m_value.SetInteger( arg ); } break; case CLR_OpcodeParam_None: if(m_ol->m_flags & CLR_RT_OpcodeLookup::ATTRIB_HAS_INDEX) { m_value.SetInteger( (CLR_UINT32)m_ol->m_index ); } if(m_ol->m_flags & CLR_RT_OpcodeLookup::ATTRIB_HAS_I4) { m_value.SetInteger( (CLR_INT32)m_ol->m_index ); } break; case CLR_OpcodeParam_R: { FETCH_ARG_UINT64(arg,ip); m_value.SetDoubleFromBits( arg ); } break; case CLR_OpcodeParam_Switch: { FETCH_ARG_UINT8(arg,ip); m_numTargets = arg; CLR_UINT32 base = (CLR_UINT32)(ip - mc->m_ipStart + arg * sizeof(CLR_INT16)); while(arg--) { CLR_INT32 offset; TINYCLR_READ_UNALIGNED_INT16( offset, ip ); if(targets) { *targets++ = (CLR_OFFSET)(base + offset); } } } break; case CLR_OpcodeParam_Var: { FETCH_ARG_UINT16(arg,ip); m_value.SetInteger( (CLR_UINT32)m_ol->m_index ); } break; case CLR_OpcodeParam_ShortI: { FETCH_ARG_INT8(arg,ip); m_value.SetInteger( (CLR_INT32)arg ); } break; case CLR_OpcodeParam_ShortR: { FETCH_ARG_UINT32(arg,ip); m_value.SetFloatFromBits( arg ); } break; case CLR_OpcodeParam_ShortVar: { FETCH_ARG_UINT8(arg,ip); m_value.SetInteger( (CLR_UINT32)arg ); } break; } if(m_token != CLR_EmptyToken) { CLR_RT_Assembly* assm = mc->m_mdInst.m_assm; switch(CLR_TypeFromTk( m_token )) { case TBL_TypeRef: case TBL_TypeDef: { if(m_tdInst.ResolveToken( m_token, assm ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_JITTER_OPCODE_INVALID_TOKEN__TYPE); } } break; case TBL_MethodRef: case TBL_MethodDef: { if(m_mdInst.ResolveToken( m_token, assm ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_JITTER_OPCODE_INVALID_TOKEN__METHOD); } if(m_ol->m_flowCtrl == CLR_FlowControl_CALL) { m_stackPop += m_mdInst.m_target->numArgs; if(m_ol->m_logicalOpcode == LO_NewObject) { m_stackPop -= 1; } if(m_mdInst.m_target->retVal != DATATYPE_VOID) { m_stackPush += 1; } } } break; case TBL_FieldRef: case TBL_FieldDef: { if(m_fdInst.ResolveToken( m_token, assm ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_JITTER_OPCODE_INVALID_TOKEN__FIELD); } } break; case TBL_TypeSpec: { CLR_RT_TypeSpec_Instance sig; CLR_RT_TypeDescriptor desc; if(sig.ResolveToken( m_token, assm ) == false) { TINYCLR_SET_AND_LEAVE(CLR_E_JITTER_OPCODE_INVALID_TOKEN__TYPE); } TINYCLR_CHECK_HRESULT(desc.InitializeFromTypeSpec( sig )); m_tdInst.InitializeFromIndex( desc.m_reflex.m_data.m_type ); m_tdInstLevels = desc.m_reflex.m_levels; } break; case TBL_Strings: break; default: TINYCLR_SET_AND_LEAVE(CLR_E_JITTER_OPCODE_INVALID_SIGNATURE); } } m_ipLength = (CLR_OFFSET)(ip - mc->m_ipStart - m_ipOffset); 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(); }
void CLR_RT_StackFrame::Pop() { NATIVE_PROFILE_CLR_CORE(); #if defined(TINYCLR_PROFILE_NEW_CALLS) { // // This passivates any outstanding handler. // CLR_PROF_HANDLER_CALLCHAIN(pm2,m_callchain); m_callchain.Leave(); } #endif #if defined(TINYCLR_PROFILE_NEW_CALLS) g_CLR_PRF_Profiler.RecordFunctionReturn( m_owningThread, m_callchain ); #endif #if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING) if(m_owningThread->m_fHasJMCStepper || (m_flags & c_HasBreakpoint)) { g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Pop( this, false ); } #endif const CLR_UINT32 c_flagsToCheck = CLR_RT_StackFrame::c_CallOnPop | CLR_RT_StackFrame::c_Synchronized | CLR_RT_StackFrame::c_SynchronizedGlobally | CLR_RT_StackFrame::c_NativeProfiled; if(m_flags & c_flagsToCheck) { if(m_flags & CLR_RT_StackFrame::c_CallOnPop) { m_flags |= CLR_RT_StackFrame::c_CalledOnPop; if(m_nativeMethod) { (void)m_nativeMethod( *this ); } } if(m_flags & CLR_RT_StackFrame::c_Synchronized) { m_flags &= ~CLR_RT_StackFrame::c_Synchronized; (void)HandleSynchronized( false, false ); } if(m_flags & CLR_RT_StackFrame::c_SynchronizedGlobally) { m_flags &= ~CLR_RT_StackFrame::c_SynchronizedGlobally; (void)HandleSynchronized( false, true ); } #if defined(ENABLE_NATIVE_PROFILER) if(m_flags & CLR_RT_StackFrame::c_NativeProfiled) { m_owningThread->m_fNativeProfiled = false; m_flags &= ~CLR_RT_StackFrame::c_NativeProfiled; Native_Profiler_Stop(); } #endif } CLR_RT_StackFrame* caller = Caller(); if(caller->Prev() != NULL) { #if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING) if(caller->m_flags & CLR_RT_StackFrame::c_HasBreakpoint) { g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Step( caller, caller->m_IP ); } #endif // // Constructors are slightly different, they push the 'this' pointer back into the caller stack. // // This is to enable the special case for strings, where the object can be recreated by the constructor... // if(caller->m_flags & CLR_RT_StackFrame::c_ExecutingConstructor) { CLR_RT_HeapBlock& src = this ->Arg0 ( ); CLR_RT_HeapBlock& dst = caller->PushValueAndAssign( src ); dst.Promote(); // // Undo the special "object -> reference" hack done by CEE_NEWOBJ. // if(dst.DataType() == DATATYPE_BYREF) { dst.ChangeDataType( DATATYPE_OBJECT ); } caller->m_flags &= ~CLR_RT_StackFrame::c_ExecutingConstructor; _ASSERTE((m_flags & CLR_RT_StackFrame::c_AppDomainTransition) == 0); } else { //Note that ExecutingConstructor is checked on 'caller', whereas the other two flags are checked on 'this' const CLR_UINT32 c_moreFlagsToCheck = CLR_RT_StackFrame::c_PseudoStackFrameForFilter | CLR_RT_StackFrame::c_AppDomainTransition; if(m_flags & c_moreFlagsToCheck) { if(m_flags & CLR_RT_StackFrame::c_PseudoStackFrameForFilter) { //Do nothing here. Pushing return values onto stack frames that don't expect them are a bad idea. } #if defined(TINYCLR_APPDOMAINS) else if((m_flags & CLR_RT_StackFrame::c_AppDomainTransition) != 0) { (void)PopAppDomainTransition(); } #endif } else //!c_moreFlagsToCheck { // // Push the return, if any. // if(m_call.m_target->retVal != DATATYPE_VOID) { if(m_owningThread->m_currentException.Dereference() == NULL) { CLR_RT_HeapBlock& src = this ->TopValue ( ); CLR_RT_HeapBlock& dst = caller->PushValueAndAssign( src ); dst.Promote(); } } } } } #if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING) else { int idx = m_owningThread->m_scratchPad; if(idx >= 0) { CLR_RT_HeapBlock_Array* array = g_CLR_RT_ExecutionEngine.m_scratchPadArray; if(array && array->m_numOfElements > (CLR_UINT32)idx) { CLR_RT_HeapBlock* dst = (CLR_RT_HeapBlock*)array->GetElement( (CLR_UINT32)idx ); CLR_RT_HeapBlock* exception = m_owningThread->m_currentException.Dereference(); dst->SetObjectReference( NULL ); if(exception != NULL) { dst->SetObjectReference( exception ); } else if(m_call.m_target->retVal != DATATYPE_VOID) { CLR_RT_SignatureParser sig; sig.Initialize_MethodSignature( this->m_call.m_assm, this->m_call.m_target ); CLR_RT_SignatureParser::Element res; CLR_RT_TypeDescriptor desc; dst->Assign( this->TopValue() ); //Perform boxing, if needed. //Box to the return value type _SIDE_ASSERTE(SUCCEEDED(sig.Advance( res ))); _SIDE_ASSERTE(SUCCEEDED(desc.InitializeFromType( res.m_cls ))); if(c_CLR_RT_DataTypeLookup[ this->DataType() ].m_flags & CLR_RT_DataTypeLookup::c_OptimizedValueType || desc.m_handlerCls.m_target->IsEnum() ) { if(FAILED(dst->PerformBoxing( desc.m_handlerCls ))) { dst->SetObjectReference( NULL ); } } } } } } #endif // // We could be jumping outside of a nested exception handler. // m_owningThread->PopEH( this, NULL ); // // If this StackFrame owns a SubThread, kill it. // { CLR_RT_SubThread* sth = (CLR_RT_SubThread*)m_owningSubThread->Next(); if(sth->Next() && sth->m_owningStackFrame == this) { CLR_RT_SubThread::DestroyInstance( sth->m_owningThread, sth, CLR_RT_SubThread::MODE_IncludeSelf ); } } g_CLR_RT_EventCache.Append_Node( this ); }