Skip to content

Commit 4cc3685

Browse files
committed
Fix error-handling and get tests passing
1 parent c48dcd4 commit 4cc3685

File tree

3 files changed

+29
-25
lines changed

3 files changed

+29
-25
lines changed

src/commands.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ function finish_stack!(@nospecialize(recurse), frame::Frame, istoplevel::Bool=fa
6060
recycle(frame)
6161
frame = caller(frame)
6262
frame === nothing && return ret
63+
frame.callee = nothing
6364
pc = frame.pc
6465
if isassign(frame, pc)
6566
lhs = getlhs(pc)
@@ -69,16 +70,16 @@ function finish_stack!(@nospecialize(recurse), frame::Frame, istoplevel::Bool=fa
6970
frame.pc = pc
7071
shouldbreak(frame) && return BreakpointRef(frame.framecode, pc)
7172
end
72-
return frame
7373
end
7474
finish_stack!(frame::Frame, istoplevel::Bool=false) = finish_stack!(finish_and_return!, frame, istoplevel)
7575

7676
"""
77-
next_until!(predicate, recurse, frame, istoplevel=false)
78-
next_until!(predicate, frame, istoplevel=false)
77+
pc = next_until!(predicate, recurse, frame, istoplevel=false)
78+
pc = next_until!(predicate, frame, istoplevel=false)
7979
8080
Execute the current statement. Then step through statements of `frame` until the next
81-
statement satifies `predicate(stmt)`.
81+
statement satifies `predicate(stmt)`. `pc` will be the index of the statement at which
82+
evaluation terminates, `nothing` (if the frame reached a `return`), or a `BreakpointRef`.
8283
"""
8384
function next_until!(@nospecialize(predicate), @nospecialize(recurse), frame::Frame, istoplevel::Bool=false)
8485
pc = step_expr!(recurse, frame, istoplevel)

src/interpret.jl

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,7 @@ function evaluate_call!(@nospecialize(recurse::Function), frame::Frame, call_exp
208208
end
209209
newframe = prepare_frame(frame, framecode, fargs, lenv)
210210
shouldbreak(newframe) && return BreakpointRef(newframe.framecode, newframe.pc)
211-
ret = try
212-
recurse(recurse, newframe)
213-
catch e
214-
frame.callee == nothing
215-
recycle(newframe)
216-
rethrow(e)
217-
end
211+
ret = recurse(recurse, newframe) # if this errors, handle_err will pop the stack and recycle newframe
218212
isa(ret, BreakpointRef) && return ret
219213
frame.callee = nothing
220214
recycle(newframe)
@@ -358,6 +352,10 @@ end
358352

359353
function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplevel::Bool)
360354
pc, code, data = frame.pc, frame.framecode, frame.framedata
355+
if !is_leaf(frame)
356+
show_stackloc(frame)
357+
@show node
358+
end
361359
@assert is_leaf(frame)
362360
local rhs
363361
# show_stackloc(frame)
@@ -525,19 +523,24 @@ function handle_err(@nospecialize(recurse), frame, err)
525523
return BreakpointRef(frame.framecode, frame.pc, err)
526524
end
527525
end
528-
# Check for world age errors, which generally indicate a failure to go back to toplevel
529-
if isa(err, MethodError)
530-
is_arg_types = isa(err.args, DataType)
531-
arg_types = is_arg_types ? err.args : Base.typesof(err.args...)
532-
if (err.world != typemax(UInt) &&
533-
hasmethod(err.f, arg_types) &&
534-
!hasmethod(err.f, arg_types, world = err.world))
535-
@warn "likely failure to return to toplevel, try JuliaInterpreter.split_expressions"
536-
rethrow(err)
526+
data = frame.framedata
527+
if isempty(data.exception_frames)
528+
if frame.caller !== nothing
529+
frame.caller.callee = nothing
530+
recycle(frame)
537531
end
532+
# Check for world age errors, which generally indicate a failure to go back to toplevel
533+
if isa(err, MethodError)
534+
is_arg_types = isa(err.args, DataType)
535+
arg_types = is_arg_types ? err.args : Base.typesof(err.args...)
536+
if (err.world != typemax(UInt) &&
537+
hasmethod(err.f, arg_types) &&
538+
!hasmethod(err.f, arg_types, world = err.world))
539+
@warn "likely failure to return to toplevel, try JuliaInterpreter.split_expressions"
540+
end
541+
end
542+
rethrow(err)
538543
end
539-
data = frame.framedata
540-
isempty(data.exception_frames) && rethrow(err)
541544
data.last_exception[] = err
542545
return (frame.pc = data.exception_frames[end])
543546
end

src/types.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ struct Unassigned end
226226
A reference to a breakpoint at a particular statement index `stmtidx` in `framecode`.
227227
If the break was due to an error, supply that as well.
228228
229-
Commands that execute complex control-flow may also return a `BreakpointRef` to indicate
230-
that the execution stack switched frames, even when no breakpoint has been set at the
231-
corresponding statement.
229+
Commands that execute complex control-flow (e.g., `next_line!`) may also return a
230+
`BreakpointRef` to indicate that the execution stack switched frames, even when no
231+
breakpoint has been set at the corresponding statement.
232232
"""
233233
struct BreakpointRef
234234
framecode::FrameCode

0 commit comments

Comments
 (0)