[runtime] Implement mono_method_signature and related signature methods for CoreCLR. (#11465)
This commit is contained in:
Родитель
625d8cd090
Коммит
63db14ec7d
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче