Skip to content

Commit e99ea2e

Browse files
committed
Squashed 'packages/JuliaInterpreter/' changes from cc89e74..0b17ba7
0b17ba7 version 0.10.3 d357d35 make it easier to overload `evaluate_call!` df933cc version 0.10.2 cf8f5fa update builtins.jl and add some simple tests for `using/import` evaluation (#688) 4ad9cbb version 0.10.1 d4c2351 quote rhs of `:const` expression (#687) a29cc79 version 0.10.0 a8b4c95 update docs dependencies ba766f9 implement a system for interpreting overlay methods (#682) 34cf432 remove the new `finish_nested_frame!` interface (#686) a3ed4cc change the `recurse` interface to `AbstractInterpreter`-like interface (#683) 43f0215 rm `gen_lookup_ex`, and fix `@lookup` 0be2e0d version 0.9.46 837b899 deprecate `@lookup` macro in favor of `lookup` function (#685) 49220f9 deprecate 3-arg `@lookup` (#684) 93f6473 Support external method tables in method evaluation (#680) 77effa3 use `isdefinedglobal` instead of `isdefined(::Module, ::Symbol)` (#681) 0c37ff5 version 0.9.44 82e3897 make `llvmcall` search logic more robust (#679) d66c5b9 Version 0.9.43 (#678) 3ab1279 Update builtins: `svec_ref` (#677) 0d1c51b Breakpoint setting for inverted linetable (#673) c3739d1 Merge pull request #675 from JuliaDebug/teh/llvmcall_ega b5340fd Assert that we only update pc in leaves 2ada170 Try harder to find llvmcalls 890cae3 Fix & improve `test/limits.jl` (#672) b552e60 Update generated functions for Julia 1.12 (#668) 4ef265f Delay file removal (#674) 119b686 Improve breakpoints on Julia 1.12 (#669) c12d8e0 Fix world age issues in test/toplevel (#671) 9f5d98d Fix kwprep stepping in Julia 1.12 and 1.11 (#667) 822632d Update builtins, allow stepping into invokelatest (#670) 22f186b Fix llvmcall/ccall and OpaqueClosure on nightly (#665) 2bbcead Fix builtins (#664) aca346c Update all builtins bd71e05 fix ir printing on 1.12 (#661) 33f1c25 bump version cdefdcb allow getindex in lookup_or_eval :call (#651) d88ba3a Bump Version d37b7d8 Correct logic for ccall symbol lookup (#659) 126ab85 Bump Version 3ab3a11 More 1.12 world age adjustments (#658) ba9783b fix builtins.jl 5fa1aaf update builtins, use `@invokelatest` instead of the function version 64cfc37 Bump Version e807fdc Lookup bindings in the latest world (#657) 443d672 Bump codecov/codecov-action from 4 to 5 (#656) b6cf649 update builtins.jl (#655) git-subtree-dir: packages/JuliaInterpreter git-subtree-split: 0b17ba720fa92256947a1015070ccbc98eb3a20d
1 parent a445a46 commit e99ea2e

25 files changed

+1241
-822
lines changed

.github/workflows/CI.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ jobs:
5959
- uses: julia-actions/julia-buildpkg@v1
6060
- uses: julia-actions/julia-runtest@v1
6161
- uses: julia-actions/julia-processcoverage@v1
62-
- uses: codecov/codecov-action@v4
62+
- uses: codecov/codecov-action@v5
6363
with:
6464
file: lcov.info

Project.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name = "JuliaInterpreter"
22
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
3-
version = "0.9.38"
3+
version = "0.10.3"
4+
authors = ["Tim Holy <[email protected]>, Kristoffer Carlsson <[email protected]>, Shuhei Kadowaki <[email protected]> and contributors"]
45

56
[deps]
67
CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
@@ -9,7 +10,7 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
910
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
1011

1112
[compat]
12-
CodeTracking = "0.5.9, 1"
13+
CodeTracking = "1.3.9"
1314
julia = "1.10"
1415

1516
[extras]
@@ -27,8 +28,7 @@ Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
2728
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
2829
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
2930
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
30-
Tensors = "48a634ad-e948-5137-8d70-aa71f2a747f4"
3131
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3232

3333
[targets]
34-
test = ["CassetteOverlay", "DataFrames", "Dates", "DeepDiffs", "Distributed", "FunctionWrappers", "HTTP", "LinearAlgebra", "Logging", "LoopVectorization", "Mmap", "PyCall", "SHA", "SparseArrays", "Tensors", "Test"]
34+
test = ["CassetteOverlay", "DataFrames", "Dates", "DeepDiffs", "Distributed", "FunctionWrappers", "HTTP", "LinearAlgebra", "Logging", "LoopVectorization", "Mmap", "PyCall", "SHA", "SparseArrays", "Test"]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
## Installation
1010

11-
```jl
12-
]add JuliaInterpreter
11+
```julia-repl
12+
pkg> add JuliaInterpreter
1313
```
1414

1515
## Usage

bin/generate_builtins.jl

Lines changed: 77 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ using InteractiveUtils
55
# Builtins not present in 1.10 (the lowest supported version)
66
const RECENTLY_ADDED = Core.Builtin[
77
Core.current_scope,
8+
isdefinedglobal,
9+
Core.memorynew,
810
Core.memoryref_isassigned,
911
Core.memoryrefget,
1012
Core.memoryrefmodify!,
@@ -20,12 +22,38 @@ const RECENTLY_ADDED = Core.Builtin[
2022
setfieldonce!,
2123
setglobalonce!,
2224
swapglobal!,
25+
Core._defaultctors,
26+
Core._import,
27+
Core._using,
28+
# Recently became builtins
29+
Base.invokelatest,
30+
Base.invoke_in_world,
2331
]
2432
# Builtins present from 1.10, not builtins (potentially still normal functions) anymore
2533
const RECENTLY_REMOVED = GlobalRef.(Ref(Core), [
26-
:arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, :set_binding_type!
34+
:arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, :set_binding_type!,
35+
:_apply_pure, :_call_in_world, :_call_latest,
2736
])
2837
const kwinvoke = Core.kwfunc(Core.invoke)
38+
const REQUIRES_WORLD = Core.Builtin[
39+
setglobal!,
40+
Core.get_binding_type,
41+
swapglobal!,
42+
modifyglobal!,
43+
replaceglobal!,
44+
setglobalonce!,
45+
]
46+
const CALL_LATEST = """args = getargs(interp, args, frame)
47+
if !expand
48+
return Some{Any}(Core._call_latest(args...))
49+
end
50+
new_expr = Expr(:call, args[1])
51+
popfirst!(args)
52+
for x in args
53+
push!(new_expr.args, QuoteNode(x))
54+
end
55+
return maybe_recurse_expanded_builtin(interp, frame, new_expr)
56+
"""
2957

3058
function scopedname(f)
3159
io = IOBuffer()
@@ -35,7 +63,7 @@ function scopedname(f)
3563
tn = typeof(f).name
3664
Base.isexported(tn.module, Symbol(fstr)) && return fstr
3765
fsym = Symbol(fstr)
38-
isdefined(tn.module, fsym) && return string(tn.module) * '.' * fstr
66+
isdefinedglobal(tn.module, fsym) && return string(tn.module) * '.' * fstr
3967
return "Base." * fstr
4068
end
4169

@@ -49,13 +77,13 @@ function nargs(f, table, id)
4977
end
5078
# Specialize ~arrayref and arrayset~ memoryrefnew for small numbers of arguments
5179
# TODO: how about other memory intrinsics?
52-
if (@static isdefined(Core, :memoryrefnew) ? f == Core.memoryrefnew : f == Core.memoryref)
80+
if (@static isdefinedglobal(Core, :memoryrefnew) ? f == Core.memoryrefnew : f == Core.memoryref)
5381
maxarg = 5
5482
end
5583
return minarg, maxarg
5684
end
5785

58-
function generate_fcall_nargs(fname, minarg, maxarg)
86+
function generate_fcall_nargs(fname, minarg, maxarg; requires_world::Bool=false)
5987
# Generate a separate call for each number of arguments
6088
maxarg < typemax(Int) || error("call this only for constrained number of arguments")
6189
annotation = fname == "fieldtype" ? "::Type" : ""
@@ -64,31 +92,41 @@ function generate_fcall_nargs(fname, minarg, maxarg)
6492
wrapper *= "$nargs\n "
6593
argcall = ""
6694
for i = 1:nargs
67-
argcall *= "@lookup(frame, args[$(i+1)])"
95+
argcall *= "lookup(interp, frame, args[$(i+1)])"
6896
if i < nargs
6997
argcall *= ", "
7098
end
7199
end
72-
wrapper *= "return Some{Any}($fname($argcall)$annotation)"
100+
wrapper *= requires_world ? "return Some{Any}(Base.invoke_in_world(frame.world, $fname, $argcall)$annotation)" :
101+
"return Some{Any}($fname($argcall)$annotation)"
73102
if nargs < maxarg
74103
wrapper *= "\n elseif nargs == "
75104
end
76105
end
77106
wrapper *= "\n else"
78-
wrapper *= "\n return Some{Any}($fname(getargs(args, frame)...)$annotation)" # to throw the correct error
107+
# To throw the correct error
108+
if requires_world
109+
wrapper *= "\n return Some{Any}(Base.invoke_in_world(frame.world, $fname, getargs(interp, args, frame)...)$annotation)"
110+
else
111+
wrapper *= "\n return Some{Any}($fname(getargs(interp, args, frame)...)$annotation)"
112+
end
79113
wrapper *= "\n end"
80114
return wrapper
81115
end
82116

83117
function generate_fcall(f, table, id)
84118
minarg, maxarg = nargs(f, table, id)
85119
fname = scopedname(f)
120+
requires_world = f REQUIRES_WORLD
86121
if maxarg < typemax(Int)
87-
return generate_fcall_nargs(fname, minarg, maxarg)
122+
return generate_fcall_nargs(fname, minarg, maxarg; requires_world)
88123
end
89124
# A built-in with arbitrary or unknown number of arguments.
90125
# This will (unfortunately) use dynamic dispatch.
91-
return "return Some{Any}($fname(getargs(args, frame)...))"
126+
if requires_world
127+
return "return Some{Any}(Base.invoke_in_world(frame.world, $fname, getargs(interp, args, frame)...))"
128+
end
129+
return "return Some{Any}($fname(getargs(interp, args, frame)...))"
92130
end
93131

94132
# `io` is for the generated source file
@@ -104,42 +142,42 @@ function generate_builtins(io::IO)
104142
"""
105143
# This file is generated by `generate_builtins.jl`. Do not edit by hand.
106144
107-
function getargs(args, frame)
145+
function getargs(interp::Interpreter, args::Vector{Any}, frame::Frame)
108146
nargs = length(args)-1 # skip f
109147
callargs = resize!(frame.framedata.callargs, nargs)
110148
for i = 1:nargs
111-
callargs[i] = @lookup(frame, args[i+1])
149+
callargs[i] = lookup(interp, frame, args[i+1])
112150
end
113151
return callargs
114152
end
115153
116154
const kwinvoke = Core.kwfunc(Core.invoke)
117155
118-
function maybe_recurse_expanded_builtin(frame, new_expr)
156+
function maybe_recurse_expanded_builtin(interp::Interpreter, frame::Frame, new_expr::Expr)
119157
f = new_expr.args[1]
120158
if isa(f, Core.Builtin) || isa(f, Core.IntrinsicFunction)
121-
return maybe_evaluate_builtin(frame, new_expr, true)
159+
return maybe_evaluate_builtin(interp, frame, new_expr, true)
122160
else
123161
return new_expr
124162
end
125163
end
126164
127165
\"\"\"
128-
ret = maybe_evaluate_builtin(frame, call_expr, expand::Bool)
166+
ret = maybe_evaluate_builtin(interp::Interpreter, frame::Frame, call_expr::Expr, expand::Bool)
129167
130168
If `call_expr` is to a builtin function, evaluate it, returning the result inside a `Some` wrapper.
131169
Otherwise, return `call_expr`.
132170
133171
If `expand` is true, `Core._apply_iterate` calls will be resolved as a call to the applied function.
134172
\"\"\"
135-
function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
173+
function maybe_evaluate_builtin(interp::Interpreter, frame::Frame, call_expr::Expr, expand::Bool)
136174
args = call_expr.args
137175
nargs = length(args) - 1
138176
fex = args[1]
139177
if isa(fex, QuoteNode)
140178
f = fex.value
141179
else
142-
f = @lookup(frame, fex)
180+
f = lookup(interp, frame, fex)
143181
end
144182
145183
if f isa Core.OpaqueClosure
@@ -172,15 +210,15 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
172210
print(io,
173211
"""
174212
$head f === tuple
175-
return Some{Any}(ntupleany(i->@lookup(frame, args[i+1]), length(args)-1))
213+
return Some{Any}(ntupleany(i::Int->lookup(interp, frame, args[i+1]), length(args)-1))
176214
""")
177215
continue
178216
elseif f === Core._apply_iterate
179217
# Resolve varargs calls
180218
print(io,
181219
"""
182220
$head f === Core._apply_iterate
183-
argswrapped = getargs(args, frame)
221+
argswrapped = getargs(interp, args, frame)
184222
if !expand
185223
return Some{Any}(Core._apply_iterate(argswrapped...))
186224
end
@@ -193,7 +231,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
193231
for x in argsflat
194232
push!(new_expr.args, QuoteNode(x))
195233
end
196-
return maybe_recurse_expanded_builtin(frame, new_expr)
234+
return maybe_recurse_expanded_builtin(interp, frame, new_expr)
197235
""")
198236
continue
199237
elseif f === Core.invoke
@@ -202,42 +240,26 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
202240
"""
203241
$head f === $fstr
204242
if !expand
205-
argswrapped = getargs(args, frame)
243+
argswrapped = getargs(interp, args, frame)
206244
return Some{Any}($fstr(argswrapped...))
207245
end
208246
# This uses the original arguments to avoid looking them up twice
209247
# See #442
210248
return Expr(:call, invoke, args[2:end]...)
211-
""")
212-
continue
213-
elseif f === Core._call_latest
214-
print(io,
215-
"""
216-
elseif f === Core._call_latest
217-
args = getargs(args, frame)
218-
if !expand
219-
return Some{Any}(Core._call_latest(args...))
220-
end
221-
new_expr = Expr(:call, args[1])
222-
popfirst!(args)
223-
for x in args
224-
push!(new_expr.args, QuoteNode(x))
225-
end
226-
return maybe_recurse_expanded_builtin(frame, new_expr)
227249
""")
228250
continue
229251
elseif f === Core.current_scope
230252
print(io,
231253
"""
232-
elseif @static isdefined(Core, :current_scope) && f === Core.current_scope
254+
elseif @static isdefinedglobal(Core, :current_scope) && f === Core.current_scope
233255
if nargs == 0
234256
currscope = Core.current_scope()
235257
for scope in frame.framedata.current_scopes
236258
currscope = Scope(currscope, scope.values...)
237259
end
238260
return Some{Any}(currscope)
239261
else
240-
return Some{Any}(Core.current_scope(getargs(args, frame)...))
262+
return Some{Any}(Core.current_scope(getargs(interp, args, frame)...))
241263
end
242264
""")
243265
continue
@@ -246,9 +268,12 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
246268
id = findfirst(isequal(f), Core.Compiler.T_FFUNC_KEY)
247269
fcall = generate_fcall(f, Core.Compiler.T_FFUNC_VAL, id)
248270
if f in RECENTLY_ADDED
271+
if f === Core.invokelatest
272+
fcall = replace(CALL_LATEST, "_call_latest" => "invokelatest")
273+
end
249274
print(io,
250275
"""
251-
$head @static isdefined($(ft.name.module), $(repr(nameof(f)))) && f === $fname
276+
$head @static isdefinedglobal($(ft.name.module), $(repr(nameof(f)))) && f === $fname
252277
$fcall
253278
""")
254279
else
@@ -270,13 +295,13 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
270295
if nargs == 1
271296
call_expr = copy(call_expr)
272297
args2 = args[2]
273-
call_expr.args[2] = isa(args2, QuoteNode) ? args2 : @lookup(frame, args2)
298+
call_expr.args[2] = isa(args2, QuoteNode) ? args2 : lookup(interp, frame, args2)
274299
return Some{Any}(Core.eval(moduleof(frame), call_expr))
275300
elseif nargs == 2
276301
call_expr = copy(call_expr)
277302
args2 = args[2]
278-
call_expr.args[2] = isa(args2, QuoteNode) ? args2 : @lookup(frame, args2)
279-
call_expr.args[3] = @lookup(frame, args[3])
303+
call_expr.args[2] = isa(args2, QuoteNode) ? args2 : lookup(interp, frame, args2)
304+
call_expr.args[3] = lookup(interp, frame, args[3])
280305
return Some{Any}(Core.eval(moduleof(frame), call_expr))
281306
end
282307
""")
@@ -292,13 +317,18 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
292317
elseif name === :set_binding_type!
293318
minarg = 2
294319
maxarg = 3
320+
elseif name in (:_apply_pure, :_call_in_world, :_call_latest)
321+
minarg = 0
322+
maxarg = typemax(Int)
295323
end
296324
_scopedname = "$mod.$name"
297-
fcall = generate_fcall_nargs(_scopedname, minarg, maxarg)
325+
fcall = name === :_call_latest ? CALL_LATEST :
326+
maxarg < typemax(Int) ? generate_fcall_nargs(_scopedname, minarg, maxarg) :
327+
"return Some{Any}($_scopedname(getargs(interp, args, frame)...))"
298328
rname = repr(name)
299329
print(io,
300330
"""
301-
elseif @static (isdefined($mod, $rname) && $_scopedname isa Core.Builtin) && f === $_scopedname
331+
elseif @static (isdefinedglobal($mod, $rname) && $_scopedname isa Core.Builtin) && f === $_scopedname
302332
$fcall
303333
""")
304334
end
@@ -307,7 +337,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
307337
minmin, maxmax = typemax(Int), 0
308338
for fsym in names(Core.Intrinsics)
309339
fsym === :Intrinsics && continue
310-
isdefined(Base, fsym) || continue
340+
isdefinedglobal(Base, fsym) || continue
311341
f = getfield(Base, fsym)
312342
id = reinterpret(Int32, f) + 1
313343
minarg, maxarg = nargs(f, Core.Compiler.T_IFUNC, id)
@@ -333,7 +363,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
333363
print(io,
334364
"""
335365
if isa(f, Core.IntrinsicFunction)
336-
cargs = getargs(args, frame)
366+
cargs = getargs(interp, args, frame)
337367
if f === Core.Intrinsics.have_fma && length(cargs) == 1
338368
cargs1 = cargs[1]
339369
if cargs1 == Float64
@@ -364,7 +394,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
364394
"""
365395
end
366396
if isa(f, typeof(kwinvoke))
367-
return Some{Any}(kwinvoke(getargs(args, frame)...))
397+
return Some{Any}(kwinvoke(getargs(interp, args, frame)...))
368398
end
369399
return call_expr
370400
end

0 commit comments

Comments
 (0)