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