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
31 changes: 20 additions & 11 deletions runtime/Delegates.cs.t4
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,15 @@ using Registrar;
namespace ObjCRuntime {
public unsafe partial class Runtime {

#if !NET
<# foreach (var d in delegates) { #>
<#
if (d.OnlyCoreCLR)
Write ("#if NET\n");
continue;
#>
internal delegate <#= d.ReturnType.MType #> <#= d.SimpleEntryPoint #>_delegate (<#= d.MArgumentSignature #>);
<#
if (d.OnlyCoreCLR)
Write ("#endif // NET\n");
#>
<# } #>
#endif // !NET

internal struct Delegates {
<# foreach (var d in delegates) { #>
Expand All @@ -56,11 +54,15 @@ namespace ObjCRuntime {
if (d.OnlyCoreCLR)
Write ("#if NET\n");
#>
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (<#= d.SimpleEntryPoint #>_delegate))]
static <#= d.ReturnType.MType #> <#= d.SimpleEntryPoint #> (<#= d.MArgumentSignature #>)
#endif
static unsafe <#= d.ReturnType.MType #> <#= d.SimpleEntryPoint #> (<#= d.MArgumentSignature #>)
<# if (d.ExceptionHandling) { #>
{
exception_gchandle = IntPtr.Zero;
*exception_gchandle = IntPtr.Zero;
try {
<# if (string.IsNullOrEmpty (d.WrappedManagedFunction)) { #>
throw new NotImplementedException ();
Expand All @@ -69,8 +71,8 @@ namespace ObjCRuntime {
<# } #>
} catch (Exception ex) {
var handle = GCHandle.Alloc (ex, GCHandleType.Normal);
exception_gchandle = GCHandle.ToIntPtr (handle);
<# if (d.SimpleEntryPoint == "get_nsobject_with_type") { #> created = false;
*exception_gchandle = GCHandle.ToIntPtr (handle);
<# if (d.SimpleEntryPoint == "get_nsobject_with_type") { #> *created = 0;
<# } #>
<# if (d.ReturnType.MType != "void") { #> return default (<#= d.ReturnType.MType #>);
<# } #>
Expand All @@ -93,7 +95,7 @@ namespace ObjCRuntime {
<# } #>

[BindingImpl (BindingImplOptions.Optimizable)] // To inline the Runtime.DynamicRegistrationSupported code if possible.
static void RegisterDelegates (InitializationOptions* options)
unsafe static void RegisterDelegates (InitializationOptions* options)
{
<# foreach (var d in delegates) {
if (d.OnlyDynamicUsage) continue; #>
Expand All @@ -102,8 +104,11 @@ namespace ObjCRuntime {
Write ("#if NET\n");
Write ("\t\t\tif (IsCoreCLR)\n\t");
}
#>
#>#if NET
options->Delegates-><#= d.SimpleEntryPoint #> = (IntPtr) (void *) <#= d.UnmanagedDelegateCast #> &<#= d.SimpleEntryPoint #>;
#else
options->Delegates-><#= d.SimpleEntryPoint #> = GetFunctionPointer (new <#= d.SimpleEntryPoint #>_delegate (<#= d.SimpleEntryPoint #>));
#endif
<#
if (d.OnlyCoreCLR)
Write ("#endif // NET\n");
Expand All @@ -125,7 +130,11 @@ namespace ObjCRuntime {
Write ("\t\t\tif (IsCoreCLR)\n\t");
}
#>
#if NET
options->Delegates-><#= d.SimpleEntryPoint #> = (IntPtr) (void *) <#= d.UnmanagedDelegateCast #> &<#= d.SimpleEntryPoint #>;
#else
options->Delegates-><#= d.SimpleEntryPoint #> = GetFunctionPointer (new <#= d.SimpleEntryPoint #>_delegate (<#= d.SimpleEntryPoint #>));
#endif
<#
if (d.OnlyCoreCLR)
Write ("#endif // NET\n");
Expand Down
60 changes: 39 additions & 21 deletions runtime/delegates.t4
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,14 @@
new XDelegate ("void", "void", "xamarin_get_method_for_selector",
"Class", "IntPtr", "cls",
"SEL", "IntPtr", "sel",
"bool", "bool", "is_static",
"int8_t", "sbyte", "is_static",
"MethodDescription *", "IntPtr", "desc"
) {
WrappedManagedFunction = "GetMethodForSelector",
OnlyDynamicUsage = true,
},

new XDelegate ("bool", "bool", "xamarin_has_nsobject",
new XDelegate ("int8_t", "sbyte", "xamarin_has_nsobject",
"id", "IntPtr", "obj"
) {
WrappedManagedFunction = "HasNSObject",
Expand Down Expand Up @@ -156,7 +156,7 @@

new XDelegate ("GCHandle->MonoObject *", "IntPtr", "xamarin_get_inative_object_dynamic",
"id", "IntPtr", "obj",
"bool", "bool", "owns",
"int8_t", "sbyte", "owns",
"GCHandle->MonoReflectionType *", "IntPtr", "type"
) {
WrappedManagedFunction = "GetINativeObject_Dynamic",
Expand All @@ -182,7 +182,7 @@

new XDelegate ("GCHandle->MonoObject *", "IntPtr", "xamarin_get_inative_object_static",
"id", "IntPtr", "obj",
"bool", "bool", "owns",
"int8_t", "sbyte", "owns",
"unsigned int", "uint", "iface_token_ref",
"unsigned int", "uint", "implementation_token_ref"
) {
Expand All @@ -193,7 +193,7 @@
new XDelegate ("GCHandle->MonoObject *", "IntPtr", "xamarin_get_nsobject_with_type",
"id", "IntPtr", "obj",
"GCHandle->MonoReflectionType *", "IntPtr", "type",
"int32_t *", "out bool", "created"
"int32_t *", "int*", "created"
) {
WrappedManagedFunction = "GetNSObjectWithType",
OnlyDynamicUsage = false,
Expand All @@ -206,15 +206,15 @@
OnlyDynamicUsage = false,
},

new XDelegate ("bool", "bool", "xamarin_is_parameter_transient",
new XDelegate ("int8_t", "sbyte", "xamarin_is_parameter_transient",
"GCHandle->MonoReflectionMethod *", "IntPtr", "method",
"int", "int", "parameter"
) {
WrappedManagedFunction = "IsParameterTransient",
OnlyDynamicUsage = true,
},

new XDelegate ("bool", "bool", "xamarin_is_parameter_out",
new XDelegate ("int8_t", "sbyte", "xamarin_is_parameter_out",
"GCHandle->MonoReflectionMethod *", "IntPtr", "method",
"int", "int", "parameter"
) {
Expand All @@ -225,9 +225,9 @@
new XDelegate ("void", "void", "xamarin_get_method_and_object_for_selector",
"Class", "IntPtr", "cls",
"SEL", "IntPtr", "sel",
"bool", "bool", "is_static",
"int8_t", "sbyte", "is_static",
"id", "IntPtr", "obj",
"GCHandle *", "ref IntPtr", "mthis",
"GCHandle *", "IntPtr*", "mthis",
"MethodDescription *", "IntPtr", "desc"
) {
WrappedManagedFunction = "GetMethodAndObjectForSelector",
Expand All @@ -237,7 +237,7 @@
new XDelegate ("GCHandle", "IntPtr", "xamarin_create_product_exception_for_error",
"int", "int", "code",
"GCHandle", "IntPtr", "inner_exception_gchandle",
"const char *", "string", "message"
"const char *", "IntPtr", "message"
) {
WrappedManagedFunction = "CreateProductException",
OnlyDynamicUsage = false,
Expand Down Expand Up @@ -266,7 +266,7 @@

new XDelegate ("enum MarshalObjectiveCExceptionMode", "MarshalObjectiveCExceptionMode", "xamarin_on_marshal_objectivec_exception",
"id", "IntPtr", "exception",
"bool", "bool", "throwManagedAsDefault"
"int8_t", "sbyte", "throwManagedAsDefault"
) {
WrappedManagedFunction = "OnMarshalObjectiveCException",
OnlyDynamicUsage = false,
Expand Down Expand Up @@ -494,7 +494,7 @@
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_isinstance",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_isinstance",
"GCHandle", "IntPtr", "gchandle",
"GCHandle", "IntPtr", "type"
) {
Expand Down Expand Up @@ -529,7 +529,7 @@
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_is_enum",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_is_enum",
"MonoObject *", "MonoObject *", "typeobj"
) {
WrappedManagedFunction = "IsEnum",
Expand All @@ -545,23 +545,23 @@
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_is_byref",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_is_byref",
"MonoObject *", "MonoObject *", "typeobj"
) {
WrappedManagedFunction = "IsByRef",
OnlyDynamicUsage = false,
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_is_valuetype",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_is_valuetype",
"MonoObject *", "MonoObject *", "typeobj"
) {
WrappedManagedFunction = "IsValueType",
OnlyDynamicUsage = false,
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_is_nullable",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_is_nullable",
"MonoObject *", "MonoObject *", "typeobj"
) {
WrappedManagedFunction = "IsNullable",
Expand All @@ -585,15 +585,15 @@
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_is_delegate",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_is_delegate",
"MonoObject *", "MonoObject *", "typeobj"
) {
WrappedManagedFunction = "IsDelegate",
OnlyDynamicUsage = false,
OnlyCoreCLR = true,
},

new XDelegate ("bool", "bool", "xamarin_bridge_is_class_of_type",
new XDelegate ("int8_t", "sbyte", "xamarin_bridge_is_class_of_type",
"MonoObject *", "MonoObject *", "classobj",
"enum XamarinLookupTypes", "Runtime.TypeLookup", "type"
) {
Expand Down Expand Up @@ -672,14 +672,14 @@
OnlyDynamicUsage = false,
},

new XDelegate ("bool", "bool", "xamarin_attempt_retain_nsobject",
new XDelegate ("int8_t", "sbyte", "xamarin_attempt_retain_nsobject",
"GCHandle->MonoObject *", "IntPtr", "obj"
) {
WrappedManagedFunction = "AttemptRetainNSObject",
OnlyDynamicUsage = false,
},

new XDelegate ("bool", "bool", "xamarin_invoke_conforms_to_protocol",
new XDelegate ("int8_t", "sbyte", "xamarin_invoke_conforms_to_protocol",
"id", "IntPtr", "obj",
"Protocol *", "IntPtr", "protocol"
) {
Expand Down Expand Up @@ -878,6 +878,24 @@
}
}

public string UnmanagedDelegateCast {
get {
var builder = new StringBuilder ();
builder.Append ("(delegate* unmanaged<");

foreach (var arg in Arguments) {
builder.Append (arg.MType);
builder.Append (", ");
}
if (ExceptionHandling)
builder.Append ("IntPtr*, ");
builder.Append (ReturnType.MType);

builder.Append (">)");
return builder.ToString ();
}
}

public string AlignEntryPoint {
get {
return new string (' ', Delegates.MaxEntryPointLength - EntryPoint.Length);
Expand Down Expand Up @@ -949,7 +967,7 @@
} else {
if (Arguments.Count > 0)
builder.Append (", ");
builder.Append ("out IntPtr exception_gchandle");
builder.Append ("IntPtr* exception_gchandle");
}
}

Expand Down
35 changes: 20 additions & 15 deletions src/ObjCRuntime/Runtime.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ static unsafe void SetPendingException (MonoObject* exception_obj)
ObjectiveCMarshal.SetMessageSendPendingException (exc);
}

unsafe static bool IsClassOfType (MonoObject *typeobj, TypeLookup match)
unsafe static sbyte IsClassOfType (MonoObject *typeobj, TypeLookup match)
{
return IsClassOfType ((Type) GetMonoObjectTarget (typeobj), match);
var rv = IsClassOfType ((Type) GetMonoObjectTarget (typeobj), match);
return (sbyte) (rv ? 1 : 0);
}

static bool IsClassOfType (Type type, TypeLookup match)
Expand Down Expand Up @@ -499,26 +500,26 @@ static IntPtr ObjectGetType (MonoObjectPtr mobj)
return GetMonoObject (obj.GetType ());
}

unsafe static bool IsDelegate (MonoObject* typeobj)
unsafe static sbyte IsDelegate (MonoObject* typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var rv = typeof (MulticastDelegate).IsAssignableFrom (type);
log_coreclr ($"IsDelegate ({type.FullName}) => {rv}");
return rv;
return (sbyte) (rv ? 1 : 0);
}

static bool IsInstance (MonoObjectPtr mobj, MonoObjectPtr mtype)
static sbyte IsInstance (MonoObjectPtr mobj, MonoObjectPtr mtype)
{
var obj = GetMonoObjectTarget (mobj);
if (obj == null)
return false;
return 0;

var type = (Type) GetMonoObjectTarget (mtype);
var rv = type.IsAssignableFrom (obj.GetType ());

log_coreclr ($"IsInstance ({obj.GetType ()}, {type})");

return rv;
return (sbyte) (rv ? 1 : 0);
}

static unsafe IntPtr GetMethodSignature (MonoObject* methodobj)
Expand Down Expand Up @@ -837,9 +838,10 @@ static object Box (Type type, IntPtr value)
return boxed;
}

static unsafe bool IsNullable (MonoObject* type)
static unsafe sbyte IsNullable (MonoObject* type)
{
return IsNullable ((Type) GetMonoObjectTarget (type));
var rv = IsNullable ((Type) GetMonoObjectTarget (type));
return (sbyte) (rv ? 1 : 0);
}

static bool IsNullable (Type type)
Expand All @@ -853,22 +855,25 @@ static bool IsNullable (Type type)
return false;
}

unsafe static bool IsByRef (MonoObject *typeobj)
unsafe static sbyte IsByRef (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
return type.IsByRef;
var rv = type.IsByRef;
return (sbyte) (rv ? 1 : 0);
}

unsafe static bool IsValueType (MonoObject *typeobj)
unsafe static sbyte IsValueType (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
return type.IsValueType;
var rv = type.IsValueType;
return (sbyte) (rv ? 1 : 0);
}

unsafe static bool IsEnum (MonoObject *typeobj)
unsafe static sbyte IsEnum (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
return type.IsEnum;
var rv = type.IsEnum;
return (sbyte) (rv ? 1 : 0);
}

static unsafe MonoObject* GetEnumBaseType (MonoObject* typeobj)
Expand Down
Loading