@@ -9625,6 +9625,8 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9625
9625
{
9626
9626
_ASSERTE (m_callThisArg == NULL ); // "m_callThisArg" non-null only for .ctor, which are not callvirts.
9627
9627
9628
+ bool staticAbstract = false ;
9629
+
9628
9630
// The constrained. prefix will be immediately followed by a ldftn, call or callvirt instruction.
9629
9631
// See Ecma-335-Augments.md#iii21-constrained---prefix-invoke-a-member-on-a-value-of-a-variable-type-page-316 for more detail
9630
9632
if (sigInfo.hasThis ())
@@ -9637,7 +9639,8 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9637
9639
else
9638
9640
{
9639
9641
// If the constrained. prefix is applied to a call or ldftn instruction, method must be a virtual static method.
9640
- // TODO: Assert it is a virtual static method.
9642
+ OPCODE opcode = (OPCODE)(*m_ILCodePtr);
9643
+ staticAbstract = (opcode == CEE_CALL || opcode == CEE_LDFTN) && methToCall->IsStatic ();
9641
9644
}
9642
9645
9643
9646
// We only cache for the CORINFO_NO_THIS_TRANSFORM case, so we may assume that if we have a cached call site,
@@ -9683,7 +9686,7 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9683
9686
DWORD exactClassAttribs = m_interpCeeInfo.getClassAttribs (exactClass);
9684
9687
// If the constraint type is a value class, then it is the exact class (which will be the
9685
9688
// "owner type" in the MDCS below.) If it is not, leave it as the (precise) interface method.
9686
- if (exactClassAttribs & CORINFO_FLG_VALUECLASS)
9689
+ if (exactClassAttribs & CORINFO_FLG_VALUECLASS && !staticAbstract )
9687
9690
{
9688
9691
MethodTable* exactClassMT = GetMethodTableFromClsHnd (exactClass);
9689
9692
// Find the method on exactClass corresponding to methToCall.
@@ -9696,6 +9699,8 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9696
9699
}
9697
9700
else
9698
9701
{
9702
+ if (staticAbstract)
9703
+ methToCall = reinterpret_cast <MethodDesc*>(callInfoPtr->hMethod );
9699
9704
exactClass = methTokPtr->hClass ;
9700
9705
}
9701
9706
}
@@ -10565,7 +10570,11 @@ void Interpreter::CallI()
10565
10570
// change the GC mode. (We'll only do this at the call if the calling convention turns out
10566
10571
// to be a managed calling convention.)
10567
10572
MethodDesc* pStubContextMD = reinterpret_cast <MethodDesc*>(m_stubContext);
10568
- bool transitionToPreemptive = (pStubContextMD != NULL && !pStubContextMD->IsIL ());
10573
+ bool transitionToPreemptive;
10574
+ {
10575
+ GCX_PREEMP ();
10576
+ transitionToPreemptive = (pStubContextMD != NULL && !pStubContextMD->IsIL () && !pStubContextMD->ShouldSuppressGCTransition ());
10577
+ }
10569
10578
mdcs.CallTargetWorker (args, &retVal, sizeof (retVal), transitionToPreemptive);
10570
10579
}
10571
10580
// retVal is now vulnerable.
@@ -11015,8 +11024,8 @@ void Interpreter::DoGetMethodTable()
11015
11024
11016
11025
MethodTable* pMT = obj->RawGetMethodTable ();
11017
11026
11018
- OpStackSet<MethodTable*>(m_curStackHt , pMT);
11019
- OpStackTypeSet (m_curStackHt , InterpreterType (CORINFO_TYPE_NATIVEINT));
11027
+ OpStackSet<MethodTable*>(ind , pMT);
11028
+ OpStackTypeSet (ind , InterpreterType (CORINFO_TYPE_NATIVEINT));
11020
11029
}
11021
11030
11022
11031
bool Interpreter::DoInterlockedCompareExchange (CorInfoType retType)
0 commit comments