Skip to content

Commit c87456e

Browse files
committed
Add Core._lower for swapping out lowering implementation
Without using JuliaLowering, this should just call `fl_lower` in flfrontend.jl and behave as usual. This structure mirrors the parsing API.
1 parent d992554 commit c87456e

File tree

11 files changed

+79
-36
lines changed

11 files changed

+79
-36
lines changed

base/Base_compiler.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,9 @@ const _return_type = Compiler.return_type
375375
# Enable compiler
376376
Compiler.bootstrap!()
377377

378-
include("flparse.jl")
378+
include("flfrontend.jl")
379379
Core._setparser!(fl_parse)
380+
Core._setlowerer!(fl_lower)
380381

381382
# Further definition of Base will happen in Base.jl if loaded.
382383

base/boot.jl

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -998,8 +998,9 @@ function struct_name_shim(@nospecialize(x), name::Symbol, mod::Module, @nospecia
998998
return x === mod ? t : getfield(x, name)
999999
end
10001000

1001-
# Binding for the julia parser, called as
1002-
#
1001+
# Bindings for the julia frontend. The internal jl_parse and jl_lower will call
1002+
# Core._parse and Core._lower respectively (if they are not `nothing`.)
1003+
10031004
# Core._parse(text, filename, lineno, offset, options)
10041005
#
10051006
# Parse Julia code from the buffer `text`, starting at `offset` and attributing
@@ -1009,11 +1010,17 @@ end
10091010
#
10101011
# `_parse` must return an `svec` containing an `Expr` and the new offset as an
10111012
# `Int`.
1012-
#
1013-
# The internal jl_parse will call into Core._parse if not `nothing`.
10141013
_parse = nothing
10151014

1015+
# Core._lower(code, module, filename="none", linenum=0, world=0xfff..., warn=false)
1016+
#
1017+
# Lower `code` (usually Expr), returning `svec(e::Any xs::Any...)` where `e` is
1018+
# the lowered code, and `xs` is possible additional information from
1019+
# JuliaLowering (TBD).
1020+
_lower = nothing
1021+
10161022
_setparser!(parser) = setglobal!(Core, :_parse, parser)
1023+
_setlowerer!(lowerer) = setglobal!(Core, :_lower, lowerer)
10171024

10181025
# support for deprecated uses of builtin functions
10191026
_apply(x...) = _apply_iterate(Main.Base.iterate, x...)

base/expr.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1669,7 +1669,8 @@ end
16691669

16701670
# Implementation of generated functions
16711671
function generated_body_to_codeinfo(ex::Expr, defmod::Module, isva::Bool)
1672-
ci = ccall(:jl_lower_expr_mod, Any, (Any, Any), ex, defmod)
1672+
ci = ccall(:jl_fl_lower, Any, (Any, Any, Ptr{UInt8}, Csize_t, Csize_t, Cint),
1673+
ex, defmod, "none", 0, typemax(Csize_t), 0)[1]
16731674
if !isa(ci, CodeInfo)
16741675
if isa(ci, Expr) && ci.head === :error
16751676
msg = ci.args[1]

base/flparse.jl renamed to base/flfrontend.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ end
1717
function fl_parse(text::AbstractString, filename::AbstractString, lineno, offset, options)
1818
fl_parse(String(text), String(filename), lineno, offset, options)
1919
end
20+
21+
function fl_lower(ex, mod::Module, filename::Union{String,Ptr{UInt8}}="none",
22+
lineno=0, world::Unsigned=typemax(Csize_t), warn::Bool=false)
23+
warn = warn ? 1 : 0
24+
ccall(:jl_fl_lower, Any, (Any, Any, Ptr{UInt8}, Csize_t, Csize_t, Cint),
25+
ex, mod, filename, lineno, world, warn)
26+
end

base/loading.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2808,7 +2808,11 @@ function include_string(mapexpr::Function, mod::Module, code::AbstractString,
28082808
loc = LineNumberNode(1, Symbol(filename))
28092809
try
28102810
ast = Meta.parseall(code, filename=filename)
2811-
@assert Meta.isexpr(ast, :toplevel)
2811+
if !Meta.isexpr(ast, :toplevel)
2812+
@assert Core._lower != fl_lower
2813+
# Only reached when JuliaLowering and alternate parse functions are activated
2814+
return Core.eval(mod, ast)
2815+
end
28122816
result = nothing
28132817
line_and_ex = Expr(:toplevel, loc, nothing)
28142818
for ex in ast.args

base/meta.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ Takes the expression `x` and returns an equivalent expression in lowered form
160160
for executing in module `m`.
161161
See also [`code_lowered`](@ref).
162162
"""
163-
lower(m::Module, @nospecialize(x)) = ccall(:jl_lower_expr_mod, Any, (Any, Any), x, m)
163+
lower(m::Module, @nospecialize(x)) = Core._lower(x, m, "none", 0, typemax(Csize_t), false)[1]
164164

165165
"""
166166
@lower [m] x

src/ast.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,13 +1275,12 @@ JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule
12751275
return expr;
12761276
}
12771277

1278-
// Main entry point to flisp lowering. Most arguments are optional; see `jl_lower_expr_mod`.
12791278
// warn: Print any lowering warnings returned; otherwise ignore
12801279
JL_DLLEXPORT jl_value_t *jl_fl_lower(jl_value_t *expr, jl_module_t *inmodule,
1281-
const char *file, int line, size_t world, bool_t warn)
1280+
const char *filename, int line, size_t world, bool_t warn)
12821281
{
12831282
JL_TIMING(LOWERING, LOWERING);
1284-
jl_timing_show_location(file, line, inmodule, JL_TIMING_DEFAULT_BLOCK);
1283+
jl_timing_show_location(filename, line, inmodule, JL_TIMING_DEFAULT_BLOCK);
12851284
jl_array_t *kwargs = NULL;
12861285
JL_GC_PUSH3(&expr, &kwargs, &inmodule);
12871286
expr = jl_copy_ast(expr);
@@ -1290,7 +1289,7 @@ JL_DLLEXPORT jl_value_t *jl_fl_lower(jl_value_t *expr, jl_module_t *inmodule,
12901289
fl_context_t *fl_ctx = &ctx->fl;
12911290
value_t arg = julia_to_scm(fl_ctx, expr);
12921291
value_t e = fl_applyn(fl_ctx, 3, symbol_value(symbol(fl_ctx, "jl-lower-to-thunk")), arg,
1293-
symbol(fl_ctx, file), fixnum(line));
1292+
symbol(fl_ctx, filename), fixnum(line));
12941293
value_t lwr = car_(e);
12951294
value_t warnings = car_(cdr_(e));
12961295
expr = scm_to_julia(fl_ctx, lwr, inmodule);
@@ -1306,6 +1305,7 @@ JL_DLLEXPORT jl_value_t *jl_fl_lower(jl_value_t *expr, jl_module_t *inmodule,
13061305
jl_error("julia-logmsg: bad argument list - expected "
13071306
":warn level (symbol) group (symbol) id file line msg . kwargs");
13081307
}
1308+
JL_GC_PUSH1(&warning);
13091309
jl_value_t *level = jl_exprarg(warning, 0);
13101310
jl_value_t *group = jl_exprarg(warning, 1);
13111311
jl_value_t *id = jl_exprarg(warning, 2);
@@ -1318,17 +1318,45 @@ JL_DLLEXPORT jl_value_t *jl_fl_lower(jl_value_t *expr, jl_module_t *inmodule,
13181318
}
13191319
JL_TYPECHK(logmsg, long, level);
13201320
jl_log(jl_unbox_long(level), NULL, group, id, file, line, (jl_value_t*)kwargs, msg);
1321+
JL_GC_POP();
13211322
}
1323+
jl_value_t *result = (jl_value_t *)jl_svec1(expr);
13221324
JL_GC_POP();
1323-
return expr;
1325+
return result;
13241326
}
13251327

1326-
// Lower an expression tree into Julia's intermediate-representation.
1328+
// Main C entry point to lowering. Calls jl_fl_lower during bootstrap, and
1329+
// Core._lower otherwise (this is also jl_fl_lower unless we have JuliaLowering)
13271330
JL_DLLEXPORT jl_value_t *jl_lower(jl_value_t *expr, jl_module_t *inmodule,
1328-
const char *file, int line, size_t world, bool_t warn)
1331+
const char *filename, int line, size_t world, bool_t warn)
13291332
{
1330-
// TODO: Allow change of lowerer
1331-
return jl_fl_lower(expr, inmodule, file, line, world, warn);
1333+
jl_value_t *core_lower = NULL;
1334+
if (jl_core_module) {
1335+
core_lower = jl_get_global(jl_core_module, jl_symbol("_lower"));
1336+
}
1337+
if (!core_lower || core_lower == jl_nothing) {
1338+
return jl_fl_lower(expr, inmodule, filename, line, world, warn);
1339+
}
1340+
jl_value_t **args;
1341+
JL_GC_PUSHARGS(args, 7);
1342+
args[0] = core_lower;
1343+
args[1] = expr;
1344+
args[2] = (jl_value_t*)inmodule;
1345+
args[3] = jl_cstr_to_string(filename);
1346+
args[4] = jl_box_ulong(line);
1347+
args[5] = jl_box_ulong(world);
1348+
args[6] = warn ? jl_true : jl_false;
1349+
jl_task_t *ct = jl_current_task;
1350+
size_t last_age = ct->world_age;
1351+
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
1352+
jl_value_t *result = jl_apply(args, 7);
1353+
ct->world_age = last_age;
1354+
args[0] = result; // root during error check below
1355+
JL_TYPECHK(parse, simplevector, result);
1356+
if (jl_svec_len(result) < 1)
1357+
jl_error("Result from lowering should be `svec(a::Any, x::Any...)`");
1358+
JL_GC_POP();
1359+
return result;
13321360
}
13331361

13341362
JL_DLLEXPORT jl_value_t *jl_lower_expr_mod(jl_value_t *expr, jl_module_t *inmodule)

src/toplevel.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,7 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
195195

196196
for (int i = 0; i < jl_array_nrows(exprs); i++) {
197197
// process toplevel form
198-
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
199-
form = jl_lower(jl_array_ptr_ref(exprs, i), newm, filename, lineno, ~(size_t)0, 0);
198+
form = jl_svecref(jl_lower(jl_array_ptr_ref(exprs, i), newm, filename, lineno, ~(size_t)0, 0), 0);
200199
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
201200
(void)jl_toplevel_eval_flex(newm, form, 1, 1, &filename, &lineno);
202201
}
@@ -806,10 +805,8 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val
806805
JL_GC_PUSH4(&mfunc, &thk, &ex, &root);
807806

808807
size_t last_age = ct->world_age;
809-
if (!expanded && jl_needs_lowering(e)) {
810-
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
811-
ex = (jl_expr_t*)jl_lower(e, m, *toplevel_filename, *toplevel_lineno, ~(size_t)0, 1);
812-
ct->world_age = last_age;
808+
if (!expanded && (jl_needs_lowering(e))) {
809+
ex = (jl_expr_t*)jl_svecref(jl_lower(e, m, *toplevel_filename, *toplevel_lineno, ~(size_t)0, 1), 0);
813810
}
814811
jl_sym_t *head = jl_is_expr(ex) ? ex->head : NULL;
815812

@@ -971,8 +968,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val
971968
for (i = 0; i < jl_array_nrows(ex->args); i++) {
972969
root = jl_array_ptr_ref(ex->args, i);
973970
if (jl_needs_lowering(root)) {
974-
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
975-
root = jl_lower(root, m, *toplevel_filename, *toplevel_lineno, ~(size_t)0, 1);
971+
root = jl_svecref(jl_lower(root, m, *toplevel_filename, *toplevel_lineno, ~(size_t)0, 1), 0);
976972
}
977973
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
978974
res = jl_toplevel_eval_flex(m, root, fast, 1, toplevel_filename, toplevel_lineno);
@@ -1150,8 +1146,7 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text,
11501146
jl_lineno = lineno;
11511147
continue;
11521148
}
1153-
ct->world_age = jl_atomic_load_relaxed(&jl_world_counter);
1154-
expression = jl_lower(expression, module, jl_string_data(filename), lineno, ~(size_t)0, 1);
1149+
expression = jl_svecref(jl_lower(expression, module, jl_string_data(filename), lineno, ~(size_t)0, 1), 0);
11551150
ct->world_age = jl_atomic_load_relaxed(&jl_world_counter);
11561151
result = jl_toplevel_eval_flex(module, expression, 1, 1, &filename_str, &lineno);
11571152
}

stdlib/InteractiveUtils/src/macros.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,8 @@ in the current environment.
558558
When using `@activate`, additional options for a component may be specified in
559559
square brackets `@activate Compiler[:option1, :option]`
560560
561-
Currently `@activate Compiler` is the only available component that may be
562-
activatived.
561+
Currently `Compiler` and `JuliaLowering` are the only available components that
562+
may be activatived.
563563
564564
For `@activate Compiler`, the following options are available:
565565
1. `:reflection` - Activate the compiler for reflection purposes only.
@@ -593,7 +593,7 @@ macro activate(what)
593593
if !isa(Component, Symbol)
594594
error("Usage Error: Component $Component is not a symbol")
595595
end
596-
allowed_components = (:Compiler,)
596+
allowed_components = (:Compiler, :JuliaLowering)
597597
if !(Component in allowed_components)
598598
error("Usage Error: Component $Component is not recognized. Expected one of $allowed_components")
599599
end

stdlib/REPL/src/REPL.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,12 @@ const install_packages_hooks = Any[]
298298
# N.B.: Any functions starting with __repl_entry cut off backtraces when printing in the REPL.
299299
# We need to do this for both the actual eval and macroexpand, since the latter can cause custom macro
300300
# code to run (and error).
301-
__repl_entry_lower_with_loc(mod::Module, @nospecialize(ast), toplevel_file::Ref{Ptr{UInt8}}, toplevel_line::Ref{Cint}) =
302-
ccall(:jl_lower, Any, (Any, Any, Ptr{UInt8}, Cint, Csize_t, Cint), ast, mod, toplevel_file[], toplevel_line[], typemax(Csize_t), 0)
303-
__repl_entry_eval_expanded_with_loc(mod::Module, @nospecialize(ast), toplevel_file::Ref{Ptr{UInt8}}, toplevel_line::Ref{Cint}) =
304-
ccall(:jl_toplevel_eval_flex, Any, (Any, Any, Cint, Cint, Ptr{Ptr{UInt8}}, Ptr{Cint}), mod, ast, 1, 1, toplevel_file, toplevel_line)
301+
__repl_entry_lower_with_loc(mod::Module, @nospecialize(ast), toplevel_file::Ref{Ptr{UInt8}}, toplevel_line::Ref{Csize_t}) =
302+
Core._lower(ast, mod, toplevel_file[], toplevel_line[])[1]
303+
__repl_entry_eval_expanded_with_loc(mod::Module, @nospecialize(ast), toplevel_file::Ref{Ptr{UInt8}}, toplevel_line::Ref{Csize_t}) =
304+
ccall(:jl_toplevel_eval_flex, Any, (Any, Any, Cint, Cint, Ptr{Ptr{UInt8}}, Ptr{Csize_t}), mod, ast, 1, 1, toplevel_file, toplevel_line)
305305

306-
function toplevel_eval_with_hooks(mod::Module, @nospecialize(ast), toplevel_file=Ref{Ptr{UInt8}}(Base.unsafe_convert(Ptr{UInt8}, :REPL)), toplevel_line=Ref{Cint}(1))
306+
function toplevel_eval_with_hooks(mod::Module, @nospecialize(ast), toplevel_file=Ref{Ptr{UInt8}}(Base.unsafe_convert(Ptr{UInt8}, :REPL)), toplevel_line=Ref{Csize_t}(1))
307307
if !isexpr(ast, :toplevel)
308308
ast = invokelatest(__repl_entry_lower_with_loc, mod, ast, toplevel_file, toplevel_line)
309309
check_for_missing_packages_and_run_hooks(ast)

0 commit comments

Comments
 (0)