[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 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 *
|
MonoObject *
|
||||||
mono_runtime_invoke (MonoMethod * method, void * obj, void ** params, MonoObject ** exc)
|
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;
|
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
|
#endif // CORECLR_RUNTIME
|
||||||
|
|
|
@ -351,6 +351,14 @@
|
||||||
OnlyCoreCLR = true,
|
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",
|
new XDelegate ("MonoObject*", "IntPtr", "xamarin_bridge_get_monoobject",
|
||||||
"GCHandle", "IntPtr", "gchandle"
|
"GCHandle", "IntPtr", "gchandle"
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -315,7 +315,9 @@
|
||||||
|
|
||||||
new Export ("MonoMethodSignature *", "mono_method_signature",
|
new Export ("MonoMethodSignature *", "mono_method_signature",
|
||||||
"MonoMethod *", "method"
|
"MonoMethod *", "method"
|
||||||
),
|
) {
|
||||||
|
HasCoreCLRBridgeFunction = true,
|
||||||
|
},
|
||||||
|
|
||||||
new Export ("MonoClass *", "mono_method_get_class",
|
new Export ("MonoClass *", "mono_method_get_class",
|
||||||
"MonoMethod *", "method"
|
"MonoMethod *", "method"
|
||||||
|
@ -391,7 +393,9 @@
|
||||||
new Export ("MonoType *", "mono_signature_get_params",
|
new Export ("MonoType *", "mono_signature_get_params",
|
||||||
"MonoMethodSignature *", "sig",
|
"MonoMethodSignature *", "sig",
|
||||||
"void **", "iter"
|
"void **", "iter"
|
||||||
),
|
) {
|
||||||
|
HasCoreCLRBridgeFunction = true,
|
||||||
|
},
|
||||||
|
|
||||||
new Export ("mono_bool", "mono_type_is_byref",
|
new Export ("mono_bool", "mono_type_is_byref",
|
||||||
"MonoType *", "type"
|
"MonoType *", "type"
|
||||||
|
@ -399,7 +403,9 @@
|
||||||
|
|
||||||
new Export ("MonoType *", "mono_signature_get_return_type",
|
new Export ("MonoType *", "mono_signature_get_return_type",
|
||||||
"MonoMethodSignature *", "sig"
|
"MonoMethodSignature *", "sig"
|
||||||
),
|
) {
|
||||||
|
HasCoreCLRBridgeFunction = true,
|
||||||
|
},
|
||||||
|
|
||||||
new Export ("int", "mono_type_get_type",
|
new Export ("int", "mono_type_get_type",
|
||||||
"MonoType *", "type"
|
"MonoType *", "type"
|
||||||
|
|
|
@ -96,7 +96,12 @@ typedef struct _MonoObject MonoMethod;
|
||||||
typedef struct _MonoMethod MonoMethod;
|
typedef struct _MonoMethod MonoMethod;
|
||||||
#endif
|
#endif
|
||||||
typedef struct _MonoMethodSignature MonoMethodSignature;
|
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;
|
typedef struct _MonoType MonoType;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* metadata/class.h */
|
/* metadata/class.h */
|
||||||
typedef struct MonoVTable MonoVTable;
|
typedef struct MonoVTable MonoVTable;
|
||||||
|
|
|
@ -284,6 +284,13 @@ xamarin_install_nsautoreleasepool_hooks ()
|
||||||
mono_profiler_install_thread (thread_start, thread_end);
|
mono_profiler_install_thread (thread_start, thread_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xamarin_bridge_free_mono_signature (MonoMethodSignature **psig)
|
||||||
|
{
|
||||||
|
// nothing to free here
|
||||||
|
*psig = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#if DOTNET
|
#if DOTNET
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -266,6 +266,8 @@ xamarin_get_parameter_type (MonoMethod *managed_method, int index)
|
||||||
p = mono_signature_get_params (msig, &iter);
|
p = mono_signature_get_params (msig, &iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xamarin_bridge_free_mono_signature (&msig);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ xamarin_invoke_trampoline (enum TrampolineType type, id self, SEL sel, iterator_
|
||||||
MonoObject *mthis = NULL;
|
MonoObject *mthis = NULL;
|
||||||
MethodDescription *desc = NULL;
|
MethodDescription *desc = NULL;
|
||||||
MonoMethod *method;
|
MonoMethod *method;
|
||||||
MonoMethodSignature *msig;
|
MonoMethodSignature *msig = NULL;
|
||||||
MonoReflectionMethod *reflection_method = NULL;
|
MonoReflectionMethod *reflection_method = NULL;
|
||||||
int semantic;
|
int semantic;
|
||||||
bool isCategoryInstance;
|
bool isCategoryInstance;
|
||||||
|
@ -730,6 +730,8 @@ exception_handling:
|
||||||
writeback = NULL;
|
writeback = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xamarin_bridge_free_mono_signature (&msig);
|
||||||
|
|
||||||
MONO_THREAD_DETACH; // COOP: This will switch to GC_SAFE
|
MONO_THREAD_DETACH; // COOP: This will switch to GC_SAFE
|
||||||
|
|
||||||
if (exception_gchandle != INVALID_GCHANDLE) {
|
if (exception_gchandle != INVALID_GCHANDLE) {
|
||||||
|
|
|
@ -29,6 +29,14 @@ struct _MonoObject {
|
||||||
GCHandle gchandle;
|
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
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#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_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle);
|
||||||
void xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle);
|
void xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle);
|
||||||
MonoMethod * xamarin_bridge_get_mono_method (MonoReflectionMethod *method);
|
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);
|
bool xamarin_register_monoassembly (MonoAssembly *assembly, GCHandle *exception_gchandle);
|
||||||
void xamarin_install_nsautoreleasepool_hooks ();
|
void xamarin_install_nsautoreleasepool_hooks ();
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,15 @@ namespace ObjCRuntime {
|
||||||
public IntPtr GCHandle;
|
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
|
// Comment out the attribute to get all printfs
|
||||||
[System.Diagnostics.Conditional ("UNDEFINED")]
|
[System.Diagnostics.Conditional ("UNDEFINED")]
|
||||||
static void log_coreclr (string message)
|
static void log_coreclr (string message)
|
||||||
|
@ -190,6 +199,40 @@ namespace ObjCRuntime {
|
||||||
return rv;
|
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)
|
static unsafe MonoObject* InvokeMethod (MonoObject* methodobj, MonoObject* instanceobj, IntPtr native_parameters)
|
||||||
{
|
{
|
||||||
var method = (MethodBase) GetMonoObjectTarget (methodobj);
|
var method = (MethodBase) GetMonoObjectTarget (methodobj);
|
||||||
|
@ -366,6 +409,9 @@ namespace ObjCRuntime {
|
||||||
|
|
||||||
[DllImport ("__Internal")]
|
[DllImport ("__Internal")]
|
||||||
static extern void xamarin_mono_object_retain (ref IntPtr mono_object);
|
static extern void xamarin_mono_object_retain (ref IntPtr mono_object);
|
||||||
|
|
||||||
|
[DllImport ("__Internal")]
|
||||||
|
unsafe static extern void xamarin_mono_object_retain (MonoObject* mono_object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче