Skip to content

Commit

Permalink
implement support for current_scope
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Dec 22, 2023
1 parent 6b1c476 commit b5f2f5e
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 23 deletions.
31 changes: 24 additions & 7 deletions bin/generate_builtins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const RECENTLY_ADDED = Core.Builtin[
Core.finalizer, Core._compute_sparams, Core._svec_ref,
Core.compilerbarrier,
Core.memoryref, Core.memoryref_isassigned, Core.memoryrefget, Core.memoryrefoffset, Core.memoryrefset!,
#=Core.current_scope=#
]
# Builtins present in 1.6, not builtins (potentially still normal functions) anymore
const RECENTLY_REMOVED = GlobalRef.(Ref(Core), [
Expand Down Expand Up @@ -187,13 +188,13 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
print(io,
"""
$head f === $fstr
if !expand
argswrapped = getargs(args, frame)
return Some{Any}($fstr(argswrapped...))
end
# This uses the original arguments to avoid looking them up twice
# See #442
return Expr(:call, invoke, args[2:end]...)
if !expand
argswrapped = getargs(args, frame)
return Some{Any}($fstr(argswrapped...))
end
# This uses the original arguments to avoid looking them up twice
# See #442
return Expr(:call, invoke, args[2:end]...)
""")
continue
elseif f === Core._call_latest
Expand All @@ -211,6 +212,22 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
end
return maybe_recurse_expanded_builtin(frame, new_expr)
""")
continue
elseif f === Core.current_scope
print(io,
"""
elseif @static isdefined(Core, :current_scope) && f === Core.current_scope
if nargs == 0
if isempty(frame.framedata.current_scopes)
return Some{Any}(nothing)
else
return Some{Any}(frame.framedata.current_scopes[end])
end
else
return Some{Any}(Core.current_scope(getargs(args, frame)...))
end
""")
continue
end

id = findfirst(isequal(f), Core.Compiler.T_FFUNC_KEY)
Expand Down
26 changes: 17 additions & 9 deletions src/builtins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
push!(new_expr.args, QuoteNode(x))
end
return maybe_recurse_expanded_builtin(frame, new_expr)
elseif f === Core._call_latest
return Some{Any}(Core._call_latest(getargs(args, frame)...))
elseif @static isdefined(Core, :_compute_sparams) && f === Core._compute_sparams
return Some{Any}(Core._compute_sparams(getargs(args, frame)...))
elseif f === Core._equiv_typedef
Expand Down Expand Up @@ -126,6 +124,16 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
else
return Some{Any}(Core.compilerbarrier(getargs(args, frame)...))
end
elseif @static isdefined(Core, :current_scope) && f === Core.current_scope
if nargs == 0
if isempty(frame.framedata.current_scopes)
return Some{Any}(nothing)
else
return Some{Any}(frame.framedata.current_scopes[end])
end
else
return Some{Any}(Core.current_scope(getargs(args, frame)...))
end
elseif @static isdefined(Core, :donotdelete) && f === Core.donotdelete
return Some{Any}(Core.donotdelete(getargs(args, frame)...))
elseif @static isdefined(Core, :finalizer) && f === Core.finalizer
Expand Down Expand Up @@ -227,13 +235,13 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
return Some{Any}(getglobal(getargs(args, frame)...))
end
elseif f === invoke
if !expand
argswrapped = getargs(args, frame)
return Some{Any}(invoke(argswrapped...))
end
# This uses the original arguments to avoid looking them up twice
# See #442
return Expr(:call, invoke, args[2:end]...)
if !expand
argswrapped = getargs(args, frame)
return Some{Any}(invoke(argswrapped...))
end
# This uses the original arguments to avoid looking them up twice
# See #442
return Expr(:call, invoke, args[2:end]...)
elseif f === isa
if nargs == 2
return Some{Any}(isa(@lookup(frame, args[2]), @lookup(frame, args[3])))
Expand Down
8 changes: 6 additions & 2 deletions src/construct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ function prepare_framedata(framecode, argvals::Vector{Any}, lenv::SimpleVector=e
if length(junk_framedata) > 0
olddata = pop!(junk_framedata)
locals, ssavalues, sparams = olddata.locals, olddata.ssavalues, olddata.sparams
exception_frames, last_reference = olddata.exception_frames, olddata.last_reference
exception_frames, current_scopes, last_reference = olddata.exception_frames, olddata.current_scopes, olddata.last_reference
last_exception = olddata.last_exception
callargs = olddata.callargs
resize!(locals, ns)
Expand All @@ -282,13 +282,15 @@ function prepare_framedata(framecode, argvals::Vector{Any}, lenv::SimpleVector=e
# for check_isdefined to work properly, we need sparams to start out unassigned
resize!(sparams, 0)
empty!(exception_frames)
empty!(current_scopes)
resize!(last_reference, ns)
last_exception[] = _INACTIVE_EXCEPTION.instance
else
locals = Vector{Union{Nothing,Some{Any}}}(nothing, ns)
ssavalues = Vector{Any}(undef, ng)
sparams = Vector{Any}(undef, 0)
exception_frames = Int[]
current_scopes = Any[]
last_reference = Vector{Int}(undef, ns)
callargs = Any[]
last_exception = Ref{Any}(_INACTIVE_EXCEPTION.instance)
Expand Down Expand Up @@ -317,7 +319,8 @@ function prepare_framedata(framecode, argvals::Vector{Any}, lenv::SimpleVector=e
isa(T, TypeVar) && continue # only fill concrete types
sparams[i] = T
end
FrameData(locals, ssavalues, sparams, exception_frames, last_exception, caller_will_catch_err, last_reference, callargs)
return FrameData(locals, ssavalues, sparams, exception_frames, current_scopes,
last_exception, caller_will_catch_err, last_reference, callargs)
end

"""
Expand All @@ -334,6 +337,7 @@ end
function prepare_frame_caller(caller::Frame, framecode::FrameCode, args::Vector{Any}, lenv::SimpleVector)
caller_will_catch_err = !isempty(caller.framedata.exception_frames) || caller.framedata.caller_will_catch_err
caller.callee = frame = prepare_frame(framecode, args, lenv, caller_will_catch_err)
copy!(frame.framedata.current_scopes, caller.framedata.current_scopes)
frame.caller = caller
return frame
end
Expand Down
12 changes: 8 additions & 4 deletions src/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,6 @@ function eval_rhs(@nospecialize(recurse), frame, node::Expr)
elseif head === :copyast
val = (node.args[1]::QuoteNode).value
return isa(val, Expr) ? copy(val) : val
elseif head === :enter
# XXX This seems to be dead code
return length(frame.framedata.exception_frames)
elseif head === :boundscheck
return true
elseif head === :meta || head === :inbounds || head === :loopinfo ||
Expand Down Expand Up @@ -486,8 +483,12 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
for i = 1:length(node.args)
targ = node.args[i]
targ === nothing && continue
frame.framecode.src.code[(targ::SSAValue).id] === nothing && continue
enterstmt = frame.framecode.src.code[(targ::SSAValue).id]
enterstmt === nothing && continue
pop!(data.exception_frames)
if isdefined(enterstmt, :scope)
pop!(data.current_scopes)
end
end
end
elseif node.head === :pop_exception
Expand Down Expand Up @@ -568,6 +569,9 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
elseif @static (isdefined(Core.IR, :EnterNode) && true) && isa(node, Core.IR.EnterNode)
rhs = node.catch_dest
push!(data.exception_frames, rhs)
if isdefined(node, :scope)
push!(data.current_scopes, @lookup(frame, node.scope))
end
else
rhs = @lookup(frame, node)
end
Expand Down
12 changes: 11 additions & 1 deletion src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,17 @@ function renumber_ssa!(stmts::Vector{Any}, ssalookup)
stmts[i] = ReturnNode(SSAValue(ssalookup[val.id]))
end
elseif @static (isdefined(Core.IR, :EnterNode) && true) && isa(stmt, Core.IR.EnterNode)
stmts[i] = Core.IR.EnterNode(jumplookup(ssalookup, stmt.catch_dest))
new_catch_dest = jumplookup(ssalookup, stmt.catch_dest)
if isdefined(stmt, :scope)
scope = stmt.scope
if isa(scope, Core.SSAValue)
stmts[i] = Core.IR.EnterNode(new_catch_dest, SSAValue(jumplookup(ssalookup, scope.id)))
else
stmts[i] = Core.IR.EnterNode(new_catch_dest, )
end
else
stmts[i] = Core.IR.EnterNode(new_catch_dest)
end
end
end
return stmts
Expand Down
6 changes: 6 additions & 0 deletions src/packagedef.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ if !isdefined(Base, Symbol("@something"))
end
end

if isdefined(Base, :ScopedValues)
using Base: ScopedValues.Scope
else
const Scope = Any
end

include("types.jl")
include("utils.jl")
include("construct.jl")
Expand Down
1 change: 1 addition & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ struct FrameData
ssavalues::Vector{Any}
sparams::Vector{Any}
exception_frames::Vector{Int}
current_scopes::Vector{Scope}
last_exception::Base.RefValue{Any}
caller_will_catch_err::Bool
last_reference::Vector{Int}
Expand Down
9 changes: 9 additions & 0 deletions test/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -997,3 +997,12 @@ end
# test for using generic functions that were previously builtin
func_arrayref(a, i) = Core.arrayref(true, a, i)
@test 2 == @interpret func_arrayref([1,2,3], 2)

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

0 comments on commit b5f2f5e

Please sign in to comment.