Skip to content

Commit 0e18180

Browse files
BrzVladmikelle-rogers
authored andcommitted
[mono][interp] Properly handle exceptions thrown by mono_marshal_get_native_wrapper (dotnet#110232)
* [mono][interp] Defer calls to mono_marshal_get_native_wrapper at execution This can end up calling into managed where exceptions can be thrown. Throwing exceptions while method compilation happens in not valid behavior. This follows the same approach from the jit side in mono/mono#20177. * [mono][interp] Check resume state when returning from method compilation * [mono][interp] Fix tiering disable condition We always optimize managed wrappers. If we are attempting to compile and execute a pinvoke method, we will use the m2n wrapper instead. Make sure we check for this when disabling tiering, since swift interop relies on these wrappers to be always optimized.
1 parent eb0f4d2 commit 0e18180

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

src/mono/mono/mini/interp/interp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,9 @@ mono_interp_get_imethod (MonoMethod *method)
502502
imethod->is_invoke = (m_class_get_parent (method->klass) == mono_defaults.multicastdelegate_class) && !strcmp(method->name, "Invoke");
503503
// always optimize code if tiering is disabled
504504
// always optimize wrappers
505-
if (!mono_interp_tiering_enabled () || method->wrapper_type != MONO_WRAPPER_NONE)
505+
if (!mono_interp_tiering_enabled () || method->wrapper_type != MONO_WRAPPER_NONE || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
506506
imethod->optimized = TRUE;
507+
507508
if (imethod->method->string_ctor)
508509
imethod->rtype = m_class_get_byval_arg (mono_defaults.string_class);
509510
else
@@ -3916,6 +3917,7 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
39163917
if (method_entry_ex)
39173918
THROW_EX (method_entry_ex, NULL);
39183919
EXCEPTION_CHECKPOINT;
3920+
CHECK_RESUME_STATE (context);
39193921
}
39203922

39213923
if (!clause_args) {
@@ -4372,6 +4374,7 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
43724374
if (call_ex)
43734375
THROW_EX (call_ex, NULL);
43744376
EXCEPTION_CHECKPOINT;
4377+
CHECK_RESUME_STATE (context);
43754378
}
43764379

43774380
context->stack_pointer = (guchar*)frame->stack + cmethod->alloca_size;

src/mono/mono/mini/interp/transform.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,8 +2691,6 @@ static MonoMethod*
26912691
interp_transform_internal_calls (MonoMethod *method, MonoMethod *target_method, MonoMethodSignature *csignature, gboolean is_virtual)
26922692
{
26932693
if (((method->wrapper_type == MONO_WRAPPER_NONE) || (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)) && target_method != NULL) {
2694-
if (target_method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2695-
target_method = mono_marshal_get_native_wrapper (target_method, FALSE, FALSE);
26962694
if (!is_virtual && target_method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
26972695
target_method = mono_marshal_get_synchronized_wrapper (target_method);
26982696

@@ -3748,9 +3746,19 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
37483746
}
37493747
}
37503748

3751-
if (op == -1)
3749+
if (op == -1) {
37523750
target_method = interp_transform_internal_calls (method, target_method, csignature, is_virtual);
37533751

3752+
if (((method->wrapper_type == MONO_WRAPPER_NONE) || (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)) && target_method != NULL) {
3753+
if (target_method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3754+
// Avoid calling mono_marshal_get_native_wrapper () too early, it might call managed callbacks.
3755+
csignature = mono_metadata_signature_dup_mempool (td->mempool, csignature);
3756+
csignature->pinvoke = FALSE;
3757+
native = FALSE;
3758+
}
3759+
}
3760+
}
3761+
37543762
if (csignature->call_convention == MONO_CALL_VARARG)
37553763
csignature = mono_method_get_signature_checked (target_method, image, token, generic_context, error);
37563764

@@ -9898,16 +9906,20 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context, Mon
98989906
generic_context = &generic_container->context;
98999907
}
99009908

9901-
if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
9909+
if ((method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) ||
9910+
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
99029911
MonoMethod *nm = NULL;
99039912
if (imethod->transformed) {
99049913
MONO_PROFILER_RAISE (jit_done, (method, imethod->jinfo));
99059914
return;
99069915
}
99079916

99089917
/* assumes all internal calls with an array this are built in... */
9909-
if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL && (! mono_method_signature_internal (method)->hasthis || m_class_get_rank (method->klass) == 0)) {
9918+
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL && (! mono_method_signature_internal (method)->hasthis || m_class_get_rank (method->klass) == 0)) ||
9919+
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
99109920
nm = mono_marshal_get_native_wrapper (method, FALSE, FALSE);
9921+
if (context->has_resume_state)
9922+
return;
99119923
} else {
99129924
const char *name = method->name;
99139925
if (m_class_get_parent (method->klass) == mono_defaults.multicastdelegate_class) {

0 commit comments

Comments
 (0)