diff --git a/bin/generate_builtins.jl b/bin/generate_builtins.jl index bfd84bd7..b638cbd0 100644 --- a/bin/generate_builtins.jl +++ b/bin/generate_builtins.jl @@ -13,7 +13,7 @@ const ALWAYS_PRESENT = Core.Builtin[ ] # Builtins present from 1.6, not builtins (potentially still normal functions) anymore const RECENTLY_REMOVED = GlobalRef.(Ref(Core), [ - :arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, + :arrayref, :arrayset, :arrayset, :const_arrayref, :memoryref, :set_binding_type! ]) const kwinvoke = Core.kwfunc(Core.invoke) @@ -274,6 +274,9 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) maxarg = 6 elseif name === :arraysize maxarg = 2 + elseif name === :set_binding_type! + minarg = 2 + maxarg = 3 end _scopedname = "$mod.$name" fcall = generate_fcall_nargs(_scopedname, minarg, maxarg) diff --git a/src/builtins.jl b/src/builtins.jl index aac504ba..846bcc32 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -220,8 +220,6 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(Core.memoryrefswap!(getargs(args, frame)...)) end - elseif @static isdefined(Core, :set_binding_type!) && f === Core.set_binding_type! - return Some{Any}(Core.set_binding_type!(getargs(args, frame)...)) elseif f === Core.sizeof if nargs == 1 return Some{Any}(Core.sizeof(@lookup(frame, args[2]))) @@ -482,6 +480,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) else return Some{Any}(Core.memoryref(getargs(args, frame)...)) end + elseif @static (isdefined(Core, :set_binding_type!) && Core.set_binding_type! isa Core.Builtin) && f === Core.set_binding_type! + if nargs == 2 + return Some{Any}(Core.set_binding_type!(@lookup(frame, args[2]), @lookup(frame, args[3]))) + elseif nargs == 3 + return Some{Any}(Core.set_binding_type!(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) + else + return Some{Any}(Core.set_binding_type!(getargs(args, frame)...)) + end elseif f === Core.Intrinsics.llvmcall return Some{Any}(Core.Intrinsics.llvmcall(getargs(args, frame)...)) end diff --git a/src/interpret.jl b/src/interpret.jl index 26afb80c..16523cfd 100644 --- a/src/interpret.jl +++ b/src/interpret.jl @@ -538,14 +538,13 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev error("this should have been handled by split_expressions") elseif node.head === :using || node.head === :import || node.head === :export Core.eval(moduleof(frame), node) - elseif node.head === :const + elseif node.head === :const || node.head === :globaldecl g = node.args[1] - if isa(g, GlobalRef) - mod, name = g.mod, g.name + if length(node.args) == 2 + Core.eval(moduleof(frame), Expr(:block, Expr(node.head, g, @lookup(frame, node.args[2])), nothing)) else - mod, name = moduleof(frame), g::Symbol + Core.eval(moduleof(frame), Expr(:block, Expr(node.head, g), nothing)) end - Core.eval(mod, Expr(:const, name)) elseif node.head === :thunk newframe = Frame(moduleof(frame), node.args[1]::CodeInfo) if isa(recurse, Compiled) diff --git a/src/optimize.jl b/src/optimize.jl index 2ae98714..68565f11 100644 --- a/src/optimize.jl +++ b/src/optimize.jl @@ -24,14 +24,14 @@ function smallest_ref(stmts, arg, idmin) end function lookup_global_ref(a::GlobalRef) - if Base.isbindingresolved(a.mod, a.name) && isdefined(a.mod, a.name) + if Base.isbindingresolved(a.mod, a.name) && isdefined(a.mod, a.name) && isconst(a.mod, a.name) return QuoteNode(getfield(a.mod, a.name)) end return a end function lookup_global_refs!(ex::Expr) - if isexpr(ex, (:isdefined, :thunk, :toplevel, :method, :global, :const)) + if isexpr(ex, (:isdefined, :thunk, :toplevel, :method, :global, :const, :globaldecl)) return nothing end for (i, a) in enumerate(ex.args)