Skip to content

Commit eafe9cb

Browse files
committed
Fixes for TypeRef of generic types
- Fix handler for CEE_CALL and CEE_CALVIRT: now checks if callee is a value type and skips resolving it. - Add ownerType to CLR_RT_TypeSpec_CrossReference. - Add new return parameter to FindMethodDef so assembly index is returned upon finding. - Add new CLR_RT_MethodDef_Instance.InitializeFromIndex() taking a TypeSpec to deal with generic types. - Add new CLR_RT_MethodDef_Instance.GetDeclaringType() helper to take advantage of pre-processed type. - Rework CLR_RT_Assembly::FindTypeSpec() to handle generic types referenced in other assembly. - Various fixes in build type and method names to deal with generic types referenced in other assembly. - CLR_RT_Assembly::FindMethodDef() now returns assembly index of method upon succesfull finding. - Fix CLR_RT_GenericParam_Instance::InitializeFromIndex() to deal with generic types referenced in other assembly. - Fix CLR_RT_MethodDef_Instance::ResolveToken() to deal with generic types referenced in other assembly. - CLR_RT_SignatureParser::Advance() now sets datatype for classes and value types.
1 parent 8725065 commit eafe9cb

File tree

3 files changed

+255
-48
lines changed

3 files changed

+255
-48
lines changed

src/CLR/Core/Interpreter.cpp

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,41 +2157,65 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
21572157
}
21582158
else // Non delegate
21592159
{
2160+
21602161
CLR_RT_MethodDef_Index calleeReal;
21612162

2162-
if ((calleeInst.target->flags & CLR_RECORD_METHODDEF::MD_Static) == 0)
2163+
bool doInstanceResolution = true;
2164+
2165+
if (calleeInst.target->flags & CLR_RECORD_METHODDEF::MD_Static)
2166+
{
2167+
doInstanceResolution = false;
2168+
}
2169+
else
21632170
{
2164-
// Instance method, pThis[ 0 ] is valid
2171+
CLR_RT_TypeDef_Instance declType;
2172+
NANOCLR_CHECK_HRESULT(calleeInst.GetDeclaringType(declType));
21652173

2166-
if (op == CEE_CALL && pThis[0].Dereference() == nullptr)
2174+
if (declType.target->dataType == DATATYPE_VALUETYPE)
21672175
{
2168-
// CALL on a null instance is allowed, and should not throw a NullReferenceException on
2169-
// the call although a NullReferenceException is likely to be thrown soon thereafter if
2170-
// the call tries to access any member variables.
2176+
// any method on a value‐type is called via byref, so skip the object‐dereference path
2177+
// altogether
2178+
doInstanceResolution = false;
21712179
}
2172-
else
2180+
}
2181+
2182+
if (doInstanceResolution)
2183+
{
2184+
if ((calleeInst.target->flags & CLR_RECORD_METHODDEF::MD_Static) == 0)
21732185
{
2174-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractTypeIndexFromObject(pThis[0], cls));
2175-
2176-
// This test is for performance reasons. c# emits a callvirt on all instance methods to
2177-
// make sure that a NullReferenceException is thrown if 'this' is nullptr. However, if
2178-
// the instance method isn't virtual we don't need to do the more expensive virtual
2179-
// method lookup.
2180-
if (op == CEE_CALLVIRT &&
2181-
(calleeInst.target->flags &
2182-
(CLR_RECORD_METHODDEF::MD_Abstract | CLR_RECORD_METHODDEF::MD_Virtual)))
2186+
// Instance method, pThis[ 0 ] is valid
2187+
2188+
if (op == CEE_CALL && pThis[0].Dereference() == nullptr)
21832189
{
2184-
if (g_CLR_RT_EventCache.FindVirtualMethod(cls, calleeInst, calleeReal) == false)
2190+
// CALL on a null instance is allowed, and should not throw a NullReferenceException
2191+
// on the call although a NullReferenceException is likely to be thrown soon
2192+
// thereafter if the call tries to access any member variables.
2193+
}
2194+
else
2195+
{
2196+
NANOCLR_CHECK_HRESULT(
2197+
CLR_RT_TypeDescriptor::ExtractTypeIndexFromObject(pThis[0], cls));
2198+
2199+
// This test is for performance reasons. c# emits a callvirt on all instance
2200+
// methods to make sure that a NullReferenceException is thrown if 'this' is
2201+
// nullptr. However, if the instance method isn't virtual we don't need to do the
2202+
// more expensive virtual method lookup.
2203+
if (op == CEE_CALLVIRT &&
2204+
(calleeInst.target->flags &
2205+
(CLR_RECORD_METHODDEF::MD_Abstract | CLR_RECORD_METHODDEF::MD_Virtual)))
21852206
{
2186-
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
2187-
}
2207+
if (g_CLR_RT_EventCache.FindVirtualMethod(cls, calleeInst, calleeReal) == false)
2208+
{
2209+
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
2210+
}
21882211

2189-
calleeInst.InitializeFromIndex(calleeReal);
2190-
}
2212+
calleeInst.InitializeFromIndex(calleeReal);
2213+
}
21912214

21922215
#if defined(NANOCLR_APPDOMAINS)
2193-
fAppDomainTransition = pThis[0].IsTransparentProxy();
2216+
fAppDomainTransition = pThis[0].IsTransparentProxy();
21942217
#endif
2218+
}
21952219
}
21962220
}
21972221
}

0 commit comments

Comments
 (0)