Browse Source

[netcore] Remap String ctors to the String:Ctor () methods. (#18357)

Zoltan Varga 6 years ago
parent
commit
ec7f4c68f9

+ 5 - 0
mono/metadata/marshal-ilgen.c

@@ -6332,7 +6332,12 @@ static void
 emit_create_string_hack_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *csig, MonoMethod *res)
 {
 	int i;
+
+#ifdef ENABLE_NETCORE
+	g_assert (!mono_method_signature_internal (res)->hasthis);
+#else
 	mono_mb_emit_byte (mb, CEE_LDARG_0);
+#endif
 	for (i = 1; i <= csig->param_count; i++)
 		mono_mb_emit_ldarg (mb, i);
 	mono_mb_emit_managed_call (mb, res, NULL);

+ 48 - 21
mono/metadata/marshal.c

@@ -3534,6 +3534,8 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions,
 
 	/* hack - redirect certain string constructors to CreateString */
 	if (piinfo->addr == ves_icall_System_String_ctor_RedirectToCreateString) {
+		MonoMethod *m;
+
 		g_assert (!pinvoke);
 		g_assert (method->string_ctor);
 		g_assert (sig->hasthis);
@@ -3543,35 +3545,60 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions,
 		csig->ret = string_type;
 		csig->pinvoke = 0;
 
+		res = NULL;
+#ifdef ENABLE_NETCORE
+		iter = NULL;
+		while ((m = mono_class_get_methods (mono_defaults.string_class, &iter))) {
+			/*
+			 * Find the corresponding String::Ctor () method which has the same signature but its static
+			 * and returns a string.
+			 */
+			if (!strcmp ("Ctor", m->name)) {
+				int i;
+
+				MonoMethodSignature *rsig = mono_method_signature_internal (m);
+				if (csig->param_count == rsig->param_count) {
+					for (i = 0; i < csig->param_count; ++i)
+						if (!mono_metadata_type_equal (csig->params [i], rsig->params [i]))
+							break;
+					if (i == csig->param_count) {
+						res = m;
+						break;
+					}
+				}
+			}
+		}
+#else
 		iter = NULL;
-		while ((res = mono_class_get_methods (mono_defaults.string_class, &iter))) {
-			if (!strcmp ("CreateString", res->name) &&
-				mono_metadata_signature_equal (csig, mono_method_signature_internal (res))) {
-				WrapperInfo *info;
+		while ((m = mono_class_get_methods (mono_defaults.string_class, &iter))) {
+			if (!strcmp ("CreateString", m->name) &&
+				mono_metadata_signature_equal (csig, mono_method_signature_internal (m))) {
+				res = m;
+				break;
+			}
+		}
+#endif
+		g_assert (res);
 
-				g_assert (!(res->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL));
-				g_assert (!(res->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL));
+		WrapperInfo *info;
 
-				/* create a wrapper to preserve .ctor in stack trace */
-				mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_MANAGED);
+		g_assert (!(res->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL));
+		g_assert (!(res->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL));
 
-				get_marshal_cb ()->emit_create_string_hack (mb, csig, res);
+		/* create a wrapper to preserve .ctor in stack trace */
+		mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_MANAGED);
 
-				info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_STRING_CTOR);
-				info->d.string_ctor.method = method;
+		get_marshal_cb ()->emit_create_string_hack (mb, csig, res);
 
-				/* use native_wrapper_cache because internal calls are looked up there */
-				res = mono_mb_create_and_cache_full (cache, method, mb, csig,
-													 csig->param_count + 1, info, NULL);
-				mono_mb_free (mb);
+		info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_STRING_CTOR);
+		info->d.string_ctor.method = method;
 
-				return res;
-			}
-		}
+		/* use native_wrapper_cache because internal calls are looked up there */
+		res = mono_mb_create_and_cache_full (cache, method, mb, csig,
+											 csig->param_count + 1, info, NULL);
+		mono_mb_free (mb);
 
-		/* exception will be thrown */
-		piinfo->addr = NULL;
-		g_warning ("cannot find CreateString for .ctor");
+		return res;
 	}
 
 	mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_NATIVE);

+ 1 - 1
netcore/System.Private.CoreLib/src/LinkerDescriptor/System.Private.CoreLib.xml

@@ -401,7 +401,7 @@
 			<method name="memcpy_aligned_8" />
 
 			<!-- marshal.c: mono_marshal_get_native_wrapper -->
-			<method name="CreateString"/>
+			<method name="Ctor"/>
 		</type>
 
 		<!-- socket-io.c: created/raised several time -->

+ 0 - 50
netcore/System.Private.CoreLib/src/System/String.Mono.cs

@@ -140,55 +140,5 @@ namespace System
 		}
 
 		#endregion
-
-		// Certain constructors are redirected to CreateString methods with
-		// matching argument list. The this pointer should not be used.
-		//
-		// TODO: Update runtime to call Ctor directly
-
-		unsafe String CreateString (sbyte* value)
-		{
-			return Ctor (value);
-		}
-
-		unsafe String CreateString (sbyte* value, int startIndex, int length)
-		{
-			return Ctor (value, startIndex, length);
-		}
-
-		unsafe String CreateString (char* value)
-		{
-			return Ctor (value);
-		}
-
-		unsafe String CreateString (char* value, int startIndex, int length)
-		{
-			return Ctor (value, startIndex, length);
-		}
-
-		String CreateString (char[] val, int startIndex, int length)
-		{
-			return Ctor (val, startIndex, length);
-		}
-
-		String CreateString (char [] val)
-		{
-			return Ctor (val);
-		}
-
-		String CreateString (char c, int count)
-		{
-			return Ctor (c, count);
-		}
-
-		unsafe String CreateString (sbyte* value, int startIndex, int length, System.Text.Encoding enc)
-		{
-			return Ctor (value, startIndex, length, enc);
-		}
-
-		String CreateString (ReadOnlySpan<char> value)
-		{
-			return Ctor (value);
-		}
 	}
 }