Skip to content

Commit

Permalink
Fix invalidations from extending ==(::Any, ::SomeType) (#408)
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy authored Jun 12, 2020
1 parent 27be397 commit 7d21908
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 116 deletions.
2 changes: 1 addition & 1 deletion bin/generate_builtins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
fva = []
minmin, maxmax = typemax(Int), 0
for fsym in names(Core.Intrinsics)
fsym == :Intrinsics && continue
fsym === :Intrinsics && continue
isdefined(Base, fsym) || continue
f = getfield(Base, fsym)
id = reinterpret(Int32, f) + 1
Expand Down
8 changes: 4 additions & 4 deletions src/breakpoints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ The supported states are:
"""
function break_on(states::Vararg{Symbol})
for state in states
if state == :error
if state === :error
break_on_error[] = true
elseif state == :throw
elseif state === :throw
break_on_throw[] = true
else
throw(ArgumentError(string("unsupported state :", state)))
Expand All @@ -354,9 +354,9 @@ See [`break_on`](@ref) for a description of valid states.
"""
function break_off(states::Vararg{Symbol})
for state in states
if state == :error
if state === :error
break_on_error[] = false
elseif state == :throw
elseif state === :throw
break_on_throw[] = false
else
throw(ArgumentError(string("unsupported state :", state)))
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
if !expand
return Some{Any}(Core._apply_iterate(argswrapped...))
end
@assert argswrapped[1] == Core.iterate || argswrapped[1] === Core.Compiler.iterate || argswrapped[1] == Base.iterate "cannot handle `_apply_iterate` with non iterate as first argument, got $(argswrapped[1]), $(typeof(argswrapped[1]))"
@assert argswrapped[1] === Core.iterate || argswrapped[1] === Core.Compiler.iterate || argswrapped[1] === Base.iterate "cannot handle `_apply_iterate` with non iterate as first argument, got $(argswrapped[1]), $(typeof(argswrapped[1]))"
new_expr = Expr(:call, argswrapped[2])
popfirst!(argswrapped) # pop the iterate
popfirst!(argswrapped) # pop the function
Expand Down
24 changes: 12 additions & 12 deletions src/commands.jl
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ end

function maybe_step_through_nkw_meta!(frame)
stmt = pc_expr(frame)
if stmt === nothing || (isexpr(stmt, :meta) && stmt.args[1] == :nkw)
if stmt === nothing || (isexpr(stmt, :meta) && (stmt::Expr).args[1] === :nkw)
@assert frame.pc == 1
frame.pc += 1
end
Expand Down Expand Up @@ -421,23 +421,23 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::Symbol, rootis
istoplevel = rootistoplevel && frame.caller === nothing
cmd0 = cmd
is_si = false
if cmd == :si
if cmd === :si
stmt = pc_expr(frame)
cmd = is_call(stmt) ? :s : :se
is_si = true
end
try
cmd == :nc && return nicereturn!(recurse, frame, next_call!(recurse, frame, istoplevel), rootistoplevel)
cmd == :n && return maybe_reset_frame!(recurse, frame, next_line!(recurse, frame, istoplevel), rootistoplevel)
cmd == :se && return maybe_reset_frame!(recurse, frame, step_expr!(recurse, frame, istoplevel), rootistoplevel)
cmd == :until && return maybe_reset_frame!(recurse, frame, until_line!(recurse, frame, line, istoplevel), rootistoplevel)
cmd === :nc && return nicereturn!(recurse, frame, next_call!(recurse, frame, istoplevel), rootistoplevel)
cmd === :n && return maybe_reset_frame!(recurse, frame, next_line!(recurse, frame, istoplevel), rootistoplevel)
cmd === :se && return maybe_reset_frame!(recurse, frame, step_expr!(recurse, frame, istoplevel), rootistoplevel)
cmd === :until && return maybe_reset_frame!(recurse, frame, until_line!(recurse, frame, line, istoplevel), rootistoplevel)

enter_generated = false
if cmd == :sg
if cmd === :sg
enter_generated = true
cmd = :s
end
if cmd == :s
if cmd === :s
pc = maybe_next_call!(recurse, frame, istoplevel)
(isa(pc, BreakpointRef) || pc === nothing) && return maybe_reset_frame!(recurse, frame, pc, rootistoplevel)
is_si || maybe_step_through_kwprep!(recurse, frame, istoplevel)
Expand All @@ -456,7 +456,7 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::Symbol, rootis
end
if isa(ret, BreakpointRef)
newframe = leaf(frame)
cmd0 == :si && return newframe, ret
cmd0 === :si && return newframe, ret
is_si || (newframe = maybe_step_through_wrapper!(recurse, newframe))
is_si || maybe_step_through_kwprep!(recurse, newframe, istoplevel)
return newframe, BreakpointRef(newframe.framecode, 0)
Expand All @@ -466,15 +466,15 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::Symbol, rootis
frame.pc += 1
return frame, frame.pc
end
if cmd == :c
if cmd === :c
r = root(frame)
ret = finish_stack!(recurse, r, rootistoplevel)
return isa(ret, BreakpointRef) ? (leaf(r), ret) : nothing
end
cmd == :finish && return maybe_reset_frame!(recurse, frame, finish!(recurse, frame, istoplevel), rootistoplevel)
cmd === :finish && return maybe_reset_frame!(recurse, frame, finish!(recurse, frame, istoplevel), rootistoplevel)
catch err
frame = unwind_exception(frame, err)
if cmd == :c
if cmd === :c
return debug_command(recurse, frame, :c, istoplevel)
else
return debug_command(recurse, frame, :nc, istoplevel)
Expand Down
18 changes: 9 additions & 9 deletions src/construct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ function prepare_framecode(method::Method, @nospecialize(argtypes); enter_genera
code = code::CodeInfo
# Currenly, our strategy to deal with llvmcall can't handle parametric functions
# (the "mini interpreter" runs in module scope, not method scope)
if (!isempty(lenv) && (hasarg(isequal(:llvmcall), code.code) ||
if (!isempty(lenv) && (hasarg(isidentical(:llvmcall), code.code) ||
hasarg(a->is_global_ref(a, Base, :llvmcall), code.code))) ||
hasarg(isequal(:iolock_begin), code.code)
hasarg(isidentical(:iolock_begin), code.code)
return Compiled()
end
framecode = FrameCode(method, code; generator=generator)
Expand Down Expand Up @@ -433,9 +433,9 @@ split_expressions!(modexs, docexprs, mod::Module, ex::Expr; kwargs...) =
function split_expressions!(modexs, docexprs, lex::Expr, mod::Module, ex::Expr; extract_docexprs=false, filename="toplevel")
# lex is the expression we'll lower; it will accumulate LineNumberNodes and a
# single top-level expression. We split blocks, module defs, etc.
if ex.head == :toplevel || ex.head == :block
if ex.head === :toplevel || ex.head === :block
split_expressions!(modexs, docexprs, lex, mod, ex.args; extract_docexprs=extract_docexprs, filename=filename)
elseif ex.head == :module
elseif ex.head === :module
newname = ex.args[2]::Symbol
if isdefined(mod, newname)
newmod = getfield(mod, newname)
Expand Down Expand Up @@ -625,9 +625,9 @@ function extract_args(__module__, ex0)
$args, $kwargs = $separate_kwargs($(ex0.args[2:end]...))
tuple(Core.kwfunc($arg1), $kwargs, $arg1, $args...)
end
elseif ex0.head == :.
elseif ex0.head === :.
return Expr(:tuple, :getproperty, ex0.args...)
elseif ex0.head == :(<:)
elseif ex0.head === :(<:)
return Expr(:tuple, :(<:), ex0.args...)
else
return Expr(:tuple,
Expand All @@ -640,14 +640,14 @@ function extract_args(__module__, ex0)
ex = Meta.lower(__module__, ex0)
if !isa(ex, Expr)
return error("expression is not a function call or symbol")
elseif ex.head == :call
elseif ex.head === :call
return Expr(:tuple,
map(x->isexpr(x, :parameters) ? QuoteNode(x) : x, ex.args)...)
elseif ex.head == :body
elseif ex.head === :body
a1 = ex.args[1]
if isexpr(a1, :call)
a11 = a1.args[1]
if a11 == :setindex!
if a11 === :setindex!
return Expr(:tuple,
map(x->isexpr(x, :parameters) ? QuoteNode(x) : x, arg.args)...)
end
Expand Down
76 changes: 38 additions & 38 deletions src/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ end

function lookup_expr(frame, e::Expr)
head = e.head
head == :the_exception && return frame.framedata.last_exception[]
if head == :static_parameter
head === :the_exception && return frame.framedata.last_exception[]
if head === :static_parameter
arg = e.args[1]::Int
if isassigned(frame.framedata.sparams, arg)
return frame.framedata.sparams[arg]
Expand All @@ -21,7 +21,7 @@ function lookup_expr(frame, e::Expr)
throw(UndefVarError(syms[arg]))
end
end
head == :boundscheck && length(e.args) == 0 && return true
head === :boundscheck && length(e.args) == 0 && return true
error("invalid lookup expr ", e)
end

Expand Down Expand Up @@ -86,7 +86,7 @@ function lookup_or_eval(@nospecialize(recurse), frame, @nospecialize(node))
for arg in node.args
push!(ex.args, lookup_or_eval(recurse, frame, arg))
end
if ex.head == :call
if ex.head === :call
f = ex.args[1]
if f === Core.svec
return Core.svec(ex.args[2:end]...)
Expand Down Expand Up @@ -124,9 +124,9 @@ function resolvefc(frame, @nospecialize(expr))
isa(expr, Tuple{Symbol,String}) && return expr
isa(expr, Tuple{String,Symbol}) && return expr
if isexpr(expr, :call)
a = expr.args[1]
(isa(a, QuoteNode) && a.value == Core.tuple) || error("unexpected ccall to ", expr)
return Expr(:call, GlobalRef(Core, :tuple), expr.args[2:end]...)
a = (expr::Expr).args[1]
(isa(a, QuoteNode) && a.value === Core.tuple) || error("unexpected ccall to ", expr)
return Expr(:call, GlobalRef(Core, :tuple), (expr::Expr).args[2:end]...)
end
error("unexpected ccall to ", expr)
end
Expand Down Expand Up @@ -154,7 +154,7 @@ function evaluate_foreigncall(frame::Frame, call_expr::Expr)
arg = args[i]
args[i] = isa(arg, Symbol) ? QuoteNode(arg) : arg
end
head == :cfunction && (args[2] = QuoteNode(args[2]))
head === :cfunction && (args[2] = QuoteNode(args[2]))
scope = frame.framecode.scope
data = frame.framedata
if !isempty(data.sparams) && scope isa Method
Expand Down Expand Up @@ -369,35 +369,35 @@ maybe_assign!(frame, @nospecialize(val)) = maybe_assign!(frame, pc_expr(frame),

function eval_rhs(@nospecialize(recurse), frame, node::Expr)
head = node.head
if head == :new
if head === :new
mod = moduleof(frame)
args = [@lookup(mod, frame, arg) for arg in node.args]
T = popfirst!(args)
rhs = ccall(:jl_new_structv, Any, (Any, Ptr{Any}, UInt32), T, args, length(args))
return rhs
elseif head == :splatnew # Julia 1.2+
elseif head === :splatnew # Julia 1.2+
mod = moduleof(frame)
rhs = ccall(:jl_new_structt, Any, (Any, Any), @lookup(mod, frame, node.args[1]), @lookup(mod, frame, node.args[2]))
return rhs
elseif head == :isdefined
elseif head === :isdefined
return check_isdefined(frame, node.args[1])
elseif head == :call
elseif head === :call
# here it's crucial to avoid dynamic dispatch
isa(recurse, Compiled) && return evaluate_call_compiled!(recurse, frame, node)
return evaluate_call_recurse!(recurse, frame, node)
elseif head == :foreigncall || head == :cfunction
elseif head === :foreigncall || head === :cfunction
return evaluate_foreigncall(frame, node)
elseif head == :copyast
elseif head === :copyast
val = (node.args[1]::QuoteNode).value
return isa(val, Expr) ? copy(val) : val
elseif head == :enter
elseif head === :enter
return length(frame.framedata.exception_frames)
elseif head == :boundscheck
elseif head === :boundscheck
return true
elseif head == :meta || head == :inbounds || head == (@static VERSION >= v"1.2.0-DEV.462" ? :loopinfo : :simdloop) ||
head == :gc_preserve_begin || head == :gc_preserve_end
elseif head === :meta || head === :inbounds || head == (@static VERSION >= v"1.2.0-DEV.462" ? :loopinfo : :simdloop) ||
head === :gc_preserve_begin || head === :gc_preserve_end
return nothing
elseif head == :method && length(node.args) == 1
elseif head === :method && length(node.args) == 1
return evaluate_methoddef(frame, node)
end
return lookup_expr(frame, node)
Expand Down Expand Up @@ -437,7 +437,7 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
# _location[location_key] = get(_location, location_key, 0) + 1
try
if isa(node, Expr)
if node.head == :(=)
if node.head === :(=)
lhs, rhs = node.args
if isa(rhs, Expr)
rhs = eval_rhs(recurse, frame, rhs)
Expand All @@ -446,40 +446,40 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
end
isa(rhs, BreakpointRef) && return rhs
do_assignment!(frame, lhs, rhs)
elseif node.head == :gotoifnot
elseif node.head === :gotoifnot
arg = @lookup(frame, node.args[1])
if !isa(arg, Bool)
throw(TypeError(nameof(frame), "if", Bool, node.args[1]))
end
if !arg
return (frame.pc = node.args[2]::Int)
end
elseif node.head == :enter
elseif node.head === :enter
rhs = node.args[1]
push!(data.exception_frames, rhs)
elseif node.head == :leave
elseif node.head === :leave
for _ = 1:node.args[1]
pop!(data.exception_frames)
end
elseif node.head == :pop_exception
elseif node.head === :pop_exception
n = lookup_var(frame, node.args[1])
deleteat!(data.exception_frames, n+1:length(data.exception_frames))
elseif node.head == :return
elseif node.head === :return
return nothing
elseif istoplevel
if node.head == :method && length(node.args) > 1
if node.head === :method && length(node.args) > 1
evaluate_methoddef(frame, node)
elseif node.head == :struct_type
elseif node.head === :struct_type
evaluate_structtype(recurse, frame, node)
elseif node.head == :abstract_type
elseif node.head === :abstract_type
evaluate_abstracttype(recurse, frame, node)
elseif node.head == :primitive_type
elseif node.head === :primitive_type
evaluate_primitivetype(recurse, frame, node)
elseif node.head == :module
elseif node.head === :module
error("this should have been handled by split_expressions")
elseif node.head == :using || node.head == :import || node.head == :export
elseif node.head === :using || node.head === :import || node.head === :export
Core.eval(moduleof(frame), node)
elseif node.head == :const
elseif node.head === :const
g = node.args[1]
if isa(g, GlobalRef)
mod, name = g.module, g.name
Expand All @@ -489,7 +489,7 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
if VERSION >= v"1.2.0-DEV.239" # depends on https://github.com/JuliaLang/julia/pull/30893
Core.eval(mod, Expr(:const, name))
end
elseif node.head == :thunk
elseif node.head === :thunk
newframe = prepare_thunk(moduleof(frame), node)
if isa(recurse, Compiled)
finish!(recurse, newframe, true)
Expand All @@ -500,9 +500,9 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
frame.callee = nothing
end
return_from(newframe)
elseif node.head == :global
elseif node.head === :global
Core.eval(moduleof(frame), node)
elseif node.head == :toplevel
elseif node.head === :toplevel
mod = moduleof(frame)
modexs, _ = split_expressions(mod, node)
rhs = Core.eval(mod, Expr(:toplevel,
Expand All @@ -514,14 +514,14 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
end
$return_from(newframe)
end)))
elseif node.head == :error
elseif node.head === :error
error("unexpected error statement ", node)
elseif node.head == :incomplete
elseif node.head === :incomplete
error("incomplete statement ", node)
else
rhs = eval_rhs(recurse, frame, node)
end
elseif node.head == :thunk || node.head == :toplevel
elseif node.head === :thunk || node.head === :toplevel
error("this frame needs to be run at top level")
else
rhs = eval_rhs(recurse, frame, node)
Expand Down
Loading

0 comments on commit 7d21908

Please sign in to comment.