Skip to content

Commit

Permalink
fixing #632
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Mar 23, 2012
1 parent 9d49090 commit 7d0c9e1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 25 deletions.
2 changes: 1 addition & 1 deletion base/stage0.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Base

if true
if false
# simple print definitions for debugging. enable these if something
# goes wrong during bootstrap before printing code is available.
length(a::Array) = arraylen(a)
Expand Down
1 change: 0 additions & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,6 @@ jl_value_t *jl_toplevel_eval_flex(jl_value_t *e, int fast,
jl_type_infer(thk, jl_tuple_type, thk);
}
result = jl_apply((jl_function_t*)thunk, NULL, 0);
jl_delete_function(thk);
}
else {
result = jl_interpret_toplevel_thunk(thk);
Expand Down
4 changes: 3 additions & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,9 @@ static jl_value_t *jl_deserialize_value(ios_t *s)
return NULL;
if (tag == 0) {
tag = read_uint8(s);
return (jl_value_t*)ptrhash_get(&deser_tag, (void*)(ptrint_t)tag);
jl_value_t *v = ptrhash_get(&deser_tag, (void*)(ptrint_t)tag);
assert(v != HT_NOTFOUND);
return v;
}
if (tag == BackRef_tag) {
assert(tree_literal_values == NULL);
Expand Down
83 changes: 61 additions & 22 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,26 +716,68 @@ static jl_function_t *cache_method(jl_methtable_t *mt, jl_tuple_t *type,
return newmeth;
}

static jl_value_t *lookup_match(jl_value_t *a, jl_value_t *b, jl_tuple_t **penv,
jl_tuple_t *tvars, int bind_all)
{
jl_value_t *ti = jl_type_intersection_matching(a, b, penv, tvars);
if (ti == (jl_value_t*)jl_bottom_type)
return ti;
jl_value_t **ee = alloca(sizeof(void*)*(*penv)->length);
int n=0;
// only keep vars in tvars list
jl_value_t **tvs;
int tvarslen;
if (jl_is_typevar(tvars)) {
tvs = (jl_value_t**)&tvars;
tvarslen = 1;
}
else {
tvs = &jl_t0(tvars);
tvarslen = tvars->length;
}
for(int i=0; i < (*penv)->length; i+=2) {
jl_value_t *v = jl_tupleref(*penv,i);
jl_value_t *val = jl_tupleref(*penv,i+1);
if (bind_all || v != val) {
for(int j=0; j < tvarslen; j++) {
if (v == tvs[j]) {
ee[n++] = v;
ee[n++] = val;
}
}
}
}
if (n != (*penv)->length) {
jl_tuple_t *en = jl_alloc_tuple_uninit(n);
memcpy(en->data, ee, n*sizeof(void*));
*penv = en;
}
return ti;
}

static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, int cache)
{
jl_methlist_t *m = mt->defs;
size_t nargs = tt->length;
size_t i;
jl_value_t *env = jl_false;
jl_value_t *ti=(jl_value_t*)jl_bottom_type;
jl_tuple_t *newsig=NULL, *env = jl_null;
JL_GC_PUSH(&env, &newsig);

while (m != NULL) {
if (m->tvars!=jl_null) {
env = jl_type_match((jl_value_t*)tt, (jl_value_t*)m->sig);
if (env != jl_false) {
ti = lookup_match((jl_value_t*)tt, (jl_value_t*)m->sig,
&env, m->tvars, 0);
if (ti != (jl_value_t*)jl_bottom_type) {
// parametric methods only match if all typevars are matched by
// non-typevars.
for(i=1; i < ((jl_tuple_t*)env)->length; i+=2) {
for(i=1; i < env->length; i+=2) {
if (jl_is_typevar(jl_tupleref(env,i)))
break;
}
if (i >= ((jl_tuple_t*)env)->length)
if (i >= env->length)
break;
env = jl_false;
ti = (jl_value_t*)jl_bottom_type;
}
}
else if (jl_tuple_subtype(&jl_tupleref(tt,0), nargs,
Expand All @@ -746,30 +788,26 @@ static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, in
m = m->next;
}

if (env == (jl_value_t*)jl_false) {
if (ti == (jl_value_t*)jl_bottom_type) {
JL_GC_POP();
if (m != NULL) {
if (!cache) {
if (!cache)
return m->func;
}
return cache_method(mt, tt, m->func, (jl_tuple_t*)m->sig, jl_null);
}
return NULL;
}

jl_tuple_t *newsig=NULL;
JL_GC_PUSH(&env, &newsig);

assert(jl_is_tuple(env));
jl_tuple_t *tpenv = (jl_tuple_t*)env;
// don't bother computing this if no arguments are tuples
for(i=0; i < tt->length; i++) {
if (jl_is_tuple(jl_tupleref(tt,i)))
break;
}
if (i < tt->length) {
newsig = (jl_tuple_t*)jl_instantiate_type_with((jl_type_t*)m->sig,
&jl_tupleref(tpenv,0),
tpenv->length/2);
&jl_tupleref(env,0),
env->length/2);
}
else {
newsig = (jl_tuple_t*)m->sig;
Expand All @@ -779,7 +817,7 @@ static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, in
if (!cache)
nf = m->func;
else
nf = cache_method(mt, tt, m->func, newsig, tpenv);
nf = cache_method(mt, tt, m->func, newsig, env);
JL_GC_POP();
return nf;
}
Expand All @@ -799,15 +837,16 @@ int jl_args_morespecific(jl_value_t *a, jl_value_t *b)
int msp = jl_type_morespecific(a,b,0);
if (jl_has_typevars(b)) {
if (jl_type_match_morespecific(a,b) == (jl_value_t*)jl_false) {
if (jl_has_typevars(a)) {
if (jl_has_typevars(a))
return 0;
}
return msp;
}
if (jl_has_typevars(a)) {
if (jl_type_match_morespecific(b,a) == (jl_value_t*)jl_false) {
//if (jl_type_match_morespecific(b,a) == (jl_value_t*)jl_false)
// return 1;
// this rule seems to work better:
if (jl_type_match(b,a) == (jl_value_t*)jl_false)
return 1;
}
}
int nmsp = jl_type_morespecific(b,a,0);
if (nmsp == msp)
Expand Down Expand Up @@ -1361,7 +1400,7 @@ DLLEXPORT jl_tuple_t *jl_match_method(jl_value_t *type, jl_value_t *sig,
jl_tuple_t *env = jl_null;
jl_value_t *ti=NULL;
JL_GC_PUSH(&env, &ti);
ti = jl_type_intersection_matching(type, (jl_value_t*)sig, &env, tvars);
ti = lookup_match(type, (jl_value_t*)sig, &env, tvars, 1);
jl_tuple_t *result = jl_tuple2(ti, env);
JL_GC_POP();
return result;
Expand All @@ -1375,7 +1414,7 @@ static jl_tuple_t *match_method(jl_value_t *type, jl_function_t *func,
jl_value_t *ti=NULL;
JL_GC_PUSH(&env, &ti, &temp);

ti = jl_type_intersection_matching(type, (jl_value_t*)sig, &env, tvars);
ti = lookup_match(type, (jl_value_t*)sig, &env, tvars, 1);
jl_tuple_t *result = NULL;
if (ti != (jl_value_t*)jl_bottom_type) {
assert(func->linfo); // no builtin methods
Expand Down

0 comments on commit 7d0c9e1

Please sign in to comment.