Skip to content

Commit aca346c

Browse files
committed
Update all builtins
1 parent bd71e05 commit aca346c

File tree

2 files changed

+82
-56
lines changed

2 files changed

+82
-56
lines changed

bin/generate_builtins.jl

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,29 @@ const RECENTLY_ADDED = Core.Builtin[
2525
]
2626
# Builtins present from 1.10, not builtins (potentially still normal functions) anymore
2727
const RECENTLY_REMOVED = GlobalRef.(Ref(Core), [
28-
:arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, :set_binding_type!
28+
:arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, :set_binding_type!,
29+
:_apply_pure, :_call_in_world, :_call_latest,
2930
])
3031
const kwinvoke = Core.kwfunc(Core.invoke)
32+
const REQUIRES_WORLD = Core.Builtin[
33+
setglobal!,
34+
Core.get_binding_type,
35+
swapglobal!,
36+
modifyglobal!,
37+
replaceglobal!,
38+
setglobalonce!,
39+
]
40+
const CALL_LATEST = """args = getargs(args, frame)
41+
if !expand
42+
return Some{Any}(Core._call_latest(args...))
43+
end
44+
new_expr = Expr(:call, args[1])
45+
popfirst!(args)
46+
for x in args
47+
push!(new_expr.args, QuoteNode(x))
48+
end
49+
return maybe_recurse_expanded_builtin(frame, new_expr)
50+
"""
3151

3252
function scopedname(f)
3353
io = IOBuffer()
@@ -57,7 +77,7 @@ function nargs(f, table, id)
5777
return minarg, maxarg
5878
end
5979

60-
function generate_fcall_nargs(fname, minarg, maxarg)
80+
function generate_fcall_nargs(fname, minarg, maxarg; requires_world::Bool=false)
6181
# Generate a separate call for each number of arguments
6282
maxarg < typemax(Int) || error("call this only for constrained number of arguments")
6383
annotation = fname == "fieldtype" ? "::Type" : ""
@@ -71,25 +91,35 @@ function generate_fcall_nargs(fname, minarg, maxarg)
7191
argcall *= ", "
7292
end
7393
end
74-
wrapper *= "return Some{Any}($fname($argcall)$annotation)"
94+
wrapper *= requires_world ? "return Some{Any}(Base.invoke_in_world(frame.world, $fname, $argcall)$annotation)" :
95+
"return Some{Any}($fname($argcall)$annotation)"
7596
if nargs < maxarg
7697
wrapper *= "\n elseif nargs == "
7798
end
7899
end
79100
wrapper *= "\n else"
80-
wrapper *= "\n return Some{Any}($fname(getargs(args, frame)...)$annotation)" # to throw the correct error
101+
# To throw the correct error
102+
if requires_world
103+
wrapper *= "\n return Some{Any}(Base.invoke_in_world(frame.world, $fname, getargs(args, frame)...)$annotation)"
104+
else
105+
wrapper *= "\n return Some{Any}($fname(getargs(args, frame)...)$annotation)"
106+
end
81107
wrapper *= "\n end"
82108
return wrapper
83109
end
84110

85111
function generate_fcall(f, table, id)
86112
minarg, maxarg = nargs(f, table, id)
87113
fname = scopedname(f)
114+
requires_world = f REQUIRES_WORLD
88115
if maxarg < typemax(Int)
89-
return generate_fcall_nargs(fname, minarg, maxarg)
116+
return generate_fcall_nargs(fname, minarg, maxarg; requires_world)
90117
end
91118
# A built-in with arbitrary or unknown number of arguments.
92119
# This will (unfortunately) use dynamic dispatch.
120+
if requires_world
121+
return "return Some{Any}(Base.invoke_in_world(frame.world, $fname, getargs(args, frame)...))"
122+
end
93123
return "return Some{Any}($fname(getargs(args, frame)...))"
94124
end
95125

@@ -210,22 +240,6 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
210240
# This uses the original arguments to avoid looking them up twice
211241
# See #442
212242
return Expr(:call, invoke, args[2:end]...)
213-
""")
214-
continue
215-
elseif f === Core._call_latest
216-
print(io,
217-
"""
218-
elseif f === Core._call_latest
219-
args = getargs(args, frame)
220-
if !expand
221-
return Some{Any}(Core._call_latest(args...))
222-
end
223-
new_expr = Expr(:call, args[1])
224-
popfirst!(args)
225-
for x in args
226-
push!(new_expr.args, QuoteNode(x))
227-
end
228-
return maybe_recurse_expanded_builtin(frame, new_expr)
229243
""")
230244
continue
231245
elseif f === Core.current_scope
@@ -294,9 +308,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
294308
elseif name === :set_binding_type!
295309
minarg = 2
296310
maxarg = 3
311+
elseif name in (:_apply_pure, :_call_in_world, :_call_latest)
312+
minarg = 0
313+
maxarg = typemax(Int)
297314
end
298315
_scopedname = "$mod.$name"
299-
fcall = generate_fcall_nargs(_scopedname, minarg, maxarg)
316+
fcall = name === :_call_latest ? CALL_LATEST :
317+
maxarg < typemax(Int) ? generate_fcall_nargs(_scopedname, minarg, maxarg) :
318+
"return Some{Any}($_scopedname(getargs(args, frame)...))"
300319
rname = repr(name)
301320
print(io,
302321
"""

src/builtins.jl

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,12 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
8282
push!(new_expr.args, QuoteNode(x))
8383
end
8484
return maybe_recurse_expanded_builtin(frame, new_expr)
85-
elseif f === Core._apply_pure
86-
return Some{Any}(Core._apply_pure(getargs(args, frame)...))
87-
elseif f === Core._call_in_world
88-
return Some{Any}(Core._call_in_world(getargs(args, frame)...))
8985
elseif f === Core._call_in_world_total
9086
return Some{Any}(Core._call_in_world_total(getargs(args, frame)...))
91-
elseif f === Core._call_latest
92-
args = getargs(args, frame)
93-
if !expand
94-
return Some{Any}(Core._call_latest(args...))
95-
end
96-
new_expr = Expr(:call, args[1])
97-
popfirst!(args)
98-
for x in args
99-
push!(new_expr.args, QuoteNode(x))
100-
end
101-
return maybe_recurse_expanded_builtin(frame, new_expr)
10287
elseif f === Core._compute_sparams
10388
return Some{Any}(Core._compute_sparams(getargs(args, frame)...))
89+
elseif f === Core._defaultctors
90+
return Some{Any}(Core._defaultctors(getargs(args, frame)...))
10491
elseif f === Core._equiv_typedef
10592
return Some{Any}(Core._equiv_typedef(getargs(args, frame)...))
10693
elseif f === Core._expr
@@ -153,16 +140,20 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
153140
end
154141
elseif f === Core.get_binding_type
155142
if nargs == 2
156-
return Some{Any}(Core.get_binding_type(@lookup(frame, args[2]), @lookup(frame, args[3])))
143+
return Some{Any}(Base.invoke_in_world(frame.world, Core.get_binding_type, @lookup(frame, args[2]), @lookup(frame, args[3])))
157144
else
158-
return Some{Any}(Core.get_binding_type(getargs(args, frame)...))
145+
return Some{Any}(Base.invoke_in_world(frame.world, Core.get_binding_type, getargs(args, frame)...))
159146
end
160147
elseif f === Core.ifelse
161148
if nargs == 3
162149
return Some{Any}(Core.ifelse(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
163150
else
164151
return Some{Any}(Core.ifelse(getargs(args, frame)...))
165152
end
153+
elseif f === Core.invoke_in_world
154+
return Some{Any}(Core.invoke_in_world(getargs(args, frame)...))
155+
elseif f === Core.invokelatest
156+
return Some{Any}(Core.invokelatest(getargs(args, frame)...))
166157
elseif @static isdefined(Core, :memorynew) && f === Core.memorynew
167158
if nargs == 2
168159
return Some{Any}(Core.memorynew(@lookup(frame, args[2]), @lookup(frame, args[3])))
@@ -303,11 +294,11 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
303294
end
304295
elseif @static isdefined(Core, :modifyglobal!) && f === modifyglobal!
305296
if nargs == 4
306-
return Some{Any}(modifyglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
297+
return Some{Any}(Base.invoke_in_world(frame.world, modifyglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
307298
elseif nargs == 5
308-
return Some{Any}(modifyglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
299+
return Some{Any}(Base.invoke_in_world(frame.world, modifyglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
309300
else
310-
return Some{Any}(modifyglobal!(getargs(args, frame)...))
301+
return Some{Any}(Base.invoke_in_world(frame.world, modifyglobal!, getargs(args, frame)...))
311302
end
312303
elseif f === nfields
313304
if nargs == 1
@@ -327,13 +318,13 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
327318
end
328319
elseif @static isdefined(Core, :replaceglobal!) && f === replaceglobal!
329320
if nargs == 4
330-
return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
321+
return Some{Any}(Base.invoke_in_world(frame.world, replaceglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
331322
elseif nargs == 5
332-
return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
323+
return Some{Any}(Base.invoke_in_world(frame.world, replaceglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
333324
elseif nargs == 6
334-
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])))
325+
return Some{Any}(Base.invoke_in_world(frame.world, 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])))
335326
else
336-
return Some{Any}(replaceglobal!(getargs(args, frame)...))
327+
return Some{Any}(Base.invoke_in_world(frame.world, replaceglobal!, getargs(args, frame)...))
337328
end
338329
elseif f === setfield!
339330
if nargs == 3
@@ -355,21 +346,21 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
355346
end
356347
elseif f === setglobal!
357348
if nargs == 3
358-
return Some{Any}(setglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
349+
return Some{Any}(Base.invoke_in_world(frame.world, setglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
359350
elseif nargs == 4
360-
return Some{Any}(setglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
351+
return Some{Any}(Base.invoke_in_world(frame.world, setglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
361352
else
362-
return Some{Any}(setglobal!(getargs(args, frame)...))
353+
return Some{Any}(Base.invoke_in_world(frame.world, setglobal!, getargs(args, frame)...))
363354
end
364355
elseif @static isdefined(Core, :setglobalonce!) && f === setglobalonce!
365356
if nargs == 3
366-
return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
357+
return Some{Any}(Base.invoke_in_world(frame.world, setglobalonce!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
367358
elseif nargs == 4
368-
return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
359+
return Some{Any}(Base.invoke_in_world(frame.world, setglobalonce!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
369360
elseif nargs == 5
370-
return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
361+
return Some{Any}(Base.invoke_in_world(frame.world, setglobalonce!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6])))
371362
else
372-
return Some{Any}(setglobalonce!(getargs(args, frame)...))
363+
return Some{Any}(Base.invoke_in_world(frame.world, setglobalonce!, getargs(args, frame)...))
373364
end
374365
elseif f === swapfield!
375366
if nargs == 3
@@ -381,11 +372,11 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
381372
end
382373
elseif @static isdefined(Core, :swapglobal!) && f === swapglobal!
383374
if nargs == 3
384-
return Some{Any}(swapglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
375+
return Some{Any}(Base.invoke_in_world(frame.world, swapglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4])))
385376
elseif nargs == 4
386-
return Some{Any}(swapglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
377+
return Some{Any}(Base.invoke_in_world(frame.world, swapglobal!, @lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5])))
387378
else
388-
return Some{Any}(swapglobal!(getargs(args, frame)...))
379+
return Some{Any}(Base.invoke_in_world(frame.world, swapglobal!, getargs(args, frame)...))
389380
end
390381
elseif f === throw
391382
if nargs == 1
@@ -503,6 +494,22 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
503494
else
504495
return Some{Any}(Core.set_binding_type!(getargs(args, frame)...))
505496
end
497+
elseif @static (isdefined(Core, :_apply_pure) && Core._apply_pure isa Core.Builtin) && f === Core._apply_pure
498+
return Some{Any}(Core._apply_pure(getargs(args, frame)...))
499+
elseif @static (isdefined(Core, :_call_in_world) && Core._call_in_world isa Core.Builtin) && f === Core._call_in_world
500+
return Some{Any}(Core._call_in_world(getargs(args, frame)...))
501+
elseif @static (isdefined(Core, :_call_latest) && Core._call_latest isa Core.Builtin) && f === Core._call_latest
502+
args = getargs(args, frame)
503+
if !expand
504+
return Some{Any}(Core._call_latest(args...))
505+
end
506+
new_expr = Expr(:call, args[1])
507+
popfirst!(args)
508+
for x in args
509+
push!(new_expr.args, QuoteNode(x))
510+
end
511+
return maybe_recurse_expanded_builtin(frame, new_expr)
512+
506513
elseif f === Core.Intrinsics.llvmcall
507514
return Some{Any}(Core.Intrinsics.llvmcall(getargs(args, frame)...))
508515
end

0 commit comments

Comments
 (0)