Skip to content

Commit

Permalink
support generic call in apply(f, ...)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengj committed Aug 14, 2014
1 parent 5b0aedd commit 0df037e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
45 changes: 35 additions & 10 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,15 @@ extern size_t jl_page_size;
JL_CALLABLE(jl_f_apply)
{
JL_NARGSV(apply, 1);
JL_TYPECHK(apply, function, args[0]);
jl_function_t *f;
if (jl_is_function(args[0]))
f = (jl_function_t*)args[0];
else { /* do generic call(args...) instead */
f = jl_call_func;
++nargs; --args; /* args[0] becomes args[1] */
}
if (nargs == 2) {
if (((jl_function_t*)args[0])->fptr == &jl_f_tuple) {
if (f->fptr == &jl_f_tuple) {
if (jl_is_tuple(args[1]))
return args[1];
if (jl_is_array(args[1])) {
Expand All @@ -273,7 +279,7 @@ JL_CALLABLE(jl_f_apply)
}
}
if (jl_is_tuple(args[1])) {
return jl_apply((jl_function_t*)args[0], &jl_tupleref(args[1],0),
return jl_apply(f, &jl_tupleref(args[1],0),
jl_tuple_len(args[1]));
}
}
Expand Down Expand Up @@ -301,7 +307,7 @@ JL_CALLABLE(jl_f_apply)
}
argarr = jl_apply(jl_append_any_func, &args[1], nargs-1);
assert(jl_typeis(argarr, jl_array_any_type));
result = jl_apply((jl_function_t*)args[0], jl_cell_data(argarr), jl_array_len(argarr));
result = jl_apply(f, jl_cell_data(argarr), jl_array_len(argarr));
JL_GC_POP();
return result;
}
Expand All @@ -328,7 +334,7 @@ JL_CALLABLE(jl_f_apply)
newargs[n++] = jl_cellref(args[i], j);
}
}
result = jl_apply((jl_function_t*)args[0], newargs, n);
result = jl_apply(f, newargs, n);
JL_GC_POP();
return result;
}
Expand All @@ -339,8 +345,16 @@ JL_CALLABLE(jl_f_kwcall)
{
if (nargs < 3)
jl_error("internal error: malformed keyword argument call");
JL_TYPECHK(apply, function, args[0]);
jl_function_t *f = (jl_function_t*)args[0];
jl_function_t *f;
jl_value_t *args0;
if (jl_is_function(args[0])) {
f = (jl_function_t*)args[0];
args0 = NULL;
}
else { /* do generic call(args...; kws...) instead */
f = jl_call_func;
args0 = args[0];
}
if (f->fptr == jl_f_ctor_trampoline)
jl_add_constructors((jl_datatype_t*)f);
if (!jl_is_gf(f))
Expand All @@ -360,13 +374,24 @@ JL_CALLABLE(jl_f_kwcall)
jl_cellset(container, i+1, args[2+i+1]);
}

args += pa-1;
nargs -= pa-1;
if (args0) {
jl_value_t **newargs = (jl_value_t**)alloca((nargs+1) * sizeof(jl_value_t*));
newargs[0] = args[0];
newargs[1] = args0; /* original 0th argument = "function" */
memcpy(newargs+2, args+1, sizeof(jl_value_t*) * (nargs-1));
args = newargs;
nargs += 1;
}

assert(jl_is_gf(sorter));
jl_function_t *m = jl_method_lookup((jl_methtable_t*)sorter->env, &args[pa-1], nargs-(pa-1), 1);
jl_function_t *m = jl_method_lookup((jl_methtable_t*)sorter->env, args, nargs, 1);
if (m == jl_bottom_func) {
return jl_no_method_error(f, &args[pa], nargs-pa);
return jl_no_method_error(f, args+1, nargs-1);
}

return jl_apply(m, &args[pa-1], nargs-(pa-1));
return jl_apply(m, args, nargs);
}

// eval -----------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1837,6 +1837,7 @@ Base.call(x::Int, y::Int) = x + 3y
issue2403func(f) = f(7)
let x = 10
@test x(3) == 19
@test apply(x, (3,)) == 19
@test issue2403func(x) == 31
end
type Issue2403
Expand Down

0 comments on commit 0df037e

Please sign in to comment.