Skip to content

Commit a89634b

Browse files
JeffBezansonKristofferC
authored andcommitted
fix serializer for compat with 1.0 for saved functions (#32028)
(cherry picked from commit 8f9ace0)
1 parent fcc28a7 commit a89634b

File tree

2 files changed

+93
-9
lines changed

2 files changed

+93
-9
lines changed

stdlib/Serialization/src/Serialization.jl

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Serializer(io::IO) = Serializer{typeof(io)}(io)
3030
## serializing values ##
3131

3232
const n_int_literals = 33
33-
const n_reserved_slots = 25
33+
const n_reserved_slots = 24
3434
const n_reserved_tags = 12
3535

3636
const TAGS = Any[
@@ -65,7 +65,7 @@ const TAGS = Any[
6565
:sub_int, :mul_int, :add_float, :sub_float, :new, :mul_float, :bitcast, :start, :done, :next,
6666
:indexed_iterate, :getfield, :meta, :eq_int, :slt_int, :sle_int, :ne_int, :push_loc, :pop_loc,
6767
:pop, :arrayset, :arrayref, :apply_type, :inbounds, :getindex, :setindex!, :Core, :!, :+,
68-
:Base, :static_parameter, :convert, :colon, Symbol("#self#"), Symbol(""), :tuple,
68+
:Base, :static_parameter, :convert, :colon, Symbol("#self#"), Symbol("#temp#"), :tuple, Symbol(""),
6969

7070
fill(:_reserved_, n_reserved_slots)...,
7171

@@ -75,7 +75,7 @@ const TAGS = Any[
7575

7676
@assert length(TAGS) == 255
7777

78-
const ser_version = 7 # do not make changes without bumping the version #!
78+
const ser_version = 8 # do not make changes without bumping the version #!
7979

8080
const NTAGS = length(TAGS)
8181

@@ -411,7 +411,9 @@ function serialize(s::AbstractSerializer, linfo::Core.MethodInstance)
411411
isa(linfo.def, Module) || error("can only serialize toplevel MethodInstance objects")
412412
writetag(s.io, METHODINSTANCE_TAG)
413413
serialize(s, linfo.uninferred)
414+
serialize(s, nothing) # for backwards compat
414415
serialize(s, linfo.sparam_vals)
416+
serialize(s, Any) # for backwards compat
415417
serialize(s, linfo.specTypes)
416418
serialize(s, linfo.def)
417419
nothing
@@ -915,7 +917,13 @@ function deserialize(s::AbstractSerializer, ::Type{Method})
915917
file = deserialize(s)::Symbol
916918
line = deserialize(s)::Int32
917919
sig = deserialize(s)::Type
918-
slot_syms = deserialize(s)::String
920+
syms = deserialize(s)
921+
if syms isa SimpleVector
922+
# < v1.2
923+
_ambig = deserialize(s)
924+
else
925+
slot_syms = syms::String
926+
end
919927
nargs = deserialize(s)::Int32
920928
isva = deserialize(s)::Bool
921929
template = deserialize(s)
@@ -926,14 +934,17 @@ function deserialize(s::AbstractSerializer, ::Type{Method})
926934
meth.file = file
927935
meth.line = line
928936
meth.sig = sig
929-
meth.slot_syms = slot_syms
930937
meth.nargs = nargs
931938
meth.isva = isva
932939
if template !== nothing
933940
# TODO: compress template
934941
meth.source = template::CodeInfo
935942
meth.pure = template.pure
943+
if !@isdefined(slot_syms)
944+
slot_syms = ccall(:jl_compress_argnames, Ref{String}, (Any,), meth.source.slotnames)
945+
end
936946
end
947+
meth.slot_syms = slot_syms
937948
if generator !== nothing
938949
linfo = ccall(:jl_new_method_instance_uninit, Ref{Core.MethodInstance}, ())
939950
linfo.specTypes = Tuple
@@ -954,12 +965,72 @@ function deserialize(s::AbstractSerializer, ::Type{Core.MethodInstance})
954965
linfo = ccall(:jl_new_method_instance_uninit, Ref{Core.MethodInstance}, (Ptr{Cvoid},), C_NULL)
955966
deserialize_cycle(s, linfo)
956967
linfo.uninferred = deserialize(s)::CodeInfo
968+
tag = Int32(read(s.io, UInt8)::UInt8)
969+
if tag != UNDEFREF_TAG
970+
# for reading files prior to v1.2
971+
handle_deserialize(s, tag)
972+
end
957973
linfo.sparam_vals = deserialize(s)::SimpleVector
974+
_rettype = deserialize(s) # for backwards compat
958975
linfo.specTypes = deserialize(s)
959976
linfo.def = deserialize(s)::Module
960977
return linfo
961978
end
962979

980+
function deserialize(s::AbstractSerializer, ::Type{Core.LineInfoNode})
981+
_meth = deserialize(s)
982+
if _meth isa Module
983+
# pre v1.2, skip
984+
_meth = deserialize(s)
985+
end
986+
return Core.LineInfoNode(_meth::Symbol, deserialize(s)::Symbol, deserialize(s)::Int, deserialize(s)::Int)
987+
end
988+
989+
function deserialize(s::AbstractSerializer, ::Type{CodeInfo})
990+
ci = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ())
991+
deserialize_cycle(s, ci)
992+
ci.code = deserialize(s)::Vector{Any}
993+
ci.codelocs = deserialize(s)::Vector{Int32}
994+
_x = deserialize(s)
995+
if _x isa Array || _x isa Int
996+
pre_12 = false
997+
ci.ssavaluetypes = _x
998+
else
999+
pre_12 = true
1000+
# < v1.2
1001+
ci.method_for_inference_limit_heuristics = _x
1002+
ci.ssavaluetypes = deserialize(s)
1003+
ci.linetable = deserialize(s)
1004+
end
1005+
ci.ssaflags = deserialize(s)
1006+
if pre_12
1007+
ci.slotflags = deserialize(s)
1008+
else
1009+
ci.method_for_inference_limit_heuristics = deserialize(s)
1010+
ci.linetable = deserialize(s)
1011+
end
1012+
ci.slotnames = deserialize(s)
1013+
if !pre_12
1014+
ci.slotflags = deserialize(s)
1015+
ci.slottypes = deserialize(s)
1016+
ci.rettype = deserialize(s)
1017+
ci.parent = deserialize(s)
1018+
ci.min_world = deserialize(s)
1019+
ci.max_world = deserialize(s)
1020+
end
1021+
ci.inferred = deserialize(s)
1022+
ci.inlineable = deserialize(s)
1023+
ci.propagate_inbounds = deserialize(s)
1024+
ci.pure = deserialize(s)
1025+
return ci
1026+
end
1027+
1028+
if Int === Int64
1029+
const OtherInt = Int32
1030+
else
1031+
const OtherInt = Int64
1032+
end
1033+
9631034
function deserialize_array(s::AbstractSerializer)
9641035
slot = s.counter; s.counter += 1
9651036
d1 = deserialize(s)
@@ -969,15 +1040,17 @@ function deserialize_array(s::AbstractSerializer)
9691040
else
9701041
elty = UInt8
9711042
end
972-
if isa(d1, Int)
1043+
if isa(d1, Int32) || isa(d1, Int64)
9731044
if elty !== Bool && isbitstype(elty)
9741045
a = Vector{elty}(undef, d1)
9751046
s.table[slot] = a
9761047
return read!(s.io, a)
9771048
end
978-
dims = (d1,)
979-
else
1049+
dims = (Int(d1),)
1050+
elseif d1 isa Dims
9801051
dims = d1::Dims
1052+
else
1053+
dims = convert(Dims, d1::Tuple{Vararg{OtherInt}})::Dims
9811054
end
9821055
if isbitstype(elty)
9831056
n = prod(dims)::Int

stdlib/Serialization/test/runtests.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3-
using Test, Random, Serialization
3+
using Test, Random, Serialization, Base64
44

55
# Check that serializer hasn't gone out-of-frame
66
@test Serialization.sertag(Symbol) == 1
@@ -551,3 +551,14 @@ let f = tempname(), x = [rand(2,2), :x, "hello"]
551551
@test deserialize(f) == x
552552
rm(f)
553553
end
554+
555+
let f_data
556+
# a serialized function from v1.0/v1.1
557+
if Int === Int64
558+
f_data = "N0pMBwQAAAA0MxMAAAAAAAAAAAEFIyM1IzYiAAAAABBYH04BBE1haW6bRCIAAAAAIgAAAABNTEy+AQIjNRUAI+AjAQAAAAAAAAAfTgEETWFpbkQBAiM1AQdSRVBMWzNdvxBTH04BBE1haW6bRAMAAAAzLAAARkYiAAAAAE7BTBsVRuIWA1YkH04BBE1haW5EAQEq4SXhFgNWJB9OAQRNYWluRJ0o4CXiFgFVKOEVAAbiAQAAAAEAAAABAAAATuIVRuA0EAEMTGluZUluZm9Ob2RlH04BBE1haW6bRB9OAQRNYWluRAECIzUBB1JFUExbM13g3xXfFeIAAAAVRuKifX5MTExMTuIp"
559+
else
560+
f_data = "N0pMBwAAAAA0MxMAAAAAAAAAAAEFIyM1IzYiAAAAABBYH04BBE1haW6bRCIAAAAAIgAAAABNTEy+AQIjNRUAI78jAQAAAAAAAAAfTgEETWFpbkQBAiM1AQdSRVBMWzJdvxBTH04BBE1haW6bRAMAAAAzLAAARkYiAAAAAE7BTBsVRsEWA1YkH04BBE1haW5EAQEqwCXAFgNWJB9OAQRNYWluRJ0ovyXBFgFVKMAVAAbBAQAAAAEAAAABAAAATsEVRr80EAEMTGluZUluZm9Ob2RlH04BBE1haW6bRB9OAQRNYWluRAECIzUBB1JFUExbMl2/vhW+FcEAAAAVRsGifX5MTExMTsEp"
561+
end
562+
f = deserialize(IOBuffer(base64decode(f_data)))
563+
@test f(10,3) == 23
564+
end

0 commit comments

Comments
 (0)