diff --git a/runtime/trampolines-invoke.m b/runtime/trampolines-invoke.m index 578b5b9ca8..addfe0850d 100644 --- a/runtime/trampolines-invoke.m +++ b/runtime/trampolines-invoke.m @@ -51,6 +51,22 @@ xamarin_get_exception_for_parameter (int code, guint32 inner_exception_gchandle, return exception_gchandle; } +NSString * +xamarin_string_to_nsstring (MonoString *obj, bool retain) +{ + if (obj == NULL) + return NULL; + + char *str = mono_string_to_utf8 ((MonoString *) obj); + NSString *arg; + if (retain) { + arg = [[NSString alloc] initWithUTF8String:str]; + } else { + arg = [NSString stringWithUTF8String:str]; + } + mono_free (str); + return arg; +} void xamarin_invoke_trampoline (enum TrampolineType type, id self, SEL sel, iterator_func iterator, marshal_return_value_func marshal_return_value, void *context) { @@ -545,10 +561,8 @@ xamarin_invoke_trampoline (enum TrampolineType type, id self, SEL sel, iterator_ *(NSObject **) arg = NULL; LOGZ (" writing back managed null string to argument at %p\n", arg); } else { - char *str = mono_string_to_utf8 (value); - *(NSObject **) arg = [[[NSString alloc] initWithUTF8String:str] autorelease]; + *(NSObject **) arg = xamarin_string_to_nsstring (value, false); LOGZ (" writing back managed string %p = %s to argument at %p\n", *(NSObject **) arg, str, arg); - mono_free (str); } } else if (xamarin_is_class_nsobject (p_klass)) { *(NSObject **) arg = xamarin_get_handle ((MonoObject *) arg_frame [ofs], &exception_gchandle); diff --git a/runtime/trampolines.m b/runtime/trampolines.m index 8c56525efc..9bba912eac 100644 --- a/runtime/trampolines.m +++ b/runtime/trampolines.m @@ -71,13 +71,7 @@ xamarin_marshal_return_value_impl (MonoType *mtype, const char *type, MonoObject 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, (void *) 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]; - - if (!retain) - [rv autorelease]; - mono_free (str); - return (void *) rv; + return xamarin_string_to_nsstring ((MonoString *) retval, retain); } else if (xamarin_is_class_array (r_klass)) { MonoClass *e_klass = mono_class_get_element_class (r_klass); bool is_string = e_klass == mono_get_string_class (); @@ -92,13 +86,7 @@ xamarin_marshal_return_value_impl (MonoType *mtype, const char *type, MonoObject MonoObject *value = mono_array_get (m_arr, MonoObject *, i); if (is_string) { - char *str = mono_string_to_utf8 ((MonoString *) value); - NSString *sv = [[NSString alloc] initWithUTF8String:str]; - - [sv autorelease]; - mono_free (str); - - v = sv; + v = xamarin_string_to_nsstring ((MonoString *) value, false); } else { v = xamarin_get_handle (value, exception_gchandle); if (*exception_gchandle != 0) { diff --git a/runtime/xamarin/trampolines.h b/runtime/xamarin/trampolines.h index b2c0fcb46f..be39a4992b 100644 --- a/runtime/xamarin/trampolines.h +++ b/runtime/xamarin/trampolines.h @@ -179,6 +179,8 @@ id xamarin_uiedgeinsets_to_nsvalue (MonoObject *value, void *context, id xamarin_uioffset_to_nsvalue (MonoObject *value, void *context, guint32 *exception_gchandle); id xamarin_nsdirectionaledgeinsets_to_nsvalue(MonoObject *value, void *context, guint32 *exception_gchandle); +NSString * xamarin_string_to_nsstring (MonoString *obj, bool retain); + /* Copied from SGen */ static inline void diff --git a/tools/common/StaticRegistrar.cs b/tools/common/StaticRegistrar.cs index 8d6becca50..36114096e6 100644 --- a/tools/common/StaticRegistrar.cs +++ b/tools/common/StaticRegistrar.cs @@ -3531,10 +3531,7 @@ namespace Registrar { setup_call_stack.AppendLine ("a{0} = *p{0} ? mono_string_new (mono_domain_get (), [(*p{0}) UTF8String]) : NULL;", i); setup_call_stack.AppendLine ("arg_ptrs [{0}] = &a{0};", i); body_setup.AppendLine ("char *str{0} = NULL;", i); - copyback.AppendLine ("str{0} = mono_string_to_utf8 (a{0});", i); - copyback.AppendLine ("*p{0} = [[NSString alloc] initWithUTF8String:str{0}];", i); - copyback.AppendLine ("[*p{0} autorelease];", i); - copyback.AppendLine ("mono_free (str{0});", i); + copyback.AppendLine ("*p{0} = xamarin_string_to_nsstring (a{0}, false);", i); } else { setup_call_stack.AppendLine ("arg_ptrs [{0}] = p{0} ? mono_string_new (mono_domain_get (), [p{0} UTF8String]) : NULL;", i); } @@ -3819,11 +3816,7 @@ namespace Registrar { setup_return.AppendLine ("MonoObject *value = mono_array_get ((MonoArray *) retval, MonoObject *, i);"); if (elementType.FullName == "System.String") { - setup_return.AppendLine ("char *str = mono_string_to_utf8 ((MonoString *) value);"); - setup_return.AppendLine ("NSString *sv = [[NSString alloc] initWithUTF8String:str];"); - setup_return.AppendLine ("[sv autorelease];"); - setup_return.AppendLine ("mono_free (str);"); - setup_return.AppendLine ("buf [i] = sv;"); + setup_return.AppendLine ("buf [i] = xamarin_string_to_nsstring ((MonoString *) value, false);"); } else if (IsNSObject (elementType)) { setup_return.AppendLine ("buf [i] = xamarin_get_nsobject_handle ((MonoObject *) value);"); } else if (IsINativeObject (elementType)) { @@ -3884,12 +3877,7 @@ namespace Registrar { setup_return.AppendLine ("res = retobj;"); } else if (type.FullName == "System.String") { // This should always be an NSString and never char* - setup_return.AppendLine ("char *str = mono_string_to_utf8 ((MonoString *) retval);"); - setup_return.AppendLine ("NSString *nsstr = [[NSString alloc] initWithUTF8String:str];"); - if (!retain) - setup_return.AppendLine ("[nsstr autorelease];"); - setup_return.AppendLine ("mono_free (str);"); - setup_return.AppendLine ("res = nsstr;"); + setup_return.AppendLine ("res = xamarin_string_to_nsstring ((MonoString *) retval, {0});", retain ? "true" : "false"); } else if (IsDelegate (type.Resolve ())) { var signature = "NULL"; var token = "INVALID_TOKEN_REF";