Skip to content

Commit

Permalink
macro: generate ad-hoc container
Browse files Browse the repository at this point in the history
it might improve performance,
and moreover it fix the known issue for estimatesize.
  • Loading branch information
miRoox committed Dec 4, 2022
1 parent ca4709b commit e32b56d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
31 changes: 31 additions & 0 deletions src/macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ function construct_impl(m::Module, source::LineNumberNode, constructname::Symbol
replacestructdef(structdef, infos)
))
append!(defs, generateconstructdef(constructname, structname))
append!(defs, generatecontainerdef(structname, fields))
push!(defs, generateserializemethod(constructname, structname, fields))
push!(defs, generatedeserializemethod(constructname, structname, fields))
push!(defs, generateestimatesizemethod(constructname, structname, fields))
Expand Down Expand Up @@ -226,6 +227,36 @@ function generateconstructdef(constructname::Symbol, structname::Symbol)
)
end

function generatecontainerdef(structname::Symbol, fields::Vector{>:FieldInfo})
containername = gensym("ShadowContainer")
bodyexpr = Expr(:block)
sizehint!(bodyexpr.args, 2 * length(fields))
for field in fields
if !ismissing(field.line)
push!(bodyexpr.args, field.line)
end
push!(bodyexpr.args, Expr(:(::), field.name, Union{field.type, UndefProperty{field.type}}))
end
tuple(
Expr(:struct,
true,
Expr(:(<:), esc(containername), Expr(:curly, GlobalRef(Constructs, :ShadowContainer), esc(structname))),
bodyexpr,
),
Expr(:function,
Expr(:call,
Expr(:curly, GlobalRef(Constructs, :Container), esc(structname)),
),
Expr(:block,
Expr(:call,
esc(containername),
Iterators.map(field -> UndefProperty{field.type}(), fields)...
)
)
)
)
end

function generateserializemethod(constructname::Symbol, structname::Symbol, fields::Vector{>:FieldInfo})
@sym s val contextkw result
sercalls = Vector{Any}()
Expand Down
8 changes: 7 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,12 @@ end
function Construct_(::Type_{STT_})
CTT_()
end
mutable struct CTN_ <: ShadowContainer_{STT_}
ctnfields__
end
function Container_{STT_}()
CTN_(ctnundefs__)
end
function serialize_(::CTT_, ss_::IO_, val_::STT_; scontextkw_...)
serializebody__
end
Expand Down Expand Up @@ -763,7 +769,7 @@ end
@test Bitmap2 <: AbstractImage
@test fieldnames(Bitmap2) == (:pixel,)
@test fieldtype(Bitmap2, :pixel) == Matrix{UInt8}
@test_broken estimatesize(Bitmap2) == UnboundedSize(4 + 2 * sizeof(UInt16)) # known issue: should redesign container
@test estimatesize(Bitmap2) == UnboundedSize(4 + 2 * sizeof(UInt16))
@test serialize(Bitmap2(UInt8[1 2 3; 7 8 9])) == b"BMP\x00\x03\x00\x02\x00\x01\x07\x02\x08\x03\x09"
@test deserialize(Bitmap2, b"BMP\xfe\x03\x00\x02\x00\x01\x07\x02\x08\x03\x09").pixel == UInt8[1 2 3; 7 8 9]
@test_throws EOFError deserialize(Bitmap2, b"BMP\xfe\x03\x00\x02\x00\x01\x07\x02\x08\x03")
Expand Down

0 comments on commit e32b56d

Please sign in to comment.