Skip to content

Commit 1b1b6d6

Browse files
vtjnashaviatesk
andauthored
adjustments for Julia v1.11 (#615)
A bunch of bugfixes and updates. Also fixed some of test cases. --------- Co-authored-by: Shuhei Kadowaki <[email protected]>
1 parent 8043dbc commit 1b1b6d6

17 files changed

+253
-141
lines changed

.github/workflows/CI.yml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,31 @@ jobs:
1313
strategy:
1414
fail-fast: false
1515
matrix:
16-
version:
17-
- '1.6' # LTS
18-
- '1' # current stable
19-
- '1.11-nightly' # next stable
20-
- 'nightly'
21-
os:
22-
- ubuntu-latest
23-
- macOS-latest
24-
- windows-latest
25-
arch:
26-
- x64
16+
include:
17+
- version: '1.6' # old LTS
18+
os: ubuntu-latest
19+
arch: x64
20+
- version: '1.10' # current stable
21+
os: ubuntu-latest
22+
arch: x64
23+
- version: '~1.11.0-0' # next release
24+
os: ubuntu-latest
25+
arch: x64
26+
- version: 'nightly' # dev
27+
os: ubuntu-latest
28+
arch: x64
29+
#- version: '1' # x86 ubuntu -- disabled since PyCall/conda is broken on this platform
30+
# os: ubuntu-latest
31+
# arch: x86
32+
- version: '1' # x86 windows
33+
os: windows-latest
34+
arch: x86
35+
- version: '1' # x64 windows
36+
os: windows-latest
37+
arch: x64
38+
- version: '1' # x64 macOS
39+
os: macos-latest
40+
arch: x64
2741
env:
2842
PYTHON: ""
2943
steps:

bin/generate_builtins.jl

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22
# Should be run on the latest Julia nightly
33
using InteractiveUtils
44

5-
# All bultins added since 1.6. Needs to be updated whenever a new builtin is added
6-
const RECENTLY_ADDED = Core.Builtin[
7-
Core._call_in_world_total, Core.donotdelete,
8-
Core.get_binding_type, Core.set_binding_type!,
9-
Core.getglobal, Core.setglobal!,
10-
Core.modifyfield!, Core.replacefield!, Core.swapfield!,
11-
Core.finalizer, Core._compute_sparams, Core._svec_ref,
12-
Core.compilerbarrier,
13-
Core.memoryref, Core.memoryref_isassigned, Core.memoryrefget, Core.memoryrefoffset, Core.memoryrefset!,
14-
#=Core.current_scope=#
5+
# All builtins present in 1.6
6+
const ALWAYS_PRESENT = Core.Builtin[
7+
(<:), (===), Core._abstracttype, Core._apply_iterate, Core._apply_pure,
8+
Core._call_in_world, Core._call_latest, Core._equiv_typedef, Core._expr,
9+
Core._primitivetype, Core._setsuper!, Core._structtype, Core._typebody!,
10+
Core._typevar, Core.apply_type, Core.ifelse, Core.sizeof, Core.svec,
11+
applicable, fieldtype, getfield, invoke, isa, isdefined, nfields,
12+
setfield!, throw, tuple, typeassert, typeof
1513
]
1614
# Builtins present in 1.6, not builtins (potentially still normal functions) anymore
1715
const RECENTLY_REMOVED = GlobalRef.(Ref(Core), [
@@ -232,7 +230,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
232230

233231
id = findfirst(isequal(f), Core.Compiler.T_FFUNC_KEY)
234232
fcall = generate_fcall(f, Core.Compiler.T_FFUNC_VAL, id)
235-
if f in RECENTLY_ADDED
233+
if !(f in ALWAYS_PRESENT)
236234
print(io,
237235
"""
238236
$head @static isdefined($(ft.name.module), $(repr(nameof(f)))) && f === $fname

src/breakpoints.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ function breakpoint!(framecode::FrameCode, pc, condition::Condition=nothing, ena
247247
framecode.breakpoints[stmtidx] = BreakpointState(enabled, Core.eval(mod, fex))
248248
end
249249
end
250-
breakpoint!(framecode::FrameCode, pcs::AbstractArray, condition::Condition=nothing, enabled=true) =
250+
breakpoint!(framecode::FrameCode, pcs::AbstractArray, condition::Condition=nothing, enabled=true) =
251251
foreach(pc -> breakpoint!(framecode, pc, condition, enabled), pcs)
252252
breakpoint!(frame::Frame, pc=frame.pc, condition::Condition=nothing) =
253253
breakpoint!(frame.framecode, pc, condition)
@@ -426,13 +426,14 @@ macro breakpoint(call_expr, args...)
426426
end
427427
end
428428

429-
const __BREAKPOINT_MARKER__ = nothing
429+
struct BreakPointMarker end
430+
const __BREAK_POINT_MARKER__ = BreakPointMarker()
430431

431432
"""
432433
@bp
433434
434435
Insert a breakpoint at a location in the source code.
435436
"""
436437
macro bp()
437-
return esc(:($(JuliaInterpreter).__BREAKPOINT_MARKER__))
438+
return :(__BREAK_POINT_MARKER__)
438439
end

src/builtins.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,42 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
184184
else
185185
return Some{Any}(Core.memoryrefget(getargs(args, frame)...))
186186
end
187+
elseif @static isdefined(Core, :memoryrefmodify!) && f === Core.memoryrefmodify!
188+
if nargs == 5
189+
return Some{Any}(Core.memoryrefmodify!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
190+
else
191+
return Some{Any}(Core.memoryrefmodify!(getargs(args, frame)...))
192+
end
187193
elseif @static isdefined(Core, :memoryrefoffset) && f === Core.memoryrefoffset
188194
if nargs == 1
189195
return Some{Any}(Core.memoryrefoffset(@lookup(frame, args[2])))
190196
else
191197
return Some{Any}(Core.memoryrefoffset(getargs(args, frame)...))
192198
end
199+
elseif @static isdefined(Core, :memoryrefreplace!) && f === Core.memoryrefreplace!
200+
if nargs == 6
201+
return Some{Any}(Core.memoryrefreplace!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6]), @lookup(frame, args[7])))
202+
else
203+
return Some{Any}(Core.memoryrefreplace!(getargs(args, frame)...))
204+
end
193205
elseif @static isdefined(Core, :memoryrefset!) && f === Core.memoryrefset!
194206
if nargs == 4
195207
return Some{Any}(Core.memoryrefset!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
196208
else
197209
return Some{Any}(Core.memoryrefset!(getargs(args, frame)...))
198210
end
211+
elseif @static isdefined(Core, :memoryrefsetonce!) && f === Core.memoryrefsetonce!
212+
if nargs == 5
213+
return Some{Any}(Core.memoryrefsetonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
214+
else
215+
return Some{Any}(Core.memoryrefsetonce!(getargs(args, frame)...))
216+
end
217+
elseif @static isdefined(Core, :memoryrefswap!) && f === Core.memoryrefswap!
218+
if nargs == 4
219+
return Some{Any}(Core.memoryrefswap!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
220+
else
221+
return Some{Any}(Core.memoryrefswap!(getargs(args, frame)...))
222+
end
199223
elseif @static isdefined(Core, :set_binding_type!) && f === Core.set_binding_type!
200224
return Some{Any}(Core.set_binding_type!(getargs(args, frame)...))
201225
elseif f === Core.sizeof
@@ -264,6 +288,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
264288
else
265289
return Some{Any}(modifyfield!(getargs(args, frame)...))
266290
end
291+
elseif @static isdefined(Core, :modifyglobal!) && f === modifyglobal!
292+
if nargs == 4
293+
return Some{Any}(modifyglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
294+
elseif nargs == 5
295+
return Some{Any}(modifyglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
296+
else
297+
return Some{Any}(modifyglobal!(getargs(args, frame)...))
298+
end
267299
elseif f === nfields
268300
if nargs == 1
269301
return Some{Any}(nfields(@lookup(frame, args[2])))
@@ -280,6 +312,16 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
280312
else
281313
return Some{Any}(replacefield!(getargs(args, frame)...))
282314
end
315+
elseif @static isdefined(Core, :replaceglobal!) && f === replaceglobal!
316+
if nargs == 4
317+
return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
318+
elseif nargs == 5
319+
return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
320+
elseif nargs == 6
321+
return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6]), @lookup(frame, args[7])))
322+
else
323+
return Some{Any}(replaceglobal!(getargs(args, frame)...))
324+
end
283325
elseif f === setfield!
284326
if nargs == 3
285327
return Some{Any}(setfield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
@@ -288,6 +330,16 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
288330
else
289331
return Some{Any}(setfield!(getargs(args, frame)...))
290332
end
333+
elseif @static isdefined(Core, :setfieldonce!) && f === setfieldonce!
334+
if nargs == 3
335+
return Some{Any}(setfieldonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
336+
elseif nargs == 4
337+
return Some{Any}(setfieldonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
338+
elseif nargs == 5
339+
return Some{Any}(setfieldonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
340+
else
341+
return Some{Any}(setfieldonce!(getargs(args, frame)...))
342+
end
291343
elseif @static isdefined(Core, :setglobal!) && f === setglobal!
292344
if nargs == 3
293345
return Some{Any}(setglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
@@ -296,6 +348,16 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
296348
else
297349
return Some{Any}(setglobal!(getargs(args, frame)...))
298350
end
351+
elseif @static isdefined(Core, :setglobalonce!) && f === setglobalonce!
352+
if nargs == 3
353+
return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
354+
elseif nargs == 4
355+
return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
356+
elseif nargs == 5
357+
return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
358+
else
359+
return Some{Any}(setglobalonce!(getargs(args, frame)...))
360+
end
299361
elseif @static isdefined(Core, :swapfield!) && f === swapfield!
300362
if nargs == 3
301363
return Some{Any}(swapfield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
@@ -304,6 +366,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
304366
else
305367
return Some{Any}(swapfield!(getargs(args, frame)...))
306368
end
369+
elseif @static isdefined(Core, :swapglobal!) && f === swapglobal!
370+
if nargs == 3
371+
return Some{Any}(swapglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
372+
elseif nargs == 4
373+
return Some{Any}(swapglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
374+
else
375+
return Some{Any}(swapglobal!(getargs(args, frame)...))
376+
end
307377
elseif f === throw
308378
if nargs == 1
309379
return Some{Any}(throw(@lookup(frame, args[2])))

src/commands.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,11 @@ If `frame.pc` points to the beginning of preparatory work for calling a keyword-
271271
function, advance forward until the actual call.
272272
"""
273273
function maybe_step_through_kwprep!(@nospecialize(recurse), frame::Frame, istoplevel::Bool=false)
274+
# XXX This code just does pattern-matching based on the current state of the compiler
275+
# internals, which means this is very fragile against any future changes to those
276+
# internals. We really need a more general and robust solution, but achieving that
277+
# would mean simplifying and unifying how "keyword function" is represented and
278+
# implemented. For the time being, our best bet is to keep tweaking it as best as we can.
274279
pc, src = frame.pc, frame.framecode.src
275280
n = length(src.code)
276281
stmt = pc_expr(frame, pc)

src/construct.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ end
8888

8989
get_source(meth::Method) = Base.uncompressed_ast(meth)
9090

91-
if Base.VERSION < v"1.10.0-DEV.873" # julia#48766
91+
@static if VERSION < v"1.10.0-DEV.873" # julia#48766
9292
function get_source(g::GeneratedFunctionStub, env, file, line)
9393
b = g(env..., g.argnames...)
9494
b isa CodeInfo && return b

src/interpret.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ function coverage_visit_line!(frame::Frame)
461461
code.report_coverage || return
462462
src = code.src
463463
codeloc = src.codelocs[pc]
464-
if codeloc != frame.last_codeloc
464+
if codeloc != frame.last_codeloc && codeloc != 0
465465
linetable = src.linetable::Vector{Any}
466466
lineinfo = linetable[codeloc]::Core.LineInfoNode
467467
file, line = String(lineinfo.file), lineinfo.line
@@ -672,7 +672,7 @@ function handle_err(@nospecialize(recurse), frame, err)
672672
rethrow(err)
673673
end
674674
data.last_exception[] = err
675-
pc = VERSION >= v"1.11-" ? pop!(data.exception_frames) : data.exception_frames[end] # implicit :leave after https://github.com/JuliaLang/julia/pull/52245
675+
pc = @static VERSION >= v"1.11-" ? pop!(data.exception_frames) : data.exception_frames[end] # implicit :leave after https://github.com/JuliaLang/julia/pull/52245
676676
frame.pc = pc
677677
return pc
678678
end

src/optimize.jl

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const compiled_calls = Dict{Any,Any}()
22

33
# Pre-frame-construction lookup
4-
function lookup_stmt(stmts, arg)
4+
function lookup_stmt(stmts::Vector{Any}, @nospecialize arg)
55
if isa(arg, SSAValue)
66
arg = stmts[arg.id]
77
end
@@ -45,16 +45,20 @@ function lookup_global_refs!(ex::Expr)
4545
return nothing
4646
end
4747

48-
function lookup_getproperties(a::Expr)
49-
if a.head === :call && length(a.args) == 3 &&
50-
a.args[1] isa QuoteNode && a.args[1].value === Base.getproperty &&
51-
a.args[2] isa QuoteNode && a.args[2].value isa Module &&
52-
a.args[3] isa QuoteNode && a.args[3].value isa Symbol
53-
return lookup_global_ref(Core.GlobalRef(a.args[2].value, a.args[3].value))
54-
end
55-
return a
48+
function lookup_getproperties(code::Vector{Any}, @nospecialize a)
49+
isexpr(a, :call) || return a
50+
length(a.args) == 3 || return a
51+
arg1 = lookup_stmt(code, a.args[1])
52+
arg1 === Base.getproperty || return a
53+
arg2 = lookup_stmt(code, a.args[2])
54+
arg2 isa Module || return a
55+
arg3 = lookup_stmt(code, a.args[3])
56+
arg3 isa Symbol || return a
57+
return lookup_global_ref(GlobalRef(arg2, arg3))
5658
end
5759

60+
# TODO This isn't optimization really, but necessary to bypass llvmcall and foreigncall
61+
5862
"""
5963
optimize!(code::CodeInfo, mod::Module)
6064
@@ -82,7 +86,7 @@ function optimize!(code::CodeInfo, scope)
8286
continue
8387
else
8488
lookup_global_refs!(stmt)
85-
code.code[i] = lookup_getproperties(stmt)
89+
code.code[i] = lookup_getproperties(code.code, stmt)
8690
end
8791
end
8892
end

src/types.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ function FrameCode(scope, src::CodeInfo; generator=false, optimize=true)
132132
end
133133
breakpoints = Vector{BreakpointState}(undef, length(src.code))
134134
for (i, pc_expr) in enumerate(src.code)
135-
if isa(pc_expr, Expr) && is_breakpoint_expr(pc_expr)
135+
if lookup_stmt(src.code, pc_expr) === __BREAK_POINT_MARKER__
136136
breakpoints[i] = BreakpointState()
137137
src.code[i] = nothing
138138
end

src/utils.jl

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ end
210210

211211
is_generated(meth::Method) = isdefined(meth, :generator)
212212

213-
if Base.VERSION < v"1.10.0-DEV.873" # julia#48766
213+
@static if VERSION < v"1.10.0-DEV.873" # julia#48766
214214
get_staged(mi::MethodInstance) = Core.Compiler.get_staged(mi)
215215
else
216216
get_staged(mi::MethodInstance) = Core.Compiler.get_staged(mi, Base.get_world_counter())
@@ -364,12 +364,25 @@ end
364364
getfile(frame::Frame, pc=frame.pc) = getfile(frame.framecode, pc)
365365

366366
function codelocation(code::CodeInfo, idx::Int)
367-
codeloc = codelocs(code)[idx]
368-
while codeloc == 0 && (code.code[idx] === nothing || isexpr(code.code[idx], :meta)) && idx < length(code.code)
369-
idx += 1
370-
codeloc = codelocs(code)[idx]
371-
end
372-
return codeloc
367+
idx′ = idx
368+
# look ahead if we are on a meta line
369+
while idx′ < length(code.code)
370+
codeloc = codelocs(code)[idx′]
371+
codeloc == 0 || return codeloc
372+
ex = code.code[idx′]
373+
ex === nothing || isexpr(ex, :meta) || break
374+
idx′ += 1
375+
end
376+
idx′ = idx - 1
377+
# if zero, look behind until we find where we last might have had a line
378+
while idx′ > 0
379+
ex = code.code[idx′]
380+
codeloc = codelocs(code)[idx′]
381+
codeloc == 0 || return codeloc
382+
idx′ -= 1
383+
end
384+
# for the start of the function, return index 1
385+
return 1
373386
end
374387

375388
function compute_corrected_linerange(method::Method)

0 commit comments

Comments
 (0)