@@ -363,7 +363,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
363363 while true
364364 pc0 = pc
365365 while ! ismethod3 (stmt)
366- pc = next_or_nothing (frame, pc)
366+ pc = next_or_nothing (recurse, frame, pc)
367367 pc === nothing && return nothing
368368 stmt = pc_expr (frame, pc)
369369 end
@@ -381,7 +381,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
381381 iscallto (bodystmt, moduleof (frame), name, body) && return signature_top (frame, stmt, pc), false
382382 end
383383 end
384- pc = next_or_nothing (frame, pc)
384+ pc = next_or_nothing (recurse, frame, pc)
385385 pc === nothing && return nothing
386386 stmt = pc_expr (frame, pc)
387387 end
@@ -427,7 +427,7 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
427427 nameinfo = find_name_caller_sig (recurse, frame, pc, name, parentname)
428428 if nameinfo === nothing
429429 pc = skip_until (@nospecialize (stmt)-> isexpr (stmt, :method , 3 ), frame, pc)
430- pc = next_or_nothing (frame, pc)
430+ pc = next_or_nothing (recurse, frame, pc)
431431 return name, pc, nothing
432432 end
433433 pctop, isgen = nameinfo
@@ -461,6 +461,52 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
461461 return cname, pc, lastpcparent
462462end
463463
464+ """
465+ nextpc = next_or_nothing([recurse], frame, pc)
466+ nextpc = next_or_nothing!([recurse], frame)
467+
468+ Advance the program counter without executing the corresponding line.
469+ If `frame` is finished, `nextpc` will be `nothing`.
470+ """
471+ next_or_nothing (frame, pc) = next_or_nothing (finish_and_return!, frame, pc)
472+ next_or_nothing (@nospecialize (recurse), frame, pc) = pc < nstatements (frame. framecode) ? pc+ 1 : nothing
473+ next_or_nothing! (frame) = next_or_nothing! (finish_and_return!, frame)
474+ function next_or_nothing! (@nospecialize (recurse), frame)
475+ pc = frame. pc
476+ if pc < nstatements (frame. framecode)
477+ return frame. pc = pc + 1
478+ end
479+ return nothing
480+ end
481+
482+ """
483+ nextpc = skip_until(predicate, [recurse], frame, pc)
484+ nextpc = skip_until!(predicate, [recurse], frame)
485+
486+ Advance the program counter until `predicate(stmt)` return `true`.
487+ """
488+ skip_until (predicate, frame, pc) = skip_until (predicate, finish_and_return!, frame, pc)
489+ function skip_until (predicate, @nospecialize (recurse), frame, pc)
490+ stmt = pc_expr (frame, pc)
491+ while ! predicate (stmt)
492+ pc = next_or_nothing (recurse, frame, pc)
493+ pc === nothing && return nothing
494+ stmt = pc_expr (frame, pc)
495+ end
496+ return pc
497+ end
498+ skip_until! (predicate, frame) = skip_until! (predicate, finish_and_return!, frame)
499+ function skip_until! (predicate, @nospecialize (recurse), frame)
500+ pc = frame. pc
501+ stmt = pc_expr (frame, pc)
502+ while ! predicate (stmt)
503+ pc = next_or_nothing! (recurse, frame)
504+ pc === nothing && return nothing
505+ stmt = pc_expr (frame, pc)
506+ end
507+ return pc
508+ end
509+
464510"""
465511 ret = methoddef!(recurse, signatures, frame; define=true)
466512 ret = methoddef!(signatures, frame; define=true)
@@ -549,14 +595,14 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
549595 sigt, pc = signature (recurse, frame, stmt, pc)
550596 stmt = pc_expr (frame, pc)
551597 while ! isexpr (stmt, :method , 3 )
552- pc = next_or_nothing (frame, pc) # this should not check define, we've probably already done this once
598+ pc = next_or_nothing (recurse, frame, pc) # this should not check define, we've probably already done this once
553599 pc === nothing && return nothing # this was just `function foo end`, signal "no def"
554600 stmt = pc_expr (frame, pc)
555601 end
556602 pc3 = pc
557603 stmt = stmt:: Expr
558604 name3 = normalize_defsig (stmt. args[1 ], frame)
559- sigt === nothing && (error (" expected a signature" ); return next_or_nothing (frame, pc)), pc3
605+ sigt === nothing && (error (" expected a signature" ); return next_or_nothing (recurse, frame, pc)), pc3
560606 # Methods like f(x::Ref{<:Real}) that use gensymmed typevars will not have the *exact*
561607 # signature of the active method. So let's get the active signature.
562608 frame. pc = pc
0 commit comments