Author: jonathan
Date: Tue Nov 11 03:43:25 2008
New Revision: 32527
Modified:
trunk/languages/perl6/src/pmc/perl6multisub.pmc
Log:
[rakudo] Fix a couple of bugs in candidate sorting for MMD. One was an
off-by-one error. The other was more subtle; we mustn't remove edges from the
graph per iteration of the topological sort, otherwise we end up not
identifying one candidate as narrower than another, depending on the order they
appear in the code.
Modified: trunk/languages/perl6/src/pmc/perl6multisub.pmc
==============================================================================
--- trunk/languages/perl6/src/pmc/perl6multisub.pmc (original)
+++ trunk/languages/perl6/src/pmc/perl6multisub.pmc Tue Nov 11 03:43:25 2008
@@ -75,6 +75,10 @@
} candidate_graph_node;
+/* Some constants for candidate sorter. */
+#define EDGE_REMOVAL_TODO -1
+#define EDGE_REMOVED -2
+
/*
=back
@@ -247,7 +251,7 @@
}
}
- return narrower > 1 && narrower + tied == a->num_types;
+ return narrower >= 1 && narrower + tied == a->num_types;
}
@@ -345,17 +349,23 @@
result[result_pos] = graph[i]->info;
result_pos++;
candidates_to_sort--;
- graph[i]->edges_in = -1;
-
- /* Now we have added this node, remove its outgoing edges. */
- for (j = 0; j < graph[i]->edges_out; j++)
- graph[i]->edges[j]->edges_in--;
+ graph[i]->edges_in = EDGE_REMOVAL_TODO;
}
}
if (rem_start_point == result_pos)
Parrot_ex_throw_from_c_args(interp, 0, 1,
"Circularity detected in multi sub types.");
+ /* Now we need to decrement edges in counts for things that had edges
+ * from candidates we added here. */
+ for (i = 0; i < num_candidates; i++) {
+ if (graph[i]->edges_in == EDGE_REMOVAL_TODO) {
+ for (j = 0; j < graph[i]->edges_out; j++)
+ graph[i]->edges[j]->edges_in--;
+ graph[i]->edges_in = EDGE_REMOVED;
+ }
+ }
+
/* This is end of a tied group, so leave a gap. */
result_pos++;
}