Skip to content

Commit

Permalink
Use Undef markers for undefined fields
Browse files Browse the repository at this point in the history
Previously BSON would skip these entirely causing mis-ordered
`setfield!` calls when loading the struct.
  • Loading branch information
topolarity committed Jan 19, 2024
1 parent 3d6da1f commit b6e05fc
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/extensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ tags[:array] = d ->

# Structs

struct Undef end
structdata(x) = isprimitivetype(typeof(x)) ? reinterpret_(UInt8, [x]) :
Any[getfield(x,f) for f in fieldnames(typeof(x)) if isdefined(x, f)]
Any[isdefined(x, f) ? getfield(x,f) : Undef() for f in fieldnames(typeof(x))]

function lower(x)
BSONDict(:tag => "struct", :type => typeof(x), :data => structdata(x))
Expand All @@ -119,6 +120,7 @@ initstruct(T) = ccall(:jl_new_struct_uninit, Any, (Any,), T)

function newstruct!(x, fs...)
for (i, f) = enumerate(fs)
isa(f, Undef) && continue
f = convert(fieldtype(typeof(x),i), f)
ccall(:jl_set_nth_field, Nothing, (Any, Csize_t, Any), x, i-1, f)
end
Expand Down

0 comments on commit b6e05fc

Please sign in to comment.