Skip to content

Commit 3c9b03e

Browse files
radekdoulikAaronRobinsonMSFTkg
authored
Fix INTOP_UNBOX_ANY on wasm (#120261)
* Fix INTOP_UNBOX_ANY on wasm Handle IL unbox helpers * Feedback * Feedback Add unbox.end opcode to finish unboxing after helper call * Remove unwanted include * Add another calli signature * Use intermediary var for result between unbox.any and unbox.end * Add generic variant * Apply suggestions from code review Co-authored-by: Aaron Robinson <[email protected]> * Fix generic version * Apply suggestions from code review Co-authored-by: Katelyn Gadd <[email protected]> --------- Co-authored-by: Aaron Robinson <[email protected]> Co-authored-by: Katelyn Gadd <[email protected]>
1 parent 1d29a71 commit 3c9b03e

File tree

4 files changed

+86
-8
lines changed

4 files changed

+86
-8
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,6 +3443,10 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1,
34433443
PushStackType(resultStackType, clsHndStack);
34443444
int resultVar = m_pStackPointer[-1].var;
34453445

3446+
PushStackType(StackTypeI, NULL);
3447+
int32_t intermediateVar = m_pStackPointer[-1].var;
3448+
m_pStackPointer--;
3449+
34463450
GenericHandleData handleData = GenericHandleToGenericHandleData(arg1);
34473451

34483452
if (handleData.argType == HelperArgType::GenericResolution)
@@ -3452,6 +3456,12 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1,
34523456
m_pLastNewIns->data[1] = handleData.dataItemIndex;
34533457

34543458
m_pLastNewIns->SetSVars2(handleData.genericVar, arg2);
3459+
m_pLastNewIns->SetDVar(intermediateVar);
3460+
3461+
AddIns(INTOP_UNBOX_END_GENERIC);
3462+
m_pLastNewIns->data[0] = handleData.dataItemIndex;
3463+
3464+
m_pLastNewIns->SetSVars2(handleData.genericVar, intermediateVar);
34553465
m_pLastNewIns->SetDVar(resultVar);
34563466
}
34573467
else
@@ -3461,6 +3471,12 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1,
34613471
m_pLastNewIns->data[1] = handleData.dataItemIndex;
34623472

34633473
m_pLastNewIns->SetSVar(arg2);
3474+
m_pLastNewIns->SetDVar(intermediateVar);
3475+
3476+
AddIns(INTOP_UNBOX_END);
3477+
m_pLastNewIns->data[0] = handleData.dataItemIndex;
3478+
3479+
m_pLastNewIns->SetSVar(intermediateVar);
34643480
m_pLastNewIns->SetDVar(resultVar);
34653481
}
34663482
}

src/coreclr/interpreter/inc/intops.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ OPDEF(INTOP_UNBOX_ANY, "unbox.any", 5, 1, 1, InterpOpHelperFtn) // [class handle
236236
OPDEF(INTOP_UNBOX_ANY_GENERIC, "unbox.any.generic", 6, 1, 2, InterpOpGenericHelperFtn) // [class handle data item] [helper data item]
237237
// Unary operations end
238238

239+
OPDEF(INTOP_UNBOX_END, "unbox.end", 4, 1, 1, InterpOpLdPtr) // [helper data item]
240+
OPDEF(INTOP_UNBOX_END_GENERIC, "unbox.end.generic", 5, 1, 2, InterpOpGenericLookup) // [helper data item]
241+
239242
OPDEF(INTOP_ADD_I4_IMM, "add.i4.imm", 4, 1, 1, InterpOpInt)
240243
OPDEF(INTOP_ADD_I8_IMM, "add.i8.imm", 4, 1, 1, InterpOpInt)
241244

src/coreclr/vm/interpexec.cpp

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,36 +2813,88 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
28132813
int opcode = *ip;
28142814
int dreg = ip[1];
28152815
int sreg = ip[2];
2816-
HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[3]);
28172816
MethodTable *pMT = (MethodTable*)pMethod->pDataItems[ip[4]];
2817+
Object *src = LOCAL_VAR(sreg, Object*);
2818+
2819+
MethodDesc *pILTargetMethod = NULL;
2820+
HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[3], &pILTargetMethod);
2821+
if (pILTargetMethod != NULL)
2822+
{
2823+
callArgsOffset = pMethod->allocaSize;
2824+
returnOffset = dreg;
2825+
2826+
// Pass arguments to the target method
2827+
LOCAL_VAR(callArgsOffset, void*) = pMT;
2828+
LOCAL_VAR(callArgsOffset + INTERP_STACK_SLOT_SIZE, void*) = src;
2829+
2830+
targetMethod = pILTargetMethod;
2831+
ip += 5;
2832+
2833+
goto CALL_INTERP_METHOD;
2834+
}
28182835

28192836
// private static ref byte Unbox(MethodTable* toTypeHnd, object obj)
2820-
Object *src = LOCAL_VAR(sreg, Object*);
2821-
void *unboxedData = helper(pMT, src);
2822-
CopyValueClassUnchecked(LOCAL_VAR_ADDR(dreg, void), unboxedData, pMT);
2837+
LOCAL_VAR(dreg, void*) = helper(pMT, src);
28232838

28242839
ip += 5;
28252840
break;
28262841
}
2842+
case INTOP_UNBOX_END:
2843+
{
2844+
MethodTable *pMT = (MethodTable*)pMethod->pDataItems[ip[3]];
2845+
void *dest = LOCAL_VAR_ADDR(ip[1], void);
2846+
void *src = LOCAL_VAR(ip[2], void*);
2847+
NULL_CHECK(dest);
2848+
CopyValueClassUnchecked(dest, src, pMT);
28272849

2850+
ip += 4;
2851+
break;
2852+
}
28282853
case INTOP_UNBOX_ANY_GENERIC:
28292854
{
28302855
int opcode = *ip;
28312856
int dreg = ip[1];
28322857
int sreg = ip[3];
28332858
InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]];
28342859
MethodTable *pMTBoxedObj = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup);
2860+
Object *src = LOCAL_VAR(sreg, Object*);
28352861

2836-
HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[4]);
2862+
MethodDesc *pILTargetMethod = NULL;
2863+
HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper<HELPER_FTN_BOX_UNBOX>(pMethod, ip[4], &pILTargetMethod);
2864+
2865+
if (pILTargetMethod != NULL)
2866+
{
2867+
callArgsOffset = pMethod->allocaSize;
2868+
returnOffset = dreg;
2869+
2870+
// Pass arguments to the target method
2871+
LOCAL_VAR(callArgsOffset, void*) = pMTBoxedObj;
2872+
LOCAL_VAR(callArgsOffset + INTERP_STACK_SLOT_SIZE, void*) = src;
2873+
2874+
targetMethod = pILTargetMethod;
2875+
ip += 6;
2876+
2877+
goto CALL_INTERP_METHOD;
2878+
}
28372879

28382880
// private static ref byte Unbox(MethodTable* toTypeHnd, object obj)
2839-
Object *src = LOCAL_VAR(sreg, Object*);
2840-
void *unboxedData = helper(pMTBoxedObj, src);
2841-
CopyValueClassUnchecked(LOCAL_VAR_ADDR(dreg, void), unboxedData, pMTBoxedObj->IsNullable() ? pMTBoxedObj->GetInstantiation()[0].AsMethodTable() : pMTBoxedObj);
2881+
LOCAL_VAR(dreg, void*) = helper(pMTBoxedObj, src);
28422882

28432883
ip += 6;
28442884
break;
28452885
}
2886+
case INTOP_UNBOX_END_GENERIC:
2887+
{
2888+
InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[4]];
2889+
MethodTable *pMT = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup);
2890+
void *dest = LOCAL_VAR_ADDR(ip[1], void);
2891+
void *src = LOCAL_VAR(ip[3], void*);
2892+
NULL_CHECK(dest);
2893+
CopyValueClassUnchecked(dest, src, pMT->IsNullable() ? pMT->GetInstantiation()[0].AsMethodTable() : pMT);
2894+
2895+
ip += 5;
2896+
break;
2897+
}
28462898
case INTOP_NEWARR:
28472899
{
28482900
int32_t length = LOCAL_VAR(ip[2], int32_t);

src/coreclr/vm/wasm/helpers.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,12 @@ namespace
548548
*(int32_t*)pRet = (*fptr)(ARG_IND(0), ARG_I32(1));
549549
}
550550

551+
void CallFunc_I32_I32IND_I32_RetI32(PCODE pcode, int8_t *pArgs, int8_t *pRet)
552+
{
553+
int32_t (*fptr)(int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t))pcode;
554+
*(int32_t*)pRet = (*fptr)(ARG_I32(0), ARG_IND(1), ARG_I32(2));
555+
}
556+
551557
void CallFunc_I32_I32IND_I32_I32IND_I32_RetI32(PCODE pcode, int8_t *pArgs, int8_t *pRet)
552558
{
553559
int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t))pcode;
@@ -720,6 +726,7 @@ namespace
720726
{ "iiiii", (void*)&CallFunc_I32_I32_I32_I32_RetI32 },
721727

722728
{ "ini", (void*)&CallFunc_I32IND_I32_RetI32 },
729+
{ "iini", (void*)&CallFunc_I32_I32IND_I32_RetI32 },
723730
{ "iinini", (void*)&CallFunc_I32_I32IND_I32_I32IND_I32_RetI32 },
724731
{ "iniiiii", (void*)&CallFunc_I32IND_I32_I32_I32_I32_I32_RetI32 },
725732

0 commit comments

Comments
 (0)