Skip to content

Commit

Permalink
[mono][aot] Generate 'native-indirect' wrappers in full-aot mode. (#8…
Browse files Browse the repository at this point in the history
…5923)

Fixes #80853.
  • Loading branch information
vargaz authored May 9, 2023
1 parent 7c1c9d8 commit 209d681
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,17 @@ static int CallbackUnmanagedStdcall(int a, int b)
return Callback(a, b);
}
}

[UnmanagedCallersOnly]
public static int Increment (int i) {
return i + 1;
}

[Fact]
public unsafe void CalliUnmanaged()
{
delegate* unmanaged<int, int> callbackProc = (delegate* unmanaged<int, int>)&Increment;
Assert.Equal(6, callbackProc(5));
}
}
}
9 changes: 2 additions & 7 deletions src/mono/mono/metadata/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -3867,17 +3867,11 @@ mono_marshal_get_native_func_wrapper_indirect (MonoClass *caller_class, MonoMeth
if ((res = mono_marshal_find_in_cache (cache, sig)))
return res;

#if 0
fprintf (stderr, "generating wrapper for signature %s\n", mono_signature_full_name (sig));
#endif

/* FIXME: better wrapper name */
char * name = g_strdup_printf ("wrapper_native_indirect_%p", sig);
char *name = mono_signature_to_name (sig, "wrapper_native_indirect");
MonoMethodBuilder *mb = mono_mb_new (caller_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
mb->method->save_lmf = 1;

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

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

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

Expand Down
7 changes: 7 additions & 0 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -9659,6 +9659,13 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
add_gsharedvt_wrappers (acfg, mono_method_signature_internal (cfg->method), FALSE, TRUE, TRUE);
}

for (GSList *l = cfg->pinvoke_calli_signatures; l; l = l->next) {
MonoMethodSignature *sig = mono_metadata_signature_dup ((MonoMethodSignature*)l->data);

MonoMethod *wrapper = mono_marshal_get_native_func_wrapper_indirect (cfg->method->klass, sig, TRUE);
add_extra_method (acfg, wrapper);
}

if (cfg->llvm_only)
acfg->stats.llvm_count ++;

Expand Down
4 changes: 4 additions & 0 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -7471,6 +7471,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
#if 0
fprintf (stderr, "generating wrapper for calli in method %s with wrapper type %s\n", method->name, mono_wrapper_type_to_str (method->wrapper_type));
#endif

if (cfg->compile_aot)
cfg->pinvoke_calli_signatures = g_slist_prepend_mempool (cfg->mempool, cfg->pinvoke_calli_signatures, fsig);

/* Call the wrapper that will do the GC transition instead */
MonoMethod *wrapper = mono_marshal_get_native_func_wrapper_indirect (method->klass, fsig, cfg->compile_aot);

Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/mini.h
Original file line number Diff line number Diff line change
Expand Up @@ -1629,6 +1629,7 @@ typedef struct {

GSList *signatures;
GSList *interp_in_signatures;
GSList *pinvoke_calli_signatures;

/* GC Maps */

Expand Down

0 comments on commit 209d681

Please sign in to comment.