@@ -11,17 +11,22 @@ function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int
11
11
nargs = length (fargs) # includes f as the first "argument"
12
12
# Determine whether we can look up the appropriate framecode in the local method table
13
13
if isassigned (parentframe. methodtables, idx) # if this is the first call, this may not yet be set
14
- tme = tme1 = parentframe. methodtables[idx]:: TypeMapEntry
15
- local tmeprev
14
+ # The case where `methodtables[idx]` is a `Compiled` has already been handled in `bypass_builtins`
15
+ d_meth = d_meth1 = parentframe. methodtables[idx]:: DispatchableMethod
16
+ local d_methprev
16
17
depth = 1
17
18
while true
18
19
# TODO : consider using world age bounds to handle cache invalidation
19
20
# Determine whether the argument types match the signature
20
- sig = tme . sig. parameters:: SimpleVector
21
+ sig = d_meth . sig. parameters:: SimpleVector
21
22
if length (sig) == nargs
22
23
# If this is generated, match only if `enter_generated` also matches
23
- mi = tme. func:: FrameInstance
24
- matches = ! is_generated (scopeof (mi. framecode)) || enter_generated == mi. enter_generated
24
+ fi = d_meth. frameinstance
25
+ if fi isa FrameInstance
26
+ matches = ! is_generated (scopeof (fi. framecode)) || enter_generated == fi. enter_generated
27
+ else
28
+ matches = ! enter_generated
29
+ end
25
30
if matches
26
31
for i = 1 : nargs
27
32
if ! isa (fargs[i], sig[i])
@@ -34,54 +39,59 @@ function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int
34
39
# Rearrange the list to place this method first
35
40
# (if we're in a loop, we'll likely match this one again on the next iteration)
36
41
if depth > 1
37
- parentframe. methodtables[idx] = tme
38
- tmeprev. next = tme. next
39
- tme. next = tme1
42
+ parentframe. methodtables[idx] = d_meth
43
+ d_methprev. next = d_meth. next
44
+ d_meth. next = d_meth1
45
+ end
46
+ if fi isa Compiled
47
+ return Compiled (), nothing
48
+ else
49
+ fi = fi:: FrameInstance
50
+ return fi. framecode, fi. sparam_vals
40
51
end
41
- return mi. framecode, mi. sparam_vals
42
52
end
43
53
end
44
54
depth += 1
45
- tmeprev = tme
46
- tme = tme . next
47
- tme === nothing && break
48
- tme = tme :: TypeMapEntry
55
+ d_methprev = d_meth
56
+ d_meth = d_meth . next
57
+ d_meth === nothing && break
58
+ d_meth = d_meth :: DispatchableMethod
49
59
end
50
60
end
51
61
# We haven't yet encountered this argtype combination and need to look it up by dispatch
52
62
fargs[1 ] = f = to_function (fargs[1 ])
53
63
ret = prepare_call (f, fargs; enter_generated= enter_generated)
54
64
ret === nothing && return f (fargs[2 : end ]. .. ), nothing
55
- isa (ret, Compiled) && return ret, nothing
56
- framecode, args, env, argtypes = ret
57
- # Store the results of the method lookup in the local method table
58
- mi = FrameInstance (framecode, env, is_generated (scopeof (framecode)) & enter_generated)
59
- # it's sort of odd to call this a TypeMapEntry, then set most of the fields incorrectly
60
- # but since we're just using it as a linked list, it's probably ok
61
- tme = ccall (:jl_new_struct_uninit , Any, (Any,), TypeMapEntry):: TypeMapEntry
62
- tme. func = mi
63
- tme. simplesig = nothing
64
- tme. sig = argtypes
65
- tme. isleafsig = true
66
- tme. issimplesig = false
67
- method = framecode. scope:: Method
68
- tme. va = method. isva
65
+ is_compiled = isa (ret[1 ], Compiled)
66
+ local framecode
67
+ if is_compiled
68
+ d_meth = DispatchableMethod (nothing , Compiled (), ret[2 ])
69
+ else
70
+ framecode, args, env, argtypes = ret
71
+ # Store the results of the method lookup in the local method table
72
+ fi = FrameInstance (framecode, env, is_generated (scopeof (framecode)) && enter_generated)
73
+ d_meth = DispatchableMethod (nothing , fi, argtypes)
74
+ end
69
75
if isassigned (parentframe. methodtables, idx)
70
- tme . next = parentframe. methodtables[idx]
71
- # Drop the oldest tme , if necessary
72
- tmetmp = tme . next
76
+ d_meth . next = parentframe. methodtables[idx]
77
+ # Drop the oldest d_meth , if necessary
78
+ d_methtmp = d_meth . next
73
79
depth = 2
74
- while isdefined (tmetmp, :next ) && tmetmp . next != = nothing
80
+ while d_methtmp . next != = nothing
75
81
depth += 1
76
- tmetmp = tmetmp . next
82
+ d_methtmp = d_methtmp . next
77
83
depth >= max_methods && break
78
84
end
79
85
if depth >= max_methods
80
- tmetmp . next = nothing
86
+ d_methtmp . next = nothing
81
87
end
82
88
else
83
- tme. next = nothing
89
+ d_meth. next = nothing
90
+ end
91
+ parentframe. methodtables[idx] = d_meth
92
+ if is_compiled
93
+ return Compiled (), nothing
94
+ else
95
+ return framecode, env
84
96
end
85
- parentframe. methodtables[idx] = tme
86
- return framecode, env
87
97
end
0 commit comments