On Thu, Nov 15, 2012 at 04:13:01PM +0000, Nicholas Clark wrote: > Following a chat on IRC today: > > 09:28 < nwc10> I see accesses to all structure members except constraints in > the rest of the code > 09:29 < jnthn> Yeah. It could be moved into Rakudo_md_candidate_graph_node if > it's only used in the sort. > 09:30 < nwc10> aha. good plan. I'd not thought of doing it like that. > > http://irclog.perlgeek.de/perl6/2012-11-15#i_6155821 > > > Is this attached patch the way to go?
After chat on IRC, this is an improved version. I forgot to send it anywhere Specifically, we both think that using lots of parameters is ugly. Improved version passes in a Rakudo_md_candidate_graph_node instead of using Rakudo_md_candidate_info > -=item C<static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info > *a, Rakudo_md_candidate_info *b)> > +=item C<static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info > *a, PMC **a_constraints, Rakudo_md_candidate_info *b, PMC **b_constraints)> Nicholas Clark
>From 77bd81d5a2ef1c1d27ddc418469e4a60d88e7a86 Mon Sep 17 00:00:00 2001 From: Nicholas Clark <n...@ccl4.org> Date: Thu, 15 Nov 2012 16:52:33 +0100 Subject: [PATCH] Move constraints from Rakudo_md_candidate_info to Rakudo_md_candidate_graph_node as it's only needed while generating the sorted candidate list. --- src/binder/multidispatch.c | 46 ++++++++++++++++++++++++++-------------------- src/binder/multidispatch.h | 3 ++- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/binder/multidispatch.c b/src/binder/multidispatch.c index 31bba2f..baec088 100644 --- a/src/binder/multidispatch.c +++ b/src/binder/multidispatch.c @@ -40,7 +40,7 @@ This implements Perl 6 multiple dispatch. =over 4 -=item C<static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_candidate_info *b)> +=item C<static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_graph_node *a, Rakudo_md_candidate_graph_node *b)> Takes two candidates and determines if the first one is narrower than the second. Returns a true value if they are. @@ -48,26 +48,30 @@ second. Returns a true value if they are. =cut */ -static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_candidate_info *b) { +static INTVAL is_narrower(PARROT_INTERP, + Rakudo_md_candidate_graph_node *a, + Rakudo_md_candidate_graph_node *b) { INTVAL narrower = 0; INTVAL tied = 0; INTVAL i, types_to_check; + Rakudo_md_candidate_info *const a_info = a->info; + Rakudo_md_candidate_info *const b_info = b->info; /* Work out how many parameters to compare, factoring in slurpiness * and optionals. */ - if (a->num_types == b->num_types) - types_to_check = a->num_types; - else if (a->min_arity == b->min_arity) - types_to_check = a->num_types > b->num_types ? b->num_types : a->num_types; - else if (a->max_arity != SLURPY_ARITY && b->max_arity == SLURPY_ARITY) + if (a_info->num_types == b_info->num_types) + types_to_check = a_info->num_types; + else if (a_info->min_arity == b_info->min_arity) + types_to_check = a_info->num_types > b_info->num_types ? b_info->num_types : a_info->num_types; + else if (a_info->max_arity != SLURPY_ARITY && b_info->max_arity == SLURPY_ARITY) return 1; else return 0; /* Analyse each parameter in the two candidates. */ for (i = 0; i < types_to_check; i++) { - PMC * const type_obj_a = a->types[i]; - PMC * const type_obj_b = b->types[i]; + PMC * const type_obj_a = a_info->types[i]; + PMC * const type_obj_b = b_info->types[i]; if (type_obj_a == type_obj_b) { /* Same type; narrower if first has constraints and other doesn't; * tied if neither has constraints or both have constraints. */ @@ -78,12 +82,12 @@ static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_ (!PMC_IS_NULL(a->constraints[i]) && !PMC_IS_NULL(b->constraints[i]))) tied++; } - else if ((a->type_flags[i] & TYPE_NATIVE_MASK) && !(b->type_flags[i] & TYPE_NATIVE_MASK)) + else if ((a_info->type_flags[i] & TYPE_NATIVE_MASK) && !(b_info->type_flags[i] & TYPE_NATIVE_MASK)) { /* Narrower because natives always are. */ narrower++; } - else if ((b->type_flags[i] & TYPE_NATIVE_MASK) && !(a->type_flags[i] & TYPE_NATIVE_MASK)) + else if ((b_info->type_flags[i] & TYPE_NATIVE_MASK) && !(a_info->type_flags[i] & TYPE_NATIVE_MASK)) { /* Wider; skip over here so we don't go counting this as tied in * the next branch. */ @@ -112,15 +116,15 @@ static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_ /* Otherwise, we see if one has a slurpy and the other not. A lack of * slurpiness makes the candidate narrower. */ - if (a->max_arity != SLURPY_ARITY && b->max_arity == SLURPY_ARITY) { + if (a_info->max_arity != SLURPY_ARITY && b_info->max_arity == SLURPY_ARITY) { return 1; } /* Also narrower if the first needs a bind check and the second doesn't, if * we wouldn't deem the other one narrower than this one int terms of * slurpyness. Otherwise, they're tied. */ - return !(b->max_arity != SLURPY_ARITY && a->max_arity == SLURPY_ARITY) - && (a->bind_check && !(b->bind_check)); + return !(b_info->max_arity != SLURPY_ARITY && a_info->max_arity == SLURPY_ARITY) + && (a_info->bind_check && !(b_info->bind_check)); } @@ -158,6 +162,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates INTVAL num_params; INTVAL j; INTVAL significant_param; + PMC **constraints; /* Get information about this candidate. */ PMC * const candidate = VTABLE_get_pmc_keyed_int(interp, candidates, i); @@ -174,7 +179,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates /* Type information. */ info->types = mem_allocate_n_zeroed_typed(num_params + 1, PMC*); info->type_flags = mem_allocate_n_zeroed_typed(num_params + 1, INTVAL); - info->constraints = mem_allocate_n_zeroed_typed(num_params + 1, PMC*); + constraints = mem_allocate_n_zeroed_typed(num_params + 1, PMC*); significant_param = 0; for (j = 0; j < num_params; j++) { @@ -220,8 +225,8 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates else { info->types[significant_param] = param->nominal_type; } - info->constraints[significant_param] = param->post_constraints; - if (!PMC_IS_NULL(info->constraints[significant_param])) + constraints[significant_param] = param->post_constraints; + if (!PMC_IS_NULL(constraints[significant_param])) info->bind_check = 1; if (param->flags & SIG_ELEM_MULTI_INVOCANT) info->num_types++; @@ -241,6 +246,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates /* Add it to graph node, and initialize list of edges. */ graph[insert_pos] = mem_allocate_zeroed_typed(Rakudo_md_candidate_graph_node); graph[insert_pos]->info = info; + graph[insert_pos]->constraints = constraints; graph[insert_pos]->edges = mem_allocate_n_zeroed_typed( num_candidates, Rakudo_md_candidate_graph_node*); @@ -262,7 +268,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates for (j = 0; j < num_candidates; j++) { if (i == j) continue; - if (is_narrower(interp, graph[i]->info, graph[j]->info)) { + if (is_narrower(interp, graph[i], graph[j])) { graph[i]->edges[graph[i]->edges_out] = graph[j]; graph[i]->edges_out++; graph[j]->edges_in++; @@ -318,10 +324,10 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates mem_sys_free(info->types); if (info->type_flags) mem_sys_free(info->type_flags); - if (info->constraints) - mem_sys_free(info->constraints); mem_sys_free(info); } + if (graph[i]->constraints) + mem_sys_free(graph[i]->constraints); mem_sys_free(graph[i]->edges); mem_sys_free(graph[i]); } diff --git a/src/binder/multidispatch.h b/src/binder/multidispatch.h index 3338f53..e9f6552 100644 --- a/src/binder/multidispatch.h +++ b/src/binder/multidispatch.h @@ -37,7 +37,6 @@ typedef struct { PMC *signature; /* The signature of the sub. */ PMC **types; /* Class or role type constraints for each parameter. */ INTVAL *type_flags; /* Definedness and native flags for each of the types. */ - PMC **constraints; /* Refinement type constraints for each parameter. */ INTVAL num_types; /* Number of entries in the above two arrays. */ INTVAL min_arity; /* Number of required positional arguments. */ INTVAL max_arity; /* Number of required and optional positional arguments. */ @@ -86,6 +85,8 @@ typedef struct { * in the graph that we have arrows to. */ typedef struct candidate_graph_node { Rakudo_md_candidate_info *info; + /* Refinement type constraints for each parameter, only used in the sort. */ + PMC **constraints; struct candidate_graph_node **edges; INTVAL edges_in; INTVAL edges_out; -- 1.8.0.1