Skip to content

Commit 31b367d

Browse files
committed
Add constrained support for calls
Rename constrainedClass to pConstrainedToken for clarity. Extract box code emit into separate method.
1 parent 9ed97ce commit 31b367d

File tree

5 files changed

+63
-32
lines changed

5 files changed

+63
-32
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,7 +2311,7 @@ int InterpCompiler::EmitGenericHandleAsVar(const CORINFO_GENERICHANDLE_RESULT &e
23112311
return resultVar;
23122312
}
23132313

2314-
void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* constrainedClass, bool readonly, bool tailcall, bool newObj, bool isCalli)
2314+
void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool readonly, bool tailcall, bool newObj, bool isCalli)
23152315
{
23162316
uint32_t token = getU4LittleEndian(m_ip + 1);
23172317
bool isVirtual = (*m_ip == CEE_CALLVIRT);
@@ -2341,19 +2341,38 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* constrainedClass, bool rea
23412341
}
23422342
else
23432343
{
2344-
23452344
ResolveToken(token, newObj ? CORINFO_TOKENKIND_Method : CORINFO_TOKENKIND_NewObj, &resolvedCallToken);
23462345

23472346
CORINFO_CALLINFO_FLAGS flags = (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_ALLOWINSTPARAM | CORINFO_CALLINFO_SECURITYCHECKS | CORINFO_CALLINFO_DISALLOW_STUB);
23482347
if (isVirtual)
23492348
flags = (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_CALLVIRT);
23502349

2351-
m_compHnd->getCallInfo(&resolvedCallToken, constrainedClass, m_methodInfo->ftn, flags, &callInfo);
2350+
m_compHnd->getCallInfo(&resolvedCallToken, pConstrainedToken, m_methodInfo->ftn, flags, &callInfo);
23522351
if (EmitCallIntrinsics(callInfo.hMethod, callInfo.sig))
23532352
{
23542353
m_ip += 5;
23552354
return;
23562355
}
2356+
2357+
if (callInfo.thisTransform != CORINFO_NO_THIS_TRANSFORM)
2358+
{
2359+
assert(pConstrainedToken != NULL);
2360+
StackInfo *pThisStackInfo = m_pStackPointer - callInfo.sig.numArgs - 1;
2361+
if (callInfo.thisTransform == CORINFO_BOX_THIS)
2362+
{
2363+
EmitBox(pThisStackInfo, pConstrainedToken->hClass, true);
2364+
}
2365+
else
2366+
{
2367+
assert(callInfo.thisTransform == CORINFO_DEREF_THIS);
2368+
AddIns(INTOP_LDIND_I);
2369+
m_pLastNewIns->SetSVar(pThisStackInfo->var);
2370+
m_pLastNewIns->data[0] = 0;
2371+
int32_t var = CreateVarExplicit(InterpTypeO, pConstrainedToken->hClass, INTERP_STACK_SLOT_SIZE);
2372+
new (pThisStackInfo) StackInfo(StackTypeO, pConstrainedToken->hClass, var);
2373+
m_pLastNewIns->SetDVar(pThisStackInfo->var);
2374+
}
2375+
}
23572376
}
23582377

23592378
if (callInfo.classFlags & CORINFO_FLG_VAROBJSIZE)
@@ -2885,12 +2904,27 @@ void InterpCompiler::EmitLdLocA(int32_t var)
28852904
m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
28862905
}
28872906

2907+
void InterpCompiler::EmitBox(StackInfo* pStackInfo, CORINFO_CLASS_HANDLE clsHnd, bool argByRef)
2908+
{
2909+
CORINFO_CLASS_HANDLE boxedClsHnd = m_compHnd->getTypeForBox(clsHnd);
2910+
CorInfoHelpFunc helpFunc = m_compHnd->getBoxHelper(clsHnd);
2911+
AddIns(argByRef ? INTOP_BOX_PTR : INTOP_BOX);
2912+
m_pLastNewIns->SetSVar(pStackInfo->var);
2913+
2914+
int32_t var = CreateVarExplicit(InterpTypeO, NULL, INTERP_STACK_SLOT_SIZE);
2915+
new (pStackInfo) StackInfo(StackTypeO, boxedClsHnd, INTERP_STACK_SLOT_SIZE, var);
2916+
2917+
m_pLastNewIns->SetDVar(pStackInfo->var);
2918+
m_pLastNewIns->data[0] = GetDataItemIndex(clsHnd);
2919+
m_pLastNewIns->data[1] = GetDataItemIndexForHelperFtn(helpFunc);
2920+
}
2921+
28882922
int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
28892923
{
28902924
bool readonly = false;
28912925
bool tailcall = false;
28922926
bool volatile_ = false;
2893-
CORINFO_RESOLVED_TOKEN* constrainedClass = NULL;
2927+
CORINFO_RESOLVED_TOKEN* pConstrainedToken = NULL;
28942928
CORINFO_RESOLVED_TOKEN constrainedToken;
28952929
uint8_t *codeEnd;
28962930
int numArgs = m_methodInfo->args.hasThis() + m_methodInfo->args.numArgs;
@@ -4037,21 +4071,21 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
40374071
break;
40384072
case CEE_CALLVIRT:
40394073
case CEE_CALL:
4040-
EmitCall(constrainedClass, readonly, tailcall, false /*newObj*/, false /*isCalli*/);
4041-
constrainedClass = NULL;
4074+
EmitCall(pConstrainedToken, readonly, tailcall, false /*newObj*/, false /*isCalli*/);
4075+
pConstrainedToken = NULL;
40424076
readonly = false;
40434077
tailcall = false;
40444078
break;
40454079
case CEE_CALLI:
4046-
EmitCall(NULL /*constrainedClass*/, false /* readonly*/, false /* tailcall*/, false /*newObj*/, true /*isCalli*/);
4047-
constrainedClass = NULL;
4080+
EmitCall(NULL /*pConstrainedToken*/, false /* readonly*/, false /* tailcall*/, false /*newObj*/, true /*isCalli*/);
4081+
pConstrainedToken = NULL;
40484082
readonly = false;
40494083
tailcall = false;
40504084
break;
40514085
case CEE_NEWOBJ:
40524086
{
4053-
EmitCall(NULL /*constrainedClass*/, false /* readonly*/, false /* tailcall*/, true /*newObj*/, false /*isCalli*/);
4054-
constrainedClass = NULL;
4087+
EmitCall(NULL /*pConstrainedToken*/, false /* readonly*/, false /* tailcall*/, true /*newObj*/, false /*isCalli*/);
4088+
pConstrainedToken = NULL;
40554089
readonly = false;
40564090
tailcall = false;
40574091
break;
@@ -4428,12 +4462,9 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
44284462
{
44294463
uint32_t token = getU4LittleEndian(m_ip + 1);
44304464

4431-
constrainedToken.tokenScope = m_compScopeHnd;
4432-
constrainedToken.tokenContext = METHOD_BEING_COMPILED_CONTEXT();
4433-
constrainedToken.token = token;
4434-
constrainedToken.tokenType = CORINFO_TOKENKIND_Constrained;
4435-
m_compHnd->resolveToken(&constrainedToken);
4436-
constrainedClass = &constrainedToken;
4465+
ResolveToken(token, CORINFO_TOKENKIND_Constrained, &constrainedToken);
4466+
4467+
pConstrainedToken = &constrainedToken;
44374468
m_ip += 5;
44384469
break;
44394470
}
@@ -4526,8 +4557,8 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
45264557
ResolveToken(token, CORINFO_TOKENKIND_Method, &resolvedToken);
45274558

45284559
CORINFO_CALL_INFO callInfo;
4529-
m_compHnd->getCallInfo(&resolvedToken, constrainedClass, m_methodInfo->ftn, (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_SECURITYCHECKS| CORINFO_CALLINFO_LDFTN), &callInfo);
4530-
constrainedClass = NULL;
4560+
m_compHnd->getCallInfo(&resolvedToken, pConstrainedToken, m_methodInfo->ftn, (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_SECURITYCHECKS| CORINFO_CALLINFO_LDFTN), &callInfo);
4561+
pConstrainedToken = NULL;
45314562

45324563
if (callInfo.kind == CORINFO_CALL)
45334564
{
@@ -4627,17 +4658,11 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
46274658

46284659
case CEE_BOX:
46294660
{
4661+
CORINFO_CLASS_HANDLE clsHnd = ResolveClassToken(getU4LittleEndian(m_ip + 1));
46304662
CHECK_STACK(1);
46314663
m_pStackPointer -= 1;
4632-
CORINFO_CLASS_HANDLE clsHnd = ResolveClassToken(getU4LittleEndian(m_ip + 1));
4633-
CORINFO_CLASS_HANDLE boxedClsHnd = m_compHnd->getTypeForBox(clsHnd);
4634-
CorInfoHelpFunc helpFunc = m_compHnd->getBoxHelper(clsHnd);
4635-
AddIns(INTOP_BOX);
4636-
m_pLastNewIns->SetSVar(m_pStackPointer[0].var);
4637-
PushStackType(StackTypeO, boxedClsHnd);
4638-
m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
4639-
m_pLastNewIns->data[0] = GetDataItemIndex(clsHnd);
4640-
m_pLastNewIns->data[1] = GetDataItemIndexForHelperFtn(helpFunc);
4664+
EmitBox(m_pStackPointer, clsHnd, false);
4665+
m_pStackPointer++;
46414666
m_ip += 5;
46424667
break;
46434668
}

src/coreclr/interpreter/compiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ class InterpCompiler
491491
void EmitUnaryArithmeticOp(int32_t opBase);
492492
void EmitShiftOp(int32_t opBase);
493493
void EmitCompareOp(int32_t opBase);
494-
void EmitCall(CORINFO_RESOLVED_TOKEN* constrainedClass, bool readonly, bool tailcall, bool newObj, bool isCalli);
494+
void EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool readonly, bool tailcall, bool newObj, bool isCalli);
495495
bool EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig);
496496
void EmitLdind(InterpType type, CORINFO_CLASS_HANDLE clsHnd, int32_t offset);
497497
void EmitStind(InterpType type, CORINFO_CLASS_HANDLE clsHnd, int32_t offset, bool reverseSVarOrder);
@@ -500,6 +500,7 @@ class InterpCompiler
500500
void EmitStaticFieldAddress(CORINFO_FIELD_INFO *pFieldInfo, CORINFO_RESOLVED_TOKEN *pResolvedToken);
501501
void EmitStaticFieldAccess(InterpType interpFieldType, CORINFO_FIELD_INFO *pFieldInfo, CORINFO_RESOLVED_TOKEN *pResolvedToken, bool isLoad);
502502
void EmitLdLocA(int32_t var);
503+
void EmitBox(StackInfo* pStackInfo, CORINFO_CLASS_HANDLE clsHnd, bool argByRef);
503504

504505
// Var Offset allocator
505506
TArray<InterpInst*> *m_pActiveCalls;

src/coreclr/interpreter/intops.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ OPDEF(INTOP_CONV_OVF_U8_R4, "conv.ovf.u8.r4", 3, 1, 1, InterpOpNoArgs)
207207
OPDEF(INTOP_CONV_OVF_U8_R8, "conv.ovf.u8.r8", 3, 1, 1, InterpOpNoArgs)
208208

209209
OPDEF(INTOP_BOX, "box", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
210+
OPDEF(INTOP_BOX_PTR, "box.ptr", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
210211
OPDEF(INTOP_UNBOX, "unbox", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
211212
OPDEF(INTOP_UNBOX_ANY, "unbox.any", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
212213
// Unary operations end

src/coreclr/vm/interpexec.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
16741674
ip += 2;
16751675
break;
16761676
case INTOP_BOX:
1677+
case INTOP_BOX_PTR:
16771678
case INTOP_UNBOX:
16781679
case INTOP_UNBOX_ANY:
16791680
{
@@ -1683,10 +1684,14 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
16831684
MethodTable *pMT = (MethodTable*)pMethod->pDataItems[ip[3]];
16841685
HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod->pDataItems[ip[4]]);
16851686

1686-
if (opcode == INTOP_BOX) {
1687+
if (opcode == INTOP_BOX || opcode == INTOP_BOX_PTR) {
16871688
// internal static object Box(MethodTable* typeMT, ref byte unboxedData)
1688-
void *unboxedData = LOCAL_VAR_ADDR(sreg, void);
1689-
LOCAL_VAR(dreg, Object*) = (Object*)helper(pMT, unboxedData);
1689+
void *unboxedData;
1690+
if (opcode == INTOP_BOX)
1691+
unboxedData = LOCAL_VAR_ADDR(sreg, void);
1692+
else
1693+
unboxedData = LOCAL_VAR(sreg, void*);
1694+
LOCAL_VAR(dreg, OBJECTREF) = ObjectToOBJECTREF((Object*)helper(pMT, unboxedData));
16901695
} else {
16911696
// private static ref byte Unbox(MethodTable* toTypeHnd, object obj)
16921697
Object *src = LOCAL_VAR(sreg, Object*);

src/tests/Loader/classloader/regressions/208900/bug.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<!-- Needed for mechanical merging of all remaining tests, this particular project may not actually need process isolation -->
44
<RequiresProcessIsolation>true</RequiresProcessIsolation>
55
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
6-
<CLRTestPriority>1</CLRTestPriority>
76
</PropertyGroup>
87
<ItemGroup>
98
<Compile Include="bug.cs" />

0 commit comments

Comments
 (0)