Skip to content

Commit 607ecff

Browse files
authored
[mono] Fix invoking string ctors on wasm in AOT mode. (#52505)
* [mono] Avoid passing a dummy string to string ctors from runtime invokes, pass NULL instead. The call will go to a wrapper method which will ignore the 'this' argument anyway. * [mono] Fix invoking string ctors on wasm in AOT mode.
1 parent 4bc509e commit 607ecff

File tree

3 files changed

+26
-31
lines changed

3 files changed

+26
-31
lines changed

src/mono/mono/metadata/marshal-ilgen.c

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,43 +1507,21 @@ emit_invoke_call (MonoMethodBuilder *mb, MonoMethod *method,
15071507
int loc_res,
15081508
gboolean virtual_, gboolean need_direct_wrapper)
15091509
{
1510-
static MonoString *string_dummy = NULL;
15111510
int i;
15121511
int *tmp_nullable_locals;
15131512
gboolean void_ret = FALSE;
15141513
gboolean string_ctor = method && method->string_ctor;
15151514

1516-
/* to make it work with our special string constructors */
1517-
if (!string_dummy) {
1518-
ERROR_DECL (error);
1519-
1520-
// FIXME Allow for static construction of MonoString.
1521-
1522-
SETUP_ICALL_FUNCTION;
1523-
SETUP_ICALL_FRAME;
1524-
1525-
MONO_GC_REGISTER_ROOT_SINGLE (string_dummy, MONO_ROOT_SOURCE_MARSHAL, NULL, "Marshal Dummy String");
1526-
1527-
MonoStringHandle string_dummy_handle = mono_string_new_utf8_len ("dummy", 5, error);
1528-
string_dummy = MONO_HANDLE_RAW (string_dummy_handle);
1529-
mono_error_assert_ok (error);
1530-
1531-
CLEAR_ICALL_FRAME;
1532-
}
1533-
15341515
if (virtual_) {
15351516
g_assert (sig->hasthis);
15361517
g_assert (method->flags & METHOD_ATTRIBUTE_VIRTUAL);
15371518
}
15381519

15391520
if (sig->hasthis) {
15401521
if (string_ctor) {
1541-
if (mono_gc_is_moving ()) {
1542-
mono_mb_emit_ptr (mb, &string_dummy);
1543-
mono_mb_emit_byte (mb, CEE_LDIND_REF);
1544-
} else {
1545-
mono_mb_emit_ptr (mb, string_dummy);
1546-
}
1522+
/* This will call the code emitted by mono_marshal_get_native_wrapper () which ignores it */
1523+
mono_mb_emit_icon (mb, 0);
1524+
mono_mb_emit_byte (mb, CEE_CONV_I);
15471525
} else {
15481526
mono_mb_emit_ldarg (mb, 0);
15491527
}

src/mono/mono/mini/aot-compiler.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4731,6 +4731,20 @@ add_wrappers (MonoAotCompile *acfg)
47314731
/* FIXME: locking - this is "safe" as full-AOT threads don't mutate the icall data */
47324732
for (int i = 0; i < MONO_JIT_ICALL_count; ++i)
47334733
add_jit_icall_wrapper (acfg, mono_find_jit_icall_info ((MonoJitICallId)i));
4734+
4735+
if (acfg->aot_opts.llvm_only) {
4736+
/* String ctors are called directly on llvmonly */
4737+
for (int i = 0; i < rows; ++i) {
4738+
ERROR_DECL (error);
4739+
4740+
token = MONO_TOKEN_METHOD_DEF | (i + 1);
4741+
method = mono_get_method_checked (acfg->image, token, NULL, NULL, error);
4742+
if (method && method->string_ctor) {
4743+
MonoMethod *w = get_runtime_invoke (acfg, method, FALSE);
4744+
add_method (acfg, w);
4745+
}
4746+
}
4747+
}
47344748
}
47354749

47364750
/*

src/mono/mono/mini/mini-runtime.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,10 +2921,7 @@ create_runtime_invoke_info (MonoMethod *method, gpointer compiled_method, gboole
29212921
info = g_new0 (RuntimeInvokeInfo, 1);
29222922
info->compiled_method = compiled_method;
29232923
info->use_interp = use_interp;
2924-
if (mono_llvm_only && method->string_ctor)
2925-
info->sig = mono_marshal_get_string_ctor_signature (method);
2926-
else
2927-
info->sig = mono_method_signature_internal (method);
2924+
info->sig = mono_method_signature_internal (method);
29282925

29292926
invoke = mono_marshal_get_runtime_invoke (method, FALSE);
29302927
(void)invoke;
@@ -3016,7 +3013,13 @@ create_runtime_invoke_info (MonoMethod *method, gpointer compiled_method, gboole
30163013
}
30173014

30183015
if (!info->dyn_call_info) {
3019-
if (mono_llvm_only) {
3016+
/*
3017+
* Can't use the normal llvmonly code for string ctors since the gsharedvt out wrapper passes
3018+
* an extra arg, which the string ctor methods don't have, which causes signature mismatches
3019+
* on wasm. Instead, call string ctors normally using a direct runtime invoke wrapper
3020+
* which is AOTed for each ctor.
3021+
*/
3022+
if (mono_llvm_only && !method->string_ctor) {
30203023
#ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
30213024
g_assert_not_reached ();
30223025
#endif
@@ -3331,7 +3334,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
33313334
if (info->use_interp) {
33323335
result = mini_get_interp_callbacks ()->runtime_invoke (method, obj, params, exc, error);
33333336
return_val_if_nok (error, NULL);
3334-
} else if (mono_llvm_only) {
3337+
} else if (mono_llvm_only && !method->string_ctor) {
33353338
result = mono_llvmonly_runtime_invoke (method, info, obj, params, exc, error);
33363339
if (!is_ok (error))
33373340
return NULL;

0 commit comments

Comments
 (0)