Skip to content

Commit 6bbedce

Browse files
Restore dropped RGF serialization (#138)
Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
1 parent a6e10c5 commit 6bbedce

3 files changed

Lines changed: 54 additions & 15 deletions

File tree

src/RuntimeGeneratedFunctions.jl

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module RuntimeGeneratedFunctions
22

33
using ExprTools: ExprTools, combinedef, splitdef
44
using SHA: SHA, SHA1_CTX, update!
5-
using Serialization: Serialization, AbstractSerializer, deserialize
5+
using Serialization: Serialization, AbstractSerializer, deserialize, serialize
66

77
export RuntimeGeneratedFunction, @RuntimeGeneratedFunction, drop_expr
88

@@ -49,10 +49,9 @@ it represents one callable method and does not participate in method dispatch.
4949
5050
# Serialization
5151
52-
`Serialization.serialize` preserves a runtime-generated function while its
53-
`body` is retained. Serialize a function before calling [`drop_expr`](@ref): a
54-
dropped function intentionally does not retain the expression needed to restore
55-
its cache in another process.
52+
`Serialization.serialize` preserves a runtime-generated function, including
53+
after [`drop_expr`](@ref). A dropped function's expression is recovered from its
54+
cache while serializing and remains dropped after deserialization.
5655
5756
# Examples
5857
@@ -112,9 +111,6 @@ function callable.
112111
The expression can still be retrieved later using [`get_expression`](@ref) as long
113112
as at least one `RuntimeGeneratedFunction` with the same body exists.
114113
115-
Serialize a generated function before calling `drop_expr`. A dropped function has
116-
discarded the expression needed to restore its cache in another process.
117-
118114
# Examples
119115
```julia
120116
ex = :((x) -> x^2)
@@ -511,6 +507,51 @@ function get_expression(
511507
return func_expr = Expr(:->, Expr(:tuple, argnames...), _lookup_body(cache_tag, id))
512508
end
513509

510+
struct _SerializedRuntimeGeneratedFunction{argnames, cache_tag, context_tag, id, B}
511+
body::B
512+
end
513+
514+
function Serialization.serialize(
515+
s::AbstractSerializer,
516+
::RuntimeGeneratedFunction{
517+
argnames, cache_tag,
518+
context_tag, id, Nothing,
519+
}
520+
) where {
521+
argnames,
522+
cache_tag,
523+
context_tag,
524+
id,
525+
}
526+
body = _lookup_body(cache_tag, id)
527+
proxy = _SerializedRuntimeGeneratedFunction{
528+
argnames, cache_tag, context_tag, id, typeof(body),
529+
}(body)
530+
return serialize(s, proxy)
531+
end
532+
533+
function Serialization.deserialize(
534+
s::AbstractSerializer,
535+
::Type{
536+
_SerializedRuntimeGeneratedFunction{
537+
argnames, cache_tag,
538+
context_tag, id, B,
539+
},
540+
}
541+
) where {
542+
argnames,
543+
cache_tag,
544+
context_tag,
545+
id,
546+
B,
547+
}
548+
body = deserialize(s)
549+
cached_body = _cache_body(cache_tag, id, body)
550+
return drop_expr(
551+
RuntimeGeneratedFunction{argnames, cache_tag, context_tag, id}(cached_body)
552+
)
553+
end
554+
514555
function Serialization.deserialize(
515556
s::AbstractSerializer,
516557
::Type{

test/core_tests.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,11 @@ proj = dirname(Base.active_project())
212212
serialize_script = joinpath(@__DIR__, "shared", "serialize_rgf.jl")
213213
julia = joinpath(Sys.BINDIR, "julia")
214214
buf = IOBuffer(read(`$julia --startup-file=no --project=$proj $serialize_script`))
215-
deserialized_f = deserialize(buf)
215+
deserialized_f, deserialized_g = deserialize(buf)
216216
@test deserialized_f(11) == "Hi from a separate process. x=11"
217217
@test deserialized_f.body isa Expr
218-
219-
serialization_buffer = IOBuffer()
220-
serialize(serialization_buffer, drop_expr(@RuntimeGeneratedFunction(:(x -> x + 1))))
221-
seekstart(serialization_buffer)
222-
@test_throws ArgumentError deserialize(serialization_buffer)
218+
@test deserialized_g(12) == "Serialization with dropped body. y=12"
219+
@test deserialized_g.body isa Nothing
223220

224221
# deepcopy
225222
ff = @RuntimeGeneratedFunction(:(x -> [x, x + 1]))

test/shared/serialize_rgf.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ using Serialization
66
RuntimeGeneratedFunctions.init(@__MODULE__)
77

88
f = @RuntimeGeneratedFunction(:(x -> "Hi from a separate process. x=$x"))
9+
g = drop_expr(@RuntimeGeneratedFunction(:(y -> "Serialization with dropped body. y=$y")))
910

10-
serialize(stdout, f)
11+
serialize(stdout, (f, g))

0 commit comments

Comments
 (0)