Skip to content

Commit

Permalink
fix serializing functions with cycles, and a bug in serializing Expr
Browse files Browse the repository at this point in the history
fixes #12848
  • Loading branch information
JeffBezanson committed Sep 16, 2015
1 parent 3b8d41a commit a9ae0ad
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
25 changes: 15 additions & 10 deletions base/serialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ function serialize(s::SerializationState, n::BigFloat)
end

function serialize(s::SerializationState, ex::Expr)
serialize_cycle(s, e) && return
serialize_cycle(s, ex) && return
l = length(ex.args)
if l <= 255
writetag(s.io, EXPR_TAG)
Expand Down Expand Up @@ -265,8 +265,6 @@ function serialize(s::SerializationState, m::Module)
end

function serialize(s::SerializationState, f::Function)
serialize_cycle(s, f) && return
writetag(s.io, FUNCTION_TAG)
name = false
if isgeneric(f)
name = f.env.name
Expand All @@ -275,6 +273,7 @@ function serialize(s::SerializationState, f::Function)
end
if isa(name,Symbol)
if isdefined(Base,name) && is(f,getfield(Base,name))
writetag(s.io, FUNCTION_TAG)
write(s.io, UInt8(0))
serialize(s, name)
return
Expand All @@ -288,18 +287,23 @@ function serialize(s::SerializationState, f::Function)
if mod !== ()
if isdefined(mod,name) && is(f,getfield(mod,name))
# toplevel named func
writetag(s.io, FUNCTION_TAG)
write(s.io, UInt8(2))
serialize(s, mod)
serialize(s, name)
return
end
end
serialize_cycle(s, f) && return
writetag(s.io, FUNCTION_TAG)
write(s.io, UInt8(3))
serialize(s, f.env)
else
serialize_cycle(s, f) && return
writetag(s.io, FUNCTION_TAG)
write(s.io, UInt8(1))
linfo = f.code
@assert isa(linfo,LambdaStaticData)
write(s.io, UInt8(1))
serialize(s, linfo)
serialize(s, f.env)
end
Expand Down Expand Up @@ -520,17 +524,18 @@ function deserialize(s::SerializationState, ::Type{Function})
f = getfield(mod,name)::Function
end
elseif b==3
env = deserialize(s)
f = ccall(:jl_new_gf_internal, Any, (Any,), env)::Function
f = ccall(:jl_new_gf_internal, Any, (Any,), nothing)::Function
deserialize_cycle(s, f)
f.env = deserialize(s)
else
linfo = deserialize(s)
f = ccall(:jl_new_closure, Any, (Ptr{Void}, Ptr{Void}, Any), C_NULL, C_NULL, linfo)::Function
f = ccall(:jl_new_closure, Any, (Ptr{Void}, Ptr{Void}, Any),
cglobal(:jl_trampoline), C_NULL, nothing)::Function
deserialize_cycle(s, f)
f.code = li = deserialize(s)
f.fptr = ccall(:jl_linfo_fptr, Ptr{Void}, (Any,), li)
f.env = deserialize(s)
return f
end

deserialize_cycle(s, f)
return f
end

Expand Down
5 changes: 5 additions & 0 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ DLLEXPORT jl_function_t *jl_new_closure(jl_fptr_t fptr, jl_value_t *env,
return f;
}

DLLEXPORT jl_fptr_t *jl_linfo_fptr(jl_lambda_info_t *linfo)
{
return linfo->fptr;
}

DLLEXPORT
jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_svec_t *sparams, jl_module_t *ctx)
{
Expand Down

0 comments on commit a9ae0ad

Please sign in to comment.