Skip to content

Commit

Permalink
fix #15451, serialization of nested functions (#16535)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed May 24, 2016
1 parent fe23b88 commit 3bed78c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
34 changes: 31 additions & 3 deletions base/serialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const TAGS = Any[
QuoteNode, :reserved23 #=was TopNode=#, TypeVar, Core.Box, LambdaInfo,
Module, #=UndefRefTag=#Symbol, Task, String,
UTF16String, UTF32String, Float16,
SimpleVector, #=BackrefTag=#Symbol, Method, :reserved12,
SimpleVector, #=BackrefTag=#Symbol, Method, GlobalRef,

(), Bool, Any, :Any, Bottom, :reserved21, :reserved22, Type,
:Array, :TypeVar, :Box,
Expand Down Expand Up @@ -72,12 +72,13 @@ const BACKREF_TAG = Int32(sertag(SimpleVector)+1)
const EXPR_TAG = sertag(Expr)
const LONGEXPR_TAG = Int32(sertag(Expr)+3)
const MODULE_TAG = sertag(Module)
const LAMBDASTATICDATA_TAG = sertag(LambdaInfo)
const LAMBDAINFO_TAG = sertag(LambdaInfo)
const METHOD_TAG = sertag(Method)
const TASK_TAG = sertag(Task)
const DATATYPE_TAG = sertag(DataType)
const TYPENAME_TAG = sertag(TypeName)
const INT_TAG = sertag(Int)
const GLOBALREF_TAG = sertag(GlobalRef)

writetag(s::IO, tag) = write(s, UInt8(tag))

Expand Down Expand Up @@ -329,7 +330,7 @@ end

function serialize(s::SerializationState, linfo::LambdaInfo)
serialize_cycle(s, linfo) && return
writetag(s.io, LAMBDASTATICDATA_TAG)
writetag(s.io, LAMBDAINFO_TAG)
serialize(s, uncompressed_ast(linfo))
serialize(s, linfo.slotnames)
serialize(s, linfo.slottypes)
Expand Down Expand Up @@ -366,6 +367,23 @@ function serialize(s::SerializationState, t::Task)
end
end

function serialize(s::SerializationState, g::GlobalRef)
writetag(s.io, GLOBALREF_TAG)
if g.mod === Main && isdefined(g.mod, g.name) && isconst(g.mod, g.name)
v = eval(g)
if isa(v, DataType) && v === v.name.primary && should_send_whole_type(s, v)
# handle references to types in Main by sending the whole type.
# needed to be able to send nested functions (#15451).
write(s.io, UInt8(1))
serialize(s, v)
return
end
end
write(s.io, UInt8(0))
serialize(s, g.mod)
serialize(s, g.name)
end

function serialize(s::SerializationState, t::TypeName)
serialize_cycle(s, t) && return
writetag(s.io, TYPENAME_TAG)
Expand Down Expand Up @@ -695,6 +713,16 @@ function deserialize_expr(s::SerializationState, len)
e
end

function deserialize(s::SerializationState, ::Type{GlobalRef})
kind = read(s.io, UInt8)
if kind == 0
return GlobalRef(deserialize(s)::Module, deserialize(s)::Symbol)
else
ty = deserialize(s)
return GlobalRef(ty.name.module, ty.name.name)
end
end

function deserialize(s::SerializationState, ::Type{Union})
types = deserialize(s)
Union{types...}
Expand Down
2 changes: 2 additions & 0 deletions test/parallel_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -978,3 +978,5 @@ for i = 1:10^n
fetch(@spawnat myid() myid())
end

# issue #15451
@test remotecall_fetch(x->(y->2y)(x)+1, workers()[1], 3) == 7

0 comments on commit 3bed78c

Please sign in to comment.