diff --git a/src/generate_builtins.jl b/src/generate_builtins.jl index 8256ce9da4bf2..a90e236b105f2 100644 --- a/src/generate_builtins.jl +++ b/src/generate_builtins.jl @@ -22,9 +22,15 @@ function nargs(f, table, id) maxarg = typemax(Int) end # The tfunc tables are wrong for fptoui and fptosi (fixed in https://github.com/JuliaLang/julia/pull/30787) - if f == "Base.fptoui" || f == "Base.fptosi" + if f == Base.fptoui || f == Base.fptosi minarg = 2 end + # Specialize arrayref and arrayset for small numbers of arguments + if f == Core.arrayref + maxarg = 5 + elseif f == Core.arrayset + maxarg = 6 + end return minarg, maxarg end @@ -139,8 +145,9 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) if !expand return Some{Any}($fstr(argswrapped...)) end - argsflat = Base.append_any((argswrapped[1],), argswrapped[2:end]...) - new_expr = Expr(:call) + new_expr = Expr(:call, argswrapped[1]) + popfirst!(argswrapped) + argsflat = Base.append_any(argswrapped...) for x in argsflat push!(new_expr.args, (isa(x, Symbol) || isa(x, Expr) || isa(x, QuoteNode)) ? QuoteNode(x) : x) end @@ -212,11 +219,11 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) """) end # Now handle calls with bounded numbers of args - fcall = generate_fcall_nargs("f", minmin, maxmax) print(io, """ if isa(f, Core.IntrinsicFunction) - $fcall + cargs = getargs(args, frame) + return Some{Any}(ccall(:jl_f_intrinsic_call, Any, (Any, Ptr{Any}, UInt32), f, cargs, length(cargs))) """) print(io, """ diff --git a/src/interpret.jl b/src/interpret.jl index d7a123def7ac1..3e74efa9c3ad5 100644 --- a/src/interpret.jl +++ b/src/interpret.jl @@ -135,7 +135,7 @@ function resolvefc(frame, @nospecialize(expr)) error("unexpected ccall to ", expr) end -function collect_args(frame, call_expr; isfc=false) +function collect_args(frame::Frame, call_expr::Expr; isfc::Bool=false) args = frame.framedata.callargs resize!(args, length(call_expr.args)) mod = moduleof(frame) diff --git a/src/utils.jl b/src/utils.jl index b1a44941d92c4..7d5e9a405ed37 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -148,7 +148,7 @@ is_leaf(frame::Frame) = frame.callee === nothing function is_vararg_type(x) if isa(x, Type) - x <: Vararg && return true + (x <: Vararg && !(x <: Union{})) && return true if isa(x, UnionAll) x = Base.unwrap_unionall(x) end diff --git a/test/interpret.jl b/test/interpret.jl index 05a6f026a89ab..1abf776062e61 100644 --- a/test/interpret.jl +++ b/test/interpret.jl @@ -99,6 +99,7 @@ end # issue #6 @test @interpret(Array.body.body.name) === Array.body.body.name @test @interpret(Vararg.body.body.name) === Vararg.body.body.name +@test !JuliaInterpreter.is_vararg_type(Union{}) frame = JuliaInterpreter.prepare_thunk(Main, :(Vararg.body.body.name)) @test JuliaInterpreter.finish_and_return!(frame, true) === Vararg.body.body.name frame = JuliaInterpreter.prepare_thunk(Base, :(Union{AbstractChar,Tuple{Vararg{<:AbstractChar}},AbstractVector{<:AbstractChar},Set{<:AbstractChar}}))