From e32c1f2de7c08758a51df578e56cf944225562dd Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 23 Jun 2011 21:05:03 -0400 Subject: [PATCH] when spawn runs something on the local machine, it needs to copy variable bindings to simulate what happens when closures are copied to other machines. fixes the bug described in issue #80. --- j/inference.j | 1 + j/multi.j | 9 +++++++++ src/alloc.c | 9 +++++++++ src/builtin_proto.h | 1 + src/dump.c | 1 + src/jltypes.c | 3 ++- 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/j/inference.j b/j/inference.j index 3f48caf0463aa..7a467d04f9c5f 100644 --- a/j/inference.j +++ b/j/inference.j @@ -300,6 +300,7 @@ fieldtype_tfunc = function (A, s, name) end t_func[fieldtype] = (2, 2, fieldtype_tfunc) t_func[Expr] = (3, 3, (a,b,c)->Expr) +t_func[Box] = (1, 1, (a,)->Box) # TODO: handle e.g. apply_type(T, R::Union(Type{Int32},Type{Float64})) apply_type_tfunc = function (A, args...) diff --git a/j/multi.j b/j/multi.j index 3badd79a34f92..646e37a0eb542 100644 --- a/j/multi.j +++ b/j/multi.j @@ -1071,6 +1071,15 @@ let lastp = 1 lastp = 1 end end + if p==myid() + # for local spawn, simulate semantics of copying bindings + if isa(env,Tuple) + env = map(x->(isa(x,Box)?Box(x.contents):x), env) + linfo = ccall(:jl_closure_linfo, Any, (Any,), thunk) + thunk = ccall(:jl_new_closure_internal, Any, (Any, Any), + linfo, env)::Function + end + end spawnat(p, thunk) end end diff --git a/src/alloc.c b/src/alloc.c index e6fd654ada26a..909d14daf602c 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -915,3 +915,12 @@ JL_CALLABLE(jl_f_new_expr) ex->etype = args[2]; return (jl_value_t*)ex; } + +JL_CALLABLE(jl_f_new_box) +{ + JL_NARGS(Box, 1, 1); + jl_value_t *box = (jl_value_t*)alloc_2w(); + box->type = jl_box_any_type; + ((jl_value_t**)box)[1] = args[0]; + return box; +} diff --git a/src/builtin_proto.h b/src/builtin_proto.h index 62efa538bf455..f79fccdfa380e 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -4,6 +4,7 @@ // declarations for julia-callable builtin functions JL_CALLABLE(jl_f_new_expr); +JL_CALLABLE(jl_f_new_box); JL_CALLABLE(jl_weakref_ctor); JL_CALLABLE(jl_new_array_internal); JL_CALLABLE(jl_f_throw); diff --git a/src/dump.c b/src/dump.c index 8cf676e08b8e0..86d3a9a4b692b 100644 --- a/src/dump.c +++ b/src/dump.c @@ -973,6 +973,7 @@ void jl_init_serializer() VALUE_TAGS = (ptrint_t)ptrhash_get(&ser_tag, jl_null); void *fptrs[] = { jl_f_new_expr, + jl_f_new_box, jl_weakref_ctor, jl_new_array_internal, jl_f_throw, diff --git a/src/jltypes.c b/src/jltypes.c index 73ce8f6abbae9..8bdd3719fba5f 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -1926,6 +1926,7 @@ static jl_tuple_t *jl_typevars(size_t n, ...) } JL_CALLABLE(jl_f_new_expr); +JL_CALLABLE(jl_f_new_box); extern void jl_init_int32_cache(); @@ -2165,7 +2166,7 @@ void jl_init_types() jl_any_type, jl_null, jl_tuple(1, jl_symbol("contents")), jl_tuple(1, jl_any_type)); - //jl_add_constructors(jl_box_type); + jl_box_type->fptr = jl_f_new_box; jl_box_typename = jl_box_type->name; jl_box_any_type = (jl_type_t*)jl_box_type;