[static registrar] Compute the conversion methods for smart enums and embed those as token references in the generated code. (#3385)

Converting to and from smart enums and their corresponding native value
requires knowing the conversion function, since each smart enum has its own
conversion function.

The dynamic registrar can do this at runtime, but it's something that can be
computed in the static registrar at build time, so do that. The static
registrar will now embed the metadata token (as a token reference) in the
generated code, which can be used at runtime to find the conversion method,
without requiring anything from dynamic registrar.

This requires some refactoring in the conversion methods to allow passing more
information around (the `context` parameter in the conversion functions, which
the smart enum conversion methods now use for the token reference).

It turns out this is a massive improvement (although the scenarios where this
is relevant are rare): a simple test case [1] is 300x faster (from ~30s to
0.1s).

[1]: https://gist.github.com/rolfbjarne/961af28d1c2727b256fbcdfd6aa65e98
This commit is contained in:
Rolf Bjarne Kvinge 2018-02-05 07:54:13 +01:00 коммит произвёл GitHub
Родитель bec116c273
Коммит 5319266503
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 288 добавлений и 175 удалений

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

@ -2554,6 +2554,17 @@ xamarin_find_assembly_directory (const char *assembly_name)
return entry ? entry->location : NULL;
}
MonoMethod *
xamarin_get_managed_method_for_token (guint32 token_ref, guint32 *exception_gchandle)
{
MonoReflectionMethod *reflection_method;
reflection_method = xamarin_get_method_from_token (token_ref, exception_gchandle);
if (*exception_gchandle != 0) return NULL;
return xamarin_get_reflection_method_method (reflection_method);
}
/*
* Object unregistration:
*

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

@ -166,7 +166,7 @@ xamarin_invoke_trampoline (enum TrampolineType type, id self, SEL sel, iterator_
if (exception_gchandle != 0)
goto exception_handling;
if (desc->bindas [i + 1].original_type != NULL) {
arg_ptrs [i + mofs] = xamarin_generate_conversion_to_managed ((id) arg, mono_reflection_type_get_type (desc->bindas [i + 1].original_type), p, method, &exception_gchandle, (void **) &free_list);
arg_ptrs [i + mofs] = xamarin_generate_conversion_to_managed ((id) arg, mono_reflection_type_get_type (desc->bindas [i + 1].original_type), p, method, &exception_gchandle, INVALID_TOKEN_REF, (void **) &free_list);
if (exception_gchandle != 0)
goto exception_handling;
ofs++;

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

@ -80,7 +80,7 @@ xamarin_marshal_return_value (MonoType *mtype, const char *type, MonoObject *ret
MonoClass *r_klass = mono_object_get_class ((MonoObject *) retval);
if (desc && desc->bindas [0].original_type != NULL) {
return xamarin_generate_conversion_to_native (retval, mono_class_get_type (r_klass), mono_reflection_type_get_type (desc->bindas [0].original_type), method, exception_gchandle);
return xamarin_generate_conversion_to_native (retval, mono_class_get_type (r_klass), mono_reflection_type_get_type (desc->bindas [0].original_type), method, INVALID_TOKEN_REF, exception_gchandle);
} else if (r_klass == mono_get_string_class ()) {
char *str = mono_string_to_utf8 ((MonoString *) retval);
NSString *rv = [[NSString alloc] initWithUTF8String:str];
@ -615,7 +615,7 @@ xamarin_get_gchandle_trampoline (id self, SEL sel)
}
id
xamarin_generate_conversion_to_native (MonoObject *value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 *exception_gchandle)
xamarin_generate_conversion_to_native (MonoObject *value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 context, guint32 *exception_gchandle)
{
// COOP: Reads managed memory, needs to be in UNSAFE mode
MONO_ASSERT_GC_UNSAFE;
@ -670,11 +670,11 @@ xamarin_generate_conversion_to_native (MonoObject *value, MonoType *inputType, M
goto exception_handling;
if (isManagedArray) {
convertedValue = xamarin_convert_managed_to_nsarray_with_func ((MonoArray *) value, func, exception_gchandle);
convertedValue = xamarin_convert_managed_to_nsarray_with_func ((MonoArray *) value, func, context, exception_gchandle);
if (*exception_gchandle != 0)
goto exception_handling;
} else {
convertedValue = func (value, exception_gchandle);
convertedValue = func (value, context, exception_gchandle);
if (*exception_gchandle != 0)
goto exception_handling;
}
@ -687,7 +687,7 @@ exception_handling:
void *
xamarin_generate_conversion_to_managed (id value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 *exception_gchandle, /*SList*/ void **free_list)
xamarin_generate_conversion_to_managed (id value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 *exception_gchandle, guint32 context, /*SList*/ void **free_list)
{
// COOP: Reads managed memory, needs to be in UNSAFE mode
MONO_ASSERT_GC_UNSAFE;
@ -742,11 +742,11 @@ xamarin_generate_conversion_to_managed (id value, MonoType *inputType, MonoType
goto exception_handling;
if (isManagedArray) {
convertedValue = xamarin_convert_nsarray_to_managed_with_func (value, underlyingManagedType, func, exception_gchandle);
convertedValue = xamarin_convert_nsarray_to_managed_with_func (value, underlyingManagedType, func, context, exception_gchandle);
if (*exception_gchandle != 0)
goto exception_handling;
} else {
convertedValue = func (value, NULL, underlyingManagedType, exception_gchandle);
convertedValue = func (value, NULL, underlyingManagedType, context, exception_gchandle);
if (*exception_gchandle != 0)
goto exception_handling;
*(SList **) free_list = s_list_prepend (*(SList **) free_list, convertedValue);
@ -766,55 +766,55 @@ exception_handling:
// Returns a pointer to the value type, which must be freed using xamarin_free.
// If called multiple times in succession, the returned pointer can be passed as the second ptr argument, and it need only be freed once done iterating.
void *xamarin_nsnumber_to_bool (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { BOOL *valueptr = (BOOL *) (ptr ? ptr : xamarin_calloc (sizeof (BOOL))); *valueptr = [number boolValue]; return valueptr; }
void *xamarin_nsnumber_to_sbyte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { int8_t *valueptr = (int8_t *) (ptr ? ptr : xamarin_calloc (sizeof (int8_t))); *valueptr = [number charValue]; return valueptr; }
void *xamarin_nsnumber_to_byte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { uint8_t *valueptr = (uint8_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint8_t))); *valueptr = [number unsignedCharValue]; return valueptr; }
void *xamarin_nsnumber_to_short (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { int16_t *valueptr = (int16_t *) (ptr ? ptr : xamarin_calloc (sizeof (int16_t))); *valueptr = [number shortValue]; return valueptr; }
void *xamarin_nsnumber_to_ushort (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { uint16_t *valueptr = (uint16_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint16_t))); *valueptr = [number unsignedShortValue]; return valueptr; }
void *xamarin_nsnumber_to_int (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { int32_t *valueptr = (int32_t *) (ptr ? ptr : xamarin_calloc (sizeof (int32_t))); *valueptr = [number intValue]; return valueptr; }
void *xamarin_nsnumber_to_uint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { uint32_t *valueptr = (uint32_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint32_t))); *valueptr = [number unsignedIntValue]; return valueptr; }
void *xamarin_nsnumber_to_long (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { int64_t *valueptr = (int64_t *) (ptr ? ptr : xamarin_calloc (sizeof (int64_t))); *valueptr = [number longLongValue]; return valueptr; }
void *xamarin_nsnumber_to_ulong (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { uint64_t *valueptr = (uint64_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint64_t))); *valueptr = [number unsignedLongLongValue]; return valueptr; }
void *xamarin_nsnumber_to_nint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { NSInteger *valueptr = (NSInteger *) (ptr ? ptr : xamarin_calloc (sizeof (NSInteger))); *valueptr = [number integerValue]; return valueptr; }
void *xamarin_nsnumber_to_nuint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { NSUInteger *valueptr = (NSUInteger *) (ptr ? ptr : xamarin_calloc (sizeof (NSUInteger))); *valueptr = [number unsignedIntegerValue]; return valueptr; }
void *xamarin_nsnumber_to_float (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { float *valueptr = (float *) (ptr ? ptr : xamarin_calloc (sizeof (float))); *valueptr = [number floatValue]; return valueptr; }
void *xamarin_nsnumber_to_double (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { double *valueptr = (double *) (ptr ? ptr : xamarin_calloc (sizeof (double))); *valueptr = [number doubleValue]; return valueptr; }
void *xamarin_nsnumber_to_bool (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { BOOL *valueptr = (BOOL *) (ptr ? ptr : xamarin_calloc (sizeof (BOOL))); *valueptr = [number boolValue]; return valueptr; }
void *xamarin_nsnumber_to_sbyte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { int8_t *valueptr = (int8_t *) (ptr ? ptr : xamarin_calloc (sizeof (int8_t))); *valueptr = [number charValue]; return valueptr; }
void *xamarin_nsnumber_to_byte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { uint8_t *valueptr = (uint8_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint8_t))); *valueptr = [number unsignedCharValue]; return valueptr; }
void *xamarin_nsnumber_to_short (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { int16_t *valueptr = (int16_t *) (ptr ? ptr : xamarin_calloc (sizeof (int16_t))); *valueptr = [number shortValue]; return valueptr; }
void *xamarin_nsnumber_to_ushort (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { uint16_t *valueptr = (uint16_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint16_t))); *valueptr = [number unsignedShortValue]; return valueptr; }
void *xamarin_nsnumber_to_int (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { int32_t *valueptr = (int32_t *) (ptr ? ptr : xamarin_calloc (sizeof (int32_t))); *valueptr = [number intValue]; return valueptr; }
void *xamarin_nsnumber_to_uint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { uint32_t *valueptr = (uint32_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint32_t))); *valueptr = [number unsignedIntValue]; return valueptr; }
void *xamarin_nsnumber_to_long (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { int64_t *valueptr = (int64_t *) (ptr ? ptr : xamarin_calloc (sizeof (int64_t))); *valueptr = [number longLongValue]; return valueptr; }
void *xamarin_nsnumber_to_ulong (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { uint64_t *valueptr = (uint64_t *) (ptr ? ptr : xamarin_calloc (sizeof (uint64_t))); *valueptr = [number unsignedLongLongValue]; return valueptr; }
void *xamarin_nsnumber_to_nint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { NSInteger *valueptr = (NSInteger *) (ptr ? ptr : xamarin_calloc (sizeof (NSInteger))); *valueptr = [number integerValue]; return valueptr; }
void *xamarin_nsnumber_to_nuint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { NSUInteger *valueptr = (NSUInteger *) (ptr ? ptr : xamarin_calloc (sizeof (NSUInteger))); *valueptr = [number unsignedIntegerValue]; return valueptr; }
void *xamarin_nsnumber_to_float (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { float *valueptr = (float *) (ptr ? ptr : xamarin_calloc (sizeof (float))); *valueptr = [number floatValue]; return valueptr; }
void *xamarin_nsnumber_to_double (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { double *valueptr = (double *) (ptr ? ptr : xamarin_calloc (sizeof (double))); *valueptr = [number doubleValue]; return valueptr; }
#if __POINTER_WIDTH__ == 32
void *xamarin_nsnumber_to_nfloat (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { float *valueptr = (float *) (ptr ? ptr : xamarin_calloc (sizeof (float))); *valueptr = [number floatValue]; return valueptr; }
void *xamarin_nsnumber_to_nfloat (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { float *valueptr = (float *) (ptr ? ptr : xamarin_calloc (sizeof (float))); *valueptr = [number floatValue]; return valueptr; }
#elif __POINTER_WIDTH__ == 64
void *xamarin_nsnumber_to_nfloat (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { double *valueptr = (double *) (ptr ? ptr : xamarin_calloc (sizeof (double))); *valueptr = [number doubleValue]; return valueptr; }
void *xamarin_nsnumber_to_nfloat (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { double *valueptr = (double *) (ptr ? ptr : xamarin_calloc (sizeof (double))); *valueptr = [number doubleValue]; return valueptr; }
#else
#error Invalid pointer size.
#endif
// Returns a pointer to the value type, which must be freed using xamarin_free.
// If called multiple times in succession, the returned pointer can be passed as the second ptr argument, and it need only be freed once done iterating.
void *xamarin_nsvalue_to_nsrange (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { NSRange *valueptr = (NSRange *) (ptr ? ptr : xamarin_calloc (sizeof (NSRange))); *valueptr = [value rangeValue]; return valueptr; }
void *xamarin_nsvalue_to_nsrange (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { NSRange *valueptr = (NSRange *) (ptr ? ptr : xamarin_calloc (sizeof (NSRange))); *valueptr = [value rangeValue]; return valueptr; }
#if HAVE_UIKIT // Yep, these CoreGraphics-looking category method is defined in UIKit.
void *xamarin_nsvalue_to_cgaffinetransform (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CGAffineTransform *valueptr = (CGAffineTransform *) (ptr ? ptr : xamarin_calloc (sizeof (CGAffineTransform))); *valueptr = [value CGAffineTransformValue]; return valueptr; }
void *xamarin_nsvalue_to_cgpoint (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CGPoint *valueptr = (CGPoint *) (ptr ? ptr : xamarin_calloc (sizeof (CGPoint))); *valueptr = [value CGPointValue]; return valueptr; }
void *xamarin_nsvalue_to_cgrect (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CGRect *valueptr = (CGRect *) (ptr ? ptr : xamarin_calloc (sizeof (CGRect))); *valueptr = [value CGRectValue]; return valueptr; }
void *xamarin_nsvalue_to_cgsize (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CGSize *valueptr = (CGSize *) (ptr ? ptr : xamarin_calloc (sizeof (CGSize))); *valueptr = [value CGSizeValue]; return valueptr; }
void *xamarin_nsvalue_to_cgvector (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CGVector *valueptr = (CGVector *) (ptr ? ptr : xamarin_calloc (sizeof (CGVector))); *valueptr = [value CGVectorValue]; return valueptr; }
void *xamarin_nsvalue_to_nsdirectionaledgeinsets(NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) {NSDirectionalEdgeInsets *valueptr =(NSDirectionalEdgeInsets *) (ptr ? ptr : xamarin_calloc (sizeof (NSDirectionalEdgeInsets)));*valueptr = [value directionalEdgeInsetsValue];return valueptr; }
void *xamarin_nsvalue_to_cgaffinetransform (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CGAffineTransform *valueptr = (CGAffineTransform *) (ptr ? ptr : xamarin_calloc (sizeof (CGAffineTransform))); *valueptr = [value CGAffineTransformValue]; return valueptr; }
void *xamarin_nsvalue_to_cgpoint (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CGPoint *valueptr = (CGPoint *) (ptr ? ptr : xamarin_calloc (sizeof (CGPoint))); *valueptr = [value CGPointValue]; return valueptr; }
void *xamarin_nsvalue_to_cgrect (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CGRect *valueptr = (CGRect *) (ptr ? ptr : xamarin_calloc (sizeof (CGRect))); *valueptr = [value CGRectValue]; return valueptr; }
void *xamarin_nsvalue_to_cgsize (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CGSize *valueptr = (CGSize *) (ptr ? ptr : xamarin_calloc (sizeof (CGSize))); *valueptr = [value CGSizeValue]; return valueptr; }
void *xamarin_nsvalue_to_cgvector (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CGVector *valueptr = (CGVector *) (ptr ? ptr : xamarin_calloc (sizeof (CGVector))); *valueptr = [value CGVectorValue]; return valueptr; }
void *xamarin_nsvalue_to_nsdirectionaledgeinsets(NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) {NSDirectionalEdgeInsets *valueptr =(NSDirectionalEdgeInsets *) (ptr ? ptr : xamarin_calloc (sizeof (NSDirectionalEdgeInsets)));*valueptr = [value directionalEdgeInsetsValue];return valueptr; }
#endif
#if HAVE_COREANIMATION
void *xamarin_nsvalue_to_catransform3d (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CATransform3D *valueptr = (CATransform3D *) (ptr ? ptr : xamarin_calloc (sizeof (CATransform3D))); *valueptr = [value CATransform3DValue]; return valueptr; }
void *xamarin_nsvalue_to_catransform3d (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CATransform3D *valueptr = (CATransform3D *) (ptr ? ptr : xamarin_calloc (sizeof (CATransform3D))); *valueptr = [value CATransform3DValue]; return valueptr; }
#endif
#if HAVE_MAPKIT // Yep, this is defined in MapKit.
void *xamarin_nsvalue_to_cllocationcoordinate2d (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CLLocationCoordinate2D *valueptr = (CLLocationCoordinate2D *) (ptr ? ptr : xamarin_calloc (sizeof (CLLocationCoordinate2D))); *valueptr = [value MKCoordinateValue]; return valueptr; }
void *xamarin_nsvalue_to_cllocationcoordinate2d (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CLLocationCoordinate2D *valueptr = (CLLocationCoordinate2D *) (ptr ? ptr : xamarin_calloc (sizeof (CLLocationCoordinate2D))); *valueptr = [value MKCoordinateValue]; return valueptr; }
#endif
#if HAVE_COREMEDIA
void *xamarin_nsvalue_to_cmtime (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CMTime *valueptr = (CMTime *) (ptr ? ptr : xamarin_calloc (sizeof (CMTime))); *valueptr = [value CMTimeValue]; return valueptr; }
void *xamarin_nsvalue_to_cmtimemapping (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CMTimeMapping *valueptr = (CMTimeMapping *) (ptr ? ptr : xamarin_calloc (sizeof (CMTimeMapping))); *valueptr = [value CMTimeMappingValue]; return valueptr; }
void *xamarin_nsvalue_to_cmtimerange (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { CMTimeRange *valueptr = (CMTimeRange *) (ptr ? ptr : xamarin_calloc (sizeof (CMTimeRange))); *valueptr = [value CMTimeRangeValue]; return valueptr; }
void *xamarin_nsvalue_to_cmtime (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CMTime *valueptr = (CMTime *) (ptr ? ptr : xamarin_calloc (sizeof (CMTime))); *valueptr = [value CMTimeValue]; return valueptr; }
void *xamarin_nsvalue_to_cmtimemapping (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CMTimeMapping *valueptr = (CMTimeMapping *) (ptr ? ptr : xamarin_calloc (sizeof (CMTimeMapping))); *valueptr = [value CMTimeMappingValue]; return valueptr; }
void *xamarin_nsvalue_to_cmtimerange (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { CMTimeRange *valueptr = (CMTimeRange *) (ptr ? ptr : xamarin_calloc (sizeof (CMTimeRange))); *valueptr = [value CMTimeRangeValue]; return valueptr; }
#endif
#if HAVE_MAPKIT
void *xamarin_nsvalue_to_mkcoordinatespan (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { MKCoordinateSpan *valueptr = (MKCoordinateSpan *) (ptr ? ptr : xamarin_calloc (sizeof (MKCoordinateSpan))); *valueptr = [value MKCoordinateSpanValue]; return valueptr; }
void *xamarin_nsvalue_to_mkcoordinatespan (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { MKCoordinateSpan *valueptr = (MKCoordinateSpan *) (ptr ? ptr : xamarin_calloc (sizeof (MKCoordinateSpan))); *valueptr = [value MKCoordinateSpanValue]; return valueptr; }
#endif
void *xamarin_nsvalue_to_scnmatrix4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { SCNMatrix4 *valueptr = (SCNMatrix4 *) (ptr ? ptr : xamarin_calloc (sizeof (SCNMatrix4))); *valueptr = [value SCNMatrix4Value]; return valueptr; }
void *xamarin_nsvalue_to_scnmatrix4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { SCNMatrix4 *valueptr = (SCNMatrix4 *) (ptr ? ptr : xamarin_calloc (sizeof (SCNMatrix4))); *valueptr = [value SCNMatrix4Value]; return valueptr; }
void *
xamarin_nsvalue_to_scnvector3 (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle)
xamarin_nsvalue_to_scnvector3 (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle)
{
#if TARGET_OS_IOS && defined (__arm__)
// In earlier versions of iOS [NSValue SCNVector3Value] would return 4
@ -852,62 +852,62 @@ xamarin_nsvalue_to_scnvector3 (NSValue *value, void *ptr, MonoClass *managedType
return valueptr;
}
void *xamarin_nsvalue_to_scnvector4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { SCNVector4 *valueptr = (SCNVector4 *) (ptr ? ptr : xamarin_calloc (sizeof (SCNVector4))); *valueptr = [value SCNVector4Value]; return valueptr; }
void *xamarin_nsvalue_to_scnvector4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { SCNVector4 *valueptr = (SCNVector4 *) (ptr ? ptr : xamarin_calloc (sizeof (SCNVector4))); *valueptr = [value SCNVector4Value]; return valueptr; }
#if HAVE_UIKIT
void *xamarin_nsvalue_to_uiedgeinsets (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { UIEdgeInsets *valueptr = (UIEdgeInsets *) (ptr ? ptr : xamarin_calloc (sizeof (UIEdgeInsets))); *valueptr = [value UIEdgeInsetsValue]; return valueptr; }
void *xamarin_nsvalue_to_uioffset (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle) { UIOffset *valueptr = (UIOffset *) (ptr ? ptr : xamarin_calloc (sizeof (UIOffset))); *valueptr = [value UIOffsetValue]; return valueptr; }
void *xamarin_nsvalue_to_uiedgeinsets (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { UIEdgeInsets *valueptr = (UIEdgeInsets *) (ptr ? ptr : xamarin_calloc (sizeof (UIEdgeInsets))); *valueptr = [value UIEdgeInsetsValue]; return valueptr; }
void *xamarin_nsvalue_to_uioffset (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle) { UIOffset *valueptr = (UIOffset *) (ptr ? ptr : xamarin_calloc (sizeof (UIOffset))); *valueptr = [value UIOffsetValue]; return valueptr; }
#endif
id xamarin_bool_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithBool: *(BOOL *) mono_object_unbox (value)]; }
id xamarin_sbyte_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithChar: *(int8_t *) mono_object_unbox (value)]; }
id xamarin_byte_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedChar: *(uint8_t *) mono_object_unbox (value)]; }
id xamarin_short_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithShort: *(int16_t *) mono_object_unbox (value)]; }
id xamarin_ushort_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedShort: *(uint16_t *) mono_object_unbox (value)]; }
id xamarin_int_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithInt: *(int32_t *) mono_object_unbox (value)]; }
id xamarin_uint_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedInt: *(uint32_t *) mono_object_unbox (value)]; }
id xamarin_long_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithLongLong: *(int64_t *) mono_object_unbox (value)]; }
id xamarin_ulong_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedLongLong: *(uint64_t *) mono_object_unbox (value)]; }
id xamarin_nint_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithInteger: *(NSInteger *) mono_object_unbox (value)]; }
id xamarin_nuint_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedInteger: *(NSUInteger *) mono_object_unbox (value)]; }
id xamarin_float_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithFloat: *(float *) mono_object_unbox (value)]; }
id xamarin_double_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithDouble: *(double *) mono_object_unbox (value)]; }
id xamarin_bool_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithBool: *(BOOL *) mono_object_unbox (value)]; }
id xamarin_sbyte_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithChar: *(int8_t *) mono_object_unbox (value)]; }
id xamarin_byte_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedChar: *(uint8_t *) mono_object_unbox (value)]; }
id xamarin_short_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithShort: *(int16_t *) mono_object_unbox (value)]; }
id xamarin_ushort_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedShort: *(uint16_t *) mono_object_unbox (value)]; }
id xamarin_int_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithInt: *(int32_t *) mono_object_unbox (value)]; }
id xamarin_uint_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedInt: *(uint32_t *) mono_object_unbox (value)]; }
id xamarin_long_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithLongLong: *(int64_t *) mono_object_unbox (value)]; }
id xamarin_ulong_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedLongLong: *(uint64_t *) mono_object_unbox (value)]; }
id xamarin_nint_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithInteger: *(NSInteger *) mono_object_unbox (value)]; }
id xamarin_nuint_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithUnsignedInteger: *(NSUInteger *) mono_object_unbox (value)]; }
id xamarin_float_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithFloat: *(float *) mono_object_unbox (value)]; }
id xamarin_double_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithDouble: *(double *) mono_object_unbox (value)]; }
#if __POINTER_WIDTH__ == 32
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithFloat: *(float *) mono_object_unbox (value)]; }
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithFloat: *(float *) mono_object_unbox (value)]; }
#elif __POINTER_WIDTH__ == 64
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 *exception_gchandle) { return [NSNumber numberWithDouble: *(double *) mono_object_unbox (value)]; }
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSNumber numberWithDouble: *(double *) mono_object_unbox (value)]; }
#else
#error Invalid pointer size.
#endif
id xamarin_nsrange_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithRange: *(NSRange *) mono_object_unbox (value)]; }
id xamarin_nsrange_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithRange: *(NSRange *) mono_object_unbox (value)]; }
#if HAVE_UIKIT // yep, these CoreGraphics-looking category methods are defined in UIKit
id xamarin_cgaffinetransform_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCGAffineTransform: *(CGAffineTransform *) mono_object_unbox (value)]; }
id xamarin_cgpoint_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCGPoint: *(CGPoint *) mono_object_unbox (value)]; }
id xamarin_cgrect_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCGRect: *(CGRect *) mono_object_unbox (value)]; }
id xamarin_cgsize_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCGSize: *(CGSize *) mono_object_unbox (value)]; }
id xamarin_cgvector_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCGVector: *(CGVector *) mono_object_unbox (value)]; }
id xamarin_nsdirectionaledgeinsets_to_nsvalue(MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithDirectionalEdgeInsets:*(NSDirectionalEdgeInsets *)mono_object_unbox (value)]; }
id xamarin_cgaffinetransform_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCGAffineTransform: *(CGAffineTransform *) mono_object_unbox (value)]; }
id xamarin_cgpoint_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCGPoint: *(CGPoint *) mono_object_unbox (value)]; }
id xamarin_cgrect_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCGRect: *(CGRect *) mono_object_unbox (value)]; }
id xamarin_cgsize_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCGSize: *(CGSize *) mono_object_unbox (value)]; }
id xamarin_cgvector_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCGVector: *(CGVector *) mono_object_unbox (value)]; }
id xamarin_nsdirectionaledgeinsets_to_nsvalue(MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithDirectionalEdgeInsets:*(NSDirectionalEdgeInsets *)mono_object_unbox (value)]; }
#endif
#if HAVE_COREANIMATION
id xamarin_catransform3d_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCATransform3D: *(CATransform3D *) mono_object_unbox (value)]; }
id xamarin_catransform3d_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCATransform3D: *(CATransform3D *) mono_object_unbox (value)]; }
#endif
#if HAVE_MAPKIT // Yep, this is defined in MapKit.
id xamarin_cllocationcoordinate2d_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithMKCoordinate: *(CLLocationCoordinate2D *) mono_object_unbox (value)]; }
id xamarin_cllocationcoordinate2d_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithMKCoordinate: *(CLLocationCoordinate2D *) mono_object_unbox (value)]; }
#endif
#if HAVE_COREMEDIA
id xamarin_cmtime_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCMTime: *(CMTime *) mono_object_unbox (value)]; }
id xamarin_cmtimemapping_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCMTimeMapping: *(CMTimeMapping *) mono_object_unbox (value)]; }
id xamarin_cmtimerange_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithCMTimeRange: *(CMTimeRange *) mono_object_unbox (value)]; }
id xamarin_cmtime_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCMTime: *(CMTime *) mono_object_unbox (value)]; }
id xamarin_cmtimemapping_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCMTimeMapping: *(CMTimeMapping *) mono_object_unbox (value)]; }
id xamarin_cmtimerange_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithCMTimeRange: *(CMTimeRange *) mono_object_unbox (value)]; }
#endif
#if HAVE_MAPKIT
id xamarin_mkcoordinatespan_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithMKCoordinateSpan: *(MKCoordinateSpan *) mono_object_unbox (value)]; }
id xamarin_mkcoordinatespan_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithMKCoordinateSpan: *(MKCoordinateSpan *) mono_object_unbox (value)]; }
#endif
id xamarin_scnmatrix4_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithSCNMatrix4: *(SCNMatrix4 *) mono_object_unbox (value)]; }
id xamarin_scnvector3_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithSCNVector3: *(SCNVector3 *) mono_object_unbox (value)]; }
id xamarin_scnvector4_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithSCNVector4: *(SCNVector4 *) mono_object_unbox (value)]; }
id xamarin_scnmatrix4_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithSCNMatrix4: *(SCNMatrix4 *) mono_object_unbox (value)]; }
id xamarin_scnvector3_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithSCNVector3: *(SCNVector3 *) mono_object_unbox (value)]; }
id xamarin_scnvector4_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithSCNVector4: *(SCNVector4 *) mono_object_unbox (value)]; }
#if HAVE_UIKIT
id xamarin_uiedgeinsets_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithUIEdgeInsets: *(UIEdgeInsets *) mono_object_unbox (value)]; }
id xamarin_uioffset_to_nsvalue (MonoObject *value, guint32 *exception_gchandle) { return [NSValue valueWithUIOffset: *(UIOffset *) mono_object_unbox (value)]; }
id xamarin_uiedgeinsets_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithUIEdgeInsets: *(UIEdgeInsets *) mono_object_unbox (value)]; }
id xamarin_uioffset_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle) { return [NSValue valueWithUIOffset: *(UIOffset *) mono_object_unbox (value)]; }
#endif
#pragma clang diagnostic pop
@ -1075,27 +1075,82 @@ xamarin_get_managed_to_nsvalue_func (MonoClass *managedType, MonoMethod *method,
}
void *
xamarin_smart_enum_to_nsstring (MonoObject *value, guint32 *exception_gchandle)
xamarin_smart_enum_to_nsstring (MonoObject *value, guint32 context /* token ref */, guint32 *exception_gchandle)
{
int handle = mono_gchandle_new (value, FALSE);
NSString *rv = xamarin_convert_smart_enum_to_nsstring (GINT_TO_POINTER (handle), exception_gchandle);
mono_gchandle_free (handle);
return rv;
if (context == INVALID_TOKEN_REF) {
// This requires the dynamic registrar to invoke the correct conversion function
int handle = mono_gchandle_new (value, FALSE);
NSString *rv = xamarin_convert_smart_enum_to_nsstring (GINT_TO_POINTER (handle), exception_gchandle);
mono_gchandle_free (handle);
return rv;
} else {
// The static registrar found the correct conversion function, and provided a token ref we can use
// to find it (and invoke it), without needing the dynamic registrar.
MonoMethod *managed_method;
MonoObject *exception = NULL;
MonoObject *retval;
void *arg_ptrs [1];
managed_method = xamarin_get_managed_method_for_token (context /* token ref */, exception_gchandle);
if (*exception_gchandle != 0) return NULL;
arg_ptrs [0] = mono_object_unbox (value);
retval = mono_runtime_invoke (managed_method, NULL, arg_ptrs, &exception);
if (exception) {
*exception_gchandle = mono_gchandle_new (exception, FALSE);
return NULL;
}
if (retval == NULL)
return NULL;
return xamarin_get_nsobject_handle (retval);
}
}
void *
xamarin_nsstring_to_smart_enum (id value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle)
xamarin_nsstring_to_smart_enum (id value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle)
{
void *rv = xamarin_convert_nsstring_to_smart_enum (value, mono_type_get_object (mono_domain_get (), mono_class_get_type (managedType)), exception_gchandle);
if (*exception_gchandle != 0)
return ptr;
int handle = GPOINTER_TO_INT (rv);
int gc_handle = 0;
MonoObject *obj;
if (context == INVALID_TOKEN_REF) {
// This requires the dynamic registrar to invoke the correct conversion function
void *rv = xamarin_convert_nsstring_to_smart_enum (value, mono_type_get_object (mono_domain_get (), mono_class_get_type (managedType)), exception_gchandle);
if (*exception_gchandle != 0)
return ptr;
gc_handle = GPOINTER_TO_INT (rv);
obj = mono_gchandle_get_target (gc_handle);
} else {
// The static registrar found the correct conversion function, and provided a token ref we can use
// to find it (and invoke it), without needing the dynamic registrar.
MonoMethod *managed_method;
void *arg_ptrs [1];
MonoObject *exception = NULL;
managed_method = xamarin_get_managed_method_for_token (context /* token ref */, exception_gchandle);
if (*exception_gchandle != 0) return NULL;
arg_ptrs [0] = xamarin_get_nsobject_with_type_for_ptr (value, false, xamarin_get_parameter_type (managed_method, 0), exception_gchandle);
if (*exception_gchandle != 0) return NULL;
obj = mono_runtime_invoke (managed_method, NULL, arg_ptrs, &exception);
if (exception) {
*exception_gchandle = mono_gchandle_new (exception, FALSE);
return NULL;
}
}
int size = mono_class_value_size (managedType, NULL);
if (!ptr)
ptr = xamarin_calloc (size);
void *value_ptr = mono_object_unbox (mono_gchandle_get_target (handle));
void *value_ptr = mono_object_unbox (obj);
memcpy (ptr, value_ptr, size);
mono_gchandle_free (handle);
if (context == INVALID_TOKEN_REF)
mono_gchandle_free (gc_handle);
return ptr;
}
@ -1112,7 +1167,7 @@ xamarin_get_smart_enum_to_nsstring_func (MonoClass *managedType, MonoMethod *met
}
NSArray *
xamarin_convert_managed_to_nsarray_with_func (MonoArray *array, xamarin_managed_to_id_func convert, guint32 *exception_gchandle)
xamarin_convert_managed_to_nsarray_with_func (MonoArray *array, xamarin_managed_to_id_func convert, guint32 context, guint32 *exception_gchandle)
{
id *buf = NULL;
NSArray *rv = NULL;
@ -1130,7 +1185,7 @@ xamarin_convert_managed_to_nsarray_with_func (MonoArray *array, xamarin_managed_
char *ptr = (char *) mono_array_addr_with_size (array, element_size, 0);
for (int i = 0; i < length; i++) {
MonoObject *value = mono_value_box (mono_domain_get (), element_class, ptr + element_size * i);
buf [i] = convert (value, exception_gchandle);
buf [i] = convert (value, context, exception_gchandle);
if (*exception_gchandle != 0)
goto exception_handling;
}
@ -1143,7 +1198,7 @@ exception_handling:
}
MonoArray *
xamarin_convert_nsarray_to_managed_with_func (NSArray *array, MonoClass *managedElementType, xamarin_id_to_managed_func convert, guint32 *exception_gchandle)
xamarin_convert_nsarray_to_managed_with_func (NSArray *array, MonoClass *managedElementType, xamarin_id_to_managed_func convert, guint32 context, guint32 *exception_gchandle)
{
if (array == NULL)
return NULL;
@ -1158,7 +1213,7 @@ xamarin_convert_nsarray_to_managed_with_func (NSArray *array, MonoClass *managed
int element_size = mono_class_value_size (managedElementType, NULL);
char *ptr = (char *) mono_array_addr_with_size (rv, element_size, 0);
for (int i = 0; i < length; i++) {
valueptr = convert ([array objectAtIndex: i], valueptr, managedElementType, exception_gchandle);
valueptr = convert ([array objectAtIndex: i], valueptr, managedElementType, context, exception_gchandle);
if (*exception_gchandle != 0)
goto exception_handling;
memcpy (ptr, valueptr, element_size);
@ -1172,23 +1227,23 @@ exception_handling:
}
NSNumber *
xamarin_convert_managed_to_nsnumber (MonoObject *value, MonoClass *managedType, MonoMethod *method, guint32 *exception_gchandle)
xamarin_convert_managed_to_nsnumber (MonoObject *value, MonoClass *managedType, MonoMethod *method, guint32 context, guint32 *exception_gchandle)
{
xamarin_managed_to_id_func convert = xamarin_get_managed_to_nsnumber_func (managedType, method, exception_gchandle);
if (*exception_gchandle != 0)
return NULL;
return convert (value, exception_gchandle);
return convert (value, context, exception_gchandle);
}
NSValue *
xamarin_convert_managed_to_nsvalue (MonoObject *value, MonoClass *managedType, MonoMethod *method, guint32 *exception_gchandle)
xamarin_convert_managed_to_nsvalue (MonoObject *value, MonoClass *managedType, MonoMethod *method, guint32 context, guint32 *exception_gchandle)
{
xamarin_managed_to_id_func convert = xamarin_get_managed_to_nsvalue_func (managedType, method, exception_gchandle);
if (*exception_gchandle != 0)
return NULL;
return convert (value, exception_gchandle);
return convert (value, context, exception_gchandle);
}
guint32

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

@ -65,6 +65,7 @@ typedef struct __attribute__((packed)) {
uint8_t assembly_index:7; /* 0-based index into the '__xamarin_registration_assemblies' array. Max 127 (registered) assemblies before a full token reference has to be used */
uint32_t token:24; /* RID of the corresponding metadata token. The exact type of metadata token depends on the context where the token reference is used. */
} MTTokenReference;
static const uint32_t INVALID_TOKEN_REF = 0xFFFFFFFF;
typedef struct __attribute__((packed)) {
void *handle;
@ -154,6 +155,7 @@ char * xamarin_strdup_printf (const char *msg, ...);
void * xamarin_calloc (size_t size);
void xamarin_free (void *ptr);
MonoMethod * xamarin_get_reflection_method_method (MonoReflectionMethod *method);
MonoMethod * xamarin_get_managed_method_for_token (guint32 token_ref, guint32 *exception_gchandle);
void xamarin_framework_peer_lock ();
void xamarin_framework_peer_unlock ();
bool xamarin_file_exists (const char *path);

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

@ -49,16 +49,41 @@ enum ArgumentSemantic /* Xcode 4.4 doesn't like this ': int' */ {
/* Conversion functions */
// Function to convert from id to managed. If `ptr` is passed, the value type
// will be stored in this pointer. Otherwise a memory is allocated, and the
// return value must be freed using xamarin_free.
// Returns: a pointer to the value type. In case of an exception, 'ptr' is returned (and no memory allocated in any circumstances).
typedef void * (*xamarin_id_to_managed_func) (id value, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
// Function to convert from managed to id.
typedef id (*xamarin_managed_to_id_func) (MonoObject *value, guint32 *exception_gchandle);
// The xamarin_id_to_managed_func and xamarin_managed_to_id_func typedefs
// represents functions to convert to/from id and managed types.
//
// The `value` parameter is the value to convert.
//
// The `ptr` parameter is optional, if passed the resulting value type will be
// stored here. If NULL, memory is allocated and returned, and the return
// value must be freed using `xamarin_free`.
//
// The `managedType` parameter is the managed type to convert to.
//
// The `context` parameter is a conversion-specific value that may or may not
// be provided:
// * Smart enum conversions: The `context` parameter represents a token ref to
// the conversion method. The static registrar bakes those token refs in to
// the generated code, thus avoiding the need for finding the conversion
// method at runtime).
// * Other conversions: The `context` parameter is not used in other
// conversions at the moment.
//
// The `exception_gchandle` parameter is required, and will contain a GCHandle
// to any exceptions that occur.
//
// The return value is:
// * xamarin_id_to_managed_func: a pointer to the resulting value type. If
// `ptr` was passed, this value is also returned, otherwise newly allocated
// memory is returned (which must be freed with `xamarin_free`). If an
// exception occurs, 'ptr' is returned (and no memory allocated).
// * xamarin_managed_to_id_func: the resulting Objective-C object.
id xamarin_generate_conversion_to_native (MonoObject *value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 *exception_gchandle);
void * xamarin_generate_conversion_to_managed (id value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 *exception_gchandle, /*SList*/ void **free_list);
typedef void * (*xamarin_id_to_managed_func) (id value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
typedef id (*xamarin_managed_to_id_func) (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_generate_conversion_to_native (MonoObject *value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 context, guint32 *exception_gchandle);
void * xamarin_generate_conversion_to_managed (id value, MonoType *inputType, MonoType *outputType, MonoMethod *method, guint32 *exception_gchandle, guint32 context, /*SList*/ void **free_list);
NSNumber * xamarin_convert_managed_to_nsnumber (MonoObject *value, MonoType *managedType, MonoType *nativeType, MonoMethod *method, guint32 *exception_gchandle);
NSValue * xamarin_convert_managed_to_nsvalue (MonoObject *value, MonoType *managedType, MonoType *nativeType, MonoMethod *method, guint32 *exception_gchandle);
NSString * xamarin_convert_managed_to_nsstring (MonoObject *value, MonoType *managedType, MonoType *nativeType, MonoMethod *method, guint32 *exception_gchandle);
@ -76,79 +101,79 @@ xamarin_managed_to_id_func xamarin_get_managed_to_nsvalue_func (MonoClass *manag
xamarin_id_to_managed_func xamarin_get_nsstring_to_smart_enum_func (MonoClass *managedType, MonoMethod *method, guint32 *exception_gchandle);
xamarin_managed_to_id_func xamarin_get_smart_enum_to_nsstring_func (MonoClass *managedType, MonoMethod *method, guint32 *exception_gchandle);
NSArray * xamarin_convert_managed_to_nsarray_with_func (MonoArray *array, xamarin_managed_to_id_func convert, guint32 *exception_gchandle);
MonoArray * xamarin_convert_nsarray_to_managed_with_func (NSArray *array, MonoClass *managedElementType, xamarin_id_to_managed_func convert, guint32 *exception_gchandle);
NSArray * xamarin_convert_managed_to_nsarray_with_func (MonoArray *array, xamarin_managed_to_id_func convert, guint32 context, guint32 *exception_gchandle);
MonoArray * xamarin_convert_nsarray_to_managed_with_func (NSArray *array, MonoClass *managedElementType, xamarin_id_to_managed_func convert, guint32 context, guint32 *exception_gchandle);
// Returns a pointer to the value type, which must be freed using xamarin_free.
void *xamarin_nsnumber_to_bool (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_sbyte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_byte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_short (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_ushort (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_int (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_uint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_long (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_ulong (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_nint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_nuint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_float (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_double (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_nfloat (NSNumber *number, void *ptr, MonoClass *managedType, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_bool (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_sbyte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_byte (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_short (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_ushort (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_int (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_uint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_long (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_ulong (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_nint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_nuint (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_float (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_double (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
void *xamarin_nsnumber_to_nfloat (NSNumber *number, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_gchandle);
// Returns a pointer to the value type, which must be freed using xamarin_free
void *xamarin_nsvalue_to_nsrange (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgaffinetransform (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgpoint (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgrect (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgsize (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgvector (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_catransform3d (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cllocationcoordinate2d (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cmtime (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cmtimemapping (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cmtimerange (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_mkcoordinatespan (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_scnmatrix4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_scnvector3 (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_scnvector4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_uiedgeinsets (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_uioffset (NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_nsdirectionaledgeinsets(NSValue *value, void *ptr, MonoClass *managedType, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_nsrange (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgaffinetransform (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgpoint (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgrect (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgsize (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cgvector (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_catransform3d (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cllocationcoordinate2d (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cmtime (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cmtimemapping (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_cmtimerange (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_mkcoordinatespan (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_scnmatrix4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_scnvector3 (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_scnvector4 (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_uiedgeinsets (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_uioffset (NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
void *xamarin_nsvalue_to_nsdirectionaledgeinsets(NSValue *value, void *ptr, MonoClass *managedType, guint32 context, guint32 *exception_ghandle);
id xamarin_bool_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_sbyte_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_byte_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_short_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_ushort_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_int_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_uint_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_long_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_ulong_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_nint_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_nuint_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_float_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_double_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 *exception_gchandle);
id xamarin_bool_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_sbyte_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_byte_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_short_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_ushort_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_int_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_uint_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_long_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_ulong_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_nint_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_nuint_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_float_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_double_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_nfloat_to_nsnumber (MonoObject *value, guint32 contxt, guint32 *exception_gchandle);
id xamarin_nsrange_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cgaffinetransform_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cgpoint_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cgrect_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cgsize_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cgvector_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_catransform3d_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cllocationcoordinate2d_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cmtime_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cmtimemapping_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_cmtimerange_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_mkcoordinatespan_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_scnmatrix4_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_scnvector3_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_scnvector4_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_uiedgeinsets_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_uioffset_to_nsvalue (MonoObject *value, guint32 *exception_gchandle);
id xamarin_nsdirectionaledgeinsets_to_nsvalue(MonoObject *value, guint32 *exception_gchandle);
id xamarin_nsrange_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cgaffinetransform_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cgpoint_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cgrect_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cgsize_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cgvector_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_catransform3d_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cllocationcoordinate2d_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cmtime_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cmtimemapping_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_cmtimerange_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_mkcoordinatespan_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_scnmatrix4_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_scnvector3_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_scnvector4_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_uiedgeinsets_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_uioffset_to_nsvalue (MonoObject *value, guint32 context, guint32 *exception_gchandle);
id xamarin_nsdirectionaledgeinsets_to_nsvalue(MonoObject *value, guint32 context, guint32 *exception_gchandle);
/* Copied from SGen */

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

@ -3887,17 +3887,28 @@ namespace XamCore.Registrar {
string func;
string nativeTypeName;
string token = "0";
if (underlyingNativeType.Is (Foundation, "NSNumber")) {
func = GetNSNumberToManagedFunc (underlyingManagedType, inputType, outputType, descriptiveMethodName, out nativeTypeName);
} else if (underlyingNativeType.Is (Foundation, "NSValue")) {
func = GetNSValueToManagedFunc (underlyingManagedType, inputType, outputType, descriptiveMethodName, out nativeTypeName);
} else if (underlyingNativeType.Is (Foundation, "NSString")) {
func = GetNSStringToSmartEnumFunc (underlyingManagedType, inputType, outputType, descriptiveMethodName, managedClassExpression, out nativeTypeName);
MethodDefinition getConstantMethod, getValueMethod;
if (!IsSmartEnum (underlyingManagedType, out getConstantMethod, out getValueMethod)) {
// method linked away!? this should already be verified
ErrorHelper.Show (ErrorHelper.CreateWarning (99, $"Internal error: the smart enum {underlyingManagedType.FullName} doesn't seem to be a smart enum after all. Please file a bug report with a test case (https://bugzilla.xamarin.com)."));
token = "INVALID_TOKEN_REF";
} else {
token = $"0x{CreateTokenReference (getValueMethod, TokenType.Method):X} /* {getValueMethod.FullName} */";
}
} else {
throw ErrorHelper.CreateError (99, $"Internal error: can't convert from '{inputType.FullName}' to '{outputType.FullName}' in {descriptiveMethodName}. Please file a bug report with a test case (https://bugzilla.xamarin.com).");
}
if (isManagedArray) {
sb.AppendLine ($"{outputName} = xamarin_convert_nsarray_to_managed_with_func ({inputName}, {classVariableName}, (xamarin_id_to_managed_func) {func}, &exception_gchandle);");
sb.AppendLine ($"xamarin_id_to_managed_func {inputName}_conv_func = (xamarin_id_to_managed_func) {func};");
sb.AppendLine ("if (exception_gchandle != 0) goto exception_handling;");
sb.AppendLine ($"{outputName} = xamarin_convert_nsarray_to_managed_with_func ({inputName}, {classVariableName}, {inputName}_conv_func, {token}, &exception_gchandle);");
sb.AppendLine ("if (exception_gchandle != 0) goto exception_handling;");
} else {
var tmpName = $"{inputName}_conv_tmp";
@ -3905,11 +3916,11 @@ namespace XamCore.Registrar {
if (isManagedNullable) {
var tmpName2 = $"{inputName}_conv_ptr";
body_setup.AppendLine ($"void *{tmpName2} = NULL;");
sb.AppendLine ($"{tmpName2} = {func} ({inputName}, &{tmpName}, {classVariableName}, &exception_gchandle);");
sb.AppendLine ($"{tmpName2} = {func} ({inputName}, &{tmpName}, {classVariableName}, {token}, &exception_gchandle);");
sb.AppendLine ("if (exception_gchandle != 0) goto exception_handling;");
sb.AppendLine ($"{outputName} = mono_value_box (mono_domain_get (), {classVariableName}, {tmpName2});");
} else {
sb.AppendLine ($"{outputName} = {func} ({inputName}, &{tmpName}, {classVariableName}, &exception_gchandle);");
sb.AppendLine ($"{outputName} = {func} ({inputName}, &{tmpName}, {classVariableName}, {token}, &exception_gchandle);");
sb.AppendLine ("if (exception_gchandle != 0) goto exception_handling;");
}
}
@ -3962,20 +3973,29 @@ namespace XamCore.Registrar {
sb.AppendLine ($"if ({inputName}) {{");
string func;
string token = "0";
if (underlyingNativeType.Is (Foundation, "NSNumber")) {
func = GetManagedToNSNumberFunc (underlyingManagedType, inputType, outputType, descriptiveMethodName);
} else if (underlyingNativeType.Is (Foundation, "NSValue")) {
func = GetManagedToNSValueFunc (underlyingManagedType, inputType, outputType, descriptiveMethodName);
} else if (underlyingNativeType.Is (Foundation, "NSString")) {
func = GetSmartEnumToNSStringFunc (underlyingManagedType, inputType, outputType, descriptiveMethodName, classVariableName);
MethodDefinition getConstantMethod, getValueMethod;
if (!IsSmartEnum (underlyingManagedType, out getConstantMethod, out getValueMethod)) {
// method linked away!? this should already be verified
ErrorHelper.Show (ErrorHelper.CreateWarning (99, $"Internal error: the smart enum {underlyingManagedType.FullName} doesn't seem to be a smart enum after all. Please file a bug report with a test case (https://bugzilla.xamarin.com)."));
token = "INVALID_TOKEN_REF";
} else {
token = $"0x{CreateTokenReference (getConstantMethod, TokenType.Method):X} /* {getConstantMethod.FullName} */";
}
} else {
throw ErrorHelper.CreateError (99, $"Internal error: can't convert from '{inputType.FullName}' to '{outputType.FullName}' in {descriptiveMethodName}. Please file a bug report with a test case (https://bugzilla.xamarin.com).");
}
if (isManagedArray) {
sb.AppendLine ($"{outputName} = xamarin_convert_managed_to_nsarray_with_func ((MonoArray *) {inputName}, (xamarin_managed_to_id_func) {func}, &exception_gchandle);");
sb.AppendLine ($"{outputName} = xamarin_convert_managed_to_nsarray_with_func ((MonoArray *) {inputName}, (xamarin_managed_to_id_func) {func}, {token}, &exception_gchandle);");
} else {
sb.AppendLine ($"{outputName} = {func} ({inputName}, &exception_gchandle);");
sb.AppendLine ($"{outputName} = {func} ({inputName}, {token}, &exception_gchandle);");
}
sb.AppendLine ($"if (exception_gchandle != 0) goto exception_handling;");