Skip to content
1 change: 1 addition & 0 deletions src/mono/mono/mini/interp/interp-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ struct InterpMethod {
MonoProfilerCallInstrumentationFlags prof_flags;
InterpMethodCodeType code_type;
int ref_slot_offset; // GC visible pointer slot
int swift_error_offset; // swift error struct
MonoBitSet *ref_slots;
#ifdef ENABLE_EXPERIMENT_TIERED
MiniTieredCounter tiered_counter;
Expand Down
35 changes: 33 additions & 2 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3176,6 +3176,21 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
/* Copy the args saved in the trampoline to the frame stack */
gpointer retp = mono_arch_get_native_call_context_args (ccontext, &frame, sig, call_info);

#ifdef MONO_ARCH_HAVE_SWIFTCALL
int swift_error_arg_index = -1;
gpointer swift_error_data;
gpointer* swift_error_pointer;
if (mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL)) {
swift_error_data = mono_arch_get_swift_error (ccontext, sig, &swift_error_arg_index);

int swift_error_offset = frame.imethod->swift_error_offset;
if (swift_error_offset >= 0) {
swift_error_pointer = (gpointer*)((guchar*)frame.stack + swift_error_offset);
*swift_error_pointer = *(gpointer*)swift_error_data;
}
}
#endif

/* Allocate storage for value types */
stackval *newsp = sp;
/* FIXME we should reuse computation on imethod for this */
Expand All @@ -3195,6 +3210,10 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
} else {
size = MINT_STACK_SLOT_SIZE;
}
#ifdef MONO_ARCH_HAVE_SWIFTCALL
if (swift_error_arg_index >= 0 && swift_error_arg_index == i)
newsp->data.p = swift_error_pointer;
#endif
newsp = STACK_ADD_BYTES (newsp, size);
}
newsp = (stackval*)ALIGN_TO (newsp, MINT_STACK_ALIGNMENT);
Expand All @@ -3205,6 +3224,11 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
mono_interp_exec_method (&frame, context, NULL);
MONO_EXIT_GC_UNSAFE;

#ifdef MONO_ARCH_HAVE_SWIFTCALL
if (swift_error_arg_index >= 0)
*(gpointer*)swift_error_data = *(gpointer*)swift_error_pointer;
#endif

context->stack_pointer = (guchar*)sp;
g_assert (!context->has_resume_state);

Expand Down Expand Up @@ -3467,9 +3491,16 @@ interp_create_method_pointer (MonoMethod *method, gboolean compile, MonoError *e
* separate temp register. We should update the wrappers for this
* if we really care about those architectures (arm).
*/
MonoMethod *wrapper = mini_get_interp_in_wrapper (sig);

entry_wrapper = mono_jit_compile_method_jit_only (wrapper, error);
MonoMethod *wrapper = NULL;
#ifdef MONO_ARCH_HAVE_SWIFTCALL
/* Methods with Swift cconv should go to trampoline */
if (!mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL))
#endif
{
wrapper = mini_get_interp_in_wrapper (sig);
entry_wrapper = mono_jit_compile_method_jit_only (wrapper, error);
}
#endif
if (!entry_wrapper) {
#ifndef MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE
Expand Down
26 changes: 26 additions & 0 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -4360,6 +4360,13 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet
td->renamable_vars_capacity = target_vars_capacity;
offset = 0;

#ifdef MONO_ARCH_HAVE_SWIFTCALL
int swift_error_index = -1;
imethod->swift_error_offset = -1;
MonoClass *swift_error = mono_class_try_get_swift_error_class ();
MonoClass *swift_error_ptr = mono_class_create_ptr (m_class_get_this_arg (swift_error));
#endif

/*
* We will load arguments as if they are locals. Unlike normal locals, every argument
* is stored in a stackval sized slot and valuetypes have special semantics since we
Expand All @@ -4384,6 +4391,15 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet
td->vars [i].offset = offset;
interp_mark_ref_slots_for_var (td, i);
offset += size;

#ifdef MONO_ARCH_HAVE_SWIFTCALL
if (swift_error_index < 0 && mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL)) {
MonoClass *klass = mono_class_from_mono_type_internal (type);
if (klass == swift_error_ptr)
swift_error_index = i;
}
#endif

}
offset = ALIGN_TO (offset, MINT_STACK_ALIGNMENT);

Expand Down Expand Up @@ -4417,6 +4433,16 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet
td->il_locals_size = offset - td->il_locals_offset;
td->total_locals_size = offset;

#ifdef MONO_ARCH_HAVE_SWIFTCALL
if (mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL) && swift_error_index >= 0) {
MonoType* type = mono_method_signature_internal (td->method)->params [swift_error_index - sig->hasthis];
int var = interp_create_var_explicit (td, type, sizeof(gpointer));
td->vars [var].global = TRUE;
interp_alloc_global_var_offset (td, var);
imethod->swift_error_offset = td->vars [var].offset;
}
#endif

imethod->clause_data_offsets = (guint32*)g_malloc (header->num_clauses * sizeof (guint32));
td->clause_vars = (int*)mono_mempool_alloc (td->mempool, sizeof (int) * header->num_clauses);
for (guint i = 0; i < header->num_clauses; i++) {
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/mini-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
storage = alloca (temp_size);
else
storage = arg_get_storage (ccontext, ainfo);
memset (ccontext, 0, sizeof (CallContext)); // FIXME

interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, -1, storage);
if (temp_size)
arg_set_val (ccontext, ainfo, storage);
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -2081,7 +2081,7 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
storage = alloca (temp_size);
else
storage = arg_get_storage (ccontext, ainfo);
memset (ccontext, 0, sizeof (CallContext)); // FIXME

interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, -1, storage);
if (temp_size)
arg_set_val (ccontext, ainfo, storage);
Expand Down
12 changes: 12 additions & 0 deletions src/mono/mono/mini/tramp-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
for (i = 0; i < FLOAT_PARAM_REGS; i++)
amd64_sse_movsd_membase_reg (code, AMD64_RSP, ctx_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double), i);

#ifdef MONO_ARCH_HAVE_SWIFTCALL
/* set context registers to CallContext */
for (i = 0; i < CTX_REGS; i++)
amd64_mov_membase_reg (code, AMD64_RSP, ctx_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + CTX_REGS_OFFSET) * sizeof (target_mgreg_t), i + CTX_REGS_OFFSET, sizeof (target_mgreg_t));
#endif

/* set the stack pointer to the value at call site */
amd64_mov_reg_reg (code, AMD64_R11, AMD64_RBP, sizeof (target_mgreg_t));
amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, 2 * sizeof (target_mgreg_t));
Expand All @@ -1283,6 +1289,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
for (i = 0; i < FLOAT_RETURN_REGS; i++)
amd64_sse_movsd_reg_membase (code, i, AMD64_RSP, ctx_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double));

#ifdef MONO_ARCH_HAVE_SWIFTCALL
/* set the context registers from CallContext */
for (i = 0; i < CTX_REGS; i++)
amd64_mov_reg_membase (code, i + CTX_REGS_OFFSET, AMD64_RSP, ctx_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + CTX_REGS_OFFSET) * sizeof (target_mgreg_t), sizeof (target_mgreg_t));
#endif

/* reset stack and return */
#if TARGET_WIN32
amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, 0);
Expand Down
12 changes: 12 additions & 0 deletions src/mono/mono/mini/tramp-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
for (i = 0; i < FP_PARAM_REGS; i++)
arm_strfpx (code, i, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double));

#ifdef MONO_ARCH_HAVE_SWIFTCALL
/* set context registers to CallContext */
for (i = 0; i < CTX_REGS; i++)
arm_strx (code, i + CTX_REGS_OFFSET, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + PARAM_REGS + 1) * sizeof (host_mgreg_t));
#endif

/* set the stack pointer to the value at call site */
arm_addx_imm (code, ARMREG_R0, ARMREG_FP, framesize);
arm_strp (code, ARMREG_R0, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, stack));
Expand All @@ -863,6 +869,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
for (i = 0; i < FP_PARAM_REGS; i++)
arm_ldrfpx (code, i, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double));

#ifdef MONO_ARCH_HAVE_SWIFTCALL
/* set the context registers from CallContext */
for (i = 0; i < CTX_REGS; i++)
arm_ldrx (code, i + CTX_REGS_OFFSET, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + PARAM_REGS + 1) * sizeof (host_mgreg_t));
#endif

/* reset stack and return */
arm_ldpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0);
arm_addx_imm (code, ARMREG_SP, ARMREG_SP, framesize);
Expand Down
3 changes: 0 additions & 3 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2145,9 +2145,6 @@
<ExcludeList Include = "$(XUnitTestBinBase)/JIT/Directed/Arrays/nintindexoutofrange/**">
<Issue>https://github.com/dotnet/runtime/issues/71656</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/Swift/SwiftErrorHandling/**">
<Issue>Reverse P/Invokes not supported yet</Issue>
</ExcludeList>
<!-- End interpreter issues -->
</ItemGroup>

Expand Down