Skip to content

Commit dd4868f

Browse files
Interpreter supports UnmanagedCallersOnly marked methods. (#2712)
1 parent 0d0df4a commit dd4868f

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

src/coreclr/vm/interpreter.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,13 @@ InterpreterMethodInfo::InterpreterMethodInfo(CEEInfo* comp, CORINFO_METHOD_INFO*
106106
#endif
107107
SetFlag<Flag_hasRetBuffArg>(hasRetBuff);
108108

109-
MetaSig sig(reinterpret_cast<MethodDesc*>(methInfo->ftn));
109+
MethodDesc* targetMD = reinterpret_cast<MethodDesc*>(methInfo->ftn);
110+
MetaSig sig(targetMD);
110111
SetFlag<Flag_hasGenericsContextArg>((methInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) != 0);
111112
SetFlag<Flag_isVarArg>((methInfo->args.callConv & CORINFO_CALLCONV_VARARG) != 0);
112113
SetFlag<Flag_typeHasGenericArgs>(methInfo->args.sigInst.classInstCount > 0);
113114
SetFlag<Flag_methHasGenericArgs>(methInfo->args.sigInst.methInstCount > 0);
115+
SetFlag<Flag_unmanagedCallersOnly>(targetMD->HasUnmanagedCallersOnlyAttribute());
114116
_ASSERTE_MSG(!GetFlag<Flag_hasGenericsContextArg>()
115117
|| ((GetFlag<Flag_typeHasGenericArgs>() && !(GetFlag<Flag_hasThisArg>() && GetFlag<Flag_thisArgIsObjPtr>())) || GetFlag<Flag_methHasGenericArgs>()),
116118
"If the method takes a generic parameter, is a static method of generic class (or meth of a value class), and/or itself takes generic parameters");
@@ -820,15 +822,15 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
820822
*ppInterpMethodInfo = interpMethInfo;
821823
}
822824
interpMethInfo->m_stubNum = s_interpreterStubNum;
823-
MethodDesc* methodDesc = reinterpret_cast<MethodDesc*>(info->ftn);
824825
if (!jmpCall)
825826
{
826827
interpMethInfo = RecordInterpreterMethodInfoForMethodHandle(info->ftn, interpMethInfo);
827828
}
828829

830+
MethodDesc* pMD = reinterpret_cast<MethodDesc*>(info->ftn);
829831
#if FEATURE_INTERPRETER_DEADSIMPLE_OPT
830832
unsigned offsetOfLd;
831-
if (IsDeadSimpleGetter(comp, methodDesc, &offsetOfLd))
833+
if (IsDeadSimpleGetter(comp, pMD, &offsetOfLd))
832834
{
833835
interpMethInfo->SetFlag<InterpreterMethodInfo::Flag_methIsDeadSimpleGetter>(true);
834836
if (offsetOfLd == ILOffsetOfLdFldInDeadSimpleInstanceGetterDbg)
@@ -892,7 +894,6 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
892894
// In the IL stub case, which uses eax, it would be problematic to do this sharing.
893895

894896
StubLinkerCPU sl;
895-
MethodDesc* pMD = reinterpret_cast<MethodDesc*>(info->ftn);
896897
if (!jmpCall)
897898
{
898899
sl.Init();
@@ -918,7 +919,7 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
918919
#endif
919920
}
920921

921-
MetaSig sig(methodDesc);
922+
MetaSig sig(pMD);
922923

923924
unsigned totalArgs = info->args.numArgs;
924925
unsigned sigArgsPlusThis = totalArgs;
@@ -956,7 +957,7 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
956957
totalArgs++; sigArgsPlusThis++;
957958
}
958959

959-
if (methodDesc->HasRetBuffArg())
960+
if (pMD->HasRetBuffArg())
960961
{
961962
hasRetBuff = true;
962963
retBuffArgIndex = totalArgs;
@@ -1403,7 +1404,9 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
14031404
interpretMethodFunc = reinterpret_cast<PCODE>(&InterpretMethodDouble);
14041405
break;
14051406
default:
1406-
interpretMethodFunc = reinterpret_cast<PCODE>(&InterpretMethod);
1407+
interpretMethodFunc = interpMethInfo->GetFlag<InterpreterMethodInfo::Flag_unmanagedCallersOnly>()
1408+
? reinterpret_cast<PCODE>(&ReversePInvokeInterpretMethod)
1409+
: reinterpret_cast<PCODE>(&InterpretMethod);
14071410
break;
14081411
}
14091412
// The argument registers have been pushed by now, so we can use them.
@@ -1921,6 +1924,18 @@ HCIMPL3(INT64, InterpretMethod, struct InterpreterMethodInfo* interpMethInfo, BY
19211924
}
19221925
HCIMPLEND
19231926

1927+
// static
1928+
HCIMPL3_RAW(INT64, ReversePInvokeInterpretMethod, struct InterpreterMethodInfo* interpMethInfo, BYTE* ilArgs, void* stubContext)
1929+
{
1930+
FCALL_CONTRACT;
1931+
1932+
_ASSERTE(CURRENT_THREAD == NULL || !CURRENT_THREAD->PreemptiveGCDisabled());
1933+
1934+
GCX_COOP();
1935+
return HCCALL3(InterpretMethod, interpMethInfo, ilArgs, stubContext);
1936+
}
1937+
HCIMPLEND_RAW
1938+
19241939
bool Interpreter::IsInCalleesFrames(void* stackPtr)
19251940
{
19261941
// We assume a downwards_growing stack.

src/coreclr/vm/interpreter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@ struct InterpreterMethodInfo
609609
// We recognize two forms of dead simple getters, one for "opt" and one for "dbg". If it is
610610
// dead simple, is it dbg or opt?
611611
Flag_methIsDeadSimpleGetterIsDbgForm,
612+
Flag_unmanagedCallersOnly,
612613
Flag_Count,
613614
};
614615

@@ -735,6 +736,7 @@ class InterpreterCEEInfo: public CEEInfo
735736
};
736737

737738
extern INT64 F_CALL_CONV InterpretMethod(InterpreterMethodInfo* methInfo, BYTE* ilArgs, void* stubContext);
739+
extern INT64 F_CALL_CONV ReversePInvokeInterpretMethod(struct InterpreterMethodInfo* interpMethInfo, BYTE* ilArgs, void* stubContext);
738740
extern float F_CALL_CONV InterpretMethodFloat(InterpreterMethodInfo* methInfo, BYTE* ilArgs, void* stubContext);
739741
extern double F_CALL_CONV InterpretMethodDouble(InterpreterMethodInfo* methInfo, BYTE* ilArgs, void* stubContext);
740742

0 commit comments

Comments
 (0)