From 51a30691c50a86542ac9b0ba052017bb66df9d77 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson <jeff.bezanson@gmail.com> Date: Sat, 11 Oct 2014 13:51:59 -0400 Subject: [PATCH] fully redesign constructors to use `call` overloading this does not work yet, but gets past the first bootstrap stage. so far this is a significant net simplification. --- base/array.jl | 8 +++ base/boot.jl | 31 +++++++++++ base/inference.jl | 79 ++++++++++---------------- base/linalg/cholmod.jl | 2 +- base/reflection.jl | 6 +- base/subarray.jl | 60 ++++++++++---------- src/alloc.c | 111 ++----------------------------------- src/builtin_proto.h | 5 -- src/builtins.c | 42 +------------- src/codegen.cpp | 20 +++---- src/dump.c | 21 ++----- src/gf.c | 27 +-------- src/interpreter.c | 16 +++--- src/jltypes.c | 87 +++++++++-------------------- src/julia-syntax.scm | 122 ++++++++++++++++++++++++++++------------- src/julia.h | 20 +++---- src/julia_internal.h | 3 - src/module.c | 11 +--- src/task.c | 27 +-------- src/toplevel.c | 37 +++++++++++-- 20 files changed, 280 insertions(+), 455 deletions(-) diff --git a/base/array.jl b/base/array.jl index cd27de4944ce6..6d64b508e5629 100644 --- a/base/array.jl +++ b/base/array.jl @@ -123,6 +123,14 @@ function getindex(T::NonTupleType, vals...) return a end +function getindex(::Type{Any}, vals::ANY...) + a = Array(Any,length(vals)) + for i = 1:length(vals) + a[i] = vals[i] + end + return a +end + getindex(T::(Type...)) = Array(T,0) # T[a:b] and T[a:s:b] also construct typed ranges diff --git a/base/boot.jl b/base/boot.jl index ffe6e6d3cb353..7e3cf56cd9994 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -245,3 +245,34 @@ end typealias ByteString Union(ASCIIString,UTF8String) include(fname::ByteString) = ccall(:jl_load_, Any, (Any,), fname) + +# constructors for built-in types + +TypeVar(n::Symbol) = + ccall(:jl_new_typevar, Any, (Any, Any, Any), n, Union(), Any)::TypeVar +TypeVar(n::Symbol, ub::ANY) = + ccall(:jl_new_typevar, Any, (Any, Any, Any), n, Union(), ub::Type)::TypeVar +TypeVar(n::Symbol, lb::ANY, ub::ANY) = + ccall(:jl_new_typevar, Any, (Any, Any, Any), n, lb::Type, ub::Type)::TypeVar +TypeVar(n::Symbol, b::Bool) = + ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, Union(), Any, b)::TypeVar +TypeVar(n::Symbol, ub::ANY, b::Bool) = + ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, Union(), ub::Type, b)::TypeVar +TypeVar(n::Symbol, lb::ANY, ub::ANY, b::Bool) = + ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, lb::Type, ub::Type, b)::TypeVar + +TypeConstructor(p::ANY, t::ANY) = ccall(:jl_new_type_constructor, Any, (Any, Any), p::Tuple, t::Type) + +Expr(hd::Symbol, args::ANY...) = ccall(:jl_new_expr, Any, (Any, Any), hd, args)::Expr + +LineNumberNode(n::Int) = ccall(:jl_new_struct, Any, (Any,Any...), LineNumberNode, n)::LineNumberNode +LabelNode(n::Int) = ccall(:jl_new_struct, Any, (Any,Any...), LabelNode, n)::LabelNode +GotoNode(n::Int) = ccall(:jl_new_struct, Any, (Any,Any...), GotoNode, n)::GotoNode +QuoteNode(x::ANY) = ccall(:jl_new_struct, Any, (Any,Any...), QuoteNode, x)::QuoteNode +NewvarNode(s::Symbol) = ccall(:jl_new_struct, Any, (Any,Any...), NewvarNode, s)::NewvarNode +TopNode(s::Symbol) = ccall(:jl_new_struct, Any, (Any,Any...), TopNode, s)::TopNode + +Module(name::Symbol) = ccall(:jl_f_new_module, Any, (Any,), name)::Module +Module() = Module(:anonymous) + +Task(f::ANY) = ccall(:jl_new_task, Any, (Any, Int), f::Function, 0)::Task diff --git a/base/inference.jl b/base/inference.jl index 65d318fdd034e..22db441361663 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -29,7 +29,7 @@ type CallStack prev::Union(EmptyCallStack,CallStack) sv::StaticVarInfo - CallStack(ast, mod, types, prev) = new(ast, mod, types, false, 0, Bottom, prev) + CallStack(ast, mod, types::ANY, prev) = new(ast, mod, types, false, 0, Bottom, prev) end inference_stack = EmptyCallStack() @@ -516,10 +516,6 @@ function builtin_tfunction(f::ANY, args::ANY, argtypes::ANY) end tf = get(t_func::ObjectIdDict, f, false) if is(tf,false) - # struct constructor - if isstructtype(f) - return f - end # unknown/unhandled builtin return Any end @@ -828,30 +824,25 @@ end function abstract_call(f, fargs, argtypes, vtypes, sv::StaticVarInfo, e) if is(f,_apply) && length(fargs)>1 a2type = argtypes[2] - if isType(a2type) && isleaftype(a2type.parameters[1]) - af = a2type.parameters[1] - _methods(af,(),0) - else - af = isconstantfunc(fargs[2], sv) - end + af = isconstantfunc(fargs[2], sv) if !is(af,false) af = _ieval(af) - if isa(af,Function) || isa(af,DataType) + if isa(af,Function) aargtypes = map(to_tuple_of_Types, argtypes[3:end]) return abstract_apply(af, aargtypes, vtypes, sv, e) end end # TODO: this slows down inference a lot - # if !(a2type===Function || a2type===DataType) && isleaftype(a2type) - # # would definitely use call() - # call_func = isconstantfunc(fargs[1]) - # if !is(call_func,false) - # aargtypes = Any[ to_tuple_of_Types(argtypes[i]) for i=2:length(argtypes) ] - # aargtypes[1] = (aargtypes[1],) # don't splat "function" - # return abstract_apply(_ieval(call_func), tuple(aargtypes...), vtypes, sv, e) - # end - # end + if !(a2type===Function) && isleaftype(a2type) + # would definitely use call() + call_func = isconstantfunc(fargs[1], sv) + if !is(call_func,false) + aargtypes = Any[ to_tuple_of_Types(argtypes[i]) for i=2:length(argtypes) ] + aargtypes[1] = (aargtypes[1],) # don't splat "function" + return abstract_apply(_ieval(call_func), tuple(aargtypes...), vtypes, sv, e) + end + end return Any end if isgeneric(f) @@ -897,9 +888,9 @@ function abstract_call(f, fargs, argtypes, vtypes, sv::StaticVarInfo, e) # TODO: call() case return Any end - if !isa(f,Function) && !isa(f,DataType) && !isa(f,IntrinsicFunction) && _iisdefined(:call) + if !isa(f,Function) && !isa(f,IntrinsicFunction) && _iisdefined(:call) call_func = _ieval(:call) - return abstract_call(call_func, e.args, tuple(Any[typeof(f),argtypes...]...), vtypes, sv, e) + return abstract_call(call_func, e.args, tuple(Any[abstract_eval_constant(f),argtypes...]...), vtypes, sv, e) end rt = builtin_tfunction(f, fargs, argtypes) #print("=> ", rt, "\n") @@ -933,21 +924,7 @@ function abstract_eval_call(e, vtypes, sv::StaticVarInfo) return result end ft = abstract_eval(called, vtypes, sv) - if isType(ft) - st = ft.parameters[1] - if isa(st,TypeVar) - st = st.ub - end - if isa(st,DataType) - _methods(st,(),0) - if isgeneric(st) && isleaftype(st) - return abstract_call_gf(st, fargs, argtypes, e) - end - # struct constructor - return st - end - end - if !(Function <: ft) && typeintersect(DataType, ft)==Bottom && _iisdefined(:call) + if !(Function <: ft) && _iisdefined(:call) call_func = _ieval(:call) return abstract_call(call_func, e.args, tuple(Any[ft,argtypes...]...), vtypes, sv, e) end @@ -1300,6 +1277,10 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop) end end end + # TODO: typeinf currently gets stuck without this + if linfo.name === :abstract_interpret || linfo.name === :tuple_elim_pass || linfo.name === :abstract_call_gf + return (linfo.ast, Any) + end ast0 = def.ast @@ -1621,6 +1602,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop) # just the return type in place of it. tfarr[idx+1] = rec ? frame.result : fulltree tfarr[idx+2] = rec + #tfunc_idx = idx+1 else def.tfunc[tfunc_idx] = rec ? frame.result : fulltree def.tfunc[tfunc_idx+1] = rec @@ -2063,7 +2045,7 @@ end # static parameters are ok if all the static parameter values are leaf types, # meaning they are fully known. function inlineable(f, e::Expr, atypes, sv, enclosing_ast) - if !(isa(f,Function) || isstructtype(f) || isa(f,IntrinsicFunction)) + if !(isa(f,Function) || isa(f,IntrinsicFunction)) return NF end argexprs = e.args[2:end] @@ -2675,18 +2657,13 @@ function inlining_pass(e::Expr, sv, ast) end if is(e.head,:call1) e.head = :call - ET = exprtype(arg1) - if isType(ET) - f = ET.parameters[1] - else - f1 = f = isconstantfunc(arg1, sv) - if !is(f,false) - f = _ieval(f) - end - if f1===false || !(isa(f,Function) || isa(f,Type) || isa(f,IntrinsicFunction)) - f = _ieval(:call) - e.args = Any[f, e.args...] - end + f1 = f = isconstantfunc(arg1, sv) + if !is(f,false) + f = _ieval(f) + end + if f1===false || !(isa(f,Function) || isa(f,IntrinsicFunction)) + f = _ieval(:call) + e.args = Any[f, e.args...] end if is(f, ^) || is(f, .^) diff --git a/base/linalg/cholmod.jl b/base/linalg/cholmod.jl index 7ac19eba71ba7..47464c6784c6e 100644 --- a/base/linalg/cholmod.jl +++ b/base/linalg/cholmod.jl @@ -294,7 +294,7 @@ type c_CholmodTriplet{Tv<:CHMVTypes,Ti<:CHMITypes} j::Ptr{Ti} x::Ptr{Tv} z::Ptr{Void} - stype:Cint + stype::Cint itype::Cint xtype::Cint dtype::Cint diff --git a/base/reflection.jl b/base/reflection.jl index d3aef01b41008..ac61eb44226ea 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -87,7 +87,7 @@ subtypes(x::DataType) = subtypes(Main, x) subtypetree(x::DataType, level=-1) = (level == 0 ? (x, []) : (x, Any[subtypetree(y, level-1) for y in subtypes(x)])) # function reflection -isgeneric(f::ANY) = (isa(f,Function)||isa(f,DataType)) && isa(f.env,MethodTable) +isgeneric(f::ANY) = (isa(f,Function) && isa(f.env,MethodTable)) function_name(f::Function) = isgeneric(f) ? f.env.name : (:anonymous) @@ -126,8 +126,8 @@ function methods(f::Function) f.env end -methods(t::DataType) = (_methods(t,Tuple,0); # force constructor creation - t.env) +#methods(t::DataType) = (_methods(t,Tuple,0); # force constructor creation +# t.env) function length(mt::MethodTable) n = 0 diff --git a/base/subarray.jl b/base/subarray.jl index 139ffb18850b7..a0d621fb43713 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -11,39 +11,39 @@ type SubArray{T,N,A<:AbstractArray,I<:(RangeIndex...,)} <: AbstractArray{T,N} first_index::Int # Note: no bounds-checking on construction. See issue #4044 + #linear indexing constructor (scalar) - if N == 0 && length(I) == 1 && A <: Array - function SubArray(p::A, i::(Int,)) - new(p, i, (), Int[], i[1]) - end - #linear indexing constructor (ranges) - elseif N == 1 && length(I) == 1 && A <: Array - function SubArray(p::A, i::(UnitRange{Int},)) - new(p, i, (length(i[1]),), [1], first(i[1])) - end - function SubArray(p::A, i::(Range{Int},)) - new(p, i, (length(i[1]),), [step(i[1])], first(i[1])) - end - else - function SubArray(p::A, i::I) - newdims = Array(Int, 0) - newstrides = Array(Int, 0) - newfirst = 1 - pstride = 1 - for j = 1:length(i) - if isa(i[j], Int) - newfirst += (i[j]-1)*pstride - else - push!(newdims, length(i[j])) - #may want to return error if step(i[j]) <= 0 - push!(newstrides, isa(i[j],UnitRange) ? pstride : - pstride * step(i[j])) - newfirst += (first(i[j])-1)*pstride - end - pstride *= size(p,j) + global call + function call{T,A<:Array,I<:(Any,)}(::Type{SubArray{T,0,A,I}}, p::A, i::(Int,)) + new(p, i, (), Int[], i[1]) + end + + function call{T,A<:Array,I<:(Any,)}(::Type{SubArray{T,1,A,I}}, p::A, i::(UnitRange{Int},)) + new(p, i, (length(i[1]),), [1], first(i[1])) + end + + function call{T,A<:Array,I<:(Any,)}(::Type{SubArray{T,1,A,I}}, p::A, i::(Range{Int},)) + new(p, i, (length(i[1]),), [step(i[1])], first(i[1])) + end + + function SubArray(p::A, i::I) + newdims = Array(Int, 0) + newstrides = Array(Int, 0) + newfirst = 1 + pstride = 1 + for j = 1:length(i) + if isa(i[j], Int) + newfirst += (i[j]-1)*pstride + else + push!(newdims, length(i[j])) + #may want to return error if step(i[j]) <= 0 + push!(newstrides, isa(i[j],UnitRange) ? pstride : + pstride * step(i[j])) + newfirst += (first(i[j])-1)*pstride end - new(p, i, tuple(newdims...), newstrides, newfirst) + pstride *= size(p,j) end + new(p, i, tuple(newdims...), newstrides, newfirst) end end diff --git a/src/alloc.c b/src/alloc.c index daaa3f64ac007..d203198bd4644 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -578,8 +578,6 @@ jl_typename_t *jl_new_typename(jl_sym_t *name) tn->module = jl_current_module; tn->primary = NULL; tn->cache = (jl_value_t*)jl_null; - tn->ctor_factory = (jl_value_t*)jl_null; - tn->static_ctor_factory = NULL; return tn; } @@ -593,65 +591,6 @@ jl_datatype_t *jl_new_abstracttype(jl_value_t *name, jl_datatype_t *super, jl_function_t *jl_instantiate_method(jl_function_t *f, jl_tuple_t *sp); -void jl_add_constructors(jl_datatype_t *t) -{ - if (t->name == jl_array_typename) { - t->fptr = jl_f_no_function; - return; - } - - jl_initialize_generic_function((jl_function_t*)t, t->name->name); - - if (t->name->ctor_factory == (jl_value_t*)jl_nothing || - t->name->ctor_factory == (jl_value_t*)jl_null) { - } - else { - assert(jl_tuple_len(t->parameters) > 0); - if (t == (jl_datatype_t*)t->name->primary) - return; - jl_function_t *cfactory = NULL; - jl_tuple_t *env = NULL; - JL_GC_PUSH2(&cfactory, &env); - if (jl_compileropts.compile_enabled) { - // instantiating - assert(jl_is_function(t->name->ctor_factory)); - // add type's static parameters to the ctor factory - size_t np = jl_tuple_len(t->parameters); - env = jl_alloc_tuple_uninit(np*2); - for(size_t i=0; i < np; i++) { - jl_tupleset(env, i*2+0, - jl_tupleref(((jl_datatype_t*)t->name->primary)->parameters, i)); - jl_tupleset(env, i*2+1, - jl_tupleref(t->parameters, i)); - } - cfactory = jl_instantiate_method((jl_function_t*)t->name->ctor_factory, env); - cfactory->linfo->ast = jl_prepare_ast(cfactory->linfo, - cfactory->linfo->sparams); - } - else { - cfactory = ((jl_datatype_t*)t)->name->static_ctor_factory; - if (cfactory == NULL) { - JL_PRINTF(JL_STDERR,"code missing for type %s\n", t->name->name); - exit(1); - } - // in generically-compiled case, pass static parameters via closure - // environment. - env = jl_tuple_append((jl_tuple_t*)cfactory->env, t->parameters); - cfactory = jl_new_closure(cfactory->fptr, (jl_value_t*)env, cfactory->linfo); - } - // call user-defined constructor factory on (type,) - jl_value_t *cfargs[1] = { (jl_value_t*)t }; - jl_apply(cfactory, cfargs, 1); - JL_GC_POP(); - } -} - -JL_CALLABLE(jl_f_ctor_trampoline) -{ - jl_add_constructors((jl_datatype_t*)F); - return jl_apply((jl_function_t*)F, args, nargs); -} - jl_datatype_t *jl_new_uninitialized_datatype(size_t nfields) { return (jl_datatype_t*) @@ -732,9 +671,6 @@ jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super, t->abstract = abstract; t->mutabl = mutabl; t->pointerfree = 0; - t->fptr = jl_f_no_function; - t->env = (jl_value_t*)t; - t->linfo = NULL; t->instance = NULL; t->struct_decl = NULL; t->size = 0; @@ -956,57 +892,22 @@ jl_expr_t *jl_exprn(jl_sym_t *head, size_t n) return ex; } -// this constructor has to be built-in for bootstrapping, because we can't -// do anything without being able to make Exprs. -JL_CALLABLE(jl_f_new_expr) +DLLEXPORT jl_value_t *jl_new_expr(jl_sym_t *head, jl_tuple_t *args) { - JL_NARGSV(Expr, 1); - JL_TYPECHK(Expr, symbol, args[0]); - jl_array_t *ar = jl_alloc_cell_1d(nargs-1); + size_t nargs = jl_tuple_len(args); + jl_array_t *ar = jl_alloc_cell_1d(nargs); JL_GC_PUSH1(&ar); - for(size_t i=1; i < nargs; i++) - jl_cellset(ar, i-1, args[i]); + for(size_t i=0; i < nargs; i++) + jl_cellset(ar, i, jl_tupleref(args,i)); jl_expr_t *ex = (jl_expr_t*)alloc_4w(); ex->type = (jl_value_t*)jl_expr_type; - ex->head = (jl_sym_t*)args[0]; + ex->head = head; ex->args = ar; ex->etype = (jl_value_t*)jl_any_type; JL_GC_POP(); return (jl_value_t*)ex; } -JL_CALLABLE(jl_f_new_box) -{ - JL_NARGS(Box, 1, 1); - jl_value_t *box = (jl_value_t*)alloc_2w(); - box->type = jl_box_any_type; - ((jl_value_t**)box)[1] = args[0]; - return box; -} - -JL_CALLABLE(jl_f_default_ctor_1) -{ - if (nargs != 1) - jl_error("wrong number of arguments (expected 1)"); - jl_value_t *ft = jl_t0(((jl_datatype_t*)F)->types); - if (!jl_subtype(args[0], ft, 1)) - jl_type_error(((jl_datatype_t*)F)->name->name->name, ft, args[0]); - return jl_new_struct((jl_datatype_t*)F, args[0]); -} - -JL_CALLABLE(jl_f_default_ctor_2) -{ - if (nargs != 2) - jl_error("wrong number of arguments (expected 2)"); - jl_value_t *ft = jl_t0(((jl_datatype_t*)F)->types); - if (!jl_subtype(args[0], ft, 1)) - jl_type_error(((jl_datatype_t*)F)->name->name->name, ft, args[0]); - ft = jl_t1(((jl_datatype_t*)F)->types); - if (!jl_subtype(args[1], ft, 1)) - jl_type_error(((jl_datatype_t*)F)->name->name->name, ft, args[1]); - return jl_new_struct((jl_datatype_t*)F, args[0], args[1]); -} - #ifdef __cplusplus } #endif diff --git a/src/builtin_proto.h b/src/builtin_proto.h index d2e361d89b1f8..76d25d6acbc25 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -7,9 +7,6 @@ extern "C" { // declarations for julia-callable builtin functions -JL_CALLABLE(jl_f_new_expr); -JL_CALLABLE(jl_f_new_box); -JL_CALLABLE(jl_f_new_module); JL_CALLABLE(jl_f_throw); JL_CALLABLE(jl_f_is); JL_CALLABLE(jl_f_typeof); @@ -33,13 +30,11 @@ JL_CALLABLE(jl_f_arrayset); JL_CALLABLE(jl_f_arraysize); JL_CALLABLE(jl_f_instantiate_type); JL_CALLABLE(jl_f_convert_default); -JL_CALLABLE(jl_f_new_type_constructor); JL_CALLABLE(jl_f_typevar); JL_CALLABLE(jl_f_union); JL_CALLABLE(jl_f_methodexists); JL_CALLABLE(jl_f_applicable); JL_CALLABLE(jl_f_invoke); -JL_CALLABLE(jl_f_task); JL_CALLABLE(jl_f_yieldto); #ifdef __cplusplus diff --git a/src/builtins.c b/src/builtins.c index 4adb71c505160..3d7a5be00b6e4 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -373,8 +373,6 @@ JL_CALLABLE(jl_f_apply) return result; } -void jl_add_constructors(jl_datatype_t *t); - JL_CALLABLE(jl_f_kwcall) { if (nargs < 4) @@ -399,8 +397,6 @@ JL_CALLABLE(jl_f_kwcall) args[pa-2] = (jl_value_t*)f; } - if (f->fptr == jl_f_ctor_trampoline) - jl_add_constructors((jl_datatype_t*)f); if (!jl_is_gf(f)) jl_error("function does not accept keyword arguments"); jl_function_t *sorter = ((jl_methtable_t*)f->env)->kwsorter; @@ -856,49 +852,15 @@ JL_CALLABLE(jl_f_instantiate_type) return jl_apply_type_(args[0], &args[1], nargs-1); } -JL_CALLABLE(jl_f_new_type_constructor) +DLLEXPORT jl_value_t *jl_new_type_constructor(jl_tuple_t *p, jl_value_t *t) { - JL_NARGS(new_type_constructor, 2, 2); - JL_TYPECHK(new_type_constructor, tuple, args[0]); - if (!jl_is_type(args[1])) - jl_type_error("typealias", (jl_value_t*)jl_type_type, args[1]); - jl_tuple_t *p = (jl_tuple_t*)args[0]; - jl_value_t *tc = (jl_value_t*)jl_new_type_ctor(p, args[1]); + jl_value_t *tc = (jl_value_t*)jl_new_type_ctor(p, t); int i; for(i=0; i < jl_tuple_len(p); i++) ((jl_tvar_t*)jl_tupleref(p,i))->bound = 0; return tc; } -JL_CALLABLE(jl_f_typevar) -{ - if (nargs < 1 || nargs > 3) { - JL_NARGS(TypeVar, 1, 1); - } - JL_TYPECHK(TypeVar, symbol, args[0]); - jl_value_t *lb = (jl_value_t*)jl_bottom_type; - jl_value_t *ub = (jl_value_t*)jl_any_type; - int b = 0; - if (args[nargs-1] == jl_true) { - b = 1; - nargs--; - } - if (nargs > 1) { - JL_TYPECHK(TypeVar, type, args[1]); - if (nargs > 2) { - JL_TYPECHK(TypeVar, type, args[2]); - lb = args[1]; - ub = args[2]; - } - else { - ub = args[1]; - } - } - jl_tvar_t *tv = jl_new_typevar((jl_sym_t*)args[0], lb, ub); - tv->bound = b; - return (jl_value_t*)tv; -} - JL_CALLABLE(jl_f_union) { if (nargs == 0) return (jl_value_t*)jl_bottom_type; diff --git a/src/codegen.cpp b/src/codegen.cpp index 84ff537beae60..485d581e1efe9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2324,13 +2324,7 @@ static Value *emit_is_function(Value *x, jl_codectx_t *ctx) { Value *xty = emit_typeof(x); Value *isfunc = - builder. - CreateOr(builder. - CreateICmpEQ(xty, - literal_pointer_val((jl_value_t*)jl_function_type)), - builder. - CreateICmpEQ(xty, - literal_pointer_val((jl_value_t*)jl_datatype_type))); + builder.CreateICmpEQ(xty, literal_pointer_val((jl_value_t*)jl_function_type)); return isfunc; } @@ -2364,10 +2358,7 @@ static Value *emit_call(jl_value_t **args, size_t arglen, jl_codectx_t *ctx, jl_ } hdtype = expr_type(a0, ctx); - definitely_function |= (hdtype == (jl_value_t*)jl_function_type || - hdtype == (jl_value_t*)jl_datatype_type || - (jl_is_type_type(hdtype) && - jl_is_datatype(jl_tparam0(hdtype)))); + definitely_function |= (hdtype == (jl_value_t*)jl_function_type); definitely_not_function |= (jl_is_leaf_type(hdtype) && !definitely_function); assert(!(definitely_function && definitely_not_function)); @@ -2894,9 +2885,11 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed, make_gcroot(a1, ctx); Value *a2 = boxed(emit_expr(args[2], ctx),ctx); make_gcroot(a2, ctx); - Value *mdargs[6] = { name, bp, literal_pointer_val(bnd), a1, a2, literal_pointer_val(args[3]) }; + Value *mdargs[7] = + { name, bp, literal_pointer_val(bnd), a1, a2, literal_pointer_val(args[3]), + literal_pointer_val((jl_value_t*)jl_module_call_func(ctx->module)) }; ctx->argDepth = last_depth; - return builder.CreateCall(prepare_call(jlmethod_func), ArrayRef<Value*>(&mdargs[0], 6)); + return builder.CreateCall(prepare_call(jlmethod_func), ArrayRef<Value*>(&mdargs[0], 7)); } else if (head == const_sym) { jl_sym_t *sym = (jl_sym_t*)args[0]; @@ -4464,6 +4457,7 @@ static void init_julia_llvm_env(Module *m) mdargs.push_back(jl_pvalue_llvmt); mdargs.push_back(jl_pvalue_llvmt); mdargs.push_back(jl_pvalue_llvmt); + mdargs.push_back(jl_pvalue_llvmt); jlmethod_func = Function::Create(FunctionType::get(jl_pvalue_llvmt, mdargs, false), Function::ExternalLinkage, diff --git a/src/dump.c b/src/dump.c index 50c8f57e9c6c2..7cec6dc7966f3 100644 --- a/src/dump.c +++ b/src/dump.c @@ -302,9 +302,6 @@ static void jl_serialize_datatype(ios_t *s, jl_datatype_t *dt) jl_serialize_value(s, dt->parameters); jl_serialize_value(s, dt->name); jl_serialize_value(s, dt->super); - jl_serialize_value(s, dt->env); - jl_serialize_value(s, dt->linfo); - jl_serialize_fptr(s, (void*)dt->fptr); } static void jl_serialize_module(ios_t *s, jl_module_t *m) @@ -650,9 +647,6 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos) dt->parameters = (jl_tuple_t*)jl_deserialize_value(s); dt->name = (jl_typename_t*)jl_deserialize_value(s); dt->super = (jl_datatype_t*)jl_deserialize_value(s); - dt->env = jl_deserialize_value(s); - dt->linfo = (jl_lambda_info_t*)jl_deserialize_value(s); - dt->fptr = jl_deserialize_fptr(s); if (dt->name == jl_array_type->name || dt->name == jl_pointer_type->name || dt->name == jl_type_type->name || dt->name == jl_vararg_type->name || dt->name == jl_abstractarray_type->name || @@ -969,8 +963,6 @@ void jl_save_system_image(char *fname) jl_idtable_type = jl_get_global(jl_base_module, jl_symbol("ObjectIdDict")); - jl_serialize_value(&f, jl_array_type->env); - jl_serialize_value(&f, jl_main_module); // deser_tag is an array indexed from 2 until HT_NOTFOUND @@ -1040,8 +1032,6 @@ void jl_restore_system_image(char *fname) datatype_list = jl_alloc_cell_1d(0); - jl_array_type->env = jl_deserialize_value(&f); - jl_main_module = (jl_module_t*)jl_deserialize_value(&f); jl_internal_main_module = jl_main_module; jl_core_module = (jl_module_t*)jl_get_global(jl_main_module, @@ -1314,8 +1304,7 @@ void jl_init_serializer(void) assert(i <= Null_tag); VALUE_TAGS = (ptrint_t)ptrhash_get(&ser_tag, jl_null); - jl_fptr_t fptrs[] = { jl_f_new_expr, jl_f_new_box, - jl_f_throw, jl_f_is, + jl_fptr_t fptrs[] = { jl_f_throw, jl_f_is, jl_f_no_function, jl_f_typeof, jl_f_subtype, jl_f_isa, jl_f_typeassert, jl_f_apply, @@ -1327,13 +1316,11 @@ void jl_init_serializer(void) jl_f_arrayset, jl_f_arraysize, jl_f_instantiate_type, jl_f_kwcall, jl_f_convert_default, - jl_trampoline, jl_f_new_type_constructor, - jl_f_typevar, jl_f_union, + jl_trampoline, jl_f_union, jl_f_methodexists, jl_f_applicable, jl_f_invoke, jl_apply_generic, - jl_unprotect_stack, jl_f_task, - jl_f_yieldto, jl_f_ctor_trampoline, - jl_f_new_module, jl_f_sizeof, + jl_unprotect_stack, + jl_f_yieldto, jl_f_sizeof, NULL }; i=2; while (fptrs[i-2] != NULL) { diff --git a/src/gf.c b/src/gf.c index 9efc13e8c87bb..1737c9672090e 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1194,10 +1194,7 @@ jl_methlist_t *jl_method_list_insert(jl_methlist_t **pml, jl_tuple_t *type, sigs_eq((jl_value_t*)type, (jl_value_t*)l->sig, 1)) { // method overwritten if (check_amb && l->func->linfo && method->linfo && - (l->func->linfo->module != method->linfo->module) && - // special case: allow adding Array() methods in Base - (pml != &((jl_methtable_t*)jl_array_type->env)->defs || - method->linfo->module != jl_base_module)) { + (l->func->linfo->module != method->linfo->module)) { jl_module_t *newmod = method->linfo->module; jl_value_t *errstream = jl_stderr_obj(); JL_STREAM *s = JL_STDERR; @@ -1335,8 +1332,8 @@ jl_value_t *jl_no_method_error(jl_function_t *f, jl_value_t **args, size_t na) { jl_value_t *argtup = jl_f_tuple(NULL, args, na); JL_GC_PUSH1(&argtup); - jl_value_t *fargs[2] = { (jl_value_t*)f, argtup }; - jl_throw(jl_apply((jl_function_t*)jl_methoderror_type, fargs, 2)); + jl_value_t *fargs[3] = { (jl_value_t*)jl_methoderror_type, (jl_value_t*)f, argtup }; + jl_throw(jl_apply(jl_module_call_func(jl_base_module), fargs, 3)); // not reached return jl_nothing; } @@ -1386,7 +1383,6 @@ jl_function_t *jl_method_lookup(jl_methtable_t *mt, jl_value_t **args, size_t na return sf; } -void jl_add_constructors(jl_datatype_t *t); DLLEXPORT jl_value_t *jl_matching_methods(jl_function_t *gf, jl_value_t *type, int lim); // compile-time method lookup @@ -1394,8 +1390,6 @@ jl_function_t *jl_get_specialization(jl_function_t *f, jl_tuple_t *types) { if (!jl_is_leaf_type((jl_value_t*)types)) return NULL; - if (f->fptr == jl_f_ctor_trampoline) - jl_add_constructors((jl_datatype_t*)f); assert(jl_is_gf(f)); // make sure exactly 1 method matches (issue #7302). @@ -1518,19 +1512,6 @@ static void _compile_all(jl_module_t *m, htable_t *h) jl_binding_t *b = (jl_binding_t*)table[i]; if (b->value != NULL) { jl_value_t *v = b->value; - if (jl_is_datatype(v)) { - jl_datatype_t *dt = (jl_datatype_t*)v; - if (dt->fptr == jl_f_ctor_trampoline) { - jl_add_constructors(dt); - jl_compile_all_defs((jl_function_t*)dt); - } - if (v == dt->name->primary && dt->parameters != jl_null && - jl_is_function(dt->name->ctor_factory) && - dt->name->static_ctor_factory == NULL) { - dt->name->static_ctor_factory = jl_instantiate_method((jl_function_t*)dt->name->ctor_factory, jl_null); - precompile_unspecialized(dt->name->static_ctor_factory, NULL, dt->parameters); - } - } if (jl_is_gf(v)) { jl_compile_all_defs((jl_function_t*)v); } @@ -1920,8 +1901,6 @@ jl_value_t *jl_matching_methods(jl_function_t *gf, jl_value_t *type, int lim) assert(jl_is_func(gf)); if (gf->fptr == jl_f_no_function) return (jl_value_t*)jl_an_empty_cell; - if (gf->fptr == jl_f_ctor_trampoline) - jl_add_constructors((jl_datatype_t*)gf); if (!jl_is_gf(gf)) { return (jl_value_t*)jl_an_empty_cell; } diff --git a/src/interpreter.c b/src/interpreter.c index 6bfdf341f731b..7c8248709fe5a 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -263,14 +263,17 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) fname = (jl_sym_t*)jl_exprarg(fname, 0); } gf = eval((jl_value_t*)fname, locals, nl); - assert(jl_is_function(gf)); - assert(jl_is_gf(gf)); + jl_value_t *bp_f = gf; + if (jl_is_datatype(bp_f)) + bp_f = jl_module_call_func(jl_current_module); + assert(jl_is_function(bp_f)); // TODO: type check for this + assert(jl_is_gf(bp_f)); if (jl_is_expr(fname)) fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); if (!kw) bp = &gf; else - bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter; + bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)bp_f)->env)->kwsorter; assert(jl_is_symbol(fname)); } else { @@ -292,7 +295,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) jl_check_static_parameter_conflicts((jl_lambda_info_t*)args[2], (jl_tuple_t*)jl_t1(atypes), fname); } meth = eval(args[2], locals, nl); - jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, args[3]); + jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, args[3], NULL); JL_GC_POP(); return *bp; } @@ -373,7 +376,6 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { - void jl_add_constructors(jl_datatype_t *t); jl_value_t *name = args[0]; assert(jl_is_symbol(name)); jl_value_t *para = eval(args[1], locals, nl); @@ -386,8 +388,6 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para, (jl_tuple_t*)temp, NULL, 0, args[6]==jl_true ? 1 : 0); - dt->fptr = jl_f_ctor_trampoline; - dt->name->ctor_factory = eval(args[3], locals, nl); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; // save old value @@ -418,8 +418,6 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); - - jl_add_constructors(dt); } else { // TODO: remove all old ctors and set temp->name->ctor_factory = dt->name->ctor_factory diff --git a/src/jltypes.c b/src/jltypes.c index 745d18e865098..ab256f65f557f 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -55,8 +55,6 @@ jl_datatype_t *jl_number_type; jl_tuple_t *jl_null; jl_value_t *jl_nothing; -void jl_add_constructors(jl_datatype_t *t); - // --- type properties and predicates --- int jl_is_type(jl_value_t *v) @@ -1931,14 +1929,8 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n, ndt->parameters = iparams_tuple; ndt->names = dt->names; ndt->types = jl_null; // to be filled in below - if (isabstract || !jl_is_function(tn->ctor_factory)) - ndt->fptr = jl_f_no_function; - else - ndt->fptr = jl_f_ctor_trampoline; ndt->mutabl = dt->mutabl; ndt->abstract = dt->abstract; - ndt->env = (jl_value_t*)ndt; - ndt->linfo = NULL; ndt->instance = NULL; ndt->uid = 0; ndt->struct_decl = NULL; @@ -2822,16 +2814,21 @@ jl_value_t *jl_type_match_morespecific(jl_value_t *a, jl_value_t *b) // initialization ------------------------------------------------------------- -jl_tvar_t *jl_new_typevar(jl_sym_t *name, jl_value_t *lb, jl_value_t *ub) +DLLEXPORT jl_tvar_t *jl_new_typevar_(jl_sym_t *name, jl_value_t *lb, jl_value_t *ub, jl_value_t *b) { jl_tvar_t *tv = (jl_tvar_t*)newobj((jl_value_t*)jl_tvar_type, 4); tv->name = name; tv->lb = lb; tv->ub = ub; - tv->bound = 0; + tv->bound = (b != jl_false); return tv; } +jl_tvar_t *jl_new_typevar(jl_sym_t *name, jl_value_t *lb, jl_value_t *ub) +{ + return jl_new_typevar_(name, lb, ub, jl_false); +} + static jl_tvar_t *tvar(const char *name) { return jl_new_typevar(jl_symbol(name), (jl_value_t*)jl_bottom_type, @@ -2843,9 +2840,9 @@ extern void jl_init_int32_int64_cache(void); void jl_init_types(void) { // create base objects - jl_datatype_type = jl_new_uninitialized_datatype(13); + jl_datatype_type = jl_new_uninitialized_datatype(10); jl_datatype_type->type = (jl_value_t*)jl_datatype_type; - jl_typename_type = jl_new_uninitialized_datatype(6); + jl_typename_type = jl_new_uninitialized_datatype(4); jl_sym_type = jl_new_uninitialized_datatype(0); jl_symbol_type = jl_sym_type; @@ -2867,10 +2864,7 @@ void jl_init_types(void) jl_datatype_type->name->primary = (jl_value_t*)jl_datatype_type; jl_datatype_type->super = jl_type_type; jl_datatype_type->parameters = jl_null; - jl_datatype_type->names = jl_tuple(13, jl_symbol("fptr"), - jl_symbol("env"), - jl_symbol("code"), - jl_symbol("name"), + jl_datatype_type->names = jl_tuple(10, jl_symbol("name"), jl_symbol("super"), jl_symbol("parameters"), jl_symbol("names"), @@ -2880,15 +2874,11 @@ void jl_init_types(void) jl_symbol("abstract"), jl_symbol("mutable"), jl_symbol("pointerfree")); - jl_datatype_type->types = jl_tuple(13, jl_any_type,jl_any_type,jl_any_type, - jl_typename_type, jl_type_type, + jl_datatype_type->types = jl_tuple(10, jl_typename_type, jl_type_type, jl_tuple_type, jl_tuple_type, jl_tuple_type, jl_any_type, jl_any_type, //types will be fixed later jl_any_type, jl_any_type, jl_any_type); - jl_datatype_type->fptr = jl_f_no_function; - jl_datatype_type->env = (jl_value_t*)jl_null; - jl_datatype_type->linfo = NULL; jl_datatype_type->instance = NULL; jl_datatype_type->uid = jl_assign_type_uid(); jl_datatype_type->struct_decl = NULL; @@ -2902,16 +2892,11 @@ void jl_init_types(void) jl_typename_type->name->primary = (jl_value_t*)jl_typename_type; jl_typename_type->super = jl_any_type; jl_typename_type->parameters = jl_null; - jl_typename_type->names = jl_tuple(6, jl_symbol("name"), jl_symbol("module"), - jl_symbol("primary"), jl_symbol("cache"), - jl_symbol("ctor_factory"), jl_symbol("static_ctor_factory")); - jl_typename_type->types = jl_tuple(6, jl_sym_type, jl_any_type, - jl_type_type, jl_any_type, - jl_any_type, jl_any_type); + jl_typename_type->names = jl_tuple(4, jl_symbol("name"), jl_symbol("module"), + jl_symbol("primary"), jl_symbol("cache")); + jl_typename_type->types = jl_tuple(4, jl_sym_type, jl_any_type, + jl_type_type, jl_any_type); jl_typename_type->uid = jl_assign_type_uid(); - jl_typename_type->fptr = jl_f_no_function; - jl_typename_type->env = (jl_value_t*)jl_null; - jl_typename_type->linfo = NULL; jl_typename_type->instance = NULL; jl_typename_type->struct_decl = NULL; jl_typename_type->abstract = 0; @@ -2924,9 +2909,6 @@ void jl_init_types(void) jl_sym_type->parameters = jl_null; jl_sym_type->names = jl_null; jl_sym_type->types = jl_null; - jl_sym_type->fptr = jl_f_no_function; - jl_sym_type->env = (jl_value_t*)jl_null; - jl_sym_type->linfo = NULL; jl_sym_type->instance = NULL; jl_sym_type->uid = jl_assign_type_uid(); jl_sym_type->struct_decl = NULL; @@ -2946,19 +2928,17 @@ void jl_init_types(void) jl_tuple(1, jl_symbol("types")), jl_tuple(1, jl_tuple_type), 0, 0); - jl_uniontype_type->fptr = jl_f_no_function; jl_bottom_type = (jl_value_t*)jl_new_struct(jl_uniontype_type, jl_null); jl_tvar_type = jl_new_datatype(jl_symbol("TypeVar"), jl_any_type, jl_null, - jl_tuple(3, jl_symbol("name"), - jl_symbol("lb"), - jl_symbol("ub")), - jl_tuple(3, jl_sym_type, jl_type_type, - jl_type_type), + jl_tuple(4, jl_symbol("name"), + jl_symbol("lb"), jl_symbol("ub"), + jl_symbol("bound")), + jl_tuple(4, jl_sym_type, jl_type_type, + jl_type_type, jl_any_type), 0, 0); - jl_tvar_type->fptr = jl_f_typevar; jl_undef_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Undef"), jl_any_type, jl_null); @@ -3012,7 +2992,6 @@ void jl_init_types(void) jl_tuple_type, jl_any_type, jl_any_type, jl_any_type), 0, 1); - jl_method_type->fptr = jl_f_no_function; jl_methtable_type = jl_new_datatype(jl_symbol("MethodTable"), jl_any_type, jl_null, @@ -3024,7 +3003,6 @@ void jl_init_types(void) jl_any_type, jl_any_type, jl_long_type, jl_any_type), 0, 1); - jl_methtable_type->fptr = jl_f_no_function; tv = jl_tuple2(tvar("T"), tvar("N")); jl_abstractarray_type = @@ -3047,10 +3025,7 @@ void jl_init_types(void) tv, jl_null, jl_null, 0, 1); jl_array_typename = jl_array_type->name; - jl_array_type->linfo = NULL; jl_array_type->pointerfree = 0; - jl_initialize_generic_function((jl_function_t*)jl_array_type, - jl_array_typename->name); jl_array_any_type = (jl_value_t*)jl_apply_type((jl_value_t*)jl_array_type, @@ -3070,49 +3045,41 @@ void jl_init_types(void) jl_tuple(3, jl_sym_type, jl_array_any_type, jl_any_type), 0, 1); - jl_expr_type->fptr = jl_f_new_expr; jl_linenumbernode_type = jl_new_datatype(jl_symbol("LineNumberNode"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("line")), jl_tuple(1, jl_long_type), 0, 0); - jl_linenumbernode_type->fptr = jl_f_default_ctor_1; jl_labelnode_type = jl_new_datatype(jl_symbol("LabelNode"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("label")), jl_tuple(1, jl_long_type), 0, 0); - jl_labelnode_type->fptr = jl_f_default_ctor_1; jl_gotonode_type = jl_new_datatype(jl_symbol("GotoNode"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("label")), jl_tuple(1, jl_long_type), 0, 0); - jl_gotonode_type->fptr = jl_f_default_ctor_1; jl_quotenode_type = jl_new_datatype(jl_symbol("QuoteNode"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("value")), jl_tuple(1, jl_any_type), 0, 0); - jl_quotenode_type->fptr = jl_f_default_ctor_1; jl_newvarnode_type = jl_new_datatype(jl_symbol("NewvarNode"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("name")), jl_tuple(1, jl_sym_type), 0, 0); - jl_newvarnode_type->fptr = jl_f_default_ctor_1; jl_topnode_type = jl_new_datatype(jl_symbol("TopNode"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("name")), jl_tuple(1, jl_sym_type), 0, 0); - jl_topnode_type->fptr = jl_f_default_ctor_1; jl_module_type = jl_new_datatype(jl_symbol("Module"), jl_any_type, jl_null, jl_tuple(2, jl_symbol("name"), jl_symbol("parent")), jl_tuple(2, jl_sym_type, jl_any_type), 0, 1); - jl_module_type->fptr = jl_f_new_module; jl_tupleset(jl_typename_type->types, 1, jl_module_type); @@ -3139,14 +3106,12 @@ void jl_init_types(void) jl_sym_type, jl_int32_type, jl_bool_type), 0, 1); - jl_lambda_info_type->fptr = jl_f_no_function; jl_box_type = jl_new_datatype(jl_symbol("Box"), jl_any_type, jl_null, jl_tuple(1, jl_symbol("contents")), jl_tuple(1, jl_any_type), 0, 1); - jl_box_type->fptr = jl_f_new_box; jl_box_typename = jl_box_type->name; jl_box_any_type = (jl_value_t*)jl_box_type; @@ -3157,7 +3122,6 @@ void jl_init_types(void) jl_symbol("body")), jl_tuple(2, jl_tuple_type, jl_any_type), 0, 0); - jl_typector_type->fptr = jl_f_new_type_constructor; jl_function_type = jl_new_datatype(jl_symbol("Function"), jl_any_type, jl_null, @@ -3166,7 +3130,6 @@ void jl_init_types(void) jl_tuple(3, jl_any_type, jl_any_type, jl_lambda_info_type), 0, 1); - jl_function_type->fptr = jl_f_no_function; jl_tupleset(jl_method_type->types, 3, jl_function_type); jl_tupleset(jl_lambda_info_type->types, 6, jl_function_type); @@ -3193,12 +3156,12 @@ void jl_init_types(void) jl_value_t *pointer_void = jl_apply_type((jl_value_t*)jl_pointer_type, jl_tuple(1,jl_void_type)); jl_voidpointer_type = (jl_datatype_t*)pointer_void; - jl_tupleset(jl_datatype_type->types, 0, pointer_void); - jl_tupleset(jl_datatype_type->types, 9, jl_int32_type); - jl_tupleset(jl_datatype_type->types, 10, (jl_value_t*)jl_bool_type); - jl_tupleset(jl_datatype_type->types, 11, (jl_value_t*)jl_bool_type); - jl_tupleset(jl_datatype_type->types, 12, (jl_value_t*)jl_bool_type); + jl_tupleset(jl_datatype_type->types, 6, jl_int32_type); + jl_tupleset(jl_datatype_type->types, 7, (jl_value_t*)jl_bool_type); + jl_tupleset(jl_datatype_type->types, 8, (jl_value_t*)jl_bool_type); + jl_tupleset(jl_datatype_type->types, 9, (jl_value_t*)jl_bool_type); jl_tupleset(jl_function_type->types, 0, pointer_void); + jl_tupleset(jl_tvar_type->types, 3, (jl_value_t*)jl_bool_type); jl_compute_field_offsets(jl_datatype_type); jl_compute_field_offsets(jl_typename_type); diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index da54ef8fd3c3e..4258c8c9dfaa3 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -732,7 +732,7 @@ `(function (call ,name ,@field-names) (block (call new ,@field-names))))) - (if gen-specific? + (if (and gen-specific? (any (lambda (t) (not (eq? t 'Any))) field-types)) (list ;; definition with field types for all arguments `(function (call ,name @@ -775,8 +775,42 @@ `(block ,stmt ,@(cdr body)))) body)) +;; insert item at start of arglist +(define (arglist-unshift sig item) + (if (and (pair? sig) (pair? (car sig)) (eq? (caar sig) 'parameters)) + `(,(car sig) ,item ,@(cdr sig)) + `(,item ,@sig))) + +(define (ctor-signature name params method-params sig) + (if (null? params) + (if (null? method-params) + (cons `(call call + ,@(arglist-unshift sig `(|::| ,(gensy) (curly Type ,name)))) + params) + (cons `(call (curly call ,@method-params) + ,@(arglist-unshift sig `(|::| ,(gensy) (curly Type ,name)))) + params)) + (if (null? method-params) + (cons `(call (curly call ,@params) + ,@(arglist-unshift sig `(|::| ,(gensy) (curly Type (curly ,name ,@params))))) + params) + ;; rename parameters that conflict with user-written method parameters + (let ((new-params (map (lambda (p) (if (memq p method-params) + (gensy) + p)) + params))) + (cons `(call (curly call ,@new-params ,@method-params) + ,@(arglist-unshift sig `(|::| ,(gensy) (curly Type (curly ,name ,@new-params))))) + new-params))))) + +(define (ctor-def keyword name params method-params sig ctor-body body) + (let* ((temp (ctor-signature name params method-params sig)) + (sig (car temp)) + (params (cdr temp))) + `(,keyword ,sig ,(ctor-body body params)))) + (define (rewrite-ctor ctor Tname params field-names field-types mutabl iname) - (define (ctor-body body) + (define (ctor-body body params) (pattern-replace (pattern-set (pattern-lambda (call (-/ new) . args) @@ -791,29 +825,39 @@ field-types mutabl))) body)) - (let ((ctor2 - (pattern-replace - (pattern-set - (pattern-lambda (function (call (curly name . p) . sig) body) - `(function (call (curly ,(if (eq? name Tname) iname name) ,@p) ,@sig) - ,(ctor-body body))) - (pattern-lambda (stagedfunction (call (curly name . p) . sig) body) - `(stagedfunction (call (curly ,(if (eq? name Tname) iname name) ,@p) ,@sig) - ,(ctor-body body))) - (pattern-lambda (function (call name . sig) body) - `(function (call ,(if (eq? name Tname) iname name) ,@sig) - ,(ctor-body body))) - (pattern-lambda (stagedfunction (call name . sig) body) - `(stagedfunction (call ,(if (eq? name Tname) iname name) ,@sig) - ,(ctor-body body))) - (pattern-lambda (= (call (curly name . p) . sig) body) - `(= (call (curly ,(if (eq? name Tname) iname name) ,@p) ,@sig) - ,(ctor-body body))) - (pattern-lambda (= (call name . sig) body) - `(= (call ,(if (eq? name Tname) iname name) ,@sig) - ,(ctor-body body)))) - ctor))) - ctor2)) + (pattern-replace + (pattern-set + (pattern-lambda (function (call (curly name . p) . sig) body) + (if (eq? name Tname) + (ctor-def 'function name params p sig ctor-body body) + `(function (call (curly ,name ,@p) ,@sig) + ,(ctor-body body params)))) + (pattern-lambda (stagedfunction (call (curly name . p) . sig) body) + (if (eq? name Tname) + (ctor-def 'stagedfunction name params p sig ctor-body body) + `(stagedfunction (call (curly ,name ,@p) ,@sig) + ,(ctor-body body params)))) + (pattern-lambda (function (call name . sig) body) + (if (eq? name Tname) + (ctor-def 'function name params '() sig ctor-body body) + `(function (call ,name ,@sig) + ,(ctor-body body params)))) + (pattern-lambda (stagedfunction (call name . sig) body) + (if (eq? name Tname) + (ctor-def 'stagedfunction name params '() sig ctor-body body) + `(stagedfunction (call ,name ,@sig) + ,(ctor-body body params)))) + (pattern-lambda (= (call (curly name . p) . sig) body) + (if (eq? name Tname) + (ctor-def 'function name params p sig ctor-body body) + `(function (call (curly ,name ,@p) ,@sig) + ,(ctor-body body params)))) + (pattern-lambda (= (call name . sig) body) + (if (eq? name Tname) + (ctor-def 'function name params '() sig ctor-body body) + `(function (call ,name ,@sig) + ,(ctor-body body params))))) + ctor)) ;; remove line numbers and nested blocks (define (flatten-blocks e) @@ -854,6 +898,7 @@ (scope-block (block (global ,name) + (global call) ,@(map (lambda (c) (rewrite-ctor c name '() field-names field-types mut name)) defs2))))) @@ -868,25 +913,24 @@ ,@(map make-assignment params (symbols->typevars params bounds #t)) (composite_type ,name (tuple ,@params) (tuple ,@(map (lambda (x) `',x) field-names)) - ,(let ((instantiation-name (gensy))) - `(lambda (,instantiation-name) - (scope-block - ;; don't capture params; in here they are static - ;; parameters - (block - (global ,@params) - ,@(map - (lambda (c) - (rewrite-ctor c name params field-names - field-types mut instantiation-name)) - defs2) - ,name)))) + (null) ,super (tuple ,@field-types) ,mut))) + ;; "inner" constructors + (call + (lambda () + (scope-block + (block + (global ,name) + (global call) + ,@(map (lambda (c) + (rewrite-ctor c name params field-names + field-types mut name)) + defs2))))) + ;; "outer" constructors (scope-block (block (global ,name) - (global ,@params) ,@(if (and (null? defs) ;; don't generate an outer constructor if the type has ;; parameters not mentioned in the field types. such a diff --git a/src/julia.h b/src/julia.h index 2952851f27df2..ae0a3633da63e 100644 --- a/src/julia.h +++ b/src/julia.h @@ -162,14 +162,11 @@ typedef struct _jl_lambda_info_t { #define LAMBDA_INFO_NW (NWORDS(sizeof(jl_lambda_info_t))-1) -#define JL_FUNC_FIELDS \ - jl_fptr_t fptr; \ - jl_value_t *env; \ - jl_lambda_info_t *linfo; - typedef struct _jl_function_t { JL_DATA_TYPE - JL_FUNC_FIELDS + jl_fptr_t fptr; + jl_value_t *env; + jl_lambda_info_t *linfo; } jl_function_t; typedef struct { @@ -188,9 +185,6 @@ typedef struct { // not the original. jl_value_t *primary; jl_value_t *cache; - // to create a set of constructors for this sort of type - jl_value_t *ctor_factory; - jl_function_t *static_ctor_factory; } jl_typename_t; typedef struct { @@ -206,7 +200,6 @@ typedef struct { typedef struct _jl_datatype_t { JL_DATA_TYPE - JL_FUNC_FIELDS jl_typename_t *name; struct _jl_datatype_t *super; jl_tuple_t *parameters; @@ -229,7 +222,7 @@ typedef struct { jl_sym_t *name; jl_value_t *lb; // lower bound jl_value_t *ub; // upper bound - uptrint_t bound; // part of a constraint environment + uint8_t bound; // part of a constraint environment } jl_tvar_t; typedef struct { @@ -526,7 +519,7 @@ extern jl_sym_t *arrow_sym; extern jl_sym_t *ldots_sym; #define jl_is_module(v) jl_typeis(v,jl_module_type) #define jl_is_mtable(v) jl_typeis(v,jl_methtable_type) #define jl_is_task(v) jl_typeis(v,jl_task_type) -#define jl_is_func(v) (jl_typeis(v,jl_function_type) || jl_is_datatype(v)) +#define jl_is_func(v) jl_typeis(v,jl_function_type) #define jl_is_function(v) jl_is_func(v) #define jl_is_ascii_string(v) jl_typeis(v,jl_ascii_string_type) #define jl_is_utf8_string(v) jl_typeis(v,jl_utf8_string_type) @@ -677,7 +670,8 @@ 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); DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, - jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged); + jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged, + jl_value_t *call_func); DLLEXPORT jl_value_t *jl_box_bool(int8_t x); DLLEXPORT jl_value_t *jl_box_int8(int32_t x); DLLEXPORT jl_value_t *jl_box_uint8(uint32_t x); diff --git a/src/julia_internal.h b/src/julia_internal.h index 157740f37f110..c8c55a03a6bff 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -33,13 +33,10 @@ void jl_set_gs_ctr(uint32_t ctr); DLLEXPORT jl_value_t *name(jl_value_t *F, jl_value_t **args, uint32_t nargs) JL_CALLABLE(jl_trampoline); -JL_CALLABLE(jl_f_ctor_trampoline); JL_CALLABLE(jl_apply_generic); JL_CALLABLE(jl_unprotect_stack); JL_CALLABLE(jl_f_no_function); JL_CALLABLE(jl_f_tuple); -JL_CALLABLE(jl_f_default_ctor_1); -JL_CALLABLE(jl_f_default_ctor_2); extern jl_function_t *jl_unprotect_stack_func; extern jl_function_t *jl_bottom_func; diff --git a/src/module.c b/src/module.c index 5f8ed958d4e14..ce9a4685416eb 100644 --- a/src/module.c +++ b/src/module.c @@ -35,17 +35,8 @@ jl_module_t *jl_new_module(jl_sym_t *name) return m; } -JL_CALLABLE(jl_f_new_module) +DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name) { - jl_sym_t *name; - if (nargs == 0) { - name = anonymous_sym; - } - else { - JL_NARGS(Module, 1, 1); - JL_TYPECHK(Module, symbol, args[0]); - name = (jl_sym_t*)args[0]; - } jl_module_t *m = jl_new_module(name); m->parent = jl_main_module; jl_add_standard_imports(m); diff --git a/src/task.c b/src/task.c index 4af206a582d64..025aa0f0218d2 100644 --- a/src/task.c +++ b/src/task.c @@ -714,7 +714,8 @@ DLLEXPORT void gdblookup(ptrint_t ip) DLLEXPORT void jlbacktrace() { - for(size_t i=0; i < bt_size; i++) + size_t n = bt_size; //bt_size > 40 ? 40 : bt_size; + for(size_t i=0; i < n; i++) gdblookup(bt_data[i]); } @@ -770,7 +771,7 @@ DLLEXPORT void jl_throw_with_superfluous_argument(jl_value_t *e, int line) jl_throw(e); } -jl_task_t *jl_new_task(jl_function_t *start, size_t ssize) +DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize) { size_t pagesz = jl_page_size; jl_task_t *t = (jl_task_t*)allocobj(sizeof(jl_task_t)); @@ -827,27 +828,6 @@ JL_CALLABLE(jl_unprotect_stack) return (jl_value_t*)jl_null; } -#define JL_MIN_STACK (4096*sizeof(void*)) -#define JL_DEFAULT_STACK (2*12288*sizeof(void*)) - -JL_CALLABLE(jl_f_task) -{ - JL_NARGS(Task, 1, 2); - JL_TYPECHK(Task, function, args[0]); - /* - we need a somewhat large stack, because execution can trigger - compilation, which uses perhaps too much stack space. - */ - size_t ssize = JL_DEFAULT_STACK; - if (nargs == 2) { - JL_TYPECHK(Task, long, args[1]); - ssize = jl_unbox_long(args[1]); - if (ssize < JL_MIN_STACK) - jl_error("Task: stack size too small"); - } - return (jl_value_t*)jl_new_task((jl_function_t*)args[0], ssize); -} - JL_CALLABLE(jl_f_yieldto) { JL_NARGSV(yieldto, 1); @@ -894,7 +874,6 @@ void jl_init_tasks(void *stack, size_t ssize) jl_any_type, jl_any_type, jl_function_type), 0, 1); jl_tupleset(jl_task_type->types, 0, (jl_value_t*)jl_task_type); - jl_task_type->fptr = jl_f_task; done_sym = jl_symbol("done"); failed_sym = jl_symbol("failed"); diff --git a/src/toplevel.c b/src/toplevel.c index c7753a2d500d0..8c966a4a057e0 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -624,7 +624,6 @@ void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super) // method definition ---------------------------------------------------------- extern int jl_boot_file_loaded; -void jl_add_constructors(jl_datatype_t *t); static int type_contains(jl_value_t *ty, jl_value_t *x) { @@ -647,12 +646,14 @@ static int type_contains(jl_value_t *ty, jl_value_t *x) void print_func_loc(JL_STREAM *s, jl_lambda_info_t *li); DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, - jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged) + jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged, + jl_value_t *call_func) { // argtypes is a tuple ((types...), (typevars...)) jl_tuple_t *t = (jl_tuple_t*)jl_t1(argtypes); argtypes = (jl_tuple_t*)jl_t0(argtypes); jl_value_t *gf=NULL; + JL_GC_PUSH3(&gf, &argtypes, &t); if (bnd && bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", @@ -662,9 +663,34 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_ if (*bp != NULL) { gf = *bp; if (!jl_is_gf(gf)) { - if (jl_is_datatype(gf) && - ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) { - jl_add_constructors((jl_datatype_t*)gf); + if (jl_is_datatype(gf)) { + // DataType: define `call`, for backwards compat with outer constructors + // TODO: this does not yet handle keyword sorters correctly + if (call_func == NULL) + call_func = (jl_value_t*)jl_module_call_func(jl_current_module); + size_t na = jl_tuple_len(argtypes); + jl_tuple_t *newargtypes = jl_alloc_tuple(1 + na); + JL_GC_PUSH1(&newargtypes); + jl_tupleset(newargtypes, 0, jl_wrap_Type(gf)); + size_t i; + for(i=0; i < na; i++) { + jl_tupleset(newargtypes, i+1, jl_tupleref(argtypes, i)); + } + argtypes = newargtypes; + JL_GC_POP(); + gf = call_func; + // TODO: edit args, insert type first + if (!jl_is_expr(f->linfo->ast)) + f->linfo->ast = jl_uncompress_ast(f->linfo, f->linfo->ast); + jl_array_t *al = jl_lam_args((jl_expr_t*)f->linfo->ast); + if (jl_array_len(al) == 0) { + al = jl_alloc_cell_1d(1); + jl_exprarg(f->linfo->ast, 0) = (jl_value_t*)al; + } + else { + jl_array_grow_beg(al, 1); + } + jl_cellset(al, 0, (jl_value_t*)jl_gensym()); } if (!jl_is_gf(gf)) { jl_error("invalid method definition: not a generic function"); @@ -702,7 +728,6 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_ gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } - JL_GC_PUSH1(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); assert(jl_is_tuple(t));