[runtime] Implement mono_method_signature and related signature methods for CoreCLR. (#11465)

This commit is contained in:
Rolf Bjarne Kvinge 2021-05-06 16:19:59 +02:00 коммит произвёл GitHub
Родитель 625d8cd090
Коммит 63db14ec7d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 146 добавлений и 4 удалений

Просмотреть файл

@ -255,6 +255,8 @@ mono_object_isinst (MonoObject * obj, MonoClass * klass)
return rv ? obj : NULL;
}
// Return value: NULL, or a retained MonoObject* that must be freed with xamarin_mono_object_release.
// Returns NULL in case of exception.
MonoObject *
mono_runtime_invoke (MonoMethod * method, void * obj, void ** params, MonoObject ** exc)
{
@ -274,4 +276,59 @@ mono_runtime_invoke (MonoMethod * method, void * obj, void ** params, MonoObject
return rv;
}
MonoMethodSignature *
mono_method_signature (MonoMethod* method)
{
MonoMethodSignature *rv = xamarin_bridge_method_get_signature (method);
LOG_CORECLR (stderr, "xamarin_bridge_mono_method_signature (%p) => %p\n", method, rv);
return rv;
}
MonoType *
mono_signature_get_params (MonoMethodSignature* sig, void ** iter)
{
int* p = (int *) iter;
if (*p >= sig->parameter_count) {
LOG_CORECLR (stderr, "%s (%p, %p => %i) => DONE\n", __func__, sig, iter, *p);
return NULL;
}
MonoObject *rv = sig->parameters [*p];
xamarin_mono_object_retain (rv);
LOG_CORECLR (stderr, "%s (%p, %p => %i) => %p NEXT\n", __func__, sig, iter, *p, rv->gchandle);
*p = *p + 1;
return rv;
}
MonoType *
mono_signature_get_return_type (MonoMethodSignature* sig)
{
MonoType *rv = sig->return_type;
xamarin_mono_object_retain (rv);
LOG_CORECLR (stderr, "%s (%p) => %p\n", __func__, sig, rv);
return rv;
}
void
xamarin_bridge_free_mono_signature (MonoMethodSignature **psig)
{
MonoMethodSignature *sig = *psig;
for (int i = 0; i < sig->parameter_count; i++) {
xamarin_mono_object_release (&sig->parameters [i]);
}
xamarin_mono_object_release (&sig->return_type);
mono_free (sig);
*psig = NULL;
}
#endif // CORECLR_RUNTIME

Просмотреть файл

@ -351,6 +351,14 @@
OnlyCoreCLR = true,
},
new XDelegate ("MonoMethodSignature *", "IntPtr", "xamarin_bridge_method_get_signature",
"MonoObject *", "MonoObject *", "method"
) {
WrappedManagedFunction = "GetMethodSignature",
OnlyDynamicUsage = false,
OnlyCoreCLR = true,
},
new XDelegate ("MonoObject*", "IntPtr", "xamarin_bridge_get_monoobject",
"GCHandle", "IntPtr", "gchandle"
) {

Просмотреть файл

@ -315,7 +315,9 @@
new Export ("MonoMethodSignature *", "mono_method_signature",
"MonoMethod *", "method"
),
) {
HasCoreCLRBridgeFunction = true,
},
new Export ("MonoClass *", "mono_method_get_class",
"MonoMethod *", "method"
@ -391,7 +393,9 @@
new Export ("MonoType *", "mono_signature_get_params",
"MonoMethodSignature *", "sig",
"void **", "iter"
),
) {
HasCoreCLRBridgeFunction = true,
},
new Export ("mono_bool", "mono_type_is_byref",
"MonoType *", "type"
@ -399,7 +403,9 @@
new Export ("MonoType *", "mono_signature_get_return_type",
"MonoMethodSignature *", "sig"
),
) {
HasCoreCLRBridgeFunction = true,
},
new Export ("int", "mono_type_get_type",
"MonoType *", "type"

Просмотреть файл

@ -96,7 +96,12 @@ typedef struct _MonoObject MonoMethod;
typedef struct _MonoMethod MonoMethod;
#endif
typedef struct _MonoMethodSignature MonoMethodSignature;
#if defined (CORECLR_RUNTIME)
// In Mono, MonoType is not related to MonoObject at all, but for the CoreCLR bridge we use the same struct representation for both types.
typedef struct _MonoObject MonoType;
#else
typedef struct _MonoType MonoType;
#endif
/* metadata/class.h */
typedef struct MonoVTable MonoVTable;

Просмотреть файл

@ -284,6 +284,13 @@ xamarin_install_nsautoreleasepool_hooks ()
mono_profiler_install_thread (thread_start, thread_end);
}
void
xamarin_bridge_free_mono_signature (MonoMethodSignature **psig)
{
// nothing to free here
*psig = NULL;
}
#if DOTNET
bool

Просмотреть файл

@ -266,6 +266,8 @@ xamarin_get_parameter_type (MonoMethod *managed_method, int index)
p = mono_signature_get_params (msig, &iter);
}
xamarin_bridge_free_mono_signature (&msig);
return p;
}

Просмотреть файл

@ -138,7 +138,7 @@ xamarin_invoke_trampoline (enum TrampolineType type, id self, SEL sel, iterator_
MonoObject *mthis = NULL;
MethodDescription *desc = NULL;
MonoMethod *method;
MonoMethodSignature *msig;
MonoMethodSignature *msig = NULL;
MonoReflectionMethod *reflection_method = NULL;
int semantic;
bool isCategoryInstance;
@ -730,6 +730,8 @@ exception_handling:
writeback = NULL;
}
xamarin_bridge_free_mono_signature (&msig);
MONO_THREAD_DETACH; // COOP: This will switch to GC_SAFE
if (exception_gchandle != INVALID_GCHANDLE) {

Просмотреть файл

@ -29,6 +29,14 @@ struct _MonoObject {
GCHandle gchandle;
};
// This struct must be kept in sync with the MonoMethodSignature struct in Runtime.CoreCLR.cs
struct _MonoMethodSignature {
MonoObject *method;
int parameter_count;
MonoObject *return_type;
MonoObject *parameters[];
};
#ifdef __cplusplus
} /* extern "C" */
#endif

Просмотреть файл

@ -209,6 +209,7 @@ void* xamarin_pinvoke_override (const char *libraryName, const char *entrypoin
void xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle);
void xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle);
MonoMethod * xamarin_bridge_get_mono_method (MonoReflectionMethod *method);
void xamarin_bridge_free_mono_signature (MonoMethodSignature **signature);
bool xamarin_register_monoassembly (MonoAssembly *assembly, GCHandle *exception_gchandle);
void xamarin_install_nsautoreleasepool_hooks ();

Просмотреть файл

@ -29,6 +29,15 @@ namespace ObjCRuntime {
public IntPtr GCHandle;
}
// This struct must be kept in sync with the _MonoMethodSignature struct in coreclr-bridge.h
[StructLayout (LayoutKind.Sequential)]
unsafe struct MonoMethodSignature {
public MonoObject* Method;
public int ParameterCount;
public MonoObject* ReturnType;
public MonoObject* Parameters;
}
// Comment out the attribute to get all printfs
[System.Diagnostics.Conditional ("UNDEFINED")]
static void log_coreclr (string message)
@ -190,6 +199,40 @@ namespace ObjCRuntime {
return rv;
}
static unsafe IntPtr GetMethodSignature (MonoObject* methodobj)
{
var method = (MethodBase) GetMonoObjectTarget (methodobj);
var parameters = method.GetParameters ();
var parameterCount = parameters.Length;
var rv = Marshal.AllocHGlobal (sizeof (MonoMethodSignature) + sizeof (MonoObjectPtr) * parameterCount);
MonoMethodSignature* signature = (MonoMethodSignature *) rv;
signature->Method = methodobj;
xamarin_mono_object_retain (methodobj);
signature->ParameterCount = parameterCount;
signature->ReturnType = (MonoObject *) GetMonoObject (GetMethodReturnType (method));
MonoObject** mparams = &signature->Parameters;
for (var i = 0; i < parameterCount; i++) {
var p = parameters [i];
mparams [i] = (MonoObject *) GetMonoObject (p.ParameterType);
}
return rv;
}
static Type GetMethodReturnType (MethodBase method)
{
if (method is MethodInfo minfo)
return minfo.ReturnType;
// Constructors return the instance that was created, which is the declaring type of the constructor.
if (method is ConstructorInfo cinfo)
return cinfo.DeclaringType;
return null;
}
static unsafe MonoObject* InvokeMethod (MonoObject* methodobj, MonoObject* instanceobj, IntPtr native_parameters)
{
var method = (MethodBase) GetMonoObjectTarget (methodobj);
@ -366,6 +409,9 @@ namespace ObjCRuntime {
[DllImport ("__Internal")]
static extern void xamarin_mono_object_retain (ref IntPtr mono_object);
[DllImport ("__Internal")]
unsafe static extern void xamarin_mono_object_retain (MonoObject* mono_object);
}
}