diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index bf7f2a10..cc0bc469 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' # lowest 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..bd2926a7 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.9.38" [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..2ea4b2ac 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 +# Builtins not present in 1.10 (the lowest supported version) +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! ]) @@ -132,9 +142,9 @@ 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 + 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" @@ -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 @@ -324,16 +334,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..c1daa054 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -38,9 +38,9 @@ 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 + 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" @@ -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,12 +151,8 @@ 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 - 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 + elseif f === Core.get_binding_type + 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]))) @@ -255,14 +251,8 @@ 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 - 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 + elseif f === getglobal + return Some{Any}(getglobal(getargs(args, frame)...)) elseif f === invoke if !expand argswrapped = getargs(args, frame) @@ -285,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 @@ -294,20 +284,14 @@ 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]))) 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 @@ -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]))) @@ -345,25 +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! - 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 + elseif f === setglobal! + 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 - elseif @static isdefined(Core, :swapfield!) && f === swapfield! + return Some{Any}(setglobalonce!(getargs(args, frame)...)) + 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 @@ -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..1b3766ef 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,10 +233,10 @@ 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 + if Base.uncompressed_ir(method).inferred @debug "not interpreting opaque closure $f since it contains inferred code" return nothing end @@ -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..d3185d47 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 = Base.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)