Skip to content

Commit

Permalink
add current_scope support for compiled frames
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Jan 9, 2024
1 parent 2d026eb commit 9ce455e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
20 changes: 15 additions & 5 deletions src/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,19 @@ function bypass_builtins(@nospecialize(recurse), frame, call_expr, pc)
return nothing
end

function native_call(fargs::Vector{Any}, frame::Frame)
f = popfirst!(fargs) # now it's really just `args`
if !isempty(frame.framedata.current_scopes)
newscope = Core.current_scope()
for scope in frame.framedata.current_scopes
newscope = Scope(newscope, scope.values...)
end
ex = Expr(:tryfinally, :($f($fargs...)), nothing, newscope)
return Core.eval(moduleof(frame), ex)
end
return Base.invokelatest(f, fargs...)
end

function evaluate_call_compiled!(::Compiled, frame::Frame, call_expr::Expr; enter_generated::Bool=false)
# @assert !enter_generated
pc = frame.pc
Expand All @@ -230,9 +243,7 @@ function evaluate_call_compiled!(::Compiled, frame::Frame, call_expr::Expr; ente
ret = maybe_evaluate_builtin(frame, call_expr, false)
isa(ret, Some{Any}) && return ret.value
fargs = collect_args(Compiled(), frame, call_expr)
f = fargs[1]
popfirst!(fargs) # now it's really just `args`
return f(fargs...)
return native_call(fargs, frame)
end

function evaluate_call_recurse!(@nospecialize(recurse), frame::Frame, call_expr::Expr; enter_generated::Bool=false)
Expand Down Expand Up @@ -263,8 +274,7 @@ function evaluate_call_recurse!(@nospecialize(recurse), frame::Frame, call_expr:
framecode, lenv = get_call_framecode(fargs, frame.framecode, frame.pc; enter_generated=enter_generated)
if lenv === nothing
if isa(framecode, Compiled)
f = popfirst!(fargs) # now it's really just `args`
return Base.invokelatest(f, fargs...)
return native_call(fargs, frame)
end
return framecode # this was a Builtin
end
Expand Down
9 changes: 8 additions & 1 deletion src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ function build_compiled_foreigncall!(stmt::Expr, code::CodeInfo, sparams::Vector
return nothing
end

function replace_coretypes!(src; rev::Bool=false)
function replace_coretypes!(@nospecialize(src); rev::Bool=false)
if isa(src, CodeInfo)
replace_coretypes_list!(src.code; rev=rev)
elseif isa(src, Expr)
Expand Down Expand Up @@ -286,6 +286,13 @@ function replace_coretypes_list!(list::AbstractVector; rev::Bool=false)
if rval !== val
list[i] = ReturnNode(rval)
end
elseif @static (isdefined(Core.IR, :EnterNode) && true) && isa(stmt, Core.IR.EnterNode)
if isdefined(stmt, :scope)
rscope = rep(stmt.scope, rev)
if rscope !== stmt.scope
list[i] = Core.IR.EnterNode(stmt.catch_dest, rscope)
end
end
elseif isa(stmt, Expr)
replace_coretypes!(stmt; rev=rev)
end
Expand Down
25 changes: 22 additions & 3 deletions test/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1000,9 +1000,28 @@ func_arrayref(a, i) = Core.arrayref(true, a, i)

@static if isdefined(Base, :ScopedValues)
const sval = ScopedValue(1)
sval_func() = @with sval => 2 begin
@test 1 == @interpret getindex(sval)

# current_scope support for interpretation
sval_func1() = @with sval => 2 begin
return sval[]
end
@test 2 == @interpret sval_func()
@test 1 == @interpret getindex(sval)
@test 2 == @interpret sval_func1()

# current_scope support for compiled calls
_sval_func2() = sval[]
sval_func2() = @with sval => 2 begin
return _sval_func2()
end
let m = only(methods(_sval_func2))
push!(JuliaInterpreter.compiled_methods, m)
try
@test 2 == @interpret sval_func2()
finally
delete!(JuliaInterpreter.compiled_methods, m)
end
end
let frame = Frame(@__MODULE__, only(code_lowered(sval_func2)))
@test 2 == JuliaInterpreter.finish_and_return!(Compiled(), frame)
end
end

0 comments on commit 9ce455e

Please sign in to comment.