Skip to content

Commit a658ea0

Browse files
committed
Add a few more arg annotations to ensure singleton methods
This is to avoid dynamic dispatch
1 parent 57a083b commit a658ea0

File tree

3 files changed

+18
-17
lines changed

3 files changed

+18
-17
lines changed

src/commands.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ In the latter case, `leaf(frame)` returns the frame in which it hit the breakpoi
1010
by normal dispatch, whereas the default `recurse = finish_and_return!` uses recursive interpretation.
1111
"""
1212
function finish!(@nospecialize(recurse), frame::Frame, istoplevel::Bool=false)
13-
local pc
1413
while true
1514
pc = step_expr!(recurse, frame, istoplevel)
1615
(pc === nothing || isa(pc, BreakpointRef)) && return pc

src/interpret.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,8 @@ function handle_err(@nospecialize(recurse), frame, err)
520520
# See if the current frame or a frame in the stack will catch this exception,
521521
# otherwise this exception would have been thrown to the user and we should
522522
# return a breakpoint
523+
# Note: this is potentially O(N^2) in the stack depth. Consider storing `exception_caught`
524+
# in the caller frames.
523525
exception_caught = false
524526
fr = frame
525527
while fr !== nothing

src/utils.jl

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
# Note: to avoid dynamic dispatch, many of these are coded as a single method using isa statements
44

5-
function scopeof(x)::Union{Method,Module}
5+
function scopeof(@nospecialize(x))::Union{Method,Module}
66
(isa(x, Method) || isa(x, Module)) && return x
77
isa(x, FrameCode) && return x.scope
88
isa(x, Frame) && return x.framecode.scope
99
error("unknown scope for ", x)
1010
end
1111

12-
function moduleof(x)
12+
function moduleof(@nospecialize(x))
1313
s = scopeof(x)
1414
return isa(s, Module) ? s : s.module
1515
end
@@ -21,11 +21,11 @@ end
2121

2222
_Typeof(x) = isa(x,Type) ? Type{x} : typeof(x)
2323

24-
function to_function(x)
24+
function to_function(@nospecialize(x))
2525
isa(x, GlobalRef) ? getfield(x.mod, x.name) : x
2626
end
2727

28-
function whichtt(tt)
28+
function whichtt(@nospecialize(tt))
2929
m = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), tt, typemax(UInt))
3030
m === nothing && return nothing
3131
return m.func::Method
@@ -48,8 +48,8 @@ separate_kwargs(args...; kwargs...) = (args, kwargs.data)
4848

4949
pc_expr(src::CodeInfo, pc) = src.code[pc]
5050
pc_expr(framecode::FrameCode, pc) = pc_expr(framecode.src, pc)
51-
pc_expr(frame, pc) = pc_expr(frame.framecode, pc)
52-
pc_expr(frame) = pc_expr(frame, frame.pc)
51+
pc_expr(frame::Frame, pc) = pc_expr(frame.framecode, pc)
52+
pc_expr(frame::Frame) = pc_expr(frame, frame.pc)
5353

5454
function find_used(code::CodeInfo)
5555
used = BitSet()
@@ -67,41 +67,41 @@ end
6767

6868
## Predicates
6969

70-
is_goto_node(node) = isa(node, GotoNode) || isexpr(node, :gotoifnot)
70+
is_goto_node(@nospecialize(node)) = isa(node, GotoNode) || isexpr(node, :gotoifnot)
7171

72-
is_loc_meta(expr, kind) = isexpr(expr, :meta) && length(expr.args) >= 1 && expr.args[1] === kind
72+
is_loc_meta(@nospecialize(expr), @nospecialize(kind)) = isexpr(expr, :meta) && length(expr.args) >= 1 && expr.args[1] === kind
7373

7474
"""
7575
is_global_ref(g, mod, name)
7676
7777
Tests whether `g` is equal to `GlobalRef(mod, name)`.
7878
"""
79-
is_global_ref(g, mod, name) = isa(g, GlobalRef) && g.mod === mod && g.name == name
79+
is_global_ref(@nospecialize(g), mod::Module, name::Symbol) = isa(g, GlobalRef) && g.mod === mod && g.name == name
8080

81-
function is_function_def(ex)
81+
function is_function_def(@nospecialize(ex))
8282
(isexpr(ex, :(=)) && isexpr(ex.args[1], :call)) ||
8383
isexpr(ex,:function)
8484
end
8585

86-
function is_call(node)
86+
function is_call(@nospecialize(node))
8787
isexpr(node, :call) ||
8888
(isexpr(node, :(=)) && (isexpr(node.args[2], :call)))
8989
end
9090

91-
is_call_or_return(node) = is_call(node) || isexpr(node, :return)
91+
is_call_or_return(@nospecialize(node)) = is_call(node) || isexpr(node, :return)
9292

9393
is_dummy(bpref::BreakpointRef) = bpref.stmtidx == 0 && bpref.err === nothing
9494

9595
"""
9696
Determine whether we are calling a function for which the current function
9797
is a wrapper (either because of optional arguments or because of keyword arguments).
9898
"""
99-
function is_wrapper_call(expr)
99+
function is_wrapper_call(@nospecialize(expr))
100100
isexpr(expr, :(=)) && (expr = expr.args[2])
101101
isexpr(expr, :call) && any(x->x==SlotNumber(1), expr.args)
102102
end
103103

104-
function is_generated(meth)
104+
function is_generated(meth::Method)
105105
isdefined(meth, :generator)
106106
end
107107

@@ -110,7 +110,7 @@ end
110110
111111
Test whether expression `ex` is a `@doc` expression.
112112
"""
113-
function is_doc_expr(ex)
113+
function is_doc_expr(@nospecialize(ex))
114114
docsym = Symbol("@doc")
115115
if isexpr(ex, :macrocall)
116116
a = ex.args[1]
@@ -124,7 +124,7 @@ function is_doc_expr(ex)
124124
return false
125125
end
126126

127-
is_leaf(frame) = frame.callee === nothing
127+
is_leaf(frame::Frame) = frame.callee === nothing
128128

129129
## Location info
130130

0 commit comments

Comments
 (0)