Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keyword argument and functors support to invoke (invoke improvement No. 4) #11165

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Main.Core.eval(Main.Core, :(baremodule Inference
using Core: Intrinsics, arraylen, arrayref, arrayset, arraysize, _expr,
kwcall, _apply, typeassert, apply_type, svec
kwcall, _apply, typeassert, apply_type, svec, _invoke
ccall(:jl_set_istopmod, Void, (Bool,), false)

eval(x) = Core.eval(Inference,x)
Expand Down
68 changes: 67 additions & 1 deletion base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ function abstract_call(f, fargs, argtypes::Vector{Any}, vtypes, sv::StaticVarInf
if isgeneric(f)
return abstract_call_gf(f, fargs, Tuple{argtypes...}, e)
end
if is(f,invoke) && length(fargs)>1
if is(f, _invoke) && length(fargs)>1
af = isconstantfunc(fargs[1], sv)
if !is(af,false) && (af=_ieval(af);isgeneric(af))
sig = argtypes[2]
Expand Down Expand Up @@ -3326,3 +3326,69 @@ end
#tfunc(f,t) = methods(f,t)[1].func.code.tfunc

ccall(:jl_set_typeinf_func, Void, (Any,), typeinf_ext)


const _enable_invoke_kw_hack = true

function _get_kwsorter(f::Function)
if !isdefined(f.env, :kwsorter)
error("function $(f.env.name) does not accept keyword arguments")
end
return f.env.kwsorter
end

@generated _argtype(t) = t

export invoke

if _enable_invoke_kw_hack
function invoke{T<:Tuple}(f::Function, types::Type{T}, args...)
_invoke(f, types, args...)
end
function invoke{T<:Tuple}(f, types::Type{T}, args...)
_invoke(call, tuple_type_cons(_argtype(f), types), f, args...)
end
function _invoke_kw{T<:Tuple}(kws::Array, f::Function,
types::Type{T}, args...)
_invoke(_get_kwsorter(f), tuple_type_cons(Array, types), kws, args...)
end
function _invoke_kw{T<:Tuple}(kws::Array, f, types::Type{T}, args...)
_invoke_kw(kws, call, tuple_type_cons(_argtype(f), types), f, args...)
end
# Making forwarding of keyword arguments and generating keyword argument
# pack much faster by directly define the kwsorter
invoke.env.kwsorter = _invoke_kw
else
# Pack keyword arguments, logic copied from jl_g_kwcall
function _pack_kwargs(kws::Array)
const kwlen = length(kws)
const ary = Array(Any, 2 * kwlen)

for i in 1:kwlen
const (key::Symbol, val) = kws[i]
@inbounds ary[2 * i - 1] = key
@inbounds ary[2 * i] = val
end
ary
end
function _invoke_imp{T<:Tuple}(f::Function, types::Type{T}, args, kws)
if isempty(kws)
_invoke(f, types, args...)
else
_invoke(_get_kwsorter(f), tuple_type_cons(Array, types),
_pack_kwargs(kws), args...)
end
end
function invoke{T<:Tuple}(f::Function, types::Type{T}, args...; kws...)
_invoke_imp(f, types, args, kws)
end
function invoke{T<:Tuple}(f, types::Type{T}, args...; kws...)
_invoke_imp(call, tuple_type_cons(_argtype(f), types),
(f, args...), kws)
end
end

# Don't worry about the performance for the old signature too much
function invoke(f, types::Tuple, args...; kws...)
invoke(f, Tuple{types...}, args...; kws...)
end
2 changes: 1 addition & 1 deletion base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ccall(:jl_new_main_module, Any, ())
baremodule Base

using Core: Intrinsics, arraylen, arrayref, arrayset, arraysize, _expr,
kwcall, _apply, typeassert, apply_type, svec
kwcall, _apply, typeassert, apply_type, svec, _invoke
ccall(:jl_set_istopmod, Void, (Bool,), true)

include = Core.include
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ void jl_init_primitives(void)
add_builtin_func("Union", jl_f_union);
add_builtin_func("method_exists", jl_f_methodexists);
add_builtin_func("applicable", jl_f_applicable);
add_builtin_func("invoke", jl_f_invoke);
add_builtin_func("_invoke", jl_f_invoke);
add_builtin_func("eval", jl_f_top_eval);
add_builtin_func("isdefined", jl_f_isdefined);

Expand Down