Skip to content

Commit 07595d1

Browse files
committed
adjustments to v1.12
There have been changes to type definitions and global variable assignments to v1.12, and this commit tries to adjust the code base to it. There might be some missing pieces still, this allow us to reduce the failures in the test suite.
1 parent c7d1b30 commit 07595d1

File tree

3 files changed

+51
-28
lines changed

3 files changed

+51
-28
lines changed

src/codeedges.jl

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ function postprint_linelinks(io::IO, idx::Int, src::CodeInfo, cl::CodeLinks, bbc
163163
printstyled(io, bbchanged ? " " : "", color=:light_black)
164164
printstyled(io, " # ", color=:yellow)
165165
stmt = src.code[idx]
166-
if is_assignment_like(stmt)
167-
lhs = normalize_defsig(stmt.args[1], cl.thismod)
166+
lhs_rhs = get_lhs_rhs(stmt)
167+
if lhs_rhs !== nothing
168+
lhs, _ = lhs_rhs
169+
lhs = normalize_defsig(lhs, cl.thismod)
168170
if @issslotnum(lhs)
169171
# id = lhs.id
170172
# preds, succs = cl.slotpreds[id], cl.slotsuccs[id]
@@ -190,8 +192,27 @@ function namedkeys(cl::CodeLinks)
190192
return ukeys
191193
end
192194

193-
is_assignment_like(stmt::Expr) = isexpr(stmt, :(=)) || (isexpr(stmt, :const) && length(stmt.args) == 2)
194-
is_assignment_like(@nospecialize stmt) = false
195+
function get_lhs_rhs(@nospecialize stmt)
196+
if isexpr(stmt, :(=))
197+
return Pair{Any,Any}(stmt.args[1], stmt.args[2])
198+
elseif isexpr(stmt, :const) && length(stmt.args) == 2
199+
return Pair{Any,Any}(stmt.args[1], stmt.args[2])
200+
elseif isexpr(stmt, :call) && length(stmt.args) == 4
201+
f = stmt.args[1]
202+
if isa(f, GlobalRef) && f.name === :setglobal!
203+
mod = stmt.args[2]
204+
mod isa Module || return nothing
205+
name = stmt.args[3]
206+
if name isa QuoteNode
207+
name = name.value
208+
end
209+
name isa Symbol || return nothing
210+
lhs = GlobalRef(mod, name)
211+
return Pair{Any,Any}(lhs, stmt.args[4])
212+
end
213+
end
214+
return nothing
215+
end
195216

196217
function direct_links!(cl::CodeLinks, src::CodeInfo)
197218
# Utility for when a stmt itself contains a CodeInfo
@@ -247,10 +268,10 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
247268
end
248269
rhs = stmt
249270
target = P(SSAValue(i), cl.ssapreds[i])
250-
elseif is_assignment_like(stmt)
271+
elseif (lhs_rhs = get_lhs_rhs(stmt); lhs_rhs !== nothing)
251272
# An assignment
252273
stmt = stmt::Expr
253-
lhs, rhs = stmt.args[1], stmt.args[2]
274+
lhs, rhs = lhs_rhs
254275
if @issslotnum(lhs)
255276
lhs = lhs::AnySlotNumber
256277
id = lhs.id
@@ -423,9 +444,9 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
423444
emptylist = Int[]
424445
for (i, stmt) in enumerate(src.code)
425446
# Identify line predecents for slots and named variables
426-
if is_assignment_like(stmt)
447+
if (lhs_rhs = get_lhs_rhs(stmt); lhs_rhs !== nothing)
427448
stmt = stmt::Expr
428-
lhs = stmt.args[1]
449+
lhs, _ = lhs_rhs
429450
# Mark predecessors and successors of this line by following ssas & named assignments
430451
if @issslotnum(lhs)
431452
lhs = lhs::AnySlotNumber
@@ -611,7 +632,7 @@ function exclude_named_typedefs(src::CodeInfo, edges::CodeEdges)
611632
i = 1
612633
nstmts = length(src.code)
613634
while i <= nstmts
614-
stmt = rhs(src.code[i])
635+
stmt = getrhs(src.code[i])
615636
if istypedef(stmt) && !isanonymous_typedef(stmt::Expr)
616637
r = typedef_range(src, i)
617638
pushall!(norequire, r)
@@ -871,7 +892,7 @@ function find_typedefs(src::CodeInfo)
871892
i = 1
872893
nstmts = length(src.code)
873894
while i <= nstmts
874-
stmt = rhs(src.code[i])
895+
stmt = getrhs(src.code[i])
875896
if istypedef(stmt) && !isanonymous_typedef(stmt::Expr)
876897
stmt = stmt::Expr
877898
r = typedef_range(src, i)
@@ -972,8 +993,8 @@ function add_inplace!(isrequired, src, edges, norequire)
972993
for k in edges.preds[j]
973994
isrequired[k] || continue
974995
predstmt = src.code[k]
975-
if is_assignment_like(predstmt)
976-
lhs = predstmt.args[1]
996+
if (lhs_rhs = get_lhs_rhs(predstmt); lhs_rhs !== nothing)
997+
lhs, _ = lhs_rhs
977998
if @issslotnum(lhs) && lhs.id == id
978999
changed |= mark_if_inplace(stmt, j)
9791000
break

src/utils.jl

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ function callee_matches(f, mod, sym)
5858
return false
5959
end
6060

61-
function rhs(stmt)
62-
is_assignment_like(stmt) && return (stmt::Expr).args[2]
63-
return stmt
61+
function getrhs(@nospecialize(stmt))
62+
lhs_rhs = get_lhs_rhs(stmt)
63+
return lhs_rhs === nothing ? stmt : lhs_rhs[2]
6464
end
6565

6666
ismethod(frame::Frame) = ismethod(pc_expr(frame))
@@ -107,7 +107,7 @@ function ismethod_with_name(src, stmt, target::AbstractString; reentrant::Bool=f
107107
end
108108

109109
# anonymous function types are defined in a :thunk expr with a characteristic CodeInfo
110-
function isanonymous_typedef(stmt)
110+
function isanonymous_typedef(@nospecialize stmt)
111111
if isa(stmt, Expr)
112112
stmt.head === :thunk || return false
113113
stmt = stmt.args[1]
@@ -119,21 +119,22 @@ function isanonymous_typedef(stmt)
119119
isexpr(stmt, :call) || return false
120120
is_global_ref(stmt.args[1], Core, :_typebody!) || return false
121121
stmt = isa(stmt.args[3], Core.SSAValue) ? src.code[end-3] : src.code[end-2]
122-
is_assignment_like(stmt) || return false
123-
name = stmt.args[1]
124-
if isa(name, GlobalRef)
125-
name = name.name
122+
lhs_rhs = get_lhs_rhs(stmt)
123+
lhs_rhs === nothing && return false
124+
lhs, _ = lhs_rhs
125+
if isa(lhs, GlobalRef)
126+
lhs = lhs.name
126127
else
127-
isa(name, Symbol) || return false
128+
isa(lhs, Symbol) || return false
128129
end
129-
return startswith(String(name), "#")
130+
return startswith(String(lhs), "#")
130131
end
131132
return false
132133
end
133134

134135
function istypedef(stmt)
135136
isa(stmt, Expr) || return false
136-
stmt = rhs(stmt)
137+
stmt = getrhs(stmt)
137138
isa(stmt, Expr) || return false
138139
@static if all(s->isdefined(Core,s), structdecls)
139140
if stmt.head === :call
@@ -162,6 +163,7 @@ function typedef_range(src::CodeInfo, idx)
162163
istart = idx
163164
while istart >= 1
164165
isexpr(src.code[istart], :global) && break
166+
isexpr(src.code[istart], :latestworld) && break
165167
istart -= 1
166168
end
167169
istart >= 1 || error("no initial :global found")
@@ -171,6 +173,7 @@ function typedef_range(src::CodeInfo, idx)
171173
stmt = src.code[iend]
172174
if isa(stmt, Expr)
173175
stmt.head === :global && break
176+
stmt.head === :latestworld && break
174177
if stmt.head === :call
175178
if (is_global_ref(stmt.args[1], Core, :_typebody!) || is_quotenode_egal(stmt.args[1], Core._typebody!))
176179
have_typebody = true
@@ -179,7 +182,7 @@ function typedef_range(src::CodeInfo, idx)
179182
# Advance to the type-assignment
180183
while iend <= n
181184
stmt = src.code[iend]
182-
is_assignment_like(stmt) && break
185+
get_lhs_rhs(stmt) !== nothing && break
183186
iend += 1
184187
end
185188
end

test/codeedges.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,8 @@ module ModSelective end
414414
end
415415

416416
@testset "selective interpretation of toplevel definitions" begin
417-
gen_mock_module() = Core.eval(@__MODULE__, :(module $(gensym(:LoweredCodeUtilsTestMock)) end))
418417
function check_toplevel_definition_interprete(ex, defs, undefs)
419-
m = gen_mock_module()
418+
m = Module(:LoweredCodeUtilsTestMock)
420419
lwr = Meta.lower(m, ex)
421420
src = first(lwr.args)
422421
stmts = src.code
@@ -426,8 +425,8 @@ end
426425
frame = Frame(m, src)
427426
selective_eval_fromstart!(frame, isrq, #=toplevel=#true)
428427

429-
for def in defs; @test isdefined(m, def); end
430-
for undef in undefs; @test !isdefined(m, undef); end
428+
for def in defs; @test @invokelatest(isdefined(m, def)); end
429+
for undef in undefs; @test !@invokelatest(isdefined(m, undef)); end
431430
end
432431

433432
@testset "case: $(i), interpret: $(defs), ignore $(undefs)" for (i, ex, defs, undefs) in (

0 commit comments

Comments
 (0)