Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/mono/mono/metadata/external-only.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "assembly-internals.h"
#include "external-only.h"
#include <mono/metadata/threads.h>
#include <mono/metadata/mono-private-unstable.h>
#include "threads-types.h"
#include "jit-info.h"

Expand Down Expand Up @@ -696,3 +697,25 @@ mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot)
{
return mono_mem_manager_mp_contains_addr (mono_mem_manager_get_ambient (), vtable_slot);
}

/**
* mono_method_get_unmanaged_callers_only_ftnptr:
* \param method method to generate a thunk for.
* \param error set on error
*
* Returns a function pointer for calling the given UnmanagedCallersOnly method from native code.
* The function pointer will use the calling convention specified on the UnmanagedCallersOnly
* attribute (or the default platform calling convention if omitted).
*
* Unlike \c mono_method_get_unmanaged_thunk, minimal marshaling is done to the method parameters in
* the wrapper. See
* https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute?view=net-6.0
* The method must be static and only use blittable argument types. There is no exception out-argument.
*
*
*/
void*
mono_method_get_unmanaged_callers_only_ftnptr (MonoMethod *method, MonoError *error)
{
MONO_EXTERNAL_ONLY_GC_UNSAFE (gpointer, mono_method_get_unmanaged_wrapper_ftnptr_internal (method, TRUE, error));
}
8 changes: 8 additions & 0 deletions src/mono/mono/metadata/icall.c
Original file line number Diff line number Diff line change
Expand Up @@ -6045,11 +6045,19 @@ ves_icall_System_Environment_get_TickCount64 (void)

gpointer
ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method, MonoError *error)
{
return mono_method_get_unmanaged_wrapper_ftnptr_internal (method, FALSE, error);
}

void*
mono_method_get_unmanaged_wrapper_ftnptr_internal (MonoMethod *method, gboolean only_unmanaged_callers_only, MonoError *error)
{
/* WISH: we should do this in managed */
if (G_UNLIKELY (mono_method_has_unmanaged_callers_only_attribute (method))) {
method = mono_marshal_get_managed_wrapper (method, NULL, (MonoGCHandle)0, error);
return_val_if_nok (error, NULL);
} else {
g_assert (!only_unmanaged_callers_only);
}
return mono_get_runtime_callbacks ()->get_ftnptr (method, error);
}
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/metadata/object-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -2137,4 +2137,7 @@ int
mono_string_instance_is_interned (MonoString *str);
#endif

gpointer
mono_method_get_unmanaged_wrapper_ftnptr_internal (MonoMethod *method, gboolean only_unmanaged_callers_only, MonoError *error);

#endif /* __MONO_OBJECT_INTERNALS_H__ */
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ MONO_API_FUNCTION(MONO_RT_EXTERNAL_ONLY MonoAssemblyLoadContextGCHandle, mono_al
MONO_API_FUNCTION(void, mono_register_bundled_satellite_assemblies, (const MonoBundledSatelliteAssembly **assemblies))

MONO_API_FUNCTION(MonoBundledSatelliteAssembly *, mono_create_new_bundled_satellite_assembly, (const char *name, const char *culture, const unsigned char *data, unsigned int size))


MONO_API_FUNCTION(MONO_RT_EXTERNAL_ONLY void*, mono_method_get_unmanaged_callers_only_ftnptr, (MonoMethod *method, MonoError *error))