From 6a2b89da68e3aa22a98de81d076ca9410d374cb3 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 14 Nov 2024 16:46:49 +0900 Subject: [PATCH 1/7] bump the minimum supported Julia version to 1.10 (LTS) Maintaining this package that closely depends on Julia internals across multiple Julia versions is very cumbersome. Now that the LTS has been updated to 1.10, let's drop compatibility with earlier versions and simplify the code. --- .github/workflows/CI.yml | 6 +- Project.toml | 4 +- bin/generate_builtins.jl | 20 +++--- src/breakpoints.jl | 7 +-- src/builtins.jl | 78 +++++------------------ src/commands.jl | 12 +--- src/construct.jl | 20 ++---- src/interpret.jl | 23 ++----- src/optimize.jl | 6 +- src/packagedef.jl | 41 +++---------- src/types.jl | 2 +- src/utils.jl | 84 ++++++++----------------- test/breakpoints.jl | 6 +- test/core.jl | 4 +- test/debug.jl | 14 ++--- test/interpret.jl | 129 ++++++++++++--------------------------- test/limits.jl | 8 +-- test/runtests.jl | 2 +- test/utils.jl | 6 -- 19 files changed, 131 insertions(+), 341 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index bf7f2a10..b64df3c0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,13 +14,13 @@ jobs: fail-fast: false matrix: include: - - version: '1.6' # old LTS + - version: '1' # current stable os: ubuntu-latest arch: x64 - - version: '1.10' # current stable + - version: '1.10' # lowerest version supported os: ubuntu-latest arch: x64 - - version: '~1.11.0-0' # next release + - version: '1.12-nightly' # next release os: ubuntu-latest arch: x64 - version: 'nightly' # dev diff --git a/Project.toml b/Project.toml index 192f50d3..82efe56c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "JuliaInterpreter" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.37" +version = "0.10.0" [deps] CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" @@ -10,7 +10,7 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" [compat] CodeTracking = "0.5.9, 1" -julia = "1.6" +julia = "1.10" [extras] CassetteOverlay = "d78b62d4-37fa-4a6f-acd8-2f19986eb9ee" diff --git a/bin/generate_builtins.jl b/bin/generate_builtins.jl index d76ea7b6..23d62077 100644 --- a/bin/generate_builtins.jl +++ b/bin/generate_builtins.jl @@ -132,7 +132,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) f = @lookup(frame, fex) end - if @static isdefined(Core, :OpaqueClosure) && f isa Core.OpaqueClosure + if f isa Core.OpaqueClosure if expand if !Core.Compiler.uncompressed_ir(f.source).inferred return Expr(:call, f, args[2:end]...) @@ -324,16 +324,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) """ if isa(f, Core.IntrinsicFunction) cargs = getargs(args, frame) - @static if isdefined(Core.Intrinsics, :have_fma) - if f === Core.Intrinsics.have_fma && length(cargs) == 1 - cargs1 = cargs[1] - if cargs1 == Float64 - return Some{Any}(FMA_FLOAT64[]) - elseif cargs1 == Float32 - return Some{Any}(FMA_FLOAT32[]) - elseif cargs1 == Float16 - return Some{Any}(FMA_FLOAT16[]) - end + if f === Core.Intrinsics.have_fma && length(cargs) == 1 + cargs1 = cargs[1] + if cargs1 == Float64 + return Some{Any}(FMA_FLOAT64[]) + elseif cargs1 == Float32 + return Some{Any}(FMA_FLOAT32[]) + elseif cargs1 == Float16 + return Some{Any}(FMA_FLOAT16[]) end end if f === Core.Intrinsics.muladd_float && length(cargs) == 3 diff --git a/src/breakpoints.jl b/src/breakpoints.jl index 79a580cb..39d03285 100644 --- a/src/breakpoints.jl +++ b/src/breakpoints.jl @@ -97,12 +97,9 @@ function framecode_matches_breakpoint(framecode::FrameCode, bp::BreakpointSignat meth isa Method || return false bp.f isa Method && return meth === bp.f f = extract_function_from_method(meth) - if !(bp.f === f || @static isdefined(Core, :kwcall) ? - f === Core.kwcall && let ftype = Base.unwrap_unionall(meth.sig).parameters[3] + if !(bp.f === f || (f === Core.kwcall && let ftype = Base.unwrap_unionall(meth.sig).parameters[3] !Base.has_free_typevars(ftype) && bp.f isa ftype - end : - Core.kwfunc(bp.f) === f - ) + end)) return false end bp.sig === nothing && return true diff --git a/src/builtins.jl b/src/builtins.jl index 2906af86..b0c5e506 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -38,7 +38,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) f = @lookup(frame, fex) end - if @static isdefined(Core, :OpaqueClosure) && f isa Core.OpaqueClosure + if f isa Core.OpaqueClosure if expand if !Core.Compiler.uncompressed_ir(f.source).inferred return Expr(:call, f, args[2:end]...) @@ -152,11 +152,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(Core.finalizer(getargs(args, frame)...)) end elseif @static isdefined(Core, :get_binding_type) && f === Core.get_binding_type - if nargs == 2 - return Some{Any}(Core.get_binding_type(@lookup(frame, args[2]), @lookup(frame, args[3]))) - else - return Some{Any}(Core.get_binding_type(getargs(args, frame)...)) - end + return Some{Any}(Core.get_binding_type(getargs(args, frame)...)) elseif f === Core.ifelse if nargs == 3 return Some{Any}(Core.ifelse(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) @@ -256,13 +252,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(getfield(getargs(args, frame)...)) end elseif @static isdefined(Core, :getglobal) && f === getglobal - if nargs == 2 - return Some{Any}(getglobal(@lookup(frame, args[2]), @lookup(frame, args[3]))) - elseif nargs == 3 - return Some{Any}(getglobal(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) - else - return Some{Any}(getglobal(getargs(args, frame)...)) - end + return Some{Any}(getglobal(getargs(args, frame)...)) elseif f === invoke if !expand argswrapped = getargs(args, frame) @@ -294,13 +284,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(modifyfield!(getargs(args, frame)...)) end elseif @static isdefined(Core, :modifyglobal!) && f === modifyglobal! - if nargs == 4 - return Some{Any}(modifyglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) - elseif nargs == 5 - return Some{Any}(modifyglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6]))) - else - return Some{Any}(modifyglobal!(getargs(args, frame)...)) - end + return Some{Any}(modifyglobal!(getargs(args, frame)...)) elseif f === nfields if nargs == 1 return Some{Any}(nfields(@lookup(frame, args[2]))) @@ -318,15 +302,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(replacefield!(getargs(args, frame)...)) end elseif @static isdefined(Core, :replaceglobal!) && f === replaceglobal! - if nargs == 4 - return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) - elseif nargs == 5 - return Some{Any}(replaceglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6]))) - elseif nargs == 6 - 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]))) - else - return Some{Any}(replaceglobal!(getargs(args, frame)...)) - end + return Some{Any}(replaceglobal!(getargs(args, frame)...)) elseif f === setfield! if nargs == 3 return Some{Any}(setfield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) @@ -346,23 +322,9 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(setfieldonce!(getargs(args, frame)...)) end elseif @static isdefined(Core, :setglobal!) && f === setglobal! - if nargs == 3 - return Some{Any}(setglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) - elseif nargs == 4 - return Some{Any}(setglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) - else - return Some{Any}(setglobal!(getargs(args, frame)...)) - end + return Some{Any}(setglobal!(getargs(args, frame)...)) elseif @static isdefined(Core, :setglobalonce!) && f === setglobalonce! - if nargs == 3 - return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) - elseif nargs == 4 - return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) - elseif nargs == 5 - return Some{Any}(setglobalonce!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]), @lookup(frame, args[6]))) - else - return Some{Any}(setglobalonce!(getargs(args, frame)...)) - end + return Some{Any}(setglobalonce!(getargs(args, frame)...)) elseif @static isdefined(Core, :swapfield!) && f === swapfield! if nargs == 3 return Some{Any}(swapfield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) @@ -372,13 +334,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(swapfield!(getargs(args, frame)...)) end elseif @static isdefined(Core, :swapglobal!) && f === swapglobal! - if nargs == 3 - return Some{Any}(swapglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) - elseif nargs == 4 - return Some{Any}(swapglobal!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) - else - return Some{Any}(swapglobal!(getargs(args, frame)...)) - end + return Some{Any}(swapglobal!(getargs(args, frame)...)) elseif f === throw if nargs == 1 return Some{Any}(throw(@lookup(frame, args[2]))) @@ -500,16 +456,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) end if isa(f, Core.IntrinsicFunction) cargs = getargs(args, frame) - @static if isdefined(Core.Intrinsics, :have_fma) - if f === Core.Intrinsics.have_fma && length(cargs) == 1 - cargs1 = cargs[1] - if cargs1 == Float64 - return Some{Any}(FMA_FLOAT64[]) - elseif cargs1 == Float32 - return Some{Any}(FMA_FLOAT32[]) - elseif cargs1 == Float16 - return Some{Any}(FMA_FLOAT16[]) - end + if f === Core.Intrinsics.have_fma && length(cargs) == 1 + cargs1 = cargs[1] + if cargs1 == Float64 + return Some{Any}(FMA_FLOAT64[]) + elseif cargs1 == Float32 + return Some{Any}(FMA_FLOAT32[]) + elseif cargs1 == Float16 + return Some{Any}(FMA_FLOAT16[]) end end if f === Core.Intrinsics.muladd_float && length(cargs) == 3 diff --git a/src/commands.jl b/src/commands.jl index 3cdfd3d6..ab958757 100644 --- a/src/commands.jl +++ b/src/commands.jl @@ -226,8 +226,7 @@ function maybe_step_through_wrapper!(@nospecialize(recurse), frame::Frame) if unwrap1 isa DataType param1 = Base.unwrap_unionall(unwrap1.parameters[1]) if param1 isa DataType - is_kw = isdefined(Core, :kwcall) ? param1.name.name === Symbol("#kwcall") : - endswith(String(param1.name.name), "#kw") + is_kw = param1.name.name === Symbol("#kwcall") end end end @@ -255,13 +254,8 @@ function maybe_step_through_wrapper!(@nospecialize(recurse), frame::Frame) end maybe_step_through_wrapper!(frame::Frame) = maybe_step_through_wrapper!(finish_and_return!, frame) -if isdefined(Core, :kwcall) - const kwhandler = Core.kwcall - const kwextrastep = 0 -else - const kwhandler = Core.kwfunc - const kwextrastep = 1 -end +const kwhandler = Core.kwcall +const kwextrastep = 0 """ frame = maybe_step_through_kwprep!(recurse, frame) diff --git a/src/construct.jl b/src/construct.jl index 64e54971..036ff60d 100644 --- a/src/construct.jl +++ b/src/construct.jl @@ -88,18 +88,10 @@ end get_source(meth::Method) = Base.uncompressed_ast(meth) -@static if VERSION < v"1.10.0-DEV.873" # julia#48766 - function get_source(g::GeneratedFunctionStub, env, file, line) - b = g(env..., g.argnames...) - b isa CodeInfo && return b - return eval(b) - end -else - function get_source(g::GeneratedFunctionStub, env, file, line::Int) - b = g(Base.get_world_counter(), LineNumberNode(line, file), env..., g.argnames...) - b isa CodeInfo && return b - return eval(b) - end +function get_source(g::GeneratedFunctionStub, env, file, line::Int) + b = g(Base.get_world_counter(), LineNumberNode(line, file), env..., g.argnames...) + b isa CodeInfo && return b + return eval(b) end """ @@ -241,7 +233,7 @@ function prepare_call(@nospecialize(f), allargs; enter_generated = false) end argtypesv = Any[_Typeof(a) for a in allargs] argtypes = Tuple{argtypesv...} - if @static isdefined(Core, :OpaqueClosure) && f isa Core.OpaqueClosure + if f isa Core.OpaqueClosure method = f.source # don't try to interpret optimized ir if Core.Compiler.uncompressed_ir(method).inferred @@ -308,7 +300,7 @@ function prepare_framedata(framecode, argvals::Vector{Any}, lenv::SimpleVector=e islastva = meth.isva && nargs >= meth_nargs for i = 1:meth_nargs-islastva # for OCs #self# actually refers to the captures instead - if @static isdefined(Core, :OpaqueClosure) && i == 1 && (oc = argvals[1]) isa Core.OpaqueClosure + if i == 1 && (oc = argvals[1]) isa Core.OpaqueClosure locals[i], last_reference[i] = Some{Any}(oc.captures), 1 elseif i <= nargs locals[i], last_reference[i] = Some{Any}(argvals[i]), 1 diff --git a/src/interpret.jl b/src/interpret.jl index 119524e2..2f295f78 100644 --- a/src/interpret.jl +++ b/src/interpret.jl @@ -184,8 +184,7 @@ function evaluate_foreigncall(@nospecialize(recurse), frame::Frame, call_expr::E sig = scope.sig args[2] = instantiate_type_in_env(args[2], sig, data.sparams) arg3 = args[3] - if (@static VERSION < v"1.7.0" && arg3 isa Core.SimpleVector) || - head === :foreigncall + if head === :foreigncall args[3] = Core.svec(map(arg3) do arg instantiate_type_in_env(arg, sig, data.sparams) end...) @@ -209,11 +208,7 @@ function bypass_builtins(@nospecialize(recurse), frame::Frame, call_expr::Expr, fmod = parentmodule(f)::Module if fmod === JuliaInterpreter.CompiledCalls || fmod === Core.Compiler # Fixing https://github.com/JuliaDebug/JuliaInterpreter.jl/issues/432. - @static if VERSION >= v"1.7.0" - return Some{Any}(Base.invoke_in_world(get_world_counter(), f, fargs[2:end]...)) - else - return Some{Any}(Base.invokelatest(f, fargs[2:end]...)) - end + return Some{Any}(Base.invoke_in_world(get_world_counter(), f, fargs[2:end]...)) else return Some{Any}(f(fargs[2:end]...)) end @@ -326,11 +321,7 @@ function evaluate_methoddef(frame::Frame, node::Expr) sig = @lookup(frame, node.args[2])::SimpleVector body = @lookup(frame, node.args[3])::Union{CodeInfo, Expr} # branching on https://github.com/JuliaLang/julia/pull/41137 - @static if isdefined(Core.Compiler, :OverlayMethodTable) - ccall(:jl_method_def, Cvoid, (Any, Ptr{Cvoid}, Any, Any), sig, C_NULL, body, moduleof(frame)::Module) - else - ccall(:jl_method_def, Cvoid, (Any, Any, Any), sig, body, moduleof(frame)::Module) - end + ccall(:jl_method_def, Cvoid, (Any, Ptr{Cvoid}, Any, Any), sig, C_NULL, body, moduleof(frame)::Module) return f end @@ -346,11 +337,7 @@ function do_assignment!(frame::Frame, @nospecialize(lhs), @nospecialize(rhs)) mod = lhs isa Symbol ? moduleof(frame) : lhs.mod name = lhs isa Symbol ? lhs : lhs.name Core.eval(mod, Expr(:global, name)) - @static if @isdefined setglobal! - setglobal!(mod, name, rhs) - else - ccall(:jl_set_global, Cvoid, (Any, Any, Any), mod, name, rhs) - end + setglobal!(mod, name, rhs) end end @@ -461,7 +448,7 @@ function step_expr!(@nospecialize(recurse), frame::Frame, @nospecialize(node), i # @show node # end @assert is_leaf(frame) - @static VERSION >= v"1.8.0-DEV.370" && coverage_visit_line!(frame) + coverage_visit_line!(frame) local rhs # For debugging: # show_stackloc(frame) diff --git a/src/optimize.jl b/src/optimize.jl index 68565f11..1dda19a2 100644 --- a/src/optimize.jl +++ b/src/optimize.jl @@ -271,11 +271,7 @@ function replace_coretypes_list!(list::AbstractVector; rev::Bool=false) isa(x, Core.SSAValue) && return SSAValue(x.id) isa(x, Core.SlotNumber) && return SlotNumber(x.id) @static if VERSION < v"1.11.0-DEV.337" - @static if VERSION ≥ v"1.10.0-DEV.631" - isa(x, Core.Compiler.TypedSlot) && return SlotNumber(x.id) - else - isa(x, Core.TypedSlot) && return SlotNumber(x.id) - end + isa(x, Core.Compiler.TypedSlot) && return SlotNumber(x.id) end return x end diff --git a/src/packagedef.jl b/src/packagedef.jl index db0f7863..17ed49c9 100644 --- a/src/packagedef.jl +++ b/src/packagedef.jl @@ -1,5 +1,5 @@ using Base.Meta -import Base: +, -, convert, isless, get_world_counter +import Base: +, -, convert, isless, get_world_counter, mapany, ntupleany using Core: CodeInfo, SimpleVector, LineInfoNode, GotoNode, GotoIfNot, ReturnNode, GeneratedFunctionStub, MethodInstance, NewvarNode, TypeName @@ -22,28 +22,7 @@ const SlotNamesType = Vector{Symbol} append_any(@nospecialize x...) = append!([], Core.svec((x...)...)) -if isdefined(Base, :mapany) - const mapany = Base.mapany -else - mapany(f, itr) = map!(f, Vector{Any}(undef, length(itr)::Int), itr) # convenient for Expr.args -end - -if isdefined(Base, :ntupleany) - const ntupleany = Base.ntupleany -else - @noinline function ntupleany(f, n) - (n >= 0) || throw(ArgumentError(string("tuple length should be ≥ 0, got ", n))) - (Any[f(i) for i = 1:n]...,) - end -end - -if !isdefined(Base, Symbol("@something")) - macro something(x...) - :(something($(map(esc, x)...))) - end -end - -if isdefined(Base, :ScopedValues) +@static if isdefined(Base, :ScopedValues) using Base: ScopedValues.Scope else const Scope = Any @@ -103,10 +82,10 @@ function set_compiled_methods() end # Does an atomic operation via llvmcall (this fixes #354) - if isdefined(Base, :load_state_acquire) - for m in methods(Base.load_state_acquire) - push!(compiled_methods, m) - end + @static if isdefined(Base, :load_state_acquire) # VERSION < v"1.12-" + for m in methods(Base.load_state_acquire) + push!(compiled_methods, m) + end end # This is about performance, not safety (issue #462) @@ -157,11 +136,9 @@ function __init__() # precompile(f, AT) # end - @static if isdefined(Base, :have_fma) - FMA_FLOAT64[] = _have_fma_compiled(Float64) - FMA_FLOAT32[] = _have_fma_compiled(Float32) - FMA_FLOAT16[] = _have_fma_compiled(Float16) - end + FMA_FLOAT64[] = _have_fma_compiled(Float64) + FMA_FLOAT32[] = _have_fma_compiled(Float32) + FMA_FLOAT16[] = _have_fma_compiled(Float16) end include("precompile.jl") diff --git a/src/types.jl b/src/types.jl index ad935213..2872ca2b 100644 --- a/src/types.jl +++ b/src/types.jl @@ -257,7 +257,7 @@ mutable struct Frame world::UInt end function Frame(framecode::FrameCode, framedata::FrameData, pc=1, caller=nothing, - world=isdefined(Base, :tls_world_age) ? Base.tls_world_age() : Base.get_world_counter()) + world=@static isdefined(Base, :tls_world_age) ? Base.tls_world_age() : Base.get_world_counter()) if length(junk_frames) > 0 frame = pop!(junk_frames) frame.framecode = framecode diff --git a/src/utils.jl b/src/utils.jl index 440ecd69..d349f850 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -33,18 +33,11 @@ and doesn't throw when there is no matching method. """ function whichtt(@nospecialize(tt)) # TODO: provide explicit control over world age? In case we ever need to call "old" methods. - @static if VERSION ≥ v"1.8-beta2" - # branch on https://github.com/JuliaLang/julia/pull/44515 - # for now, actual code execution doesn't ever need to consider overlayed method table - match, _ = Core.Compiler._findsup(tt, nothing, get_world_counter()) - match === nothing && return nothing - return match.method - else - m = ccall(:jl_gf_invoke_lookup, Any, (Any, Csize_t), tt, get_world_counter()) - m === nothing && return nothing - isa(m, Method) && return m - return m.func::Method - end + # branch on https://github.com/JuliaLang/julia/pull/44515 + # for now, actual code execution doesn't ever need to consider overlayed method table + match, _ = Core.Compiler._findsup(tt, nothing, get_world_counter()) + match === nothing && return nothing + return match.method end instantiate_type_in_env(arg, spsig::UnionAll, spvals::Vector{Any}) = @@ -210,11 +203,7 @@ end is_generated(meth::Method) = isdefined(meth, :generator) -@static if VERSION < v"1.10.0-DEV.873" # julia#48766 - get_staged(mi::MethodInstance) = Core.Compiler.get_staged(mi) -else - get_staged(mi::MethodInstance) = Core.Compiler.get_staged(mi, Base.get_world_counter()) -end +get_staged(mi::MethodInstance) = Core.Compiler.get_staged(mi, Base.get_world_counter()) """ is_doc_expr(ex) @@ -239,20 +228,7 @@ end is_leaf(frame::Frame) = frame.callee === nothing -function is_vararg_type(x) - @static if isa(Vararg, Type) - if isa(x, Type) - (x <: Vararg && !(x <: Union{})) && return true - if isa(x, UnionAll) - x = Base.unwrap_unionall(x) - end - return isa(x, DataType) && nameof(x) === :Vararg - end - else - return isa(x, typeof(Vararg)) - end - return false -end +is_vararg_type(@nospecialize x) = x isa Core.TypeofVararg ## Location info @@ -524,26 +500,24 @@ end function framecode_lines(src::CodeInfo) buf = IOBuffer() - if isdefined(Base.IRShow, :show_ir_stmt) - lines = String[] - src = replace_coretypes!(copy(src); rev=true) - reverse_lookup_globalref!(src.code) - io = IOContext(buf, :displaysize => displaysize(stdout), - :SOURCE_SLOTNAMES => Base.sourceinfo_slotnames(src)) - used = BitSet() - cfg = Core.Compiler.compute_basic_blocks(src.code) - for stmt in src.code - Core.Compiler.scan_ssa_use!(push!, used, stmt) - end - line_info_preprinter = Base.IRShow.lineinfo_disabled - line_info_postprinter = Base.IRShow.default_expr_type_printer - bb_idx = 1 - for idx = 1:length(src.code) - bb_idx = Base.IRShow.show_ir_stmt(io, src, idx, line_info_preprinter, line_info_postprinter, used, cfg, bb_idx) - push!(lines, chomp(String(take!(buf)))) - end - return lines - end + lines = String[] + src = replace_coretypes!(copy(src); rev=true) + reverse_lookup_globalref!(src.code) + io = IOContext(buf, :displaysize => displaysize(stdout), + :SOURCE_SLOTNAMES => Base.sourceinfo_slotnames(src)) + used = BitSet() + cfg = Core.Compiler.compute_basic_blocks(src.code) + for stmt in src.code + Core.Compiler.scan_ssa_use!(push!, used, stmt) + end + line_info_preprinter = Base.IRShow.lineinfo_disabled + line_info_postprinter = Base.IRShow.default_expr_type_printer + bb_idx = 1 + for idx = 1:length(src.code) + bb_idx = Base.IRShow.show_ir_stmt(io, src, idx, line_info_preprinter, line_info_postprinter, used, cfg, bb_idx) + push!(lines, chomp(String(take!(buf)))) + end + return lines show(buf, src) code = filter!(split(String(take!(buf)), '\n')) do line !(line == "CodeInfo(" || line == ")" || isempty(line) || occursin("within `", line)) @@ -829,12 +803,8 @@ function Base.show_backtrace(io::IO, frame::Frame) nd = ndigits(length(stackframes)) for (i, (last_frame, n)) in enumerate(stackframes) frame_counter += 1 - if isdefined(Base, :print_stackframe) - println(io) - Base.print_stackframe(io, i, last_frame, n, nd, Base.info_color()) - else - Base.show_trace_entry(IOContext(io, :backtrace => true), last_frame, n, prefix = string(" [", frame_counter, "] ")) - end + println(io) + Base.print_stackframe(io, i, last_frame, n, nd, Base.info_color()) end end diff --git a/test/breakpoints.jl b/test/breakpoints.jl index ecf352c3..91660d34 100644 --- a/test/breakpoints.jl +++ b/test/breakpoints.jl @@ -195,11 +195,7 @@ struct Squarer end # Breakpoint display io = IOBuffer() frame = JuliaInterpreter.enter_call(loop_radius2, 2) - @static if VERSION < v"1.9.0-DEV.846" # https://github.com/JuliaLang/julia/pull/45069 - LOC = " in $(@__MODULE__) at $(@__FILE__)" - else - LOC = " @ $(@__MODULE__) $(contractuser(@__FILE__))" - end + LOC = " @ $(@__MODULE__) $(contractuser(@__FILE__))" bp = JuliaInterpreter.BreakpointRef(frame.framecode, 1) @test repr(bp) == "breakpoint(loop_radius2(n)$LOC:$(3-Δ), line 3)" bp = JuliaInterpreter.BreakpointRef(frame.framecode, 0) # fictive breakpoint diff --git a/test/core.jl b/test/core.jl index b845f7a5..0480a004 100644 --- a/test/core.jl +++ b/test/core.jl @@ -20,9 +20,7 @@ using Test frame = JuliaInterpreter.enter_call(buildexpr) lines = JuliaInterpreter.framecode_lines(frame.framecode.src) # Test that the :copyast ends up on the same line as the println - if isdefined(Base.IRShow, :show_ir_stmt) # only works on Julia 1.6 and higher - @test any(str->occursin(":copyast", str) && occursin("println", str), lines) - end + @test any(str->occursin(":copyast", str) && occursin("println", str), lines) thunk = Meta.lower(Main, :(return 1+2)) stmt = thunk.args[1].code[end]::Core.ReturnNode # the return diff --git a/test/debug.jl b/test/debug.jl index 78fafb45..d381e89b 100644 --- a/test/debug.jl +++ b/test/debug.jl @@ -146,8 +146,7 @@ end cframe, pc = debug_command(frame, :sg) # Aside: generators can have `Expr(:line, ...)` in their line tables, test that this is OK lt = JuliaInterpreter.linetable(cframe, 2) - @test isexpr(lt, :line) || isa(lt, Core.LineInfoNode) || - (isdefined(Base.IRShow, :LineInfoNode) && isa(lt, Base.IRShow.LineInfoNode)) + @test isexpr(lt, :line) || isa(lt, Core.LineInfoNode) || isa(lt, Base.IRShow.LineInfoNode) @test isa(pc, BreakpointRef) @test JuliaInterpreter.scopeof(cframe).name === :generatedfoo cframe, pc = debug_command(cframe, :finish) @@ -392,7 +391,7 @@ end @test get_return(frame) == f_inv(2) end - f_inv_latest(x::Real) = 1 + (@static isdefined(Core, :_call_latest) ? Core._call_latest(f_inv, x) : Core._apply_latest(f_inv, x)) + f_inv_latest(x::Real) = 1 + Core._call_latest(f_inv, x) @testset "invokelatest" begin fr = JuliaInterpreter.enter_call(f_inv_latest, 2.0) fr, pc = JuliaInterpreter.debug_command(fr, :nc) @@ -427,12 +426,7 @@ end frame = JuliaInterpreter.enter_call(sort, a) frame = stepkw!(frame) - @static if VERSION ≥ v"1.7" - # TODO fix this broken test (@aviatesk) - @test frame.pc == JuliaInterpreter.nstatements(frame.framecode) - 1 broken=VERSION≥v"1.11-" - else - @test frame.pc == JuliaInterpreter.nstatements(frame.framecode) - 1 - end + @test frame.pc == JuliaInterpreter.nstatements(frame.framecode) - 1 broken=VERSION≥v"1.11-" frame, pc = debug_command(frame, :s) frame, pc = debug_command(frame, :se) # get past copymutable @@ -477,7 +471,7 @@ end @testset "si should not step through wrappers or kwprep" begin frame = JuliaInterpreter.enter_call(h_1, 2, 1) frame, pc = debug_command(frame, :si) - @test frame.pc == (VERSION >= v"1.11-" ? 2 : 1) + @test frame.pc == (@static VERSION >= v"1.11-" ? 2 : 1) end @testset "breakpoints hit during wrapper step through" begin diff --git a/test/interpret.jl b/test/interpret.jl index d36ef916..35e898b0 100644 --- a/test/interpret.jl +++ b/test/interpret.jl @@ -256,13 +256,6 @@ let a = ['0'], b = ['a'] @test @interpret(vcat(a, b)) == vcat(a, b) end -# issue #51 -if isdefined(Core.Compiler, :SNCA) - ci = @code_lowered gcd(10, 20) - cfg = Core.Compiler.compute_basic_blocks(ci.code) - @test isa(@interpret(Core.Compiler.SNCA(cfg)), Vector{Int}) -end - # llvmcall function add1234(x::Tuple{Int32,Int32,Int32,Int32}) Base.llvmcall("""%3 = extractvalue [4 x i32] %0, 0 @@ -472,13 +465,9 @@ fr = JuliaInterpreter.enter_call(Test.eval, 1) file, line = JuliaInterpreter.whereis(fr) @test isfile(file) @static if VERSION < v"1.12.0-DEV.173" - @test isfile(JuliaInterpreter.getfile(fr.framecode.src.linetable[1])) -end -@static if VERSION < v"1.9.0-DEV.846" # https://github.com/JuliaLang/julia/pull/45069 - @test occursin(Sys.STDLIB, repr(fr)) -else - @test occursin(contractuser(Sys.STDLIB), repr(fr)) +@test isfile(JuliaInterpreter.getfile(fr.framecode.src.linetable[1])) end +@test occursin(contractuser(Sys.STDLIB), repr(fr)) # Test undef sparam (https://github.com/JuliaDebug/JuliaInterpreter.jl/issues/165) function foo(x::T) where {T <: AbstractString, S <: AbstractString} @@ -509,32 +498,21 @@ g_2(x) = g_3(x) g_3(x) = error("foo") line_g = @__LINE__ -if isdefined(Base, :replaceuserpath) - _contractuser = Base.replaceuserpath -else - _contractuser = Base.contractuser -end +_contractuser = Base.contractuser try break_on(:error) local frame, bp = @interpret g_1(2.0) stacktrace_lines = split(sprint(Base.display_error, bp.err, leaf(frame)), '\n') @test occursin(string("ERROR: ", sprint(showerror, ErrorException("foo"))), stacktrace_lines[1]) - if isdefined(Base, :print_stackframe) - @test occursin("[1] error(s::String)", stacktrace_lines[3]) - @test occursin("[2] g_3(x::Float64)", stacktrace_lines[5]) - thefile = _contractuser(@__FILE__) - @test occursin("$thefile:$(line_g - 1)", stacktrace_lines[6]) - @test occursin("[3] g_2(x::Float64)", stacktrace_lines[7]) - @test occursin("$thefile:$(line_g - 2)", stacktrace_lines[8]) - @test occursin("[4] g_1(x::Float64)", stacktrace_lines[9]) - @test occursin("$thefile:$(line_g - 3)", stacktrace_lines[10]) - else - @test occursin("[1] error(::String) at error.jl:", stacktrace_lines[3]) - @test occursin("[2] g_3(::Float64) at $(@__FILE__):$(line_g - 1)", stacktrace_lines[4]) - @test occursin("[3] g_2(::Float64) at $(@__FILE__):$(line_g - 2)", stacktrace_lines[5]) - @test occursin("[4] g_1(::Float64) at $(@__FILE__):$(line_g - 3)", stacktrace_lines[6]) - end + @test occursin("[1] error(s::String)", stacktrace_lines[3]) + @test occursin("[2] g_3(x::Float64)", stacktrace_lines[5]) + thefile = _contractuser(@__FILE__) + @test occursin("$thefile:$(line_g - 1)", stacktrace_lines[6]) + @test occursin("[3] g_2(x::Float64)", stacktrace_lines[7]) + @test occursin("$thefile:$(line_g - 2)", stacktrace_lines[8]) + @test occursin("[4] g_1(x::Float64)", stacktrace_lines[9]) + @test occursin("$thefile:$(line_g - 3)", stacktrace_lines[10]) finally break_off(:error) end @@ -549,24 +527,16 @@ try frame, bp = JuliaInterpreter.debug_command(frame, :c, true) stacktrace_lines = split(sprint(Base.display_error, bp.err, leaf(frame)), '\n') @test occursin(string("ERROR: ", sprint(showerror, ErrorException("foo"))), stacktrace_lines[1]) - if isdefined(Base, :print_stackframe) - @test occursin("[1] error(s::String)", stacktrace_lines[3]) - thefile = _contractuser(@__FILE__) - @test occursin("[2] g_3(x::Float64)", stacktrace_lines[5]) - @test occursin("$thefile:$(line_g - 1)", stacktrace_lines[6]) - @test occursin("[3] g_2(x::Float64)", stacktrace_lines[7]) - @test occursin("$thefile:$(line_g - 2)", stacktrace_lines[8]) - @test occursin("[4] g_1(x::Float64)", stacktrace_lines[9]) - @test occursin("$thefile:$(line_g - 3)", stacktrace_lines[10]) - @test occursin("[5] top-level scope", stacktrace_lines[11]) - @test occursin("$thefile:$(line2_g - 2)", stacktrace_lines[12]) - else - @test occursin("[1] error(::String) at error.jl:", stacktrace_lines[3]) - @test occursin("[2] g_3(::Float64) at $(@__FILE__):$(line_g - 1)", stacktrace_lines[4]) - @test occursin("[3] g_2(::Float64) at $(@__FILE__):$(line_g - 2)", stacktrace_lines[5]) - @test occursin("[4] g_1(::Float64) at $(@__FILE__):$(line_g - 3)", stacktrace_lines[6]) - @test occursin("[5] top-level scope at $(@__FILE__):$(line2_g - 2)", stacktrace_lines[7]) - end + @test occursin("[1] error(s::String)", stacktrace_lines[3]) + thefile = _contractuser(@__FILE__) + @test occursin("[2] g_3(x::Float64)", stacktrace_lines[5]) + @test occursin("$thefile:$(line_g - 1)", stacktrace_lines[6]) + @test occursin("[3] g_2(x::Float64)", stacktrace_lines[7]) + @test occursin("$thefile:$(line_g - 2)", stacktrace_lines[8]) + @test occursin("[4] g_1(x::Float64)", stacktrace_lines[9]) + @test occursin("$thefile:$(line_g - 3)", stacktrace_lines[10]) + @test occursin("[5] top-level scope", stacktrace_lines[11]) + @test occursin("$thefile:$(line2_g - 2)", stacktrace_lines[12]) finally break_off(:error) end @@ -678,9 +648,7 @@ end let # NOTE we need to make sure this code block is compiled, since vecadd is generated function, # but currently `@interpret` doesn't handle a call to generated functions very well - @static if isdefined(Base.Experimental, Symbol("@force_compile")) - Base.Experimental.@force_compile - end + Base.Experimental.@force_compile a = (VecElement{Float64}(1.0), VecElement{Float64}(2.0)) @test @interpret(VecTest.vecadd(a, a)) == VecTest.vecadd(a, a) end @@ -814,11 +782,7 @@ end end # this shouldn't throw "type DataType has no field hasfreetypevars" # even after https://github.com/JuliaLang/julia/pull/41018 - @static if VERSION ≥ v"1.9.0-DEV.1556" - @test Int === @interpret Core.Compiler.getfield_tfunc(Core.Compiler.fallback_lattice, m.Foo, Core.Compiler.Const(:foo)) - else - @test Int === @interpret Core.Compiler.getfield_tfunc(m.Foo, Core.Compiler.Const(:foo)) - end + @test Int === @interpret Core.Compiler.getfield_tfunc(Core.Compiler.fallback_lattice, m.Foo, Core.Compiler.Const(:foo)) end @testset "https://github.com/JuliaDebug/JuliaInterpreter.jl/issues/488" begin @@ -835,14 +799,12 @@ module ForInclude end @test JuliaInterpreter.finish_and_return!(Frame(ForInclude, ex), true) == 55 end -@static if VERSION >= v"1.7.0" - @testset "issue #432" begin - function f() - t = @ccall time(C_NULL::Ptr{Cvoid})::Cint - end - @test @interpret(f()) !== 0 - @test @interpret(f()) !== 0 +@testset "issue #432" begin + function f() + t = @ccall time(C_NULL::Ptr{Cvoid})::Cint end + @test @interpret(f()) !== 0 + @test @interpret(f()) !== 0 end @testset "issue #385" begin @@ -874,11 +836,7 @@ end end ci = code_typed(foo, NTuple{2, Int}; optimize=false)[][1] - @static if VERSION ≥ v"1.10.0-DEV.873" - mi = Core.Compiler.method_instances(foo, NTuple{2, Int}, Base.get_world_counter())[] - else - mi = Core.Compiler.method_instances(foo, NTuple{2, Int})[] - end + mi = Core.Compiler.method_instances(foo, NTuple{2, Int}, Base.get_world_counter())[] frameargs = Any[foo, 1, 2] framecode = JuliaInterpreter.FrameCode(mi.def, ci) @@ -923,7 +881,6 @@ end @test (@interpret iscallexpr(:(sin(3.14)))) end -if isdefined(Base, :have_fma) f_fma() = Base.have_fma(Float64) @testset "fma" begin @test (@interpret f_fma()) == f_fma() @@ -932,7 +889,6 @@ f_fma() = Base.have_fma(Float64) a = 1.0883740903666346; b = 2/3 @test (@interpret a^b) === a^b end -end # issue 536 function foo_536(y::T) where {T} @@ -943,34 +899,27 @@ end @test !@interpret foo_536(0x00) @test @interpret foo_536(UInt8('A')) -@static if isdefined(Base.Experimental, Symbol("@opaque")) - @testset "opaque closures" begin - g(x) = 3x - f = Base.Experimental.@opaque x -> g(x) - @test @interpret(f(4)) == 12 +@testset "opaque closures" begin + g(x) = 3x + f = Base.Experimental.@opaque x -> g(x) + @test @interpret(f(4)) == 12 - # test stepping into opaque closures - @breakpoint g(1) - fr = JuliaInterpreter.enter_call_expr(Expr(:call, f, 4)) - @test JuliaInterpreter.finish_and_return!(fr) isa JuliaInterpreter.BreakpointRef - end + # test stepping into opaque closures + @breakpoint g(1) + fr = JuliaInterpreter.enter_call_expr(Expr(:call, f, 4)) + @test JuliaInterpreter.finish_and_return!(fr) isa JuliaInterpreter.BreakpointRef end # CassetteOverlay, issue #552 -@static if VERSION >= v"1.8" using CassetteOverlay -end - -@static if VERSION >= v"1.8" -function foo() +function cassette_overlay_func() x = IdDict() x[:foo] = 1 end @MethodTable SinTable; @testset "CassetteOverlay" begin pass = @overlaypass SinTable; - @test (@interpret pass(foo)) == 1 -end + @test (@interpret pass(cassette_overlay_func)) == 1 end using LoopVectorization diff --git a/test/limits.jl b/test/limits.jl index b3429a40..73e92044 100644 --- a/test/limits.jl +++ b/test/limits.jl @@ -89,14 +89,8 @@ module EvalLimited end nstmts = 10*21 + 27 # 10 * 21 statements per iteration + α elseif VERSION >= v"1.11-" nstmts = 10*17 + 20 # 10 * 17 statements per iteration + α - elseif VERSION >= v"1.10-" - nstmts = 10*15 + 20 # 10 * 15 statements per iteration + α - elseif isdefined(Core, :get_binding_type) - nstmts = 10*14 + 20 # 10 * 14 statements per iteration + α - elseif VERSION >= v"1.7-" - nstmts = 10*11 + 20 # 10 * 9 statements per iteration + α else - nstmts = 10*10 + 20 # 10 * 10 statements per iteration + α + nstmts = 10*15 + 20 # 10 * 15 statements per iteration + α end for (mod, ex) in modexs frame = Frame(mod, ex) diff --git a/test/runtests.jl b/test/runtests.jl index f43c24d7..46e4aae2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -18,7 +18,7 @@ Core.eval(JuliaInterpreter, :(debug_mode() = true)) @testset "limits.jl" begin include("limits.jl") end @testset "eval_code.jl" begin include("eval_code.jl") end @testset "breakpoints.jl" begin include("breakpoints.jl") end - @static VERSION >= v"1.8.0-DEV.370" && @testset "code_coverage/code_coverage.jl" begin include("code_coverage/code_coverage.jl") end + @testset "code_coverage/code_coverage.jl" begin include("code_coverage/code_coverage.jl") end remove() @testset "debug.jl" begin include("debug.jl") end end diff --git a/test/utils.jl b/test/utils.jl index 96729a06..2fdd5758 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -31,15 +31,9 @@ end ## For running interpreter frames under resource limitations -if isdefined(Base.IRShow, :LineInfoNode) struct Aborted # for signaling that some statement or test blocks were interrupted at::Base.IRShow.LineInfoNode end -else -struct Aborted # for signaling that some statement or test blocks were interrupted - at::Core.LineInfoNode -end -end function Aborted(frame::Frame, pc) lineidx = JuliaInterpreter.codelocs(frame, pc) From ce6a008dcf7956ef2111a5cc63f3a7b9fe5aeeb6 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 14 Nov 2024 21:06:39 +0900 Subject: [PATCH 2/7] use `Base._uncompressed_ir` --- bin/generate_builtins.jl | 2 +- src/builtins.jl | 2 +- src/construct.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/generate_builtins.jl b/bin/generate_builtins.jl index 23d62077..7a306712 100644 --- a/bin/generate_builtins.jl +++ b/bin/generate_builtins.jl @@ -134,7 +134,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) if f isa Core.OpaqueClosure if expand - if !Core.Compiler.uncompressed_ir(f.source).inferred + if !Base.uncompressed_ir(f.source).inferred return Expr(:call, f, args[2:end]...) else @debug "not interpreting opaque closure \$f since it contains inferred code" diff --git a/src/builtins.jl b/src/builtins.jl index b0c5e506..9eb9fe3f 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -40,7 +40,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) if f isa Core.OpaqueClosure if expand - if !Core.Compiler.uncompressed_ir(f.source).inferred + if !Base.uncompressed_ir(f.source).inferred return Expr(:call, f, args[2:end]...) else @debug "not interpreting opaque closure $f since it contains inferred code" diff --git a/src/construct.jl b/src/construct.jl index 036ff60d..1b3766ef 100644 --- a/src/construct.jl +++ b/src/construct.jl @@ -236,7 +236,7 @@ function prepare_call(@nospecialize(f), allargs; enter_generated = false) if f isa Core.OpaqueClosure method = f.source # don't try to interpret optimized ir - if Core.Compiler.uncompressed_ir(method).inferred + if Base.uncompressed_ir(method).inferred @debug "not interpreting opaque closure $f since it contains inferred code" return nothing end From 55809d4ca6590d5e09965840752cc4c500c21380 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 14 Nov 2024 21:07:45 +0900 Subject: [PATCH 3/7] use `Base.method_instances` --- test/interpret.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/interpret.jl b/test/interpret.jl index 35e898b0..d3185d47 100644 --- a/test/interpret.jl +++ b/test/interpret.jl @@ -836,7 +836,7 @@ end end ci = code_typed(foo, NTuple{2, Int}; optimize=false)[][1] - mi = Core.Compiler.method_instances(foo, NTuple{2, Int}, Base.get_world_counter())[] + mi = Base.method_instances(foo, NTuple{2, Int}, Base.get_world_counter())[] frameargs = Any[foo, 1, 2] framecode = JuliaInterpreter.FrameCode(mi.def, ci) From a95583fab2c79335985d0afee48c516149dec41f Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 14 Nov 2024 22:34:13 +0900 Subject: [PATCH 4/7] remove unnecessary `@static` from `bulitins.jl` --- bin/generate_builtins.jl | 30 ++++++++++++++++++++---------- src/builtins.jl | 24 ++++++++++++------------ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/bin/generate_builtins.jl b/bin/generate_builtins.jl index 7a306712..32095e3f 100644 --- a/bin/generate_builtins.jl +++ b/bin/generate_builtins.jl @@ -2,16 +2,26 @@ # Should be run on the latest Julia nightly using InteractiveUtils -# All builtins present in 1.6 -const ALWAYS_PRESENT = Core.Builtin[ - (<:), (===), Core._abstracttype, Core._apply_iterate, Core._apply_pure, - Core._call_in_world, Core._call_latest, Core._equiv_typedef, Core._expr, - Core._primitivetype, Core._setsuper!, Core._structtype, Core._typebody!, - Core._typevar, Core.apply_type, Core.ifelse, Core.sizeof, Core.svec, - applicable, fieldtype, getfield, invoke, isa, isdefined, nfields, - setfield!, throw, tuple, typeassert, typeof +# All builtins present in 1.10 +const RECENTLY_ADDED = Core.Builtin[ + Core.current_scope, + Core.memoryref_isassigned, + Core.memoryrefget, + Core.memoryrefmodify!, + Core.memoryrefnew, + Core.memoryrefoffset, + Core.memoryrefreplace!, + Core.memoryrefset!, + Core.memoryrefsetonce!, + Core.memoryrefswap!, + Core.throw_methoderror, + modifyglobal!, + replaceglobal!, + setfieldonce!, + setglobalonce!, + swapglobal!, ] -# Builtins present from 1.6, not builtins (potentially still normal functions) anymore +# Builtins present from 1.10, not builtins (potentially still normal functions) anymore const RECENTLY_REMOVED = GlobalRef.(Ref(Core), [ :arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, :set_binding_type! ]) @@ -235,7 +245,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) id = findfirst(isequal(f), Core.Compiler.T_FFUNC_KEY) fcall = generate_fcall(f, Core.Compiler.T_FFUNC_VAL, id) - if !(f in ALWAYS_PRESENT) + if f in RECENTLY_ADDED print(io, """ $head @static isdefined($(ft.name.module), $(repr(nameof(f)))) && f === $fname diff --git a/src/builtins.jl b/src/builtins.jl index 9eb9fe3f..c1daa054 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -86,7 +86,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(Core._apply_pure(getargs(args, frame)...)) elseif f === Core._call_in_world return Some{Any}(Core._call_in_world(getargs(args, frame)...)) - elseif @static isdefined(Core, :_call_in_world_total) && f === Core._call_in_world_total + elseif f === Core._call_in_world_total return Some{Any}(Core._call_in_world_total(getargs(args, frame)...)) elseif f === Core._call_latest args = getargs(args, frame) @@ -99,7 +99,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) push!(new_expr.args, QuoteNode(x)) end return maybe_recurse_expanded_builtin(frame, new_expr) - elseif @static isdefined(Core, :_compute_sparams) && f === Core._compute_sparams + elseif f === Core._compute_sparams return Some{Any}(Core._compute_sparams(getargs(args, frame)...)) elseif f === Core._equiv_typedef return Some{Any}(Core._equiv_typedef(getargs(args, frame)...)) @@ -111,7 +111,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(Core._setsuper!(getargs(args, frame)...)) elseif f === Core._structtype return Some{Any}(Core._structtype(getargs(args, frame)...)) - elseif @static isdefined(Core, :_svec_ref) && f === Core._svec_ref + elseif f === Core._svec_ref return Some{Any}(Core._svec_ref(getargs(args, frame)...)) elseif f === Core._typebody! return Some{Any}(Core._typebody!(getargs(args, frame)...)) @@ -123,7 +123,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) end elseif f === Core.apply_type return Some{Any}(Core.apply_type(getargs(args, frame)...)) - elseif @static isdefined(Core, :compilerbarrier) && f === Core.compilerbarrier + elseif f === Core.compilerbarrier if nargs == 2 return Some{Any}(Core.compilerbarrier(@lookup(frame, args[2]), @lookup(frame, args[3]))) else @@ -139,9 +139,9 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(Core.current_scope(getargs(args, frame)...)) end - elseif @static isdefined(Core, :donotdelete) && f === Core.donotdelete + elseif f === Core.donotdelete return Some{Any}(Core.donotdelete(getargs(args, frame)...)) - elseif @static isdefined(Core, :finalizer) && f === Core.finalizer + elseif f === Core.finalizer if nargs == 2 return Some{Any}(Core.finalizer(@lookup(frame, args[2]), @lookup(frame, args[3]))) elseif nargs == 3 @@ -151,7 +151,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(Core.finalizer(getargs(args, frame)...)) end - elseif @static isdefined(Core, :get_binding_type) && f === Core.get_binding_type + elseif f === Core.get_binding_type return Some{Any}(Core.get_binding_type(getargs(args, frame)...)) elseif f === Core.ifelse if nargs == 3 @@ -251,7 +251,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(getfield(getargs(args, frame)...)) end - elseif @static isdefined(Core, :getglobal) && f === getglobal + elseif f === getglobal return Some{Any}(getglobal(getargs(args, frame)...)) elseif f === invoke if !expand @@ -275,7 +275,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(isdefined(getargs(args, frame)...)) end - elseif @static isdefined(Core, :modifyfield!) && f === modifyfield! + elseif f === modifyfield! if nargs == 4 return Some{Any}(modifyfield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) elseif nargs == 5 @@ -291,7 +291,7 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(nfields(getargs(args, frame)...)) end - elseif @static isdefined(Core, :replacefield!) && f === replacefield! + elseif f === replacefield! if nargs == 4 return Some{Any}(replacefield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]), @lookup(frame, args[5]))) elseif nargs == 5 @@ -321,11 +321,11 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(setfieldonce!(getargs(args, frame)...)) end - elseif @static isdefined(Core, :setglobal!) && f === setglobal! + elseif f === setglobal! return Some{Any}(setglobal!(getargs(args, frame)...)) elseif @static isdefined(Core, :setglobalonce!) && f === setglobalonce! return Some{Any}(setglobalonce!(getargs(args, frame)...)) - elseif @static isdefined(Core, :swapfield!) && f === swapfield! + elseif f === swapfield! if nargs == 3 return Some{Any}(swapfield!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) elseif nargs == 4 From 5dd1ac5370750da4b4713dd3bd76bf4030137a15 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Fri, 15 Nov 2024 04:46:21 +0900 Subject: [PATCH 5/7] Update .github/workflows/CI.yml Co-authored-by: Kristoffer Carlsson --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b64df3c0..cc0bc469 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,7 +17,7 @@ jobs: - version: '1' # current stable os: ubuntu-latest arch: x64 - - version: '1.10' # lowerest version supported + - version: '1.10' # lowest version supported os: ubuntu-latest arch: x64 - version: '1.12-nightly' # next release From 69c28b2de0366647a589e96e94362ed061a3fc89 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Fri, 15 Nov 2024 04:47:50 +0900 Subject: [PATCH 6/7] fix comment --- bin/generate_builtins.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/generate_builtins.jl b/bin/generate_builtins.jl index 32095e3f..2ea4b2ac 100644 --- a/bin/generate_builtins.jl +++ b/bin/generate_builtins.jl @@ -2,7 +2,7 @@ # Should be run on the latest Julia nightly using InteractiveUtils -# All builtins present in 1.10 +# Builtins not present in 1.10 (the lowest supported version) const RECENTLY_ADDED = Core.Builtin[ Core.current_scope, Core.memoryref_isassigned, From 86cac97a05616c278124ebf73c6b2c817c34c755 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 21 Nov 2024 22:18:15 +0900 Subject: [PATCH 7/7] make this a patch bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 82efe56c..bd2926a7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "JuliaInterpreter" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.10.0" +version = "0.9.38" [deps] CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"