Skip to content

Commit 4185f94

Browse files
authoredMay 17, 2024··
[Mono] added simple reverse pinvoke support to interpreter (#102185)
1 parent 202b1be commit 4185f94

File tree

8 files changed

+86
-7
lines changed

8 files changed

+86
-7
lines changed
 

‎src/mono/mono/mini/interp/interp-internals.h

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ struct InterpMethod {
155155
MonoProfilerCallInstrumentationFlags prof_flags;
156156
InterpMethodCodeType code_type;
157157
int ref_slot_offset; // GC visible pointer slot
158+
int swift_error_offset; // swift error struct
158159
MonoBitSet *ref_slots;
159160
#ifdef ENABLE_EXPERIMENT_TIERED
160161
MiniTieredCounter tiered_counter;

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

+33-2
Original file line numberDiff line numberDiff line change
@@ -3176,6 +3176,21 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
31763176
/* Copy the args saved in the trampoline to the frame stack */
31773177
gpointer retp = mono_arch_get_native_call_context_args (ccontext, &frame, sig, call_info);
31783178

3179+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
3180+
int swift_error_arg_index = -1;
3181+
gpointer swift_error_data;
3182+
gpointer* swift_error_pointer;
3183+
if (mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL)) {
3184+
swift_error_data = mono_arch_get_swift_error (ccontext, sig, &swift_error_arg_index);
3185+
3186+
int swift_error_offset = frame.imethod->swift_error_offset;
3187+
if (swift_error_offset >= 0) {
3188+
swift_error_pointer = (gpointer*)((guchar*)frame.stack + swift_error_offset);
3189+
*swift_error_pointer = *(gpointer*)swift_error_data;
3190+
}
3191+
}
3192+
#endif
3193+
31793194
/* Allocate storage for value types */
31803195
stackval *newsp = sp;
31813196
/* FIXME we should reuse computation on imethod for this */
@@ -3195,6 +3210,10 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
31953210
} else {
31963211
size = MINT_STACK_SLOT_SIZE;
31973212
}
3213+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
3214+
if (swift_error_arg_index >= 0 && swift_error_arg_index == i)
3215+
newsp->data.p = swift_error_pointer;
3216+
#endif
31983217
newsp = STACK_ADD_BYTES (newsp, size);
31993218
}
32003219
newsp = (stackval*)ALIGN_TO (newsp, MINT_STACK_ALIGNMENT);
@@ -3205,6 +3224,11 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
32053224
mono_interp_exec_method (&frame, context, NULL);
32063225
MONO_EXIT_GC_UNSAFE;
32073226

3227+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
3228+
if (swift_error_arg_index >= 0)
3229+
*(gpointer*)swift_error_data = *(gpointer*)swift_error_pointer;
3230+
#endif
3231+
32083232
context->stack_pointer = (guchar*)sp;
32093233
g_assert (!context->has_resume_state);
32103234

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

3472-
entry_wrapper = mono_jit_compile_method_jit_only (wrapper, error);
3495+
MonoMethod *wrapper = NULL;
3496+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
3497+
/* Methods with Swift cconv should go to trampoline */
3498+
if (!mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL))
3499+
#endif
3500+
{
3501+
wrapper = mini_get_interp_in_wrapper (sig);
3502+
entry_wrapper = mono_jit_compile_method_jit_only (wrapper, error);
3503+
}
34733504
#endif
34743505
if (!entry_wrapper) {
34753506
#ifndef MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE

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

+26
Original file line numberDiff line numberDiff line change
@@ -4360,6 +4360,13 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet
43604360
td->renamable_vars_capacity = target_vars_capacity;
43614361
offset = 0;
43624362

4363+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
4364+
int swift_error_index = -1;
4365+
imethod->swift_error_offset = -1;
4366+
MonoClass *swift_error = mono_class_try_get_swift_error_class ();
4367+
MonoClass *swift_error_ptr = mono_class_create_ptr (m_class_get_this_arg (swift_error));
4368+
#endif
4369+
43634370
/*
43644371
* We will load arguments as if they are locals. Unlike normal locals, every argument
43654372
* is stored in a stackval sized slot and valuetypes have special semantics since we
@@ -4384,6 +4391,15 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet
43844391
td->vars [i].offset = offset;
43854392
interp_mark_ref_slots_for_var (td, i);
43864393
offset += size;
4394+
4395+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
4396+
if (swift_error_index < 0 && mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL)) {
4397+
MonoClass *klass = mono_class_from_mono_type_internal (type);
4398+
if (klass == swift_error_ptr)
4399+
swift_error_index = i;
4400+
}
4401+
#endif
4402+
43874403
}
43884404
offset = ALIGN_TO (offset, MINT_STACK_ALIGNMENT);
43894405

@@ -4417,6 +4433,16 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet
44174433
td->il_locals_size = offset - td->il_locals_offset;
44184434
td->total_locals_size = offset;
44194435

4436+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
4437+
if (mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL) && swift_error_index >= 0) {
4438+
MonoType* type = mono_method_signature_internal (td->method)->params [swift_error_index - sig->hasthis];
4439+
int var = interp_create_var_explicit (td, type, sizeof(gpointer));
4440+
td->vars [var].global = TRUE;
4441+
interp_alloc_global_var_offset (td, var);
4442+
imethod->swift_error_offset = td->vars [var].offset;
4443+
}
4444+
#endif
4445+
44204446
imethod->clause_data_offsets = (guint32*)g_malloc (header->num_clauses * sizeof (guint32));
44214447
td->clause_vars = (int*)mono_mempool_alloc (td->mempool, sizeof (int) * header->num_clauses);
44224448
for (guint i = 0; i < header->num_clauses; i++) {

‎src/mono/mono/mini/mini-amd64.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
13241324
storage = alloca (temp_size);
13251325
else
13261326
storage = arg_get_storage (ccontext, ainfo);
1327-
memset (ccontext, 0, sizeof (CallContext)); // FIXME
1327+
13281328
interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, -1, storage);
13291329
if (temp_size)
13301330
arg_set_val (ccontext, ainfo, storage);

‎src/mono/mono/mini/mini-arm64.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2081,7 +2081,7 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
20812081
storage = alloca (temp_size);
20822082
else
20832083
storage = arg_get_storage (ccontext, ainfo);
2084-
memset (ccontext, 0, sizeof (CallContext)); // FIXME
2084+
20852085
interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, -1, storage);
20862086
if (temp_size)
20872087
arg_set_val (ccontext, ainfo, storage);

‎src/mono/mono/mini/tramp-amd64.c

+12
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
12631263
for (i = 0; i < FLOAT_PARAM_REGS; i++)
12641264
amd64_sse_movsd_membase_reg (code, AMD64_RSP, ctx_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double), i);
12651265

1266+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
1267+
/* set context registers to CallContext */
1268+
for (i = 0; i < CTX_REGS; i++)
1269+
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));
1270+
#endif
1271+
12661272
/* set the stack pointer to the value at call site */
12671273
amd64_mov_reg_reg (code, AMD64_R11, AMD64_RBP, sizeof (target_mgreg_t));
12681274
amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, 2 * sizeof (target_mgreg_t));
@@ -1283,6 +1289,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
12831289
for (i = 0; i < FLOAT_RETURN_REGS; i++)
12841290
amd64_sse_movsd_reg_membase (code, i, AMD64_RSP, ctx_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double));
12851291

1292+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
1293+
/* set the context registers from CallContext */
1294+
for (i = 0; i < CTX_REGS; i++)
1295+
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));
1296+
#endif
1297+
12861298
/* reset stack and return */
12871299
#if TARGET_WIN32
12881300
amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, 0);

‎src/mono/mono/mini/tramp-arm64.c

+12
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
846846
for (i = 0; i < FP_PARAM_REGS; i++)
847847
arm_strfpx (code, i, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double));
848848

849+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
850+
/* set context registers to CallContext */
851+
for (i = 0; i < CTX_REGS; i++)
852+
arm_strx (code, i + CTX_REGS_OFFSET, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + PARAM_REGS + 1) * sizeof (host_mgreg_t));
853+
#endif
854+
849855
/* set the stack pointer to the value at call site */
850856
arm_addx_imm (code, ARMREG_R0, ARMREG_FP, framesize);
851857
arm_strp (code, ARMREG_R0, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, stack));
@@ -863,6 +869,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
863869
for (i = 0; i < FP_PARAM_REGS; i++)
864870
arm_ldrfpx (code, i, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double));
865871

872+
#ifdef MONO_ARCH_HAVE_SWIFTCALL
873+
/* set the context registers from CallContext */
874+
for (i = 0; i < CTX_REGS; i++)
875+
arm_ldrx (code, i + CTX_REGS_OFFSET, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + PARAM_REGS + 1) * sizeof (host_mgreg_t));
876+
#endif
877+
866878
/* reset stack and return */
867879
arm_ldpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0);
868880
arm_addx_imm (code, ARMREG_SP, ARMREG_SP, framesize);

‎src/tests/issues.targets

-3
Original file line numberDiff line numberDiff line change
@@ -2145,9 +2145,6 @@
21452145
<ExcludeList Include = "$(XUnitTestBinBase)/JIT/Directed/Arrays/nintindexoutofrange/**">
21462146
<Issue>https://github.com/dotnet/runtime/issues/71656</Issue>
21472147
</ExcludeList>
2148-
<ExcludeList Include="$(XunitTestBinBase)/Interop/Swift/SwiftErrorHandling/**">
2149-
<Issue>Reverse P/Invokes not supported yet</Issue>
2150-
</ExcludeList>
21512148
<!-- End interpreter issues -->
21522149
</ItemGroup>
21532150

0 commit comments

Comments
 (0)
Please sign in to comment.