mirror of
https://github.com/Stichting-MINIX-Research-Foundation/pkgsrc-ng.git
synced 2025-08-03 01:38:07 -04:00
208 lines
5.7 KiB
Plaintext
208 lines
5.7 KiB
Plaintext
$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)
|