Skip to content

Commit

Permalink
Merge pull request #125 from topolarity/fix-anonymous-methods-1.10
Browse files Browse the repository at this point in the history
Fix anonymous method serialization for Julia v1.10
  • Loading branch information
DhairyaLGandhi authored Jan 19, 2024
2 parents 40803db + efc9a6c commit c2bd76d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
22 changes: 19 additions & 3 deletions src/anonymous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function newstruct!(meth::Method, mod, name, file, line, sig,
meth.pure = ast.pure
return meth
end
else
elseif VERSION < v"1.10-"
function newstruct!(meth::Method, mod, name, file, line, sig,
syms, nargs, isva, nospecialize, ast)
meth.module = mod
Expand All @@ -58,6 +58,22 @@ function newstruct!(meth::Method, mod, name, file, line, sig,
meth.pure = ast.pure
return meth
end
else
function newstruct!(meth::Method, mod, name, file, line, sig,
syms, nargs, isva, nospecialize, ast)
meth.module = mod
meth.name = name
meth.file = file
meth.line = line
meth.sig = sig
setfield!(meth, syms_fieldname, syms)
meth.nospecialize = nospecialize
meth.nargs = nargs
meth.isva = isva
meth.source = ast
meth.purity = ast.purity
return meth
end
end

# Type Names
Expand Down Expand Up @@ -92,7 +108,7 @@ end

baremodule __deserialized_types__ end

if VERSION < v"1.7-"
@static if VERSION < v"1.7-"
function newstruct_raw(cache, ::Type{TypeName}, d, init)
name = raise_recursive(d[:data][2], cache, init)
name = isdefined(__deserialized_types__, name) ? gensym() : name
Expand Down Expand Up @@ -148,7 +164,7 @@ else
mtname, defs, maxa, kwsorter = mt
mt = ccall(:jl_new_method_table, Any, (Any, Any), name, tn.module)
mt.name = mtname
mt.max_args = maxa
@atomic mt.max_args = maxa
ccall(:jl_set_nth_field, Cvoid, (Any, Csize_t, Any), tn, Base.fieldindex(Core.TypeName, :mt)-1, mt)
for def in defs
isdefined(def, :sig) || continue
Expand Down
15 changes: 13 additions & 2 deletions src/extensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,16 @@ tags[:array] = d ->

# Structs

structdata(x) = isprimitivetype(typeof(x)) ? reinterpret_(UInt8, [x]) :
Any[getfield(x,f) for f in fieldnames(typeof(x)) if isdefined(x, f)]
struct Undef end
function structdata(x)
if isprimitivetype(typeof(x))
return reinterpret_(UInt8, [x])
elseif !ismutabletype(typeof(x))
return Any[getfield(x,f) for f in fieldnames(typeof(x)) if isdefined(x, f)]
else # mutable structs can have defined fields following undefined fields
return Any[isdefined(x, f) ? getfield(x,f) : Undef() for f in fieldnames(typeof(x))]
end
end

function lower(x)
BSONDict(:tag => "struct", :type => typeof(x), :data => structdata(x))
Expand All @@ -119,6 +127,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 All @@ -136,6 +145,7 @@ function newstruct(T, xs...)
x = initstruct(T)

for (i, f) = enumerate(xs)
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 All @@ -154,6 +164,7 @@ function newstruct(T, xs...)
x = initstruct(T)

for (i, f) = enumerate(xs)
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
23 changes: 23 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@ struct Bar
Bar() = new()
end

mutable struct Baz
x
y
z
Baz() = new()
end

function is_field_equal(a, b, field::Symbol)
!isdefined(a, field) && return !isdefined(b, field)
!isdefined(b, field) && return false
return getfield(a, field) == getfield(b, field)
end

function Base.:(==)(a::Baz, b::Baz)
return is_field_equal(a, b, :x) &&
is_field_equal(a, b, :y) &&
is_field_equal(a, b, :z)
end

module A
using DataFrames, BSON
d = DataFrame(a = 1:10, b = rand(10))
Expand Down Expand Up @@ -72,6 +91,10 @@ end
@test_broken roundtrip_equal(Dict(:x => x))

@test roundtrip_equal(Bar())

o = Baz()
o.y = 1
@test roundtrip_equal(o)
end

@testset "Complex Types" begin
Expand Down

0 comments on commit c2bd76d

Please sign in to comment.