Skip to content

Commit 63d509a

Browse files
authored
Merge pull request #72 from c42f/avi/generated-module
Some general clean ups and type stability improvements.
2 parents 03d9e89 + 7159cc2 commit 63d509a

File tree

8 files changed

+49
-47
lines changed

8 files changed

+49
-47
lines changed

src/eval.jl

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ end
120120

121121
# Convert SyntaxTree to the CodeInfo+Expr data stuctures understood by the
122122
# Julia runtime
123-
function to_code_info(ex, mod, funcname, slots)
124-
input_code = children(ex)
123+
function to_code_info(ex::SyntaxTree, slots::Vector{Slot})
125124
stmts = Any[]
126125

127126
current_codelocs_stack = ir_debug_info_state(ex)
@@ -156,7 +155,7 @@ function to_code_info(ex, mod, funcname, slots)
156155

157156
stmt_offset = length(stmts)
158157
for stmt in children(ex)
159-
push!(stmts, _to_lowered_expr(mod, stmt, stmt_offset))
158+
push!(stmts, _to_lowered_expr(stmt, stmt_offset))
160159
add_ir_debug_info!(current_codelocs_stack, stmt)
161160
end
162161

@@ -223,11 +222,11 @@ function to_code_info(ex, mod, funcname, slots)
223222
)
224223
end
225224

226-
@fzone "JL: to_lowered_expr" function to_lowered_expr(mod, ex)
227-
_to_lowered_expr(mod, ex, 0)
225+
@fzone "JL: to_lowered_expr" function to_lowered_expr(ex::SyntaxTree)
226+
_to_lowered_expr(ex, 0)
228227
end
229228

230-
function _to_lowered_expr(mod, ex, stmt_offset)
229+
function _to_lowered_expr(ex::SyntaxTree, stmt_offset::Int)
231230
k = kind(ex)
232231
if is_literal(k)
233232
ex.value
@@ -263,15 +262,12 @@ function _to_lowered_expr(mod, ex, stmt_offset)
263262
elseif k == K"SSAValue"
264263
Core.SSAValue(ex.var_id + stmt_offset)
265264
elseif k == K"return"
266-
Core.ReturnNode(_to_lowered_expr(mod, ex[1], stmt_offset))
265+
Core.ReturnNode(_to_lowered_expr(ex[1], stmt_offset))
267266
elseif k == K"inert"
268267
e1 = ex[1]
269268
getmeta(ex, :as_Expr, false) ? QuoteNode(Expr(e1)) : e1
270269
elseif k == K"code_info"
271-
funcname = ex.is_toplevel_thunk ?
272-
"top-level scope" :
273-
"none" # FIXME
274-
ir = to_code_info(ex[1], mod, funcname, ex.slots)
270+
ir = to_code_info(ex[1], ex.slots)
275271
if ex.is_toplevel_thunk
276272
Expr(:thunk, ir)
277273
else
@@ -282,36 +278,40 @@ function _to_lowered_expr(mod, ex, stmt_offset)
282278
elseif k == K"goto"
283279
Core.GotoNode(ex[1].id + stmt_offset)
284280
elseif k == K"gotoifnot"
285-
Core.GotoIfNot(_to_lowered_expr(mod, ex[1], stmt_offset), ex[2].id + stmt_offset)
281+
Core.GotoIfNot(_to_lowered_expr(ex[1], stmt_offset), ex[2].id + stmt_offset)
286282
elseif k == K"enter"
287283
catch_idx = ex[1].id
288284
numchildren(ex) == 1 ?
289285
Core.EnterNode(catch_idx) :
290-
Core.EnterNode(catch_idx, _to_lowered_expr(mod, ex[2], stmt_offset))
286+
Core.EnterNode(catch_idx, _to_lowered_expr(ex[2], stmt_offset))
291287
elseif k == K"method"
292-
cs = map(e->_to_lowered_expr(mod, e, stmt_offset), children(ex))
288+
cs = map(e->_to_lowered_expr(e, stmt_offset), children(ex))
293289
# Ad-hoc unwrapping to satisfy `Expr(:method)` expectations
294-
c1 = cs[1] isa QuoteNode ? cs[1].value : cs[1]
290+
cs1 = cs[1]
291+
c1 = cs1 isa QuoteNode ? cs1.value : cs1
295292
Expr(:method, c1, cs[2:end]...)
296293
elseif k == K"newvar"
297-
Core.NewvarNode(_to_lowered_expr(mod, ex[1], stmt_offset))
294+
Core.NewvarNode(_to_lowered_expr(ex[1], stmt_offset))
298295
elseif k == K"opaque_closure_method"
299-
args = map(e->_to_lowered_expr(mod, e, stmt_offset), children(ex))
296+
args = map(e->_to_lowered_expr(e, stmt_offset), children(ex))
300297
# opaque_closure_method has special non-evaluated semantics for the
301298
# `functionloc` line number node so we need to undo a level of quoting
302-
@assert args[4] isa QuoteNode
303-
args[4] = args[4].value
299+
arg4 = args[4]
300+
@assert arg4 isa QuoteNode
301+
args[4] = arg4.value
304302
Expr(:opaque_closure_method, args...)
305303
elseif k == K"meta"
306-
args = Any[_to_lowered_expr(mod, e, stmt_offset) for e in children(ex)]
304+
args = Any[_to_lowered_expr(e, stmt_offset) for e in children(ex)]
307305
# Unpack K"Symbol" QuoteNode as `Expr(:meta)` requires an identifier here.
308-
args[1] = args[1].value
306+
arg1 = args[1]
307+
@assert arg1 isa QuoteNode
308+
args[1] = arg1.value
309309
Expr(:meta, args...)
310310
elseif k == K"static_eval"
311311
@assert numchildren(ex) == 1
312-
_to_lowered_expr(mod, ex[1], stmt_offset)
312+
_to_lowered_expr(ex[1], stmt_offset)
313313
elseif k == K"cfunction"
314-
args = Any[_to_lowered_expr(mod, e, stmt_offset) for e in children(ex)]
314+
args = Any[_to_lowered_expr(e, stmt_offset) for e in children(ex)]
315315
if kind(ex[2]) == K"static_eval"
316316
args[2] = QuoteNode(args[2])
317317
end
@@ -343,7 +343,11 @@ function _to_lowered_expr(mod, ex, stmt_offset)
343343
if isnothing(head)
344344
throw(LoweringError(ex, "Unhandled form for kind $k"))
345345
end
346-
Expr(head, map(e->_to_lowered_expr(mod, e, stmt_offset), children(ex))...)
346+
ret = Expr(head)
347+
for e in children(ex)
348+
push!(ret.args, _to_lowered_expr(e, stmt_offset))
349+
end
350+
return ret
347351
end
348352
end
349353

@@ -359,7 +363,7 @@ end
359363
return x
360364
end
361365
linear_ir = lower(mod, ex; expr_compat_mode)
362-
thunk = to_lowered_expr(mod, linear_ir)
366+
thunk = to_lowered_expr(linear_ir)
363367
Core.eval(mod, thunk)
364368
end
365369

@@ -400,4 +404,3 @@ function include_string(mod::Module, code::AbstractString, filename::AbstractStr
400404
expr_compat_mode=false)
401405
eval(mod, parseall(SyntaxTree, code; filename=filename); expr_compat_mode)
402406
end
403-

src/hooks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function core_lowering_hook(@nospecialize(code), mod::Module,
2222
ctx3, st3 = resolve_scopes( ctx2, st2)
2323
ctx4, st4 = convert_closures(ctx3, st3)
2424
ctx5, st5 = linearize_ir( ctx4, st4)
25-
ex = to_lowered_expr(mod, st5)
25+
ex = to_lowered_expr(st5)
2626
return Core.svec(ex, st5, ctx5)
2727
catch exc
2828
@info("JuliaLowering threw given input:", code=code, st0=st0, file=file, line=line, mod=mod)

src/macro_expansion.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ function eval_macro_name(ctx::MacroExpansionContext, mctx::MacroContext, ex::Syn
147147
ctx4, ex4 = convert_closures(ctx3, ex3)
148148
ctx5, ex5 = linearize_ir(ctx4, ex4)
149149
mod = current_layer(ctx).mod
150-
expr_form = to_lowered_expr(mod, ex5)
150+
expr_form = to_lowered_expr(ex5)
151151
try
152152
Core.eval(mod, expr_form)
153153
catch err
@@ -216,7 +216,7 @@ function expand_macro(ctx, ex)
216216
# We use a specific well defined world age for the next checks and macro
217217
# expansion invocations. This avoids inconsistencies if the latest world
218218
# age changes concurrently.
219-
#
219+
#
220220
# TODO: Allow this to be passed in
221221
if hasmethod(macfunc, Tuple{typeof(mctx), typeof.(raw_args)...}; world=ctx.macro_world)
222222
macro_args = prepare_macro_args(ctx, mctx, raw_args)

src/precompile.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ if Base.get_bool_env("JULIA_LOWERING_PRECOMPILE", true)
2121
JuliaSyntax.parse!(stream; rule=:all)
2222
st0 = JuliaSyntax.build_tree(SyntaxTree, stream; filename=@__FILE__)
2323
lwrst = lower(@__MODULE__, st0[1])
24-
lwr = to_lowered_expr(@__MODULE__, lwrst)
24+
lwr = to_lowered_expr(lwrst)
2525
@assert Meta.isexpr(lwr, :thunk) && only(lwr.args) isa Core.CodeInfo
2626
end
2727
end

src/runtime.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ function eval_closure_type(mod::Module, closure_type_name::Symbol, field_names,
195195
end
196196

197197
# Interpolate captured local variables into the CodeInfo for a global method
198-
function replace_captured_locals!(codeinfo, locals)
198+
function replace_captured_locals!(codeinfo::Core.CodeInfo, locals::Core.SimpleVector)
199199
for (i, ex) in enumerate(codeinfo.code)
200200
if Meta.isexpr(ex, :captured_local)
201-
codeinfo.code[i] = locals[ex.args[1]]
201+
codeinfo.code[i] = locals[ex.args[1]::Int]
202202
end
203203
end
204204
codeinfo
@@ -352,11 +352,13 @@ function (g::GeneratedFunctionStub)(world::UInt, source::Method, @nospecialize a
352352
is_toplevel_thunk=Bool
353353
)
354354

355+
__module__ = source.module
356+
355357
# Macro expansion. Looking at Core.GeneratedFunctionStub, it seems that
356358
# macros emitted by the generator are currently expanded in the latest
357359
# world, so do that for compatibility.
358360
macro_world = typemax(UInt)
359-
ctx1 = MacroExpansionContext(graph, source.module, false, macro_world)
361+
ctx1 = MacroExpansionContext(graph, __module__, false, macro_world)
360362

361363
# Run code generator - this acts like a macro expander and like a macro
362364
# expander it gets a MacroContext.
@@ -397,7 +399,7 @@ function (g::GeneratedFunctionStub)(world::UInt, source::Method, @nospecialize a
397399
# Rest of lowering
398400
ctx4, ex4 = convert_closures(ctx3, ex3)
399401
ctx5, ex5 = linearize_ir(ctx4, ex4)
400-
ci = to_lowered_expr(mod, ex5)
402+
ci = to_lowered_expr(ex5)
401403
@assert ci isa Core.CodeInfo
402404

403405
# See GeneratedFunctionStub code in base/expr.jl

test/demo.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function formatsrc(ex; kws...)
3232
Text(JuliaSyntaxFormatter.formatsrc(ex; kws...))
3333
end
3434

35-
function debug_lower(mod, ex; expr_compat_mode=false, verbose=false, do_eval=false)
35+
function debug_lower(mod::Module, ex::SyntaxTree; expr_compat_mode::Bool=false, verbose::Bool=false, do_eval::Bool=false)
3636
ctx1, ex_macroexpand = JuliaLowering.expand_forms_1(mod, ex, expr_compat_mode, Base.get_world_counter())
3737

3838
verbose && @info "Macro expanded" formatsrc(ex_macroexpand, color_by=:scope_layer)
@@ -49,7 +49,7 @@ function debug_lower(mod, ex; expr_compat_mode=false, verbose=false, do_eval=fal
4949
ctx5, ex_compiled = JuliaLowering.linearize_ir(ctx4, ex_converted)
5050
verbose && @info "Linear IR" formatsrc(ex_compiled, color_by=:var_id) Text(sprint(JuliaLowering.print_ir, ex_compiled))
5151

52-
ex_expr = JuliaLowering.to_lowered_expr(mod, ex_compiled)
52+
ex_expr = JuliaLowering.to_lowered_expr(ex_compiled)
5353
verbose && @info "CodeInfo" ex_expr
5454

5555
if do_eval
@@ -502,7 +502,7 @@ end
502502

503503
src = """
504504
function f(y)
505-
x =
505+
x =
506506
try
507507
try
508508
error("hi")
@@ -908,4 +908,3 @@ ex = parsestmt(SyntaxTree, src, filename="foo.jl")
908908
# for e in Meta.parseall(text).args
909909
# Meta.lower(JuliaLowering, e)
910910
# end
911-

test/repl_mode.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function is_incomplete(prompt_state)
1919
end
2020
end
2121

22-
function eval_ish(mod, ex, do_eval, do_print_ir)
22+
function eval_ish(mod::Module, ex::SyntaxTree, do_eval::Bool, do_print_ir::Bool)
2323
k = kind(ex)
2424
if k == K"toplevel"
2525
x = nothing
@@ -34,7 +34,7 @@ function eval_ish(mod, ex, do_eval, do_print_ir)
3434
end
3535
if do_eval
3636
println(stdout, "#----------------------")
37-
expr_form = JuliaLowering.to_lowered_expr(mod, linear_ir)
37+
expr_form = JuliaLowering.to_lowered_expr(linear_ir)
3838
Base.eval(mod, expr_form)
3939
end
4040
end
@@ -79,4 +79,3 @@ function __init__()
7979
end
8080

8181
end
82-

test/utils.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,9 @@ function watch_ir_tests(dir, delay=0.5)
262262
end
263263
end
264264

265-
function lower_str(mod, s)
265+
function lower_str(mod::Module, s::AbstractString)
266266
ex = parsestmt(JuliaLowering.SyntaxTree, s)
267-
return JuliaLowering.to_lowered_expr(mod, JuliaLowering.lower(mod, ex))
267+
return JuliaLowering.to_lowered_expr(JuliaLowering.lower(mod, ex))
268268
end
269269

270270
# See Julia Base tests in "test/docs.jl"
@@ -356,13 +356,13 @@ end
356356
# Parse a file and lower the top level expression one child at a time, finding
357357
# any top level statement that fails lowering and producing a partially reduced
358358
# test case.
359-
function reduce_any_failing_toplevel(mod, filename; do_eval=false)
359+
function reduce_any_failing_toplevel(mod::Module, filename::AbstractString; do_eval::Bool=false)
360360
text = read(filename, String)
361361
ex0 = parseall(SyntaxTree, text; filename)
362362
for ex in children(ex0)
363363
try
364364
ex_compiled = JuliaLowering.lower(mod, ex)
365-
ex_expr = JuliaLowering.to_lowered_expr(mod, ex_compiled)
365+
ex_expr = JuliaLowering.to_lowered_expr(ex_compiled)
366366
if do_eval
367367
Base.eval(mod, ex_expr)
368368
end
@@ -373,7 +373,7 @@ function reduce_any_failing_toplevel(mod, filename; do_eval=false)
373373
end
374374
(reduced,was_reduced) = block_reduction(e->throws_lowering_exc(mod,e), ex)
375375
if !was_reduced
376-
@info "No reduction possible"
376+
@info "No reduction possible"
377377
return ex
378378
else
379379
@info "Reduced code" reduced
@@ -383,4 +383,3 @@ function reduce_any_failing_toplevel(mod, filename; do_eval=false)
383383
end
384384
nothing
385385
end
386-

0 commit comments

Comments
 (0)