Skip to content

Commit 209d681

Browse files
authored
[mono][aot] Generate 'native-indirect' wrappers in full-aot mode. (#85923)
Fixes #80853.
1 parent 7c1c9d8 commit 209d681

File tree

5 files changed

+26
-7
lines changed

5 files changed

+26
-7
lines changed

src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/FunctionPointerTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,17 @@ static int CallbackUnmanagedStdcall(int a, int b)
115115
return Callback(a, b);
116116
}
117117
}
118+
119+
[UnmanagedCallersOnly]
120+
public static int Increment (int i) {
121+
return i + 1;
122+
}
123+
124+
[Fact]
125+
public unsafe void CalliUnmanaged()
126+
{
127+
delegate* unmanaged<int, int> callbackProc = (delegate* unmanaged<int, int>)&Increment;
128+
Assert.Equal(6, callbackProc(5));
129+
}
118130
}
119131
}

src/mono/mono/metadata/marshal.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,17 +3867,11 @@ mono_marshal_get_native_func_wrapper_indirect (MonoClass *caller_class, MonoMeth
38673867
if ((res = mono_marshal_find_in_cache (cache, sig)))
38683868
return res;
38693869

3870-
#if 0
3871-
fprintf (stderr, "generating wrapper for signature %s\n", mono_signature_full_name (sig));
3872-
#endif
3873-
3874-
/* FIXME: better wrapper name */
3875-
char * name = g_strdup_printf ("wrapper_native_indirect_%p", sig);
3870+
char *name = mono_signature_to_name (sig, "wrapper_native_indirect");
38763871
MonoMethodBuilder *mb = mono_mb_new (caller_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
38773872
mb->method->save_lmf = 1;
38783873

38793874
WrapperInfo *info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NATIVE_FUNC_INDIRECT);
3880-
//info->d.managed_to_native.method = NULL;
38813875
info->d.native_func.klass = caller_class;
38823876
info->d.native_func.sig = sig;
38833877

@@ -3889,6 +3883,7 @@ mono_marshal_get_native_func_wrapper_indirect (MonoClass *caller_class, MonoMeth
38893883
mono_marshal_emit_native_wrapper (image, mb, sig, piinfo, mspecs, /*func*/NULL, flags);
38903884
g_free (mspecs);
38913885

3886+
/* Add an extra argument which the caller will use to pass in the ftnptr to call */
38923887
MonoMethodSignature *csig = mono_metadata_signature_dup_add_this (image, sig, mono_defaults.int_class);
38933888
csig->pinvoke = 0;
38943889

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9659,6 +9659,13 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
96599659
add_gsharedvt_wrappers (acfg, mono_method_signature_internal (cfg->method), FALSE, TRUE, TRUE);
96609660
}
96619661

9662+
for (GSList *l = cfg->pinvoke_calli_signatures; l; l = l->next) {
9663+
MonoMethodSignature *sig = mono_metadata_signature_dup ((MonoMethodSignature*)l->data);
9664+
9665+
MonoMethod *wrapper = mono_marshal_get_native_func_wrapper_indirect (cfg->method->klass, sig, TRUE);
9666+
add_extra_method (acfg, wrapper);
9667+
}
9668+
96629669
if (cfg->llvm_only)
96639670
acfg->stats.llvm_count ++;
96649671

src/mono/mono/mini/method-to-ir.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7471,6 +7471,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
74717471
#if 0
74727472
fprintf (stderr, "generating wrapper for calli in method %s with wrapper type %s\n", method->name, mono_wrapper_type_to_str (method->wrapper_type));
74737473
#endif
7474+
7475+
if (cfg->compile_aot)
7476+
cfg->pinvoke_calli_signatures = g_slist_prepend_mempool (cfg->mempool, cfg->pinvoke_calli_signatures, fsig);
7477+
74747478
/* Call the wrapper that will do the GC transition instead */
74757479
MonoMethod *wrapper = mono_marshal_get_native_func_wrapper_indirect (method->klass, fsig, cfg->compile_aot);
74767480

src/mono/mono/mini/mini.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,7 @@ typedef struct {
16291629

16301630
GSList *signatures;
16311631
GSList *interp_in_signatures;
1632+
GSList *pinvoke_calli_signatures;
16321633

16331634
/* GC Maps */
16341635

0 commit comments

Comments
 (0)