summaryrefslogtreecommitdiff
path: root/lang/mono2/patches/patch-ai
diff options
context:
space:
mode:
Diffstat (limited to 'lang/mono2/patches/patch-ai')
-rw-r--r--lang/mono2/patches/patch-ai207
1 files changed, 207 insertions, 0 deletions
diff --git a/lang/mono2/patches/patch-ai b/lang/mono2/patches/patch-ai
new file mode 100644
index 00000000000..27dd7fde259
--- /dev/null
+++ b/lang/mono2/patches/patch-ai
@@ -0,0 +1,207 @@
+$NetBSD: patch-ai,v 1.1 2013/06/17 12:43:28 wiz Exp $
+
+--- mono/metadata/object.c.orig 2009-10-26 20:44:10.000000000 +0000
++++ mono/metadata/object.c
+@@ -3353,6 +3353,135 @@ mono_install_runtime_invoke (MonoInvokeF
+ default_mono_runtime_invoke = func ? func: dummy_mono_runtime_invoke;
+ }
+
++/*
++ * is_widen_compatible:
++ *
++ * Tests if @candidate can be used in place of @type by means of a widening conversion.
++ * This means, for example, that a byte can be widened to an int and be used as argument in
++ * a reflection call.
++ *
++ * Returns true if @candidate can be widened to @type.
++ */
++static gboolean
++is_widen_compatible (MonoType * type, MonoType *candidate)
++{
++ if (type->type == candidate->type)
++ return TRUE;
++
++ switch (candidate->type) {
++ case MONO_TYPE_U1:
++ switch (type->type) {
++ case MONO_TYPE_U2:
++ case MONO_TYPE_I2:
++ case MONO_TYPE_CHAR:
++ case MONO_TYPE_U:
++ case MONO_TYPE_I:
++ case MONO_TYPE_U4:
++ case MONO_TYPE_I4:
++ case MONO_TYPE_U8:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_I1:
++ switch (type->type) {
++ case MONO_TYPE_I2:
++ case MONO_TYPE_I:
++ case MONO_TYPE_I4:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ case MONO_TYPE_BOOLEAN:
++ return type->type == MONO_TYPE_BOOLEAN;
++ case MONO_TYPE_U2:
++ switch (type->type) {
++ case MONO_TYPE_U2:
++ case MONO_TYPE_U:
++ case MONO_TYPE_I:
++ case MONO_TYPE_U4:
++ case MONO_TYPE_I4:
++ case MONO_TYPE_U8:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_I2:
++ switch (type->type) {
++ case MONO_TYPE_I:
++ case MONO_TYPE_I4:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_CHAR:
++ switch (type->type) {
++ case MONO_TYPE_U2:
++ case MONO_TYPE_U:
++ case MONO_TYPE_I:
++ case MONO_TYPE_U4:
++ case MONO_TYPE_I4:
++ case MONO_TYPE_U8:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_U:
++ switch (type->type) {
++ case MONO_TYPE_U4:
++ case MONO_TYPE_U8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_I:
++ switch (type->type) {
++ case MONO_TYPE_I:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_U4:
++ switch (type->type) {
++ case MONO_TYPE_U:
++ case MONO_TYPE_U8:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_I4:
++ switch (type->type) {
++ case MONO_TYPE_I:
++ case MONO_TYPE_I8:
++ case MONO_TYPE_R4:
++ case MONO_TYPE_R8:
++ return TRUE;
++ }
++ return FALSE;
++ case MONO_TYPE_U8:
++ case MONO_TYPE_I8:
++ return type->type == MONO_TYPE_R4 || type->type == MONO_TYPE_R8;
++ case MONO_TYPE_R4:
++ return type->type == MONO_TYPE_R8;
++ case MONO_TYPE_R8:
++ break;
++ }
++ return FALSE;
++}
+
+ /**
+ * mono_runtime_invoke_array:
+@@ -3405,6 +3534,8 @@ mono_runtime_invoke_array (MonoMethod *m
+ pa = alloca (sizeof (gpointer) * mono_array_length (params));
+ for (i = 0; i < mono_array_length (params); i++) {
+ MonoType *t = sig->params [i];
++ MonoClass *par_class = mono_class_from_mono_type (t);
++ MonoObject *pao;
+
+ again:
+ switch (t->type) {
+@@ -3429,9 +3560,16 @@ mono_runtime_invoke_array (MonoMethod *m
+ if (t->byref)
+ has_byref_nullables = TRUE;
+ } else {
++ pao = mono_array_get (params, MonoObject*, i);
+ /* MS seems to create the objects if a null is passed in */
+- if (!mono_array_get (params, MonoObject*, i))
+- mono_array_setref (params, i, mono_object_new (mono_domain_get (), mono_class_from_mono_type (sig->params [i])));
++ if (pao) {
++ if ((t->type == MONO_TYPE_VALUETYPE && pao->vtable->klass != par_class) ||
++ (t->type != MONO_TYPE_VALUETYPE && !is_widen_compatible (t, &pao->vtable->klass->byval_arg)))
++ mono_raise_exception (mono_get_exception_argument ("", "Incompatible type passed"));
++ } else {
++ pao = mono_object_new (mono_domain_get (), par_class);
++ mono_array_setref (params, i, pao);
++ }
+
+ if (t->byref) {
+ /*
+@@ -3441,12 +3579,13 @@ mono_runtime_invoke_array (MonoMethod *m
+ * object, pass that to the callee, and replace the original
+ * boxed object in the arg array with the copy.
+ */
+- MonoObject *orig = mono_array_get (params, MonoObject*, i);
++ MonoObject *orig = pao;
+ MonoObject *copy = mono_value_box (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig));
+ mono_array_setref (params, i, copy);
++ pao = copy;
+ }
+
+- pa [i] = mono_object_unbox (mono_array_get (params, MonoObject*, i));
++ pa [i] = mono_object_unbox (pao);
+ }
+ break;
+ case MONO_TYPE_STRING:
+@@ -3454,11 +3593,19 @@ mono_runtime_invoke_array (MonoMethod *m
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+- if (t->byref)
++ if (t->byref) {
+ pa [i] = mono_array_addr (params, MonoObject*, i);
+ // FIXME: I need to check this code path
+- else
+- pa [i] = mono_array_get (params, MonoObject*, i);
++ } else {
++ pao = mono_array_get (params, MonoObject*, i);
++ pa [i] = pao;
++
++ if (pao != NULL && !mono_class_is_assignable_from (par_class, pao->vtable->klass) &&
++ (pao->vtable->klass == mono_defaults.transparent_proxy_class &&
++ !mono_class_is_assignable_from (par_class, ((MonoTransparentProxy*)pao)->remote_class->proxy_class))) {
++ mono_raise_exception (mono_get_exception_argument ("", "Incompatible type passed"));
++ }
++ }
+ break;
+ case MONO_TYPE_GENERICINST:
+ if (t->byref)