Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/lowered.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function defines_function(@nospecialize(ci))
end

"""
isrequired, evalassign = minimal_evaluation!([predicate,] methodinfo, src::Core.CodeInfo, mode::Symbol)
isrequired, evalassign = minimal_evaluation!([predicate,] src::Core.CodeInfo, mode::Symbol)

Mark required statements in `src`: `isrequired[i]` is `true` if `src.code[i]` should be evaluated.
Statements are analyzed by `isreq, haseval = predicate(stmt)`, and `predicate` defaults
Expand All @@ -117,7 +117,7 @@ to `Revise.is_method_or_eval`.
Since the contents of such expression are difficult to analyze, it is generally
safest to execute all such evals.
"""
function minimal_evaluation!(@nospecialize(predicate), methodinfo, mod::Module, src::Core.CodeInfo, mode::Symbol)
function minimal_evaluation!(@nospecialize(predicate), mod::Module, src::Core.CodeInfo, mode::Symbol)
edges = CodeEdges(mod, src)
# LoweredCodeUtils.print_with_code(stdout, src, edges)
isrequired = fill(false, length(src.code))
Expand Down Expand Up @@ -177,11 +177,11 @@ function minimal_evaluation!(@nospecialize(predicate), methodinfo, mod::Module,
# LoweredCodeUtils.print_with_code(stdout, src, isrequired)
return isrequired, evalassign
end
@noinline minimal_evaluation!(@nospecialize(predicate), methodinfo, frame::Frame, mode::Symbol) =
minimal_evaluation!(predicate, methodinfo, moduleof(frame), frame.framecode.src, mode)
@noinline minimal_evaluation!(@nospecialize(predicate), frame::Frame, mode::Symbol) =
minimal_evaluation!(predicate, moduleof(frame), frame.framecode.src, mode)

function minimal_evaluation!(methodinfo, frame::Frame, mode::Symbol)
minimal_evaluation!(methodinfo, frame, mode) do @nospecialize(stmt), code::Vector{Any}
function minimal_evaluation!(frame::Frame, mode::Symbol)
minimal_evaluation!(frame, mode) do @nospecialize(stmt), code::Vector{Any}
ismeth, haseval, isinclude, isnamespace, istoplevel = categorize_stmt(stmt, code)
isreq = ismeth | isinclude | istoplevel
return mode === :sigs ? (isreq, haseval) : (isreq | isnamespace, haseval)
Expand All @@ -190,7 +190,7 @@ end

function methods_by_execution(mod::Module, ex::Expr; kwargs...)
methodinfo = MethodInfo()
value, thk = methods_by_execution!(JuliaInterpreter.Compiled(), methodinfo, mod, ex; kwargs...)
_, thk = methods_by_execution!(JuliaInterpreter.Compiled(), methodinfo, mod, ex; kwargs...)
return methodinfo, thk
end

Expand Down Expand Up @@ -252,7 +252,7 @@ function methods_by_execution!(interp::Interpreter, methodinfo, mod::Module, ex:
frame = Frame(mod, lwr.args[1]::CodeInfo)
mode === :eval || LoweredCodeUtils.rename_framemethods!(interp, frame)
# Determine whether we need interpreted mode
isrequired, evalassign = minimal_evaluation!(methodinfo, frame, mode)
isrequired, evalassign = minimal_evaluation!(frame, mode)
# LoweredCodeUtils.print_with_code(stdout, frame.framecode.src, isrequired)
if !any(isrequired) && (mode===:eval || !evalassign)
# We can evaluate the entire expression in compiled mode
Expand Down Expand Up @@ -283,7 +283,7 @@ function methods_by_execution!(interp::Interpreter, methodinfo, mod::Module, ex:
ret = try
_methods_by_execution!(interp, methodinfo, frame, isrequired; mode, kwargs...)
catch err
(always_rethrow || isa(err, InterruptException)) && (disablebp && foreach(enable, active_bp_refs); rethrow(err))
(always_rethrow || isa(err, InterruptException)) && (@isdefined(active_bp_refs) && foreach(enable, active_bp_refs); rethrow(err))
loc = location_string(whereis(frame))
sfs = [] # crafted for interaction with Base.show_backtrace
frame = JuliaInterpreter.leaf(frame)
Expand All @@ -293,7 +293,7 @@ function methods_by_execution!(interp::Interpreter, methodinfo, mod::Module, ex:
end
throw(ReviseEvalException(loc, err, sfs))
end
if disablebp
if @isdefined active_bp_refs
foreach(enable, active_bp_refs)
end
end
Expand Down Expand Up @@ -327,7 +327,7 @@ function _methods_by_execution!(interp::Interpreter, methodinfo, frame::Frame, i
ex isa Expr || continue
value, _ = methods_by_execution!(interp, methodinfo, mod, ex; mode, disablebp=false, skip_include)
end
isassign(frame, pc) && assign_this!(frame, value)
isassign(frame, pc) && @isdefined(value) && assign_this!(frame, value)
pc = next_or_nothing!(frame)
elseif head === :thunk && defines_function(only(stmt.args))
mode !== :sigs && Core.eval(mod, stmt)
Expand Down
2 changes: 1 addition & 1 deletion src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function _precompile_()
@warnpcfail precompile(Tuple{typeof(setindex!), Dict{String,WatchList}, WatchList, String})

MI = CodeTrackingMethodInfo
@warnpcfail precompile(Tuple{typeof(minimal_evaluation!), Any, MI, Module, Core.CodeInfo, Symbol})
@warnpcfail precompile(Tuple{typeof(minimal_evaluation!), Any, Module, Core.CodeInfo, Symbol})
@warnpcfail precompile(Tuple{typeof(methods_by_execution!), Compiled, MI, Module, Expr})
@warnpcfail precompile(Tuple{typeof(_methods_by_execution!), Compiled, MI, Frame, Vector{Bool}})
@warnpcfail precompile(Tuple{typeof(Core.kwfunc(methods_by_execution!)),
Expand Down
3 changes: 1 addition & 2 deletions test/backedges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ do_test("Backedges") && @testset "Backedges" begin
# Find the inner struct def for the anonymous function
idtype = findall(stmt->isexpr(stmt, :thunk) && isa(stmt.args[1], Core.CodeInfo), src.code)[end]
src2 = src.code[idtype].args[1]
methodinfo = Revise.MethodInfo()
isrequired = Revise.minimal_evaluation!(methodinfo, frame, :sigs)[1]
isrequired = Revise.minimal_evaluation!(frame, :sigs)[1]
laststmt = src.code[end]
@assert isa(laststmt, Core.ReturnNode)
to_skip = isa(laststmt.val, Revise.JuliaInterpreter.SSAValue) ? 2 : 1
Expand Down
Loading