Skip to content

Commit

Permalink
fix keyword args in constructors-via-call
Browse files Browse the repository at this point in the history
REPL now works with sys0.ji
  • Loading branch information
JeffBezanson committed Oct 11, 2014
1 parent 51a3069 commit 2604610
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 36 deletions.
2 changes: 1 addition & 1 deletion base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ function abstract_call(f, fargs, argtypes, vtypes, sv::StaticVarInfo, e)
return Any
end
kwcount = fargs[2]
ff = isconstantfunc(fargs[4 + 2*kwcount], sv)
ff = isconstantfunc(fargs[3 + 2*kwcount], sv)
if !(ff===false)
ff = _ieval(ff)
if isgeneric(ff) && isdefined(ff.env,:kwsorter)
Expand Down
10 changes: 2 additions & 8 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,20 +382,14 @@ JL_CALLABLE(jl_f_kwcall)
assert(jl_is_function(call_func));
size_t nkeys = jl_unbox_long(args[1]);
size_t pa = 4 + 2*nkeys;
jl_array_t *container = (jl_array_t*)args[pa-2];
jl_array_t *container = (jl_array_t*)args[pa-1];
assert(jl_array_len(container) > 0);
f = (jl_function_t*)args[pa-1];
f = (jl_function_t*)args[pa-2];
if (!jl_is_function(f)) {
// do generic call(args...; kws...) instead
f = call_func;
pa--;
}
else {
// switch (container f pa...) to (f container pa...)
// TODO: this is not as legitimate as it could be.
args[pa-1] = args[pa-2];
args[pa-2] = (jl_value_t*)f;
}

if (!jl_is_gf(f))
jl_error("function does not accept keyword arguments");
Expand Down
16 changes: 6 additions & 10 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2863,13 +2863,7 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed,
Value *name = literal_pointer_val(mn);
jl_binding_t *bnd = NULL;
Value *bp;
if (iskw) {
// fenv = theF->env
Value *fenv = emit_nthptr(theF, 2, tbaa_func);
// bp = &((jl_methtable_t*)fenv)->kwsorter
bp = emit_nthptr_addr(fenv, 7);
}
else if (theF != NULL) {
if (theF != NULL) {
bp = make_gcroot(theF, ctx);
}
else {
Expand All @@ -2885,11 +2879,12 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed,
make_gcroot(a1, ctx);
Value *a2 = boxed(emit_expr(args[2], ctx),ctx);
make_gcroot(a2, ctx);
Value *mdargs[7] =
Value *mdargs[8] =
{ name, bp, literal_pointer_val(bnd), a1, a2, literal_pointer_val(args[3]),
literal_pointer_val((jl_value_t*)jl_module_call_func(ctx->module)) };
literal_pointer_val((jl_value_t*)jl_module_call_func(ctx->module)),
ConstantInt::get(T_int32, (int)iskw) };
ctx->argDepth = last_depth;
return builder.CreateCall(prepare_call(jlmethod_func), ArrayRef<Value*>(&mdargs[0], 7));
return builder.CreateCall(prepare_call(jlmethod_func), ArrayRef<Value*>(&mdargs[0], 8));
}
else if (head == const_sym) {
jl_sym_t *sym = (jl_sym_t*)args[0];
Expand Down Expand Up @@ -4458,6 +4453,7 @@ static void init_julia_llvm_env(Module *m)
mdargs.push_back(jl_pvalue_llvmt);
mdargs.push_back(jl_pvalue_llvmt);
mdargs.push_back(jl_pvalue_llvmt);
mdargs.push_back(T_int32);
jlmethod_func =
Function::Create(FunctionType::get(jl_pvalue_llvmt, mdargs, false),
Function::ExternalLinkage,
Expand Down
12 changes: 2 additions & 10 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,17 +263,9 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl)
fname = (jl_sym_t*)jl_exprarg(fname, 0);
}
gf = eval((jl_value_t*)fname, locals, nl);
jl_value_t *bp_f = gf;
if (jl_is_datatype(bp_f))
bp_f = jl_module_call_func(jl_current_module);
assert(jl_is_function(bp_f)); // TODO: type check for this
assert(jl_is_gf(bp_f));
if (jl_is_expr(fname))
fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0);
if (!kw)
bp = &gf;
else
bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)bp_f)->env)->kwsorter;
bp = &gf;
assert(jl_is_symbol(fname));
}
else {
Expand All @@ -295,7 +287,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl)
jl_check_static_parameter_conflicts((jl_lambda_info_t*)args[2], (jl_tuple_t*)jl_t1(atypes), fname);
}
meth = eval(args[2], locals, nl);
jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, args[3], NULL);
jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, args[3], NULL, kw);
JL_GC_POP();
return *bp;
}
Expand Down
6 changes: 3 additions & 3 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1514,8 +1514,8 @@
keys))))
(if (null? restkeys)
`(call (top kwcall) call ,(length keys) ,@keyargs
(call (top Array) (top Any) ,(* 2 (length keys)))
,f ,@pa)
,f (call (top Array) (top Any) ,(* 2 (length keys)))
,@pa)
(let ((container (gensy)))
`(block
(= ,container (call (top Array) (top Any) ,(* 2 (length keys))))
Expand All @@ -1536,7 +1536,7 @@
(if (call (top isempty) ,container)
(call ,f ,@pa)
(call (top kwcall) call ,(length keys) ,@keyargs
,container ,f ,@pa))))))))
,f ,container ,@pa))))))))

(define (expand-transposed-op e ops)
(let ((a (caddr e))
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ void jl_add_method(jl_function_t *gf, jl_tuple_t *types, jl_function_t *meth,
jl_tuple_t *tvars, int8_t isstaged);
DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd,
jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged,
jl_value_t *call_func);
jl_value_t *call_func, int iskw);
DLLEXPORT jl_value_t *jl_box_bool(int8_t x);
DLLEXPORT jl_value_t *jl_box_int8(int32_t x);
DLLEXPORT jl_value_t *jl_box_uint8(uint32_t x);
Expand Down
10 changes: 7 additions & 3 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ void print_func_loc(JL_STREAM *s, jl_lambda_info_t *li);

DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd,
jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged,
jl_value_t *call_func)
jl_value_t *call_func, int iskw)
{
// argtypes is a tuple ((types...), (typevars...))
jl_tuple_t *t = (jl_tuple_t*)jl_t1(argtypes);
Expand All @@ -665,7 +665,6 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_
if (!jl_is_gf(gf)) {
if (jl_is_datatype(gf)) {
// DataType: define `call`, for backwards compat with outer constructors
// TODO: this does not yet handle keyword sorters correctly
if (call_func == NULL)
call_func = (jl_value_t*)jl_module_call_func(jl_current_module);
size_t na = jl_tuple_len(argtypes);
Expand All @@ -679,7 +678,8 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_
argtypes = newargtypes;
JL_GC_POP();
gf = call_func;
// TODO: edit args, insert type first
name = call_sym;
// edit args, insert type first
if (!jl_is_expr(f->linfo->ast))
f->linfo->ast = jl_uncompress_ast(f->linfo, f->linfo->ast);
jl_array_t *al = jl_lam_args((jl_expr_t*)f->linfo->ast);
Expand All @@ -696,6 +696,10 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_
jl_error("invalid method definition: not a generic function");
}
}
if (iskw) {
bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter;
gf = *bp;
}
}

size_t na = jl_tuple_len(argtypes);
Expand Down

0 comments on commit 2604610

Please sign in to comment.