Skip to content

Commit 6571654

Browse files
committed
stage 1 bootstrapping now works
to try it, run "julia stage1.j", then "julia -J sys.ji.new". stage 0 is still the default until more testing has been done. eliminate all C-implemented generic function methods some were replaced with ccalls, which can be removed entirely or kept for debugging during stage0 bootstrapping. separate top-level binding lookup for read vs. assignment. allows using different import rules for assign, i.e. assignments go to the current environment rather than existing bindings in imported envs. removing more unused code move more stuff out of boot.j simplify recursive function type inference; just use a loop
1 parent ec7571d commit 6571654

File tree

18 files changed

+362
-480
lines changed

18 files changed

+362
-480
lines changed

j/base.j

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,67 @@
11
# important core definitions
22

3+
convert(T, x) = convert_default(T, x, convert)
4+
convert(T::Tuple, x::Tuple) = convert_tuple(T, x, convert)
5+
6+
type ErrorException <: Exception
7+
msg::String
8+
end
9+
10+
type SystemError <: Exception
11+
prefix::String
12+
errnum::Int32
13+
SystemError(p::String, e::Integer) = new(p, int32(e))
14+
SystemError(p::String) = new(p, errno())
15+
end
16+
17+
type TypeError <: Exception
18+
func::Symbol
19+
context::String
20+
expected::Type
21+
got
22+
end
23+
24+
type ParseError <: Exception
25+
msg::String
26+
end
27+
28+
type ArgumentError <: Exception
29+
msg::String
30+
end
31+
32+
type UnboundError <: Exception
33+
var::Symbol
34+
end
35+
36+
type KeyError <: Exception
37+
key
38+
end
39+
40+
type LoadError <: Exception
41+
file::String
42+
line::Int32
43+
error
44+
end
45+
46+
type MethodError <: Exception
47+
f
48+
args
49+
end
50+
51+
type UnionTooComplexError <: Exception
52+
types::Tuple
53+
end
54+
55+
type BackTrace <: Exception
56+
e
57+
trace::Array{Any,1}
58+
end
59+
60+
method_missing(f, args...) = throw(MethodError(f, args))
61+
62+
ccall(:jl_get_system_hooks, Void, ())
63+
64+
365
int(x) = convert(Int, x)
466
int(x::Int) = x
567
uint(x) = convert(Uint, x)
@@ -72,6 +134,9 @@ function compile_hint(f, args::Tuple)
72134
nothing
73135
end
74136

137+
# we share Array with Base so we can add definitions to it
138+
const Array = eval(Base, :Array)
139+
75140
Array{T} (::Type{T}, d::(Integer,)) =
76141
ccall(:jl_alloc_array_1d, Array{T,1}, (Any,Int), Array{T,1},
77142
int(d[1]))

j/inference.j

Lines changed: 60 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -158,23 +158,27 @@ function static_convert(to::ANY, from::ANY)
158158
end
159159
# tuple conversion calls convert recursively
160160
if isseqtype(ce)
161-
R = abstract_call_gf(convert, (), (Type{pe}, ce.parameters[1]), ())
161+
#R = abstract_call_gf(convert, (), (Type{pe}, ce.parameters[1]), ())
162+
R = static_convert(pe, ce.parameters[1])
162163
isType(R) && (R = R.parameters[1])
163164
result[i] = ...{R}
164165
else
165-
R = abstract_call_gf(convert, (), (Type{pe}, ce), ())
166+
#R = abstract_call_gf(convert, (), (Type{pe}, ce), ())
167+
R = static_convert(pe, ce)
166168
isType(R) && (R = R.parameters[1])
167169
result[i] = R
168170
end
169171
end
170172
a2t(result)
171173
end
172-
t_func[:convert] =
173-
(2, 2, (t,x)->(if isa(t,Tuple) && allp(isType,t)
174-
t = Type{map(t->t.parameters[1],t)}
175-
end;
176-
isType(t) ? static_convert(t.parameters[1],x) :
177-
Any))
174+
t_func[convert_default] =
175+
(3, 3, (t,x,f)->(isType(t) ? static_convert(t.parameters[1],x) : Any))
176+
t_func[convert_tuple] =
177+
(3, 3, (t,x,f)->(if isa(t,Tuple) && allp(isType,t)
178+
t = Type{map(t->t.parameters[1],t)}
179+
end;
180+
isType(t) ? static_convert(t.parameters[1],x) :
181+
Any))
178182
typeof_tfunc = function (t)
179183
if isType(t)
180184
t = t.parameters[1]
@@ -486,6 +490,9 @@ function abstract_call(f, fargs, argtypes, vtypes, sv::StaticVarInfo, e)
486490
end
487491
end
488492
end
493+
if !is(f,apply) && isa(e,Expr) && isa(f,Function)
494+
e.head = :call1
495+
end
489496
rt = builtin_tfunction(f, fargs, argtypes)
490497
#print("=> ", rt, "\n")
491498
return rt
@@ -497,8 +504,8 @@ function abstract_call(f, fargs, argtypes, vtypes, sv::StaticVarInfo, e)
497504
end
498505
end
499506

500-
ft_tfunc(ft, argtypes) = ccall(:jl_func_type_tfunc, Any,
501-
(Any, Any), ft, argtypes)
507+
ft_tfunc(ft, argtypes) = ccall(:jl_func_type_tfunc, Any, (Any, Any),
508+
ft, argtypes)
502509

503510
function abstract_eval_call(e, vtypes, sv::StaticVarInfo)
504511
fargs = a2t_butfirst(e.args)
@@ -828,10 +835,6 @@ end
828835
typeinf(linfo,atypes,sparams) = typeinf(linfo,atypes,sparams,linfo,true)
829836
typeinf(linfo,atypes,sparams,linfo) = typeinf(linfo,atypes,sparams,linfo,true)
830837

831-
abstract RecPending{T}
832-
833-
isRecPending(t) = isa(t, AbstractKind) && is(t.name, RecPending.name)
834-
835838
ast_rettype(ast) = ast.args[3].typ
836839

837840
# def is the original unspecialized version of a method. we aggregate all
@@ -840,8 +843,6 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
840843
#dbg =
841844
#dotrace = true#is(linfo,sizestr)
842845
local ast::Expr
843-
redo = false
844-
curtype = None
845846
# check cached t-functions
846847
tf = def.tfunc
847848
while !is(tf,())
@@ -853,15 +854,9 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
853854
# if the frame above this one recurred, rerun type inf
854855
# here instead of returning, and update the cache, until the new
855856
# inferred type equals the cached type (fixed point)
856-
rt = ast_rettype(tf[2])
857-
if isRecPending(rt)
858-
curtype = rt.parameters[1]
859-
redo = true
860-
ast = tf[2]
861-
break
862-
else
863-
return (tf[2], rt)
864-
end
857+
ast = tf[2]
858+
rt = ast_rettype(ast)
859+
return (ast, rt)
865860
end
866861
tf = tf[3]
867862
end
@@ -893,12 +888,9 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
893888
f = f.prev
894889
end
895890

896-
rec = false
897-
898891
#print("typeinf ", linfo.name, " ", atypes, "\n")
899892

900-
if redo
901-
elseif cop
893+
if cop
902894
sparams = append(sparams, linfo.sparams)
903895
ast = ccall(:jl_prepare_ast, Any, (Any,Any), linfo, sparams)::Expr
904896
else
@@ -910,8 +902,20 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
910902
locals = (ast.args[2].args[1].args)::Array{Any,1}
911903
vars = append(args, locals)
912904
body = (ast.args[3].args)::Array{Any,1}
913-
914905
n = length(body)
906+
907+
# our stack frame
908+
frame = CallStack(ast0, linfo.module, atypes, inference_stack)
909+
inference_stack = frame
910+
curtype = None
911+
frame.result = curtype
912+
913+
local s, sv
914+
915+
while true
916+
917+
rec = false
918+
915919
s = { () | i=1:n }
916920
recpts = IntSet(n+1) # statements that depend recursively on our value
917921
W = IntSet(n+1)
@@ -958,11 +962,6 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
958962
end
959963
sv = StaticVarInfo(sparams, cenv)
960964

961-
# our stack frame
962-
frame = CallStack(ast0, linfo.module, atypes, inference_stack)
963-
frame.result = curtype
964-
inference_stack = frame
965-
966965
# exception handlers
967966
cur_hand = ()
968967
handler_at = { () | i=1:n }
@@ -1069,23 +1068,23 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
10691068
end
10701069
#print("\n",ast,"\n")
10711070
#print("==> ", frame.result,"\n")
1072-
if redo && typeseq(curtype, frame.result)
1073-
rec = false
1074-
end
1075-
fulltree = type_annotate(ast, s, sv,
1076-
rec ? RecPending{frame.result} : frame.result,
1077-
vars)
1078-
if !rec
1079-
fulltree.args[3] = inlining_pass(fulltree.args[3], s[1])
1080-
tuple_elim_pass(fulltree)
1081-
linfo.inferred = true
1082-
end
1083-
if !redo
1084-
compressed = ccall(:jl_compress_ast, Any, (Any,), fulltree)
1085-
fulltree = compressed
1086-
#compressed = fulltree
1087-
def.tfunc = (atypes, compressed, def.tfunc)
1088-
end
1071+
if !rec || typeseq(curtype, frame.result)
1072+
break
1073+
end
1074+
curtype = frame.result
1075+
end # while
1076+
1077+
fulltree = type_annotate(ast, s, sv, frame.result, vars)
1078+
1079+
fulltree.args[3] = inlining_pass(fulltree.args[3], s[1])
1080+
tuple_elim_pass(fulltree)
1081+
linfo.inferred = true
1082+
1083+
compressed = ccall(:jl_compress_ast, Any, (Any,), fulltree)
1084+
fulltree = compressed
1085+
#compressed = fulltree
1086+
def.tfunc = (atypes, compressed, def.tfunc)
1087+
10891088
inference_stack = (inference_stack::CallStack).prev
10901089
return (fulltree, frame.result)
10911090
end
@@ -1173,11 +1172,6 @@ function type_annotate(ast::Expr, states::Array{Any,1},
11731172
end
11741173
end
11751174

1176-
# do inference on inner functions
1177-
if isRecPending(rettype)
1178-
return ast
1179-
end
1180-
11811175
for li in closures
11821176
if !li.inferred
11831177
a = li.ast
@@ -1286,6 +1280,15 @@ end
12861280
function inlineable(f, e::Expr, vars)
12871281
argexprs = a2t_butfirst(e.args)
12881282
atypes = map(exprtype, argexprs)
1283+
1284+
if is(f, convert_default) && length(atypes)==3
1285+
# builtin case of convert. convert(T,x::S) => x, when S<:T
1286+
if isType(atypes[1]) && subtype(atypes[2],atypes[1].parameters[1])
1287+
# todo: if T expression has side effects??!
1288+
return e.args[3]
1289+
end
1290+
end
1291+
12891292
meth = getmethods(f, atypes)
12901293
if length(meth) != 1
12911294
return NF
@@ -1297,13 +1300,6 @@ function inlineable(f, e::Expr, vars)
12971300
if !subtype(atypes, meth[1])
12981301
return NF
12991302
end
1300-
if is(meth[3],:convert) && length(atypes)==2
1301-
# builtin case of convert. convert(T,x::S) => x, when S<:T
1302-
if isType(atypes[1]) && subtype(atypes[2],atypes[1].parameters[1])
1303-
# todo: if T expression has side effects??!
1304-
return e.args[3]
1305-
end
1306-
end
13071303
if !isa(meth[3],LambdaStaticData) || !is(meth[4],())
13081304
return NF
13091305
end

j/show.j

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# formerly built-in methods. can be replaced any time.
2+
print(a::Array{Uint8,1}) = ccall(:jl_print_array_uint8, Void, (Any,), a)
3+
print(s::Symbol) = ccall(:jl_print_symbol, Void, (Any,), s)
4+
show(x) = ccall(:jl_show_any, Void, (Any,), x)
5+
16
print(x) = show(x)
27
showcompact(x) = show(x)
38
show_to_string(x) = print_to_string(show, x)
@@ -7,7 +12,7 @@ show(s::Symbol) = print(s)
712
show(tn::TypeName) = show(tn.name)
813
show(::Nothing) = print("nothing")
914
show(b::Bool) = print(b ? "true" : "false")
10-
show(n::Integer) = show(int64(n))
15+
show(n::Integer) = print(dec(int64(n)))
1116

1217
function show_trailing_hex(n::Uint64, ndig::Integer)
1318
for s = ndig-1:-1:0

j/stage0.j

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ if false
44
# simple print definitions for debugging. enable these if something
55
# goes wrong during bootstrap before printing code is available.
66
length(a::Array) = arraylen(a)
7+
print(a::Array{Uint8,1}) = ccall(:jl_print_array_uint8, Void, (Any,), a)
8+
print(s::Symbol) = ccall(:jl_print_symbol, Void, (Any,), s)
79
print(s::ASCIIString) = print(s.data)
810
print(x) = show(x)
911
println(x) = (print(x);print("\n"))
12+
show(x) = ccall(:jl_show_any, Void, (Any,), x)
1013
show(s::ASCIIString) = print(s.data)
1114
show(s::Symbol) = print(s)
1215
show(b::Bool) = print(b ? "true" : "false")
16+
show(n::Int64) = ccall(:jl_print_int64, Void, (Int64,), n)
1317
show(n::Integer) = show(int64(n))
14-
show(n::Unsigned) = show(uint64(n))
1518
print(a...) = for x=a; print(x); end
1619
function show(e::Expr)
1720
print(e.head)

src/alloc.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ jl_typename_t *jl_array_typename;
3232
jl_type_t *jl_array_uint8_type;
3333
jl_type_t *jl_array_any_type;
3434
jl_struct_type_t *jl_weakref_type;
35-
jl_tag_type_t *jl_string_type;
3635
jl_struct_type_t *jl_ascii_string_type;
3736
jl_struct_type_t *jl_utf8_string_type;
3837
jl_struct_type_t *jl_expr_type;
@@ -70,7 +69,7 @@ jl_sym_t *goto_sym; jl_sym_t *goto_ifnot_sym;
7069
jl_sym_t *label_sym; jl_sym_t *return_sym;
7170
jl_sym_t *lambda_sym; jl_sym_t *assign_sym;
7271
jl_sym_t *null_sym; jl_sym_t *body_sym;
73-
jl_sym_t *isbound_sym; jl_sym_t *macro_sym;
72+
jl_sym_t *macro_sym;
7473
jl_sym_t *locals_sym; jl_sym_t *colons_sym;
7574
jl_sym_t *Any_sym; jl_sym_t *method_sym;
7675
jl_sym_t *enter_sym; jl_sym_t *leave_sym;
@@ -625,18 +624,6 @@ jl_typector_t *jl_new_type_ctor(jl_tuple_t *params, jl_type_t *body)
625624
return (jl_typector_t*)tc;
626625
}
627626

628-
// struct constructors --------------------------------------------------------
629-
630-
JL_CALLABLE(jl_weakref_ctor)
631-
{
632-
if (nargs > 1) {
633-
JL_NARGS(WeakRef, 1, 1);
634-
}
635-
if (nargs == 1)
636-
return (jl_value_t*)jl_gc_new_weakref(args[0]);
637-
return (jl_value_t*)jl_gc_new_weakref((jl_value_t*)jl_nothing);
638-
}
639-
640627
// bits constructors ----------------------------------------------------------
641628

642629
#define BOX_FUNC(typ,c_type,pfx,nw) \

0 commit comments

Comments
 (0)