Skip to content

Commit

Permalink
Merge pull request xamarin#2785 from rolfbjarne/bind-as-d15-5
Browse files Browse the repository at this point in the history
[registrar] Add support for the BindAs attribute.
  • Loading branch information
Aguilex authored Sep 27, 2017
2 parents cdd9eba + 78e2a48 commit 90eecf4
Show file tree
Hide file tree
Showing 50 changed files with 3,926 additions and 304 deletions.
54 changes: 54 additions & 0 deletions docs/bindas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# How to add BindAs support for new types

Currently the BindAs code only supports converting between a certain set of
types and NSValue, NSNumber and smart enums.

If your BindAs support does not involve NSValue or NSNumber, then the required
changes are a bit more extensive than I explain here (but this is still a good
starting point).

[Sample code][8]

The sample code is to support a new type for NSValue, the exact code locations will differ slightly for NSNumber (different switches, etc).

1. Add a test (or three)

* Add an entry to [tests/test-libraries/testgenerator.cs][1] for the new type.
testgenerator.cs will generate the code required to test your new BindAs
support for all known scenarios.

* Any other manual tests should go in monotouch-test.

2. Add native conversions functions to runtime/trampolines.m|h. In the sample
code this is the two functions to convert between NSValue and
NSDirectionalEdgeInsets:

`xamarin_nsdirectionaledgeinsets_to_nsvalue`: [trampolines.h#151][2], [trampolines.m#889][3]
`xamarin_nsvalue_to_nsdirectionaledgeinsets`: [trampolines.h#116][4], [trampolines.m#799][5]

3. Add a switch entry to [trampolines.m#1007][6] to use the two new conversion functions.

4. The registrar also needs to know ([Registrar.cs#687][7]).

5. And the static registrar needs to know too, so that it can call the right native conversion function ([StaticRegistrar.cs#3796][9], [StaticRegistrar.cs#3830][10]).

6. Now there's just the generator support left ([generator.cs#1223][11], [generator.cs#1369][12]).

7. Finally run the following tests (at least)

* All variations of monotouch-test (iOS/watchOS/tvOS) on both simulator and device.
* link all on both simulator and device.


[1]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/tests/test-libraries/testgenerator.cs#L100
[2]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/runtime/xamarin/trampolines.h#L151
[3]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/runtime/trampolines.m#L889
[4]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/runtime/xamarin/trampolines.h#L116
[5]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/runtime/trampolines.m#L799
[6]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/runtime/trampolines.m#L1007-L1008
[7]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/src/ObjCRuntime/Registrar.cs#L687
[8]: https://github.com/xamarin/xamarin-macios/pull/2288/commits/b38c114fbe8c9d229ec41a312dc36802cb4f027e
[9]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/tools/common/StaticRegistrar.cs#L3796
[10]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/tools/common/StaticRegistrar.cs#L3830
[11]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/src/generator.cs#L1223
[12]: https://github.com/rolfbjarne/xamarin-macios/blob/b38c114fbe8c9d229ec41a312dc36802cb4f027e/src/generator.cs#L1369
32 changes: 32 additions & 0 deletions docs/website/mtouch-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,10 @@ Something unexpected occured when trying to mark `NSObject` subclasses from the

Something unexpected occured when trying to inline code from the application. The assembly causing the issue is named in the error message. In order to fix this issue the assembly will need to be provided in a [bug report](https://bugzilla.xamarin.com) along with a complete build log with verbosity enabled (i.e. `-v -v -v -v` in the **Additional mtouch arguments**).

### <a name="MT2100"/>MT2100: Smart Enum Conversion Preserver failed processing `...`.

Something unexpected occured when trying to mark the conversion methods for smart enums from the application. The assembly causing the issue is named in the error message. In order to fix this issue the assembly will need to be provided in a [bug report](https://bugzilla.xamarin.com) along with a complete build log with verbosity enabled (i.e. `-v -v -v -v` in the **Additional mtouch arguments**).

<!-- MT21xx: more linker errors -->

<!--- 2100 used by mmp -->
Expand Down Expand Up @@ -1544,6 +1548,29 @@ Please use a valid Objective-C identifier.
Xamarin.iOS failed to generate a P/Invoke wrapper function for the mentioned.
Please check the reported error message for the underlying cause.

### <a name="MT4170"/>MT4170: The registrar can't convert from '{managed type}' to '{native type}' for the return value in the method {method}.

See the description of error <a href="#MT4172">MT4172</a>.

### <a name="MT4171"/>MT4171: The BindAs attribute on the member {member} is invalid: the BindAs type {type} is different from the property type {type}.

Please make sure the type in the BindAs attribute matches the type of the member it's attached to.

### <a name="MT4172"/>MT4172: The registrar can't convert from '{native type}' to '{managed type}' for the parameter '{parameter name}' in the method {method}.

The registrar does not support converting between the mentioned types.

This is a bug in Xamarin.iOS if the API in question is provided by Xamarin.iOS;
please file a bug at [http://bugzilla.xamarin.com][1].

If you run into this while developing a binding project for a native library,
we're open to adding support for new combinations of types. If this is the
case, please file an enhancement request ([http://bugzilla.xamarin.com][2])
with a test case and we'll evaluate it.

[1]: https://bugzilla.xamarin.com/enter_bug.cgi?product=iOS
[2]: https://bugzilla.xamarin.com/enter_bug.cgi?product=iOS&component=General&bug_severity=enhancement

# MT5xxx: GCC and toolchain error messages

### MT51xx: Compilation
Expand Down Expand Up @@ -2234,3 +2261,8 @@ This indicates a bug in Xamarin.iOS. Please file a bug at [http://bugzilla.xamar
### <a name="MT8023"/>MT8023: An instance object is required to construct a closed generic method for the open generic method: * (token reference: *). Please file a bug report at http://bugzilla.xamarin.com.

This indicates a bug in Xamarin.iOS. Please file a bug at [http://bugzilla.xamarin.com](https://bugzilla.xamarin.com/enter_bug.cgi?product=iOS).

### <a name="MT8024"/>MT8024: Could not find a valid extension type for the smart enum '{smart_type}'. Please file a bug at https://bugzilla.xamarin.com.

This indicates a bug in Xamarin.iOS. Please file a bug at [http://bugzilla.xamarin.com](https://bugzilla.xamarin.com/enter_bug.cgi?product=iOS).

19 changes: 15 additions & 4 deletions runtime/delegates.t4
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@
"MonoObject *", "IntPtr", "obj"
) { WrappedManagedFunction = "GetSelectorHandle" },

new XDelegate ("MethodDescription", "UnmanagedMethodDescription", "xamarin_get_method_for_selector",
new XDelegate ("void", "void", "xamarin_get_method_for_selector",
"Class", "IntPtr", "cls",
"SEL", "IntPtr", "sel",
"bool", "bool", "is_static"
"bool", "bool", "is_static",
"MethodDescription *", "IntPtr", "desc"
) { WrappedManagedFunction = "GetMethodForSelector" },

new XDelegate ("MonoObject *", "IntPtr", "xamarin_get_nsobject",
Expand Down Expand Up @@ -138,12 +139,13 @@
"int", "int", "parameter"
) { WrappedManagedFunction = "IsParameterOut" },

new XDelegate ("MethodDescription", "UnmanagedMethodDescription", "xamarin_get_method_and_object_for_selector",
new XDelegate ("void", "void", "xamarin_get_method_and_object_for_selector",
"Class", "IntPtr", "cls",
"SEL", "IntPtr", "sel",
"bool", "bool", "is_static",
"id", "IntPtr", "obj",
"MonoObject **", "ref IntPtr", "mthis"
"MonoObject **", "ref IntPtr", "mthis",
"MethodDescription *", "IntPtr", "desc"
) { WrappedManagedFunction = "GetMethodAndObjectForSelector" },

new XDelegate ("guint32", "int", "xamarin_create_product_exception_for_error",
Expand All @@ -167,6 +169,15 @@
"id", "IntPtr", "exception",
"bool", "bool", "throwManagedAsDefault"
) { WrappedManagedFunction = "OnMarshalObjectiveCException" },

new XDelegate ("NSString *", "IntPtr", "xamarin_convert_smart_enum_to_nsstring",
"void *", "IntPtr", "value"
) { WrappedManagedFunction = "ConvertSmartEnumToNSString" },

new XDelegate ("void *", "IntPtr", "xamarin_convert_nsstring_to_smart_enum",
"NSString *", "IntPtr", "value",
"MonoReflectionType *", "IntPtr", "type"
) { WrappedManagedFunction = "ConvertNSStringToSmartEnum" },
};
delegates.CalculateLengths ();
#><#+
Expand Down
26 changes: 26 additions & 0 deletions runtime/exports.t4
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
"MonoClass *", "klass"
),

new Export ("MonoType *", "mono_class_enum_basetype",
"MonoClass *", "klass"
),

new Export ("int32_t", "mono_class_value_size",
"MonoClass *", "klass",
"uint32_t *", "align"
Expand All @@ -76,7 +80,16 @@
new Export ("MonoType *", "mono_class_get_type",
"MonoClass *", "klass"
),
#endregion

#region metadata/class-internals.h
new Export (true, "gboolean", "mono_class_is_nullable",
"MonoClass *", "klass"
),

new Export (true, "MonoClass *", "mono_class_get_nullable_param",
"MonoClass *", "klass"
),
#endregion

#region metadata/debug-helpers.h
Expand Down Expand Up @@ -173,6 +186,12 @@
"void *", "value"
),

new Export ("MonoObject *", "mono_value_box",
"MonoDomain *", "domain",
"MonoClass *", "klass",
"void *", "val"
),

#endregion

#region metadata/profiler.h
Expand Down Expand Up @@ -348,6 +367,9 @@
"MonoType *", "type"
),

new Export ("MonoType *", "mono_reflection_type_get_type",
"MonoReflectionType *", "reftype"
),
#endregion

#region metadata/metadata.h
Expand All @@ -365,6 +387,10 @@
"MonoMethodSignature *", "sig"
),

new Export ("int", "mono_type_get_type",
"MonoType *", "type"
),

#endregion

#region metadata/mono-debug.h
Expand Down
23 changes: 23 additions & 0 deletions runtime/frameworks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
#define HAVE_UIKIT 1
#else
#define HAVE_UIKIT 0
#endif

#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH || defined (__x86_64__)
#define HAVE_MAPKIT 1
#else
#define HAVE_MAPKIT 0
#endif

#if !TARGET_OS_WATCH
#define HAVE_COREMEDIA 1
#else
#define HAVE_COREMEDIA 0
#endif

#if !TARGET_OS_WATCH
#define HAVE_COREANIMATION 1
#else
#define HAVE_COREANIMATION 0
#endif
53 changes: 53 additions & 0 deletions runtime/mono-runtime.h.t4
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,52 @@ typedef void (*MonoUnhandledExceptionFunc) (MonoObject *exc, gpointer u
typedef unsigned char* (*MonoLoadAotDataFunc) (MonoAssembly *assembly, int size, gpointer user_data, void **out_handle);
typedef void (*MonoFreeAotDataFunc) (MonoAssembly *assembly, int size, gpointer user_data, void *handle);

/* metadata/blob.h */

/*
* Encoding for type signatures used in the Metadata
*/
typedef enum {
MONO_TYPE_END = 0x00, /* End of List */
MONO_TYPE_VOID = 0x01,
MONO_TYPE_BOOLEAN = 0x02,
MONO_TYPE_CHAR = 0x03,
MONO_TYPE_I1 = 0x04,
MONO_TYPE_U1 = 0x05,
MONO_TYPE_I2 = 0x06,
MONO_TYPE_U2 = 0x07,
MONO_TYPE_I4 = 0x08,
MONO_TYPE_U4 = 0x09,
MONO_TYPE_I8 = 0x0a,
MONO_TYPE_U8 = 0x0b,
MONO_TYPE_R4 = 0x0c,
MONO_TYPE_R8 = 0x0d,
MONO_TYPE_STRING = 0x0e,
MONO_TYPE_PTR = 0x0f, /* arg: <type> token */
MONO_TYPE_BYREF = 0x10, /* arg: <type> token */
MONO_TYPE_VALUETYPE = 0x11, /* arg: <type> token */
MONO_TYPE_CLASS = 0x12, /* arg: <type> token */
MONO_TYPE_VAR = 0x13, /* number */
MONO_TYPE_ARRAY = 0x14, /* type, rank, boundsCount, bound1, loCount, lo1 */
MONO_TYPE_GENERICINST= 0x15, /* <type> <type-arg-count> <type-1> \x{2026} <type-n> */
MONO_TYPE_TYPEDBYREF = 0x16,
MONO_TYPE_I = 0x18,
MONO_TYPE_U = 0x19,
MONO_TYPE_FNPTR = 0x1b, /* arg: full method signature */
MONO_TYPE_OBJECT = 0x1c,
MONO_TYPE_SZARRAY = 0x1d, /* 0-based one-dim-array */
MONO_TYPE_MVAR = 0x1e, /* number */
MONO_TYPE_CMOD_REQD = 0x1f, /* arg: typedef or typeref token */
MONO_TYPE_CMOD_OPT = 0x20, /* optional arg: typedef or typref token */
MONO_TYPE_INTERNAL = 0x21, /* CLR internal type */

MONO_TYPE_MODIFIER = 0x40, /* Or with the following types */
MONO_TYPE_SENTINEL = 0x41, /* Sentinel for varargs method signature */
MONO_TYPE_PINNED = 0x45, /* Local var that points to pinned object */

MONO_TYPE_ENUM = 0x55 /* an enumeration */
} MonoTypeEnum;

/*
* From internal headers
*/
Expand Down Expand Up @@ -238,6 +284,13 @@ MONO_API <#= export.ReturnType #>
<#= export.EntryPoint #> (<#= export.ArgumentSignature #>);
<# } #>

<# foreach (var export in exports) {
if (!export.Optional)
continue; #>
bool
<#= export.EntryPoint #>_exists ();

<# } #>
#ifdef __cplusplus
} /* extern "C" */
#endif
Expand Down
10 changes: 10 additions & 0 deletions runtime/mono-runtime.m.t4
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ MONO_API <#= export.ReturnType #>
<# } #>
return <#= export.EntryPoint #>_func (<#= export.ArgumentNames #>);
}
<# } #>

<# foreach (var export in exports) {
if (!export.Optional)
continue; #>
bool
<#= export.EntryPoint #>_exists ()
{
return <#= export.EntryPoint #>_func != NULL;
}

<# } #>
#else
Expand Down
2 changes: 1 addition & 1 deletion runtime/runtime-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
extern "C" {
#endif

void *xamarin_marshal_return_value (MonoType *mtype, const char *type, MonoObject *retval, bool retain, MonoMethod *method, guint32 *exception_gchandle);
void *xamarin_marshal_return_value (MonoType *mtype, const char *type, MonoObject *retval, bool retain, MonoMethod *method, MethodDescription *desc, guint32 *exception_gchandle);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit 90eecf4

Please sign in to comment.