Author: kumpera
Date: 2008-02-06 10:24:56 -0500 (Wed, 06 Feb 2008)
New Revision: 95033
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/verify.c
Log:
2008-02-06 Rodrigo Kumpera <[EMAIL PROTECTED]>
* verify.c: guarded some debug functions around and #ifdef.
* verify.c (merge_stacks): implement proper PIII 1.8.1.3 stack state
merging.
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2008-02-06 15:22:17 UTC (rev 95032)
+++ trunk/mono/mono/metadata/ChangeLog 2008-02-06 15:24:56 UTC (rev 95033)
@@ -1,3 +1,9 @@
+2008-02-06 Rodrigo Kumpera <[EMAIL PROTECTED]>
+
+ * verify.c: guarded some debug functions around and #ifdef.
+
+ * verify.c (merge_stacks): implement proper PIII 1.8.1.3 stack state
merging.
+
2008-02-06 Zoltan Varga <[EMAIL PROTECTED]>
* marshal.c (mono_marshal_get_runtime_invoke): Revert the direct_wrapper
Modified: trunk/mono/mono/metadata/verify.c
===================================================================
--- trunk/mono/mono/metadata/verify.c 2008-02-06 15:22:17 UTC (rev 95032)
+++ trunk/mono/mono/metadata/verify.c 2008-02-06 15:24:56 UTC (rev 95033)
@@ -1492,6 +1492,7 @@
{TYPE_INV, TYPE_INV, TYPE_INV, TYPE_INV, TYPE_INV, TYPE_INV},
};
+#ifdef MONO_VERIFIER_DEBUG
/*debug helpers */
static void
@@ -1588,6 +1589,7 @@
dump_stack_value (state->stack + i);
printf ("\n");
}
+#endif
/*Returns TRUE if candidate array type can be assigned to target.
*Both parameters MUST be of type MONO_TYPE_ARRAY (target->type ==
MONO_TYPE_ARRAY)
@@ -3630,11 +3632,19 @@
stack_push_val (ctx, TYPE_COMPLEX,
&mono_defaults.string_class->byval_arg);
}
-/*Merge the stacks and perform compat checks*/
+/*
+ * merge_stacks:
+ * Merge the stacks and perform compat checks. The merge check if types of
@from are mergeable with type of @to
+ *
+ * @from holds new values for a given control path
+ * @to holds the current values of a given control path
+ *
+ * TODO we can eliminate the from argument as all callers pass &ctx->eval
+ */
static void
merge_stacks (VerifyContext *ctx, ILCodeDesc *from, ILCodeDesc *to, int start,
gboolean external)
{
- int i;
+ int i, j, k;
stack_init (ctx, to);
if (start) {
@@ -3655,17 +3665,64 @@
goto end_verify;
}
+ //FIXME we need to preserve CMMP attributes
+ //FIXME we must take null literals and boxes values into consideration.
for (i = 0; i < from->size; ++i) {
- ILStackDesc *from_slot = from->stack + i;
- ILStackDesc *to_slot = to->stack + i;
+ ILStackDesc *new_slot = from->stack + i;
+ ILStackDesc *old_slot = to->stack + i;
+ MonoType *new_type = mono_type_from_stack_slot (new_slot);
+ MonoType *old_type = mono_type_from_stack_slot (old_slot);
+ MonoClass *old_class = mono_class_from_mono_type (old_type);
+ MonoClass *new_class = mono_class_from_mono_type (new_type);
+ MonoClass *match_class = NULL;
- if (!verify_type_compatibility (ctx, mono_type_from_stack_slot
(to_slot), mono_type_from_stack_slot (from_slot))) {
- CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Could not
merge stacks, types not compatible at 0x%04x", ctx->ip_offset));
- goto end_verify;
+ // S := T then U = S (new value is compatible with current
value, keep current)
+ if (verify_type_compatibility (ctx, old_type, new_type)) {
+ copy_stack_value (new_slot, old_slot);
+ continue;
}
- /*TODO we need to choose the base class for merging reference
types*/
- copy_stack_value (to_slot, from_slot);
+ // T := S then U = T (old value is compatible with current
value, use new)
+ if (verify_type_compatibility (ctx, new_type, old_type)) {
+ copy_stack_value (old_slot, new_slot);
+ continue;
+ }
+
+ //both are reference types, use closest common super type
+ if (!mono_class_from_mono_type (old_type)->valuetype
+ && !mono_class_from_mono_type (new_type)->valuetype
+ && !stack_slot_is_managed_pointer (old_slot)
+ && !stack_slot_is_managed_pointer (new_slot)) {
+
+ for (j = MIN (old_class->idepth, new_class->idepth) -
1; j > 0; --j) {
+ if (mono_metadata_type_equal
(&old_class->supertypes [j]->byval_arg, &new_class->supertypes [j]->byval_arg))
{
+ match_class = old_class->supertypes [j];
+ goto match_found;
+ }
+ }
+
+ for (j = 0; j < old_class->interface_count; ++j) {
+ for (k = 0; k < new_class->interface_count;
++k) {
+ if (mono_metadata_type_equal
(&old_class->interfaces [j]->byval_arg, &new_class->interfaces [k]->byval_arg))
{
+ match_class =
old_class->interfaces [j];
+ goto match_found;
+ }
+ }
+ }
+
+ //No decent super type found, use object
+ match_class = mono_defaults.object_class;
+ goto match_found;
+ }
+
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Could not merge
stacks, types not compatible at 0x%04x", ctx->ip_offset));
+ goto end_verify;
+
+match_found:
+ g_assert (match_class);
+ set_stack_value (ctx, old_slot, &match_class->byval_arg,
stack_slot_is_managed_pointer (old_slot));
+ set_stack_value (ctx, new_slot, &match_class->byval_arg,
stack_slot_is_managed_pointer (old_slot));
+ continue;
}
end_verify:
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches