From 246c0784bae64a7ec9d88838c650b040fc205150 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 2 Mar 2015 16:54:50 -0500 Subject: [PATCH] begin implementing redesign of tuples and tuple types [ci skip] --- src/alloc.c | 96 ------- src/jltypes.c | 628 +++++++++++++++++++++++---------------------- src/julia.h | 172 +++++++------ src/simplevector.c | 93 +++++++ 4 files changed, 509 insertions(+), 480 deletions(-) create mode 100644 src/simplevector.c diff --git a/src/alloc.c b/src/alloc.c index 2c8ad19c43243..c5af28e8ad154 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -333,102 +333,6 @@ DLLEXPORT jl_value_t *jl_new_struct_uninit(jl_datatype_t *type) return jv; } -DLLEXPORT jl_tuple_t *jl_tuple(size_t n, ...) -{ - va_list args; - if (n == 0) return jl_null; - va_start(args, n); - jl_tuple_t *jv = jl_alloc_tuple_uninit(n); - for(size_t i=0; i < n; i++) { - jl_tupleset(jv, i, va_arg(args, jl_value_t*)); - } - va_end(args); - return jv; -} - -DLLEXPORT jl_tuple_t *jl_tuplev(size_t n, jl_value_t **v) -{ - jl_tuple_t *jv = jl_alloc_tuple_uninit(n); - for(size_t i=0; i < n; i++) { - jl_tupleset(jv, i, v[i]); - } - return jv; -} - -jl_tuple_t *jl_tuple1(void *a) -{ -#ifdef OVERLAP_TUPLE_LEN - jl_tuple_t *t = (jl_tuple_t*)alloc_2w(); -#else - jl_tuple_t *t = (jl_tuple_t*)alloc_3w(); -#endif - t->type = (jl_value_t*)jl_tuple_type; - jl_tuple_set_len_unsafe(t, 1); - jl_tupleset(t, 0, a); - return t; -} - -jl_tuple_t *jl_tuple2(void *a, void *b) -{ -#ifdef OVERLAP_TUPLE_LEN - jl_tuple_t *t = (jl_tuple_t*)alloc_3w(); -#else - jl_tuple_t *t = (jl_tuple_t*)alloc_4w(); -#endif - t->type = (jl_value_t*)jl_tuple_type; - jl_tuple_set_len_unsafe(t, 2); - jl_tupleset(t, 0, a); - jl_tupleset(t, 1, b); - return t; -} - -jl_tuple_t *jl_alloc_tuple_uninit(size_t n) -{ - if (n == 0) return jl_null; -#ifdef OVERLAP_TUPLE_LEN - jl_tuple_t *jv = (jl_tuple_t*)newobj((jl_value_t*)jl_tuple_type, n); -#else - jl_tuple_t *jv = (jl_tuple_t*)newobj((jl_value_t*)jl_tuple_type, n+1); -#endif - jl_tuple_set_len_unsafe(jv, n); - return jv; -} - -jl_tuple_t *jl_alloc_tuple(size_t n) -{ - if (n == 0) return jl_null; - jl_tuple_t *jv = jl_alloc_tuple_uninit(n); - for(size_t i=0; i < n; i++) { - jl_tupleset(jv, i, NULL); - } - return jv; -} - -jl_tuple_t *jl_tuple_append(jl_tuple_t *a, jl_tuple_t *b) -{ - jl_tuple_t *c = jl_alloc_tuple_uninit(jl_tuple_len(a) + jl_tuple_len(b)); - size_t i=0, j; - for(j=0; j < jl_tuple_len(a); j++) { - jl_tupleset(c, i, jl_tupleref(a,j)); - i++; - } - for(j=0; j < jl_tuple_len(b); j++) { - jl_tupleset(c, i, jl_tupleref(b,j)); - i++; - } - return c; -} - -jl_tuple_t *jl_tuple_fill(size_t n, jl_value_t *v) -{ - if (n==0) return jl_null; - jl_tuple_t *tup = jl_alloc_tuple_uninit(n); - for(size_t i=0; i < n; i++) { - jl_tupleset(tup, i, v); - } - return tup; -} - DLLEXPORT jl_function_t *jl_new_closure(jl_fptr_t fptr, jl_value_t *env, jl_lambda_info_t *linfo) { diff --git a/src/jltypes.c b/src/jltypes.c index a64e936be08be..24dd8b5ed5db7 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -24,8 +24,10 @@ jl_datatype_t *jl_typename_type; jl_datatype_t *jl_sym_type; jl_datatype_t *jl_symbol_type; jl_datatype_t *jl_gensym_type; -jl_tuple_t *jl_tuple_type; -jl_value_t *jl_tupletype_type; +jl_datatype_t *jl_simplevector_type; +jl_typename_t *jl_tuple_typename; +jl_tuple_t *jl_anytuple_type; +//jl_value_t *jl_tupletype_type; jl_datatype_t *jl_ntuple_type; jl_typename_t *jl_ntuple_typename; jl_datatype_t *jl_tvar_type; @@ -33,7 +35,7 @@ jl_datatype_t *jl_uniontype_type; jl_datatype_t *jl_datatype_type; jl_value_t *jl_bottom_type; -jl_datatype_t *jl_vararg_type; +//jl_datatype_t *jl_vararg_type; jl_datatype_t *jl_abstractarray_type; jl_datatype_t *jl_densearray_type; @@ -52,27 +54,16 @@ jl_datatype_t *jl_float64_type; jl_datatype_t *jl_floatingpoint_type; jl_datatype_t *jl_number_type; -jl_tuple_t *jl_null; +jl_value_t *jl_emptytuple; jl_value_t *jl_nothing; // --- type properties and predicates --- int jl_is_type(jl_value_t *v) { - if (jl_is_tuple(v)) { - jl_tuple_t *t = (jl_tuple_t*)v; - size_t i, l = jl_tuple_len(t); - for(i=0; i < l; i++) { - jl_value_t *vv = jl_tupleref(t, i); - if (!jl_is_type(vv)) - return 0; - if (i < l-1 && jl_is_vararg_type(vv)) - return 0; - } - return 1; - } - if (jl_is_typevar(v)) return 1; - return jl_is_nontuple_type(v); + jl_value_t *t = jl_typeof(v); + //if (jl_is_typevar(v)) return 1; + return (t == jl_datatype_type || t == jl_uniontype_type || t == jl_typector_type); } STATIC_INLINE int is_unspec(jl_datatype_t *dt) @@ -80,14 +71,14 @@ STATIC_INLINE int is_unspec(jl_datatype_t *dt) return (jl_datatype_t*)dt->name->primary == dt; } -static int jl_has_typevars__(jl_value_t *v, int incl_wildcard, jl_tuple_t *p) +static int jl_has_typevars__(jl_value_t *v, int incl_wildcard, jl_sv_t *p) { size_t i; if (jl_typeis(v, jl_tvar_type)) { if (p != NULL) { - size_t l = jl_tuple_len(p); + size_t l = jl_sv_len(p); for(i=0; i < l; i++) { - if (v == jl_tupleref(p, i)) + if (v == jl_svref(p, i)) return 1; } return 0; @@ -98,21 +89,21 @@ static int jl_has_typevars__(jl_value_t *v, int incl_wildcard, jl_tuple_t *p) } if (jl_is_typector(v)) return incl_wildcard; - jl_tuple_t *t; - if (jl_is_uniontype(v)) + jl_sv_t *t; + if (jl_is_uniontype(v)) { t = ((jl_uniontype_t*)v)->types; + } else if (jl_is_datatype(v)) { if (is_unspec((jl_datatype_t*)v)) return 0; t = ((jl_datatype_t*)v)->parameters; } - else if (jl_is_tuple(v)) - t = (jl_tuple_t*)v; - else - t = jl_null; - size_t l = jl_tuple_len(t); + else { + return 0; + } + size_t l = jl_sv_len(t); for(i=0; i < l; i++) { - jl_value_t *elt = jl_tupleref(t, i); + jl_value_t *elt = jl_svref(t, i); if (elt != v) { if (jl_has_typevars__(elt, incl_wildcard, p)) return 1; @@ -131,9 +122,9 @@ static int jl_has_typevars_(jl_value_t *v, int incl_wildcard) return jl_has_typevars__(v, incl_wildcard, NULL); } -static int jl_has_typevars_from(jl_value_t *v, jl_tuple_t *p) +static int jl_has_typevars_from(jl_value_t *v, jl_sv_t *p) { - if (jl_tuple_len(p) == 0) + if (jl_sv_len(p) == 0) return 0; return jl_has_typevars__(v, 0, p); } @@ -152,49 +143,35 @@ int jl_is_leaf_type(jl_value_t *v) return !jl_is_typevar(jl_tparam0(v)); return 0; } - jl_tuple_t *t = ((jl_datatype_t*)v)->parameters; - for(int i=0; i < jl_tuple_len(t); i++) { - if (jl_is_typevar(jl_tupleref(t,i))) - return 0; + jl_sv_t *t = ((jl_datatype_t*)v)->parameters; + size_t l = jl_sv_len(t); + if (((jl_datatype_t*)v)->name == jl_tuple_typename) { + if (((jl_datatype_t*)v)->va) return 0; + for(int i=0; i < l; i++) { + if (!jl_is_leaf_type(jl_svref(t,i))) + return 0; + } } - return 1; - } - if (jl_is_tuple(v)) { - jl_tuple_t *t = (jl_tuple_t*)v; - for(int i=0; i < jl_tuple_len(t); i++) { - if (!jl_is_leaf_type(jl_tupleref(t, i))) - return 0; + else { + for(int i=0; i < l; i++) { + if (jl_is_typevar(jl_svref(t,i))) + return 0; + } } return 1; } return 0; } -// construct the full type of a value, possibly making a tuple type -jl_value_t *jl_full_type(jl_value_t *v) -{ - if (!jl_is_tuple(v)) - return (jl_value_t*)jl_typeof(v); - jl_tuple_t *in = (jl_tuple_t*)v; - jl_tuple_t *out = jl_alloc_tuple(jl_tuple_len(in)); - JL_GC_PUSH1(&out); - size_t i; - for(i=0; i < jl_tuple_len(in); i++) { - jl_tupleset(out, i, jl_full_type(jl_tupleref(in, i))); - } - JL_GC_POP(); - return (jl_value_t*)out; -} - static int type_eqv_(jl_value_t *a, jl_value_t *b); // --- type union --- -static int count_union_components(jl_tuple_t *types) +static int count_union_components(jl_sv_t *types) { size_t i, c=0; - for(i=0; i < jl_tuple_len(types); i++) { - jl_value_t *e = jl_tupleref(types,i); + for(i=0; i < jl_sv_len(types); i++) { + jl_value_t *e = jl_svref(types,i); if (jl_is_uniontype(e)) { c += count_union_components(((jl_uniontype_t*)e)->types); } @@ -205,11 +182,11 @@ static int count_union_components(jl_tuple_t *types) return c; } -static void flatten_type_union(jl_tuple_t *types, jl_value_t **out, size_t *idx) +static void flatten_type_union(jl_sv_t *types, jl_value_t **out, size_t *idx) { size_t i; - for(i=0; i < jl_tuple_len(types); i++) { - jl_value_t *e = jl_tupleref(types,i); + for(i=0; i < jl_sv_len(types); i++) { + jl_value_t *e = jl_svref(types,i); if (jl_is_uniontype(e)) { flatten_type_union(((jl_uniontype_t*)e)->types, out, idx); } @@ -237,7 +214,7 @@ static int union_elt_morespecific(const void *a, const void *b) // type definitions. (issue #2365) int inside_typedef = 0; -jl_tuple_t *jl_compute_type_union(jl_tuple_t *types) +jl_sv_t *jl_compute_type_union(jl_sv_t *types) { size_t n = count_union_components(types); jl_value_t **temp; @@ -264,12 +241,12 @@ jl_tuple_t *jl_compute_type_union(jl_tuple_t *types) } } temp[n] = NULL; - jl_tuple_t *result = jl_alloc_tuple_uninit(n - ndel); + jl_sv_t *result = jl_alloc_sv_uninit(n - ndel); temp[n] = (jl_value_t*)result; // root result tuple while sorting j=0; for(i=0; i < n; i++) { if (temp[i] != NULL) { - jl_tupleset(result, j, temp[i]); + jl_svset(result, j, temp[i]); j++; } } @@ -282,12 +259,12 @@ jl_tuple_t *jl_compute_type_union(jl_tuple_t *types) return result; } -jl_value_t *jl_type_union(jl_tuple_t *types) +jl_value_t *jl_type_union(jl_sv_t *types) { types = jl_compute_type_union(types); - if (jl_tuple_len(types) == 1) + if (jl_sv_len(types) == 1) return jl_tupleref(types, 0); - if (jl_tuple_len(types) == 0) + if (jl_sv_len(types) == 0) return (jl_value_t*)jl_bottom_type; JL_GC_PUSH1(&types); jl_value_t *tu = (jl_value_t*)jl_new_uniontype(types); @@ -311,8 +288,8 @@ STATIC_INLINE int is_bnd(jl_tvar_t *tv, cenv_t *env) { if (jl_is_typevar(env->tvars)) return (jl_tvar_t*)env->tvars == tv; - for(size_t i=0; i < jl_tuple_len(env->tvars); i++) { - if ((jl_tvar_t*)jl_tupleref(env->tvars,i) == tv) + for(size_t i=0; i < jl_sv_len(env->tvars); i++) { + if ((jl_tvar_t*)jl_svref(env->tvars,i) == tv) return 1; } return 0; @@ -323,8 +300,7 @@ STATIC_INLINE int is_btv(jl_value_t *v) return jl_is_typevar(v) && ((jl_tvar_t*)v)->bound; } -static void extend_(jl_value_t *var, jl_value_t *val, cenv_t *soln, int allow, - int ordered) +static void extend_(jl_value_t *var, jl_value_t *val, cenv_t *soln, int allow, int ordered) { if (!allow && var == val) return; @@ -362,16 +338,16 @@ static jl_value_t *intersect_union(jl_uniontype_t *a, jl_value_t *b, cenv_t *penv, cenv_t *eqc, variance_t var) { int eq0 = eqc->n, co0 = penv->n; - jl_tuple_t *t = jl_alloc_tuple(jl_tuple_len(a->types)); + jl_sv_t *t = jl_alloc_sv(jl_sv_len(a->types)); JL_GC_PUSH1(&t); - size_t i, l=jl_tuple_len(t); + size_t i, l=jl_sv_len(t); for(i=0; i < l; i++) { int eq_l = eqc->n, co_l = penv->n; - jl_value_t *ti = jl_type_intersect(jl_tupleref(a->types,i), b, + jl_value_t *ti = jl_type_intersect(jl_svref(a->types,i), b, penv, eqc, var); if (ti == (jl_value_t*)jl_bottom_type) { eqc->n = eq0; penv->n = co0; - ti = jl_type_intersect(jl_tupleref(a->types,i), b, + ti = jl_type_intersect(jl_svref(a->types,i), b, penv, eqc, var); if (ti != (jl_value_t*)jl_bottom_type) { // tvar conflict among union elements; keep the conflicting @@ -384,7 +360,7 @@ static jl_value_t *intersect_union(jl_uniontype_t *a, jl_value_t *b, eqc->n = eq_l; penv->n = co_l; } } - jl_tupleset(t, i, ti); + jl_svset(t, i, ti); } // problem: an intermediate union type we make here might be too // complex, even though the final type after typevars are replaced @@ -395,16 +371,16 @@ static jl_value_t *intersect_union(jl_uniontype_t *a, jl_value_t *b, } // if returns with *bot!=0, then intersection is Union() -static size_t tuple_intersect_size(jl_tuple_t *a, jl_tuple_t *b, int *bot) +static size_t tuple_intersect_size(jl_sv_t *a, int ava, jl_sv_t *b, int bva, int *bot) { - size_t al = jl_tuple_len(a); - size_t bl = jl_tuple_len(b); + size_t al = jl_sv_len(a); + size_t bl = jl_sv_len(b); *bot = 0; if (al == bl) return al; - if (al > bl) return tuple_intersect_size(b, a, bot); + if (al > bl) return tuple_intersect_size(b, bva, a, ava, bot); assert(al < bl); - if (jl_is_vararg_type(jl_tupleref(b,bl-1))) { - if (al > 0 && jl_is_vararg_type(jl_tupleref(a,al-1))) { + if (bva) { + if (ava) { return bl; } else { @@ -414,45 +390,41 @@ static size_t tuple_intersect_size(jl_tuple_t *a, jl_tuple_t *b, int *bot) return 0; } } - if (al > 0 && jl_is_vararg_type(jl_tupleref(a,al-1))) { + if (ava) { return bl; } *bot=1; return 0; } -static jl_value_t *intersect_tuple(jl_tuple_t *a, jl_tuple_t *b, +static jl_value_t *intersect_tuple(jl_datatype_t *a, jl_datatype_t *b, cenv_t *penv, cenv_t *eqc, variance_t var) { - size_t al = jl_tuple_len(a); - size_t bl = jl_tuple_len(b); + jl_sv_t *ap = a->parameters, *bp = b->parameters; + size_t al = jl_sv_len(ap), bl = jl_sv_len(bp); int bot=0; - size_t n = tuple_intersect_size(a, b, &bot); + size_t n = tuple_intersect_size(ap, a->va, bp, b->va, &bot); if (bot) return (jl_value_t*)jl_bottom_type; - if (n == 0) return (jl_value_t*)jl_null; - jl_tuple_t *tc = jl_alloc_tuple(n); + if (n == 0) return (jl_value_t*)jl_emptytuple->type; + jl_sv_t *tc = jl_alloc_sv(n); jl_value_t *result = (jl_value_t*)tc; jl_value_t *ce = NULL; JL_GC_PUSH2(&tc, &ce); size_t ai=0, bi=0, ci; jl_value_t *ae=NULL, *be=NULL; - int aseq=0, bseq=0; + int aseq=0, bseq=0, va=0; for(ci=0; ci < n; ci++) { if (ai < al) { - ae = jl_tupleref(a,ai); - if (jl_is_vararg_type(ae)) { + ae = jl_svref(ap,ai); + if (a->va && ai == al-1) aseq=1; - ae = jl_tparam0(ae); - } ai++; } if (bi < bl) { - be = jl_tupleref(b,bi); - if (jl_is_vararg_type(be)) { + be = jl_svref(bp,bi); + if (b->va && bi == bl-1) bseq=1; - be = jl_tparam0(be); - } bi++; } assert(ae!=NULL && be!=NULL); @@ -461,21 +433,22 @@ static jl_value_t *intersect_tuple(jl_tuple_t *a, jl_tuple_t *b, if (var!=invariant && aseq && bseq) { // (X∩Y)==∅ → (X...)∩(Y...) == () if (n == 1) { - result = (jl_value_t*)jl_null; - goto done_intersect_tuple; + JL_GC_POP(); + return (jl_value_t*)jl_emptytuple->type; } - jl_tuple_set_len_unsafe(tc,jl_tuple_len(tc)-1); + jl_sv_set_len_unsafe(tc,jl_sv_len(tc)-1); goto done_intersect_tuple; } - result = (jl_value_t*)jl_bottom_type; - goto done_intersect_tuple; + JL_GC_POP(); + return (jl_value_t*)jl_bottom_type; } if (aseq && bseq) { - ce = (jl_value_t*)jl_wrap_vararg(ce); + va = 1; } - jl_tupleset(tc, ci, ce); + jl_svset(tc, ci, ce); } done_intersect_tuple: + result = (jl_value_t*)jl_apply_tuple_type(tc, va); JL_GC_POP(); return result; } @@ -484,28 +457,28 @@ static jl_value_t *intersect_tag(jl_datatype_t *a, jl_datatype_t *b, cenv_t *penv, cenv_t *eqc, variance_t var) { assert(a->name == b->name); - assert(jl_tuple_len(a->parameters) == jl_tuple_len(b->parameters)); - jl_tuple_t *p = jl_alloc_tuple(jl_tuple_len(a->parameters)); + assert(jl_sv_len(a->parameters) == jl_sv_len(b->parameters)); + jl_sv_t *p = jl_alloc_sv(jl_sv_len(a->parameters)); JL_GC_PUSH1(&p); jl_value_t *ti; size_t i; if (a->name == jl_ntuple_typename) { - assert(jl_tuple_len(p) == 2); + assert(jl_sv_len(p) == 2); // NOTE: tuples are covariant, so NTuple element type is too ti = jl_type_intersect(jl_tparam0(a),jl_tparam0(b),penv,eqc,invariant); - jl_tupleset(p, 0, ti); + jl_svset(p, 0, ti); ti = jl_type_intersect(jl_tparam1(a),jl_tparam1(b),penv,eqc,var); if (ti==(jl_value_t*)jl_bottom_type || jl_t0(p)==(jl_value_t*)jl_bottom_type) { JL_GC_POP(); return (jl_value_t*)jl_bottom_type; } - jl_tupleset(p, 1, ti); + jl_svset(p, 1, ti); } else { - for(i=0; i < jl_tuple_len(p); i++) { - jl_value_t *ap = jl_tupleref(a->parameters,i); - jl_value_t *bp = jl_tupleref(b->parameters,i); + for(i=0; i < jl_sv_len(p); i++) { + jl_value_t *ap = jl_svref(a->parameters,i); + jl_value_t *bp = jl_svref(b->parameters,i); if (jl_is_typevar(ap)) { if (var==invariant && jl_is_typevar(bp)) { if (((jl_tvar_t*)ap)->bound != ((jl_tvar_t*)bp)->bound) { @@ -524,7 +497,7 @@ static jl_value_t *intersect_tag(jl_datatype_t *a, jl_datatype_t *b, if (bp == (jl_value_t*)jl_bottom_type && !((jl_tvar_t*)ap)->bound) { // "Union()" as a type parameter - jl_tupleset(p, i, ti); + jl_svset(p, i, ti); continue; } } @@ -533,7 +506,7 @@ static jl_value_t *intersect_tag(jl_datatype_t *a, jl_datatype_t *b, if (ap == (jl_value_t*)jl_bottom_type && !((jl_tvar_t*)bp)->bound) { // "Union()" as a type parameter - jl_tupleset(p, i, ti); + jl_svset(p, i, ti); continue; } } @@ -553,7 +526,7 @@ static jl_value_t *intersect_tag(jl_datatype_t *a, jl_datatype_t *b, ti = ap; if (ti == (jl_value_t*)jl_bottom_type) { // "Union()" as a type parameter - jl_tupleset(p, i, ti); + jl_svset(p, i, ti); continue; } } @@ -565,7 +538,7 @@ static jl_value_t *intersect_tag(jl_datatype_t *a, jl_datatype_t *b, JL_GC_POP(); return (jl_value_t*)jl_bottom_type; } - jl_tupleset(p, i, ti); + jl_svset(p, i, ti); } } if (a->name->primary != NULL) { @@ -627,22 +600,29 @@ static long meet_tuple_lengths(long bv, long vv, int *bot) // convert a type to the value it would have if assigned to a static parameter // in covariant context. -// example: (Type{Int},) => (DataType,) -// calling f{T}(x::T) as f((Int,)) should give T == (DataType,), but we -// might temporarily represent this type as (Type{Int},) for more precision. +// example: {Type{Int},} => {DataType,} +// calling f{T}(x::T) as f({Int,}) should give T == {DataType,}, but we +// might temporarily represent this type as {Type{Int},} for more precision. static jl_value_t *type_to_static_parameter_value(jl_value_t *t) { if (jl_is_type_type(t) && !jl_is_typevar(jl_tparam0(t))) - return jl_full_type(jl_tparam0(t)); - if (jl_is_tuple(t)) { - size_t l = jl_tuple_len(t); - jl_tuple_t *nt = jl_alloc_tuple(l); - JL_GC_PUSH1(&nt); + return jl_typeof(jl_tparam0(t)); + if (jl_is_tuple_type(t)) { + jl_sv_t *p = ((jl_datatype_t*)t)->parameters; + size_t l = jl_sv_len(p); + int changed = 0; + jl_tuple_t *np = jl_alloc_sv(l); + JL_GC_PUSH1(&np); for(size_t i=0; i < l; i++) { - jl_tupleset(nt, i, type_to_static_parameter_value(jl_tupleref(t,i))); + jl_value_t *el = type_to_static_parameter_value(jl_svref(p,i)); + if (el != jl_svref(p,i)) { + jl_svset(np, i, el); + changed = 1; + } } + jl_value_t *result = changed ? jl_apply_tuple_type(np, ((jl_datatype_t*)t)->va) : t; JL_GC_POP(); - return (jl_value_t*)nt; + return result; } return t; } @@ -769,40 +749,39 @@ static jl_value_t *intersect_typevar(jl_tvar_t *a, jl_value_t *b, return (jl_value_t*)a; } -// convert (Type{T}, Type{S}, ...) to Type{(T,S,...)} +// convert {Type{T}, Type{S}, ...} to Type{{T,S,...}} // NOTE: ptemp must be rooted by the caller -static int tuple_to_Type(jl_tuple_t *a, jl_tuple_t **ptemp) +static int tuple_to_Type(jl_datatype_t *a, jl_value_t **ptemp) { - int alen = jl_tuple_len(a); - *ptemp = jl_alloc_tuple(alen); + jl_value_t *ap = a->parameters; + int alen = jl_sv_len(ap); + *ptemp = jl_alloc_sv(alen); int i; for(i=0; i < alen; i++) { - jl_value_t *el = jl_tupleref(a, i); + jl_value_t *el = jl_svref(ap, i); if (jl_is_type_type(el)) { - jl_tupleset(*ptemp, i, jl_tparam0(el)); - } - else if (i==alen-1 && jl_is_vararg_type(el) && jl_is_type_type(jl_tparam0(el))) { - jl_tupleset(*ptemp, i, jl_wrap_vararg(jl_tparam0(jl_tparam0(el)))); + jl_svset(*ptemp, i, jl_tparam0(el)); } else { *ptemp = NULL; return 0; } } + *ptemp = jl_apply_tuple_type(*ptemp, a->va); return 1; } -static jl_value_t *approxify_type(jl_datatype_t *dt, jl_tuple_t *pp) +static jl_value_t *approxify_type(jl_datatype_t *dt, jl_sv_t *pp) { - size_t i, l = jl_tuple_len(dt->parameters); - jl_tuple_t *p = jl_alloc_tuple(l); + size_t i, l = jl_sv_len(dt->parameters); + jl_sv_t *p = jl_alloc_sv(l); JL_GC_PUSH1(&p); for(i=0; i < l; i++) { - jl_value_t *el = jl_tupleref(dt->parameters, i); + jl_value_t *el = jl_svref(dt->parameters, i); if (jl_has_typevars_from(el, pp)) - jl_tupleset(p, i, jl_new_typevar(underscore_sym, jl_bottom_type, el)); + jl_svset(p, i, jl_new_typevar(underscore_sym, jl_bottom_type, el)); else - jl_tupleset(p, i, el); + jl_svset(p, i, el); } jl_value_t *nt = jl_apply_type(dt->name->primary, p); JL_GC_POP(); @@ -866,7 +845,7 @@ static jl_value_t *jl_type_intersect(jl_value_t *a, jl_value_t *b, } } } - b = (jl_value_t*)jl_tuple_fill(alen, elty); + b = (jl_value_t*)jl_tupletype_fill(alen, elty); if (i >= eqc->n) { // don't know N yet, so add a constraint for it based on // the length of the other tuple @@ -1696,8 +1675,8 @@ jl_value_t *jl_apply_type_(jl_value_t *tc, jl_value_t **params, size_t n) if (tc == (jl_value_t*)jl_ntuple_type && (n==1||n==2) && jl_is_long(params[0])) { size_t nt = jl_unbox_long(params[0]); - return (jl_value_t*)jl_tuple_fill(nt, (n==2) ? params[1] : - (jl_value_t*)jl_any_type); + return (jl_value_t*)jl_tupletype_fill(nt, (n==2) ? params[1] : + (jl_value_t*)jl_any_type); } size_t ntp = jl_tuple_len(tp); if (n > ntp) @@ -1752,6 +1731,17 @@ jl_value_t *jl_apply_type(jl_value_t *tc, jl_tuple_t *params) return t; } +DLLEXPORT jl_value_t *jl_tupletype_fill(size_t n, jl_value_t *v) +{ + // TODO: replace with just using NTuple + jl_value_t *p = NULL; + JL_GC_PUSH1(&p); + p = (jl_value_t*)jl_sv_fill(n, v); + p = jl_apply_tuple_type(p, 0); + JL_GC_POP(); + return p; +} + static int typekey_compare(jl_datatype_t *tt, jl_value_t **key, size_t n) { size_t j; @@ -1860,10 +1850,118 @@ typedef struct _jl_typestack_t { struct _jl_typestack_t *prev; } jl_typestack_t; +DLLEXPORT jl_value_t *jl_apply_tuple_type(jl_sv_t *params, int va) +{ + size_t l = jl_sv_len(params); + int isabstract = va; + if (!va) { + for(size_t i=0; i < l; i++) { + if (!jl_is_leaf_type(jl_svref(params,i))) { + isabstract = 1; break; + } + } + } + jl_datatype_t *ndt = (jl_datatype_t*)inst_datatype(jl_anytuple_type, params, jl_sv_data(params), l, + !isabstract, isabstract, NULL); + if (va) ndt->va = 1; + return ndt; +} + +static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_sv_t *p, jl_value_t **iparams, size_t ntp, + int cacheable, int isabstract, + jl_typestack_t *stack) +{ + jl_typestack_t top; + jl_typename_t *tn = dt->name; + jl_value_t *tc = tn->primary; + int istuple = (tn == jl_tuple_typename); + // check type cache + if (cacheable) { + jl_value_t *lkup = (jl_value_t*)lookup_type(tn, iparams, ntp); + if (lkup != NULL) + return lkup; + } + + // always use original type constructor + if (!istuple && tc != (jl_value_t*)dt) { + return (jl_value_t*)jl_apply_type_(tc, iparams, ntp); + } + + jl_datatype_t *ndt=NULL; + + // move array of instantiated parameters to heap; we need to keep it + JL_GC_PUSH2(&p, &ndt); + if (p == NULL) { + p = jl_alloc_sv_uninit(ntp); + for(i=0; i < ntp; i++) + jl_svset(p, i, iparams[i]); + } + + // create and initialize new type + ndt = jl_new_uninitialized_datatype(istuple ? ntp : jl_sv_len(dt->types)); + // associate these parameters with the new type on + // the stack, in case one of its field types references it. + top.tt = (jl_datatype_t*)ndt; + top.prev = stack; + stack = ⊤ + ndt->name = tn; + gc_wb(ndt, ndt->name); + ndt->super = jl_any_type; + ndt->parameters = p; + gc_wb(ndt, ndt->parameters); + gc_wb(ndt, ndt->names); + ndt->types = istuple ? p : jl_emptysv; // to be filled in below + ndt->mutabl = dt->mutabl; + ndt->abstract = dt->abstract; + ndt->instance = NULL; + ndt->uid = 0; + ndt->struct_decl = NULL; + ndt->ditype = NULL; + ndt->size = 0; + ndt->alignment = 1; + ndt->va = 0; + + if (istuple) + ndt->super = jl_any_type; + else + ndt->super = (jl_datatype_t*)inst_type_w_((jl_value_t*)dt->super, env,n,stack, 1); + gc_wb(ndt, ndt->super); + ftypes = dt->types; + if (ftypes != NULL) { + if (!istuple) { + // recursively instantiate the types of the fields + ndt->types = (jl_tuple_t*)inst_type_w_((jl_value_t*)ftypes, env, n, stack, 1); + gc_wb(ndt, ndt->types); + } + if (!isabstract) { + if (jl_tuple_len(ftypes) == 0) { + ndt->size = dt->size; + ndt->alignment = dt->alignment; + ndt->pointerfree = dt->pointerfree; + } + else { + jl_compute_field_offsets(ndt); + } + if (jl_is_datatype_singleton(ndt) && tn != jl_array_typename) + ndt->instance = newstruct(ndt); + } + else { + ndt->size = 0; + ndt->pointerfree = 0; + } + if (tn == jl_array_typename) + ndt->pointerfree = 0; + } + ndt->ninitialized = dt->ninitialized; + if (cacheable) cache_type_((jl_value_t*)ndt); + result = (jl_value_t*)ndt; + JL_GC_POP(); + return result; +} + static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n, jl_typestack_t *stack, int check) { - jl_typestack_t top; size_t i, j; if (n == 0) return t; if (jl_is_typevar(t)) { @@ -1880,6 +1978,15 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n, } return (jl_value_t*)t; } + if (jl_is_uniontype(t)) { + jl_tuple_t *tw = (jl_tuple_t*)inst_type_w_((jl_value_t*)((jl_uniontype_t*)t)->types, + env, n, stack, 1); + assert(jl_is_tuple(tw)); + JL_GC_PUSH1(&tw); + jl_value_t *res = (jl_value_t*)jl_type_union(tw); + JL_GC_POP(); + return res; + } if (jl_is_tuple(t)) { jl_tuple_t *p = (jl_tuple_t*)t; jl_tuple_t *nt = jl_alloc_tuple(jl_tuple_len(p)); @@ -1890,170 +1997,83 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n, JL_GC_POP(); return (jl_value_t*)nt; } - if (jl_is_uniontype(t)) { - jl_tuple_t *tw = (jl_tuple_t*)inst_type_w_((jl_value_t*)((jl_uniontype_t*)t)->types, - env, n, stack, 1); - assert(jl_is_tuple(tw)); - JL_GC_PUSH1(&tw); - jl_value_t *res = (jl_value_t*)jl_type_union(tw); - JL_GC_POP(); - return res; + if (!jl_is_datatype(t)) { + return t; } - if (jl_is_datatype(t)) { - jl_datatype_t *tt = (jl_datatype_t*)t; - jl_tuple_t *tp = tt->parameters; - if (jl_is_null(tp)) - return (jl_value_t*)t; - jl_typename_t *tn = tt->name; - jl_value_t *tc = tn->primary; - // don't instantiate "Foo" without parameters inside Foo - if (t == tc && stack!=NULL) - return (jl_value_t*)t; - jl_value_t *result; - size_t ntp = jl_tuple_len(tp); - assert(jl_is_datatype(tc)); - assert(ntp == jl_tuple_len(((jl_datatype_t*)tc)->parameters)); - jl_value_t **iparams; - JL_GC_PUSHARGS(iparams, ntp+2); - for(i=0; i < ntp+2; i++) iparams[i] = NULL; - jl_value_t **rt1 = &iparams[ntp+0]; // some extra gc roots - jl_value_t **rt2 = &iparams[ntp+1]; - int cacheable = 1, isabstract = 0, bound = 0; - for(i=0; i < ntp; i++) { - jl_value_t *elt = jl_tupleref(tp, i); - if (elt == t) { - iparams[i] = t; - } - else { - jl_value_t *tv = jl_tupleref(((jl_datatype_t*)tc)->parameters, i); - iparams[i] = (jl_value_t*)inst_type_w_(elt, env, n, stack, elt != tv); - if (jl_is_typevar(tv) && !jl_is_typevar(iparams[i])) { - if (!jl_subtype(iparams[i], tv, 0)) { - jl_type_error_rt(tt->name->name->name, - ((jl_tvar_t*)tv)->name->name, - tv, iparams[i]); - } + jl_datatype_t *tt = (jl_datatype_t*)t; + jl_tuple_t *tp = tt->parameters; + if (jl_is_null(tp)) + return (jl_value_t*)t; + jl_typename_t *tn = tt->name; + jl_value_t *tc = tn->primary; + // don't instantiate "Foo" without parameters inside Foo + if (t == tc && stack!=NULL) + return (jl_value_t*)t; + size_t ntp = jl_tuple_len(tp); + assert(jl_is_datatype(tc)); + assert(ntp == jl_tuple_len(((jl_datatype_t*)tc)->parameters)); + jl_value_t **iparams; + JL_GC_PUSHARGS(iparams, ntp); + for(i=0; i < ntp+2; i++) iparams[i] = NULL; + //jl_value_t **rt1 = &iparams[ntp+0]; // some extra gc roots + //jl_value_t **rt2 = &iparams[ntp+1]; + int cacheable = 1, isabstract = 0, bound = 0; + for(i=0; i < ntp; i++) { + jl_value_t *elt = jl_tupleref(tp, i); + if (elt == t) { + iparams[i] = t; + } + else { + jl_value_t *tv = jl_tupleref(((jl_datatype_t*)tc)->parameters, i); + iparams[i] = (jl_value_t*)inst_type_w_(elt, env, n, stack, elt != tv); + if (jl_is_typevar(tv) && !jl_is_typevar(iparams[i])) { + if (!jl_subtype(iparams[i], tv, 0)) { + jl_type_error_rt(tt->name->name->name, + ((jl_tvar_t*)tv)->name->name, + tv, iparams[i]); } - if (!bound) { - for(j=0; j < n; j++) { - if (env[j*2] == tv) { - bound = 1; break; - } + } + if (!bound) { + for(j=0; j < n; j++) { + if (env[j*2] == tv) { + bound = 1; break; } } } - if (jl_is_typevar(iparams[i])) - isabstract = 1; - if (jl_has_typevars_(iparams[i],0)) - cacheable = 0; - } - // if t's parameters are not bound in the environment, return it uncopied (#9378) - if (!bound && t == tc) { JL_GC_POP(); return (jl_value_t*)t; } - - jl_tuple_t *iparams_tuple; - jl_datatype_t *dt; - jl_datatype_t *ndt; - jl_tuple_t *ftypes; - - // if an identical instantiation is already in process somewhere - // up the stack, return it. this computes a fixed point for - // recursive types. - jl_typestack_t *tmp = stack; - jl_value_t *lkup = NULL; - while (tmp != NULL) { - if (tmp->tt->name==tn && ntp==jl_tuple_len(tmp->tt->parameters) && - typekey_compare(tmp->tt, iparams, ntp)) { - lkup = (jl_value_t*)tmp->tt; - break; - } - tmp = tmp->prev; } - if (lkup != NULL && lkup != (jl_value_t*)tc) { - result = lkup; goto done_inst_tt; - } - - // check type cache - if (cacheable) { - lkup = (jl_value_t*)lookup_type(tn, iparams, ntp); - if (lkup != NULL) { - result = lkup; goto done_inst_tt; - } - } - - // always use original type constructor - if (tc != t) { - //(tc != NULL && tc != t) - result = (jl_value_t*)jl_apply_type_(tc, iparams, ntp); - goto done_inst_tt; - } - - // move array of instantiated parameters to heap; we need to keep it - iparams_tuple = jl_alloc_tuple_uninit(ntp); - for(i=0; i < ntp; i++) - jl_tupleset(iparams_tuple, i, iparams[i]); - *rt1 = (jl_value_t*)iparams_tuple; - - dt = (jl_datatype_t*)t; - // create and initialize new type - ndt = jl_new_uninitialized_datatype(jl_tuple_len(dt->names)); - *rt2 = (jl_value_t*)ndt; - // associate these parameters with the new type on - // the stack, in case one of its field types references it. - top.tt = (jl_datatype_t*)ndt; - top.prev = stack; - stack = ⊤ - ndt->name = tn; - gc_wb(ndt, ndt->name); - ndt->super = jl_any_type; - ndt->parameters = iparams_tuple; - gc_wb(ndt, ndt->parameters); - ndt->names = dt->names; - gc_wb(ndt, ndt->names); - ndt->types = jl_null; // to be filled in below - ndt->mutabl = dt->mutabl; - ndt->abstract = dt->abstract; - ndt->instance = NULL; - ndt->uid = 0; - ndt->struct_decl = NULL; - ndt->ditype = NULL; - ndt->size = 0; - ndt->alignment = 1; - - ndt->super = (jl_datatype_t*)inst_type_w_((jl_value_t*)dt->super, env,n,stack, 1); - gc_wb(ndt, ndt->super); - ftypes = dt->types; - if (ftypes != NULL) { - // recursively instantiate the types of the fields - ndt->types = (jl_tuple_t*)inst_type_w_((jl_value_t*)ftypes, env, n, stack, 1); - gc_wb(ndt, ndt->types); - if (!isabstract) { - if (jl_tuple_len(ftypes) == 0) { - ndt->size = dt->size; - ndt->alignment = dt->alignment; - ndt->pointerfree = dt->pointerfree; - } - else { - jl_compute_field_offsets(ndt); - } - if (jl_is_datatype_singleton(ndt) && tn != jl_array_typename) - ndt->instance = newstruct(ndt); - } - else { - ndt->size = 0; - ndt->pointerfree = 0; - } - if (tn == jl_array_typename) - ndt->pointerfree = 0; + if (jl_is_typevar(iparams[i])) + isabstract = 1; + if (jl_has_typevars_(iparams[i],0)) + cacheable = 0; + } + // if t's parameters are not bound in the environment, return it uncopied (#9378) + if (!bound && t == tc) { JL_GC_POP(); return (jl_value_t*)t; } + + jl_tuple_t *iparams_tuple; + jl_datatype_t *dt; + jl_datatype_t *ndt; + jl_tuple_t *ftypes; + + // if an identical instantiation is already in process somewhere + // up the stack, return it. this computes a fixed point for + // recursive types. + jl_typestack_t *tmp = stack; + jl_value_t *lkup = NULL; + while (tmp != NULL) { + if (tmp->tt->name==tn && ntp==jl_tuple_len(tmp->tt->parameters) && + typekey_compare(tmp->tt, iparams, ntp)) { + lkup = (jl_value_t*)tmp->tt; + break; } - ndt->ninitialized = dt->ninitialized; - if (cacheable) cache_type_((jl_value_t*)ndt); - result = (jl_value_t*)ndt; - - done_inst_tt: + tmp = tmp->prev; + } + if (lkup != NULL && lkup != (jl_value_t*)tc) { JL_GC_POP(); - return result; + return lkup; } - return (jl_value_t*)t; + jl_value_t *result = inst_datatype(tn, NULL, iparams, ntp); + JL_GC_POP(); + return result; } jl_value_t *jl_instantiate_type_with(jl_value_t *t, jl_value_t **env, size_t n) diff --git a/src/julia.h b/src/julia.h index 8454e58e6a94d..ea9f88eb594f9 100644 --- a/src/julia.h +++ b/src/julia.h @@ -53,7 +53,7 @@ extern "C" { // core data types ------------------------------------------------------------ -#ifdef OVERLAP_TUPLE_LEN +#ifdef OVERLAP_SV_LEN #define JL_DATA_TYPE \ size_t type : 52; \ size_t _resvd : 12; @@ -80,7 +80,7 @@ typedef struct _jl_gensym_t { } jl_gensym_t; typedef struct { -#ifdef OVERLAP_TUPLE_LEN +#ifdef OVERLAP_SV_LEN size_t type : 52; size_t length : 12; #else @@ -88,7 +88,7 @@ typedef struct { size_t length; #endif jl_value_t *data[]; -} jl_tuple_t; +} jl_sv_t; typedef struct { JL_DATA_TYPE @@ -132,6 +132,8 @@ STATIC_INLINE int jl_array_ndimwords(uint32_t ndims) typedef jl_value_t *(*jl_fptr_t)(jl_value_t*, jl_value_t**, uint32_t); +typedef struct _jl_datatype_t jl_tupletype_t; + typedef struct _jl_lambda_info_t { JL_DATA_TYPE // this holds the static data for a function: @@ -140,12 +142,12 @@ typedef struct _jl_lambda_info_t { // this is the stuff that's shared among different instantiations // (different environments) of a closure. jl_value_t *ast; - // sparams is a tuple (symbol, value, symbol, value, ...) - jl_tuple_t *sparams; + // sparams is a vector (symbol, value, symbol, value, ...) + jl_sv_t *sparams; jl_value_t *tfunc; jl_sym_t *name; // for error reporting jl_array_t *roots; // pointers in generated code - jl_tuple_t *specTypes; // argument types this is specialized for + jl_tupletype_t *specTypes; // argument types this is specialized for // a slower-but-works version of this function as a fallback struct _jl_function_t *unspecialized; // array of all lambda infos with code generated from this one @@ -180,7 +182,7 @@ typedef struct _jl_function_t { typedef struct { JL_DATA_TYPE - jl_tuple_t *parameters; + jl_sv_t *parameters; jl_value_t *body; } jl_typector_t; @@ -188,6 +190,7 @@ typedef struct { JL_DATA_TYPE jl_sym_t *name; struct _jl_module_t *module; + jl_sv_t *names; // field names // if this is the name of a parametric type, this field points to the // original type. // a type alias, for example, might make a type constructor that is @@ -198,7 +201,7 @@ typedef struct { typedef struct { JL_DATA_TYPE - jl_tuple_t *types; + jl_sv_t *types; } jl_uniontype_t; typedef struct { @@ -211,11 +214,11 @@ typedef struct _jl_datatype_t { JL_DATA_TYPE jl_typename_t *name; struct _jl_datatype_t *super; - jl_tuple_t *parameters; - jl_tuple_t *names; - jl_tuple_t *types; + jl_sv_t *parameters; + jl_sv_t *types; jl_value_t *instance; // for singletons int32_t size; + uint8_t va; uint8_t abstract; uint8_t mutabl; uint8_t pointerfree; @@ -264,10 +267,10 @@ typedef struct _jl_module_t { typedef struct _jl_methlist_t { JL_DATA_TYPE - jl_tuple_t *sig; + jl_tupletype_t *sig; int8_t va; int8_t isstaged; - jl_tuple_t *tvars; + jl_sv_t *tvars; jl_function_t *func; // cache of specializations of this method for invoke(), i.e. // cases where this method was called even though it was not necessarily @@ -311,8 +314,11 @@ extern DLLEXPORT jl_datatype_t *jl_typector_type; extern DLLEXPORT jl_datatype_t *jl_sym_type; extern DLLEXPORT jl_datatype_t *jl_symbol_type; extern DLLEXPORT jl_datatype_t *jl_gensym_type; -extern DLLEXPORT jl_tuple_t *jl_tuple_type; -extern DLLEXPORT jl_value_t *jl_tupletype_type; +//extern DLLEXPORT jl_typename_t *jl_simplevector_typename; +extern DLLEXPORT jl_datatype_t *jl_simplevector_type; +extern DLLEXPORT jl_typename_t *jl_tuple_typename; +extern DLLEXPORT jl_datatype_t *jl_anytuple_type; +//extern DLLEXPORT jl_value_t *jl_tupletype_type; extern DLLEXPORT jl_datatype_t *jl_ntuple_type; extern DLLEXPORT jl_typename_t *jl_ntuple_typename; extern DLLEXPORT jl_datatype_t *jl_tvar_type; @@ -324,7 +330,7 @@ extern DLLEXPORT jl_datatype_t *jl_datatype_type; extern DLLEXPORT jl_value_t *jl_bottom_type; extern DLLEXPORT jl_datatype_t *jl_lambda_info_type; extern DLLEXPORT jl_datatype_t *jl_module_type; -extern DLLEXPORT jl_datatype_t *jl_vararg_type; +//extern DLLEXPORT jl_datatype_t *jl_vararg_type; extern DLLEXPORT jl_datatype_t *jl_function_type; extern DLLEXPORT jl_datatype_t *jl_abstractarray_type; extern DLLEXPORT jl_datatype_t *jl_densearray_type; @@ -385,8 +391,8 @@ extern DLLEXPORT jl_datatype_t *jl_methtable_type; extern DLLEXPORT jl_datatype_t *jl_method_type; extern DLLEXPORT jl_datatype_t *jl_task_type; -extern DLLEXPORT jl_tuple_t *jl_null; -#define JL_NULL ((void*)jl_null) +extern DLLEXPORT jl_sv_t *jl_emptysv; +extern DLLEXPORT jl_value_t *jl_emptytuple; DLLEXPORT extern jl_value_t *jl_true; DLLEXPORT extern jl_value_t *jl_false; DLLEXPORT extern jl_value_t *jl_nothing; @@ -463,7 +469,7 @@ static inline void gc_wb_back(void *ptr) // object accessors ----------------------------------------------------------- -#ifdef OVERLAP_TUPLE_LEN +#ifdef OVERLAP_SV_LEN #define jl_typeof(v) ((jl_value_t*)((uptrint_t)((jl_value_t*)(v))->type & 0x000ffffffffffffeULL)) #else #define jl_typeof(v) ((jl_value_t*)((uptrint_t)((jl_value_t*)(v))->type & ((uintptr_t)~3))) @@ -471,10 +477,25 @@ static inline void gc_wb_back(void *ptr) #define jl_typeis(v,t) (jl_typeof(v)==(jl_value_t*)(t)) -#define jl_tuple_len(t) (((jl_tuple_t*)(t))->length) -#define jl_tuple_set_len_unsafe(t,n) (((jl_tuple_t*)(t))->length=(n)) -#define jl_tuple_data(t) (((jl_tuple_t*)(t))->data) -#define TUPLE_DATA_OFFSET offsetof(jl_tuple_t,data)/sizeof(void*) +#define jl_sv_len(t) (((jl_sv_t*)(t))->length) +#define jl_sv_set_len_unsafe(t,n) (((jl_sv_t*)(t))->length=(n)) +#define jl_sv_data(t) (((jl_sv_t*)(t))->data) + +STATIC_INLINE jl_value_t *jl_svref(void *t, size_t i) +{ + assert(i < jl_sv_len(t)); + return jl_sv_data(t)[i]; +} +STATIC_INLINE jl_value_t *jl_svset(void *t, size_t i, void *x) +{ + assert(i < jl_sv_len(t)); + jl_sv_data(t)[i] = (jl_value_t*)x; + if (x) gc_wb(t, x); + return (jl_value_t*)x; +} + +#define jl_sv0(t) jl_svref(t,0) +#define jl_sv1(t) jl_svref(t,1) #ifdef STORE_ARRAY_LEN #define jl_array_len(a) (((jl_array_t*)(a))->length) @@ -489,18 +510,6 @@ DLLEXPORT size_t jl_array_len_(jl_array_t *a); #define jl_array_ndims(a) ((int32_t)(((jl_array_t*)a)->ndims)) #define jl_array_data_owner(a) (*((jl_value_t**)(&a->ncols+1+jl_array_ndimwords(jl_array_ndims(a))))) -STATIC_INLINE jl_value_t *jl_tupleref(void *t, size_t i) -{ - assert(i < jl_tuple_len(t)); - return jl_tuple_data(t)[i]; -} -STATIC_INLINE jl_value_t *jl_tupleset(void *t, size_t i, void *x) -{ - assert(i < jl_tuple_len(t)); - jl_tuple_data(t)[i] = (jl_value_t*)x; - if(x) gc_wb(t, x); - return (jl_value_t*)x; -} STATIC_INLINE jl_value_t *jl_cellref(void *a, size_t i) { assert(i < jl_array_len(a)); @@ -510,17 +519,15 @@ STATIC_INLINE jl_value_t *jl_cellset(void *a, size_t i, void *x) { assert(i < jl_array_len(a)); ((jl_value_t**)(jl_array_data(a)))[i] = (jl_value_t*)x; - if(x) gc_wb(a, x); + if (x) gc_wb(a, x); return (jl_value_t*)x; } -# define jl_t0(t) jl_tupleref(t,0) -# define jl_t1(t) jl_tupleref(t,1) - #define jl_exprarg(e,n) (((jl_value_t**)jl_array_data(((jl_expr_t*)(e))->args))[n]) #define jl_exprargset(e, n, v) jl_cellset(((jl_expr_t*)(e))->args, n, v) #define jl_fieldref(s,i) jl_get_nth_field(((jl_value_t*)s),i) +#define jl_nfields(v) jl_sv_len(((jl_datatype_t*)jl_typeof(v))->types) #define jl_symbolnode_sym(s) ((jl_sym_t*)jl_fieldref(s,0)) #define jl_symbolnode_type(s) (jl_fieldref(s,1)) @@ -531,9 +538,8 @@ STATIC_INLINE jl_value_t *jl_cellset(void *a, size_t i, void *x) #define jl_getfieldnode_name(s) ((jl_sym_t*)jl_fieldref(s,1)) #define jl_getfieldnode_type(s) (jl_fieldref(s,2)) -#define jl_tparam0(t) jl_tupleref(((jl_datatype_t*)(t))->parameters, 0) -#define jl_tparam1(t) jl_tupleref(((jl_datatype_t*)(t))->parameters, 1) - +#define jl_tparam0(t) jl_svref(((jl_datatype_t*)(t))->parameters, 0) +#define jl_tparam1(t) jl_svref(((jl_datatype_t*)(t))->parameters, 1) #define jl_cell_data(a) ((jl_value_t**)((jl_array_t*)a)->data) #define jl_string_data(s) ((char*)((jl_array_t*)((jl_value_t**)(s))[1])->data) @@ -551,9 +557,8 @@ STATIC_INLINE jl_value_t *jl_cellset(void *a, size_t i, void *x) #define jl_datatype_size(t) (((jl_datatype_t*)t)->size) // basic predicates ----------------------------------------------------------- -#define jl_is_null(v) (((jl_value_t*)(v)) == ((jl_value_t*)jl_null)) #define jl_is_nothing(v) (((jl_value_t*)(v)) == ((jl_value_t*)jl_nothing)) -#define jl_is_tuple(v) jl_typeis(v,jl_tuple_type) +#define jl_is_tuple(v) (((jl_datatype_t*)jl_typeof(v))->name == jl_tuple_typename) #define jl_is_datatype(v) jl_typeis(v,jl_datatype_type) #define jl_is_pointerfree(t) (((jl_datatype_t*)t)->pointerfree) #define jl_is_mutable(t) (((jl_datatype_t*)t)->mutabl) @@ -605,7 +610,7 @@ STATIC_INLINE jl_value_t *jl_cellset(void *a, size_t i, void *x) STATIC_INLINE int jl_is_bitstype(void *v) { return (jl_is_datatype(v) && jl_is_immutable(v) && - jl_tuple_len(((jl_datatype_t*)(v))->names)==0 && + jl_sv_len(((jl_datatype_t*)(v))->types)==0 && !((jl_datatype_t*)(v))->abstract && ((jl_datatype_t*)(v))->size > 0); } @@ -613,7 +618,7 @@ STATIC_INLINE int jl_is_bitstype(void *v) STATIC_INLINE int jl_is_structtype(void *v) { return (jl_is_datatype(v) && - (jl_tuple_len(((jl_datatype_t*)(v))->names) > 0 || + (jl_sv_len(((jl_datatype_t*)v)->name->names) > 0 || ((jl_datatype_t*)(v))->size == 0) && !((jl_datatype_t*)(v))->abstract); } @@ -651,26 +656,32 @@ STATIC_INLINE int jl_is_cpointer_type(void *t) return (jl_is_datatype(t) && ((jl_datatype_t*)(t))->name == jl_pointer_type->name); } - +/* STATIC_INLINE int jl_is_vararg_type(jl_value_t *v) { return (jl_is_datatype(v) && ((jl_datatype_t*)(v))->name == jl_vararg_type->name); } +*/ +STATIC_INLINE int jl_is_tuple_type(void *t) +{ + return (jl_is_datatype(t) && + ((jl_datatype_t*)(t))->name == jl_tuple_typename); +} STATIC_INLINE int jl_is_ntuple_type(jl_value_t *v) { return (jl_is_datatype(v) && ((jl_datatype_t*)v)->name == jl_ntuple_typename); } - +/* STATIC_INLINE int jl_is_nontuple_type(jl_value_t *v) { return (jl_typeis(v, jl_uniontype_type) || jl_typeis(v, jl_datatype_type) || jl_typeis(v, jl_typector_type)); } - +*/ STATIC_INLINE int jl_is_type_type(jl_value_t *v) { return (jl_is_datatype(v) && @@ -682,16 +693,16 @@ DLLEXPORT int jl_egal(jl_value_t *a, jl_value_t *b); DLLEXPORT uptrint_t jl_object_id(jl_value_t *v); // type predicates and basic operations -jl_value_t *jl_full_type(jl_value_t *v); +//jl_value_t *jl_full_type(jl_value_t *v); int jl_is_type(jl_value_t *v); DLLEXPORT int jl_is_leaf_type(jl_value_t *v); int jl_has_typevars(jl_value_t *v); DLLEXPORT int jl_subtype(jl_value_t *a, jl_value_t *b, int ta); int jl_type_morespecific(jl_value_t *a, jl_value_t *b); DLLEXPORT int jl_types_equal(jl_value_t *a, jl_value_t *b); -jl_value_t *jl_type_union(jl_tuple_t *types); +jl_value_t *jl_type_union(jl_sv_t *types); jl_value_t *jl_type_intersection_matching(jl_value_t *a, jl_value_t *b, - jl_tuple_t **penv, jl_tuple_t *tvars); + jl_sv_t **penv, jl_sv_t *tvars); DLLEXPORT jl_value_t *jl_type_intersection(jl_value_t *a, jl_value_t *b); DLLEXPORT int jl_args_morespecific(jl_value_t *a, jl_value_t *b); DLLEXPORT const char *jl_typename_str(jl_value_t *v); @@ -700,22 +711,23 @@ DLLEXPORT const char *jl_typeof_str(jl_value_t *v); // type constructors DLLEXPORT jl_typename_t *jl_new_typename(jl_sym_t *name); DLLEXPORT jl_tvar_t *jl_new_typevar(jl_sym_t *name,jl_value_t *lb,jl_value_t *ub); -jl_typector_t *jl_new_type_ctor(jl_tuple_t *params, jl_value_t *body); -DLLEXPORT jl_value_t *jl_apply_type(jl_value_t *tc, jl_tuple_t *params); +jl_typector_t *jl_new_type_ctor(jl_sv_t *params, jl_value_t *body); +DLLEXPORT jl_value_t *jl_apply_type(jl_value_t *tc, jl_sv_t *params); +DLLEXPORT jl_value_t *jl_apply_tuple_type(jl_sv_t *params); jl_value_t *jl_apply_type_(jl_value_t *tc, jl_value_t **params, size_t n); jl_value_t *jl_instantiate_type_with(jl_value_t *t, jl_value_t **env, size_t n); -DLLEXPORT jl_uniontype_t *jl_new_uniontype(jl_tuple_t *types); +DLLEXPORT jl_uniontype_t *jl_new_uniontype(jl_sv_t *types); jl_datatype_t *jl_new_abstracttype(jl_value_t *name, jl_datatype_t *super, - jl_tuple_t *parameters); + jl_sv_t *parameters); DLLEXPORT jl_datatype_t *jl_new_uninitialized_datatype(size_t nfields); DLLEXPORT jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super, - jl_tuple_t *parameters, - jl_tuple_t *fnames, jl_tuple_t *ftypes, + jl_sv_t *parameters, + jl_sv_t *fnames, jl_sv_t *ftypes, int abstract, int mutabl, int ninitialized); DLLEXPORT jl_datatype_t *jl_new_bitstype(jl_value_t *name, jl_datatype_t *super, - jl_tuple_t *parameters, size_t nbits); + jl_sv_t *parameters, size_t nbits); jl_datatype_t *jl_wrap_Type(jl_value_t *t); // x -> Type{x} -jl_datatype_t *jl_wrap_vararg(jl_value_t *t); // x -> x... +//jl_datatype_t *jl_wrap_vararg(jl_value_t *t); // x -> x... // constructors DLLEXPORT jl_value_t *jl_new_bits(jl_value_t *bt, void *data); @@ -725,15 +737,16 @@ DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uin DLLEXPORT jl_value_t *jl_new_struct_uninit(jl_datatype_t *type); DLLEXPORT jl_function_t *jl_new_closure(jl_fptr_t proc, jl_value_t *env, jl_lambda_info_t *li); -DLLEXPORT jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_tuple_t *sparams); -DLLEXPORT jl_tuple_t *jl_tuple(size_t n, ...); -DLLEXPORT jl_tuple_t *jl_tuplev(size_t n, jl_value_t **v); -DLLEXPORT jl_tuple_t *jl_tuple1(void *a); -DLLEXPORT jl_tuple_t *jl_tuple2(void *a, void *b); -DLLEXPORT jl_tuple_t *jl_alloc_tuple(size_t n); -DLLEXPORT jl_tuple_t *jl_alloc_tuple_uninit(size_t n); -DLLEXPORT jl_tuple_t *jl_tuple_append(jl_tuple_t *a, jl_tuple_t *b); -DLLEXPORT jl_tuple_t *jl_tuple_fill(size_t n, jl_value_t *v); +DLLEXPORT jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_sv_t *sparams); +DLLEXPORT jl_sv_t *jl_sv(size_t n, ...); +//DLLEXPORT jl_tuple_t *jl_tuplev(size_t n, jl_value_t **v); +DLLEXPORT jl_sv_t *jl_sv1(void *a); +DLLEXPORT jl_sv_t *jl_sv2(void *a, void *b); +DLLEXPORT jl_sv_t *jl_alloc_sv(size_t n); +DLLEXPORT jl_sv_t *jl_alloc_sv_uninit(size_t n); +DLLEXPORT jl_sv_t *jl_sv_append(jl_sv_t *a, jl_sv_t *b); +DLLEXPORT jl_sv_t *jl_sv_fill(size_t n, jl_value_t *x); +DLLEXPORT jl_value_t *jl_tupletype_fill(size_t n, jl_value_t *v); DLLEXPORT jl_sym_t *jl_symbol(const char *str); DLLEXPORT jl_sym_t *jl_symbol_lookup(const char *str); DLLEXPORT jl_sym_t *jl_symbol_n(const char *str, int32_t len); @@ -742,10 +755,10 @@ DLLEXPORT jl_sym_t *jl_tagged_gensym(const char *str, int32_t len); DLLEXPORT jl_sym_t *jl_get_root_symbol(void); jl_expr_t *jl_exprn(jl_sym_t *head, size_t n); jl_function_t *jl_new_generic_function(jl_sym_t *name); -void jl_add_method(jl_function_t *gf, jl_tuple_t *types, jl_function_t *meth, - jl_tuple_t *tvars, int8_t isstaged); +void jl_add_method(jl_function_t *gf, jl_value_t *types, jl_function_t *meth, + jl_sv_t *tvars, int8_t isstaged); DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_value_t *bp_owner, jl_binding_t *bnd, - jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged, + jl_value_t *argtypes, jl_function_t *f, jl_value_t *isstaged, jl_value_t *call_func, int iskw); DLLEXPORT jl_value_t *jl_box_bool(int8_t x); DLLEXPORT jl_value_t *jl_box_int8(int32_t x); @@ -804,14 +817,14 @@ DLLEXPORT void *jl_value_ptr(jl_value_t *a); // arrays -DLLEXPORT jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims); +DLLEXPORT jl_array_t *jl_new_array(jl_value_t *atype, jl_value_t *dims); DLLEXPORT jl_array_t *jl_new_arrayv(jl_value_t *atype, ...); DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data, - jl_tuple_t *dims); + jl_value_t *dims); DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data, size_t nel, int own_buffer); DLLEXPORT jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data, - jl_tuple_t *dims, int own_buffer); + jl_value_t *dims, int own_buffer); int jl_array_store_unboxed(jl_value_t *el_type); DLLEXPORT jl_array_t *jl_alloc_array_1d(jl_value_t *atype, size_t nr); @@ -1007,13 +1020,12 @@ jl_value_t *jl_static_eval(jl_value_t *ex, void *ctx_, jl_module_t *mod, jl_value_t *sp, jl_expr_t *ast, int sparams, int allow_alloc); int jl_is_toplevel_only_expr(jl_value_t *e); jl_module_t *jl_base_relative_to(jl_module_t *m); -void jl_type_infer(jl_lambda_info_t *li, jl_tuple_t *argtypes, - jl_lambda_info_t *def); +void jl_type_infer(jl_lambda_info_t *li, jl_value_t *argtypes, jl_lambda_info_t *def); -jl_function_t *jl_method_lookup_by_type(jl_methtable_t *mt, jl_tuple_t *types, +jl_function_t *jl_method_lookup_by_type(jl_methtable_t *mt, jl_value_t *types, int cache, int inexact); jl_function_t *jl_method_lookup(jl_methtable_t *mt, jl_value_t **args, size_t nargs, int cache); -jl_value_t *jl_gf_invoke(jl_function_t *gf, jl_tuple_t *types, +jl_value_t *jl_gf_invoke(jl_function_t *gf, jl_value_t *types, jl_value_t **args, size_t nargs); // AST access @@ -1029,7 +1041,7 @@ DLLEXPORT jl_value_t *jl_ast_rettype(jl_lambda_info_t *li, jl_value_t *ast); jl_sym_t *jl_decl_var(jl_value_t *ex); DLLEXPORT int jl_is_rest_arg(jl_value_t *ex); -DLLEXPORT jl_value_t *jl_prepare_ast(jl_lambda_info_t *li, jl_tuple_t *sparams); +DLLEXPORT jl_value_t *jl_prepare_ast(jl_lambda_info_t *li, jl_sv_t *sparams); DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr); DLLEXPORT jl_value_t *jl_compress_ast(jl_lambda_info_t *li, jl_value_t *ast); diff --git a/src/simplevector.c b/src/simplevector.c new file mode 100644 index 0000000000000..7db05cccfbb92 --- /dev/null +++ b/src/simplevector.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include "julia.h" +#include "julia_internal.h" + +DLLEXPORT jl_sv_t *jl_sv(size_t n, ...) +{ + va_list args; + if (n == 0) return jl_emptysv; + va_start(args, n); + jl_tuple_t *jv = jl_alloc_sv_uninit(n); + for(size_t i=0; i < n; i++) { + jl_svset(jv, i, va_arg(args, jl_value_t*)); + } + va_end(args); + return jv; +} + +jl_sv_t *jl_sv1(void *a) +{ +#ifdef OVERLAP_SV_LEN + jl_sv_t *v = (jl_sv_t*)alloc_2w(); +#else + jl_sv_t *v = (jl_sv_t*)alloc_3w(); +#endif + v->type = (jl_value_t*)jl_simplevector_type; + jl_sv_set_len_unsafe(v, 1); + jl_svset(v, 0, a); + return v; +} + +jl_sv_t *jl_sv2(void *a, void *b) +{ +#ifdef OVERLAP_TUPLE_LEN + jl_sv_t *v = (jl_sv_t*)alloc_3w(); +#else + jl_sv_t *v = (jl_sv_t*)alloc_4w(); +#endif + v->type = (jl_value_t*)jl_simplevector_type; + jl_sv_set_len_unsafe(v, 2); + jl_svset(v, 0, a); + jl_svset(v, 1, b); + return v; +} + +jl_sv_t *jl_alloc_sv_uninit(size_t n) +{ + if (n == 0) return jl_emptysv; +#ifdef OVERLAP_TUPLE_LEN + jl_sv_t *jv = (jl_tuple_t*)newobj((jl_value_t*)jl_simplevector_type, n); +#else + jl_sv_t *jv = (jl_tuple_t*)newobj((jl_value_t*)jl_simplevector_type, n+1); +#endif + jl_sv_set_len_unsafe(jv, n); + return jv; +} + +jl_tuple_t *jl_alloc_sv(size_t n) +{ + if (n == 0) return jl_emptysv; + jl_sv_t *jv = jl_alloc_sv_uninit(n); + for(size_t i=0; i < n; i++) { + jl_svset(jv, i, NULL); + } + return jv; +} + +jl_sv_t *jl_sv_append(jl_sv_t *a, jl_sv_t *b) +{ + jl_sv_t *c = jl_alloc_sv_uninit(jl_sv_len(a) + jl_sv_len(b)); + size_t i=0, j; + for(j=0; j < jl_sv_len(a); j++) { + jl_svset(c, i, jl_svref(a,j)); + i++; + } + for(j=0; j < jl_sv_len(b); j++) { + jl_svset(c, i, jl_svref(b,j)); + i++; + } + return c; +} + +jl_sv_t *jl_sv_fill(size_t n, jl_value_t *x) +{ + if (n==0) return jl_emptysv; + jl_sv_t *v = jl_alloc_sv_uninit(n); + for(size_t i=0; i < n; i++) { + jl_svset(v, i, x); + } + return v; +}