From: Zoltan Varga Date: Wed, 26 Feb 2014 21:16:34 +0000 (-0500) Subject: [runtime] Add support for jagged array ctors which create an array of arrays. Fixes... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=92388f7d09b0aeae25271229d438d6e065310fd9;p=mono.git [runtime] Add support for jagged array ctors which create an array of arrays. Fixes #17944. --- diff --git a/mcs/class/corlib/Test/System/ArrayTest.cs b/mcs/class/corlib/Test/System/ArrayTest.cs index fbea6549dc9..a1cc1a008cb 100644 --- a/mcs/class/corlib/Test/System/ArrayTest.cs +++ b/mcs/class/corlib/Test/System/ArrayTest.cs @@ -3618,5 +3618,22 @@ public class ArrayTest #endif + [Test] + public void JaggedArrayCtor () + { + var type = Type.GetType ("System.Object[][]"); + + ConstructorInfo ctor = null; + foreach (var c in type.GetConstructors ()) { + if (c.GetParameters ().Length == 2) + ctor = c; + } + Assert.IsNotNull (ctor); + var arr = (object[])ctor.Invoke (new object [] { 4, 10 }); + for (int i = 0; i < 4; ++i) { + Assert.IsNotNull (arr [i]); + Assert.AreEqual (10, ((object[])arr [i]).Length); + } + } } } diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 9ae7c6e3325..93853e594c1 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -2148,12 +2148,18 @@ mono_class_setup_methods (MonoClass *class) MonoMethodSignature *sig; int count_generic = 0, first_generic = 0; int method_num = 0; + gboolean jagged_ctor = FALSE; count = 3 + (class->rank > 1? 2: 1); mono_class_setup_interfaces (class, &error); g_assert (mono_error_ok (&error)); /*FIXME can this fail for array types?*/ + if (class->rank == 1 && class->element_class->rank) { + jagged_ctor = TRUE; + class->method.count ++; + } + if (class->interface_count) { count_generic = generic_array_methods (class); first_generic = count; @@ -2182,6 +2188,19 @@ mono_class_setup_methods (MonoClass *class) amethod = create_array_method (class, ".ctor", sig); methods [method_num++] = amethod; } + + if (jagged_ctor) { + /* Jagged arrays have an extra ctor in .net which creates an array of arrays */ + sig = mono_metadata_signature_alloc (class->image, class->rank + 1); + sig->ret = &mono_defaults.void_class->byval_arg; + sig->pinvoke = TRUE; + sig->hasthis = TRUE; + for (i = 0; i < class->rank + 1; ++i) + sig->params [i] = &mono_defaults.int32_class->byval_arg; + amethod = create_array_method (class, ".ctor", sig); + methods [method_num++] = amethod; + } + /* element Get (idx11, [idx2, ...]) */ sig = mono_metadata_signature_alloc (class->image, class->rank); sig->ret = &class->element_class->byval_arg; diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index e3241865924..e91e9e99d26 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -2843,6 +2843,18 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr for (i = 0; i < pcount; ++i) lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject)); + if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) { + /* This is a ctor for jagged arrays. MS creates an array of arrays. */ + MonoArray *arr = mono_array_new_full (mono_object_domain (params), m->klass, lengths, NULL); + + for (i = 0; i < mono_array_length (arr); ++i) { + MonoArray *subarray = mono_array_new_full (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL); + + mono_array_setref_fast (arr, i, subarray); + } + return (MonoObject*)arr; + } + if (m->klass->rank == pcount) { /* Only lengths provided. */ lower_bounds = NULL;