Skip to content

Commit

Permalink
Merge pull request JuliaLang#13134 from JuliaLang/amitm/12848
Browse files Browse the repository at this point in the history
fix tracking of serialization state for Function types and Expr
  • Loading branch information
JeffBezanson committed Sep 17, 2015
2 parents 5b82198 + a9ae0ad commit afaa4de
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 17 deletions.
39 changes: 25 additions & 14 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 @@ -507,24 +511,31 @@ function deserialize(s::SerializationState, ::Type{Function})
if b==0
name = deserialize(s)::Symbol
if !isdefined(Base,name)
return (args...)->error("function $name not defined on process $(myid())")
f = (args...)->error("function $name not defined on process $(myid())")
else
f = getfield(Base,name)::Function
end
return getfield(Base,name)::Function
elseif b==2
mod = deserialize(s)::Module
name = deserialize(s)::Symbol
if !isdefined(mod,name)
return (args...)->error("function $name not defined on process $(myid())")
f = (args...)->error("function $name not defined on process $(myid())")
else
f = getfield(mod,name)::Function
end
return getfield(mod,name)::Function
elseif b==3
env = deserialize(s)
return 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
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)
end
linfo = deserialize(s)
f = ccall(:jl_new_closure, Any, (Ptr{Void}, Ptr{Void}, Any), C_NULL, C_NULL, linfo)::Function
deserialize_cycle(s, f)
f.env = deserialize(s)

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
24 changes: 21 additions & 3 deletions test/serialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -280,16 +280,34 @@ create_serialization_stream() do s
end

# cycles
module CycleFoo
echo(x)=x
end
create_serialization_stream() do s
A = Any[1,2,3,4,5]
echo(x) = x
afunc = (x)->x
A = Any[1,2,3,abs,abs,afunc,afunc,echo,echo,CycleFoo.echo,CycleFoo.echo,4,5]
A[3] = A
serialize(s, A)
seekstart(s)
b = deserialize(s)
@test b[3] === b
@test b[1] == 1
@test b[5] == 5
@test length(b) == 5
@test b[4] === abs
@test b[5] === b[4]
@test b[5](-1) == 1

@test b[6] === b[7]
@test b[6]("Hello") == "Hello"

@test b[8] === b[9]
@test b[8]("World") == "World"

@test b[10] === b[11]
@test b[10]("foobar") == "foobar"

@test b[end] == 5
@test length(b) == length(A)
@test isa(b,Vector{Any})
end

Expand Down

0 comments on commit afaa4de

Please sign in to comment.