From 99952fffb2f55746ff020d8802ae19b7ea20bb38 Mon Sep 17 00:00:00 2001 From: Timo Larson <44177396+TimoLarson@users.noreply.github.com> Date: Wed, 20 Feb 2019 15:39:51 -0500 Subject: [PATCH 1/2] Add optional parameter to 'load' function to specify module for resolving names --- src/extensions.jl | 18 +++++++++--------- src/read.jl | 26 +++++++++++++++----------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/extensions.jl b/src/extensions.jl index 7d03dae..fc8126a 100644 --- a/src/extensions.jl +++ b/src/extensions.jl @@ -17,9 +17,9 @@ tags[:svec] = d -> Core.svec(d[:data]...) ref(path::Symbol...) = BSONDict(:tag => "ref", :path => Base.string.([path...])) -resolve(fs) = reduce((m, f) -> getfield(m, Symbol(f)), fs; init = Main) +resolve(fs, init) = reduce((m, f) -> getfield(m, Symbol(f)), fs; init = init) -tags[:ref] = d -> resolve(d[:path]) +tags[:ref] = (d, init) -> resolve(d[:path], init) function modpath(x::Module) y = parentmodule(x) @@ -45,7 +45,7 @@ end constructtype(T, Ts) = (length(Ts) == 0) ? T : T{Ts...} constructtype(T::Type{Tuple}, Ts) = T{Ts...} -tags[:datatype] = d -> constructtype(resolve(d[:name]), d[:params]) +tags[:datatype] = (d, init) -> constructtype(resolve(d[:name], init), d[:params]) lower(v::UnionAll) = BSONDict(:tag => "unionall", @@ -112,9 +112,9 @@ function newstruct(T, xs...) end end -function newstruct_raw(cache, T, d) +function newstruct_raw(cache, T, d, init) x = cache[d] = initstruct(T) - fs = map(x -> raise_recursive(x, cache), d[:data]) + fs = map(x -> raise_recursive(x, cache, init), d[:data]) return newstruct!(x, fs...) end @@ -127,10 +127,10 @@ tags[:struct] = d -> iscyclic(T) = ismutable(T) -raise[:struct] = function (d, cache) - T = d[:type] = raise_recursive(d[:type], cache) - iscyclic(T) || return _raise_recursive(d, cache) - return newstruct_raw(cache, T, d) +raise[:struct] = function (d, cache, init) + T = d[:type] = raise_recursive(d[:type], cache, init) + iscyclic(T) || return _raise_recursive(d, cache, init) + return newstruct_raw(cache, T, d, init) end lower(v::Type{Union{}}) = BSONDict(:tag=>"jl_bottom_type") diff --git a/src/read.jl b/src/read.jl index bd3177c..25a0c80 100644 --- a/src/read.jl +++ b/src/read.jl @@ -74,34 +74,38 @@ const tags = Dict{Symbol,Function}() const raise = Dict{Symbol,Function}() -function _raise_recursive(d::AbstractDict, cache) +function _raise_recursive(d::AbstractDict, cache, init) if haskey(d, :tag) && haskey(tags, Symbol(d[:tag])) - cache[d] = tags[Symbol(d[:tag])](applychildren!(x -> raise_recursive(x, cache), d)) + if Symbol(d[:tag]) in (:ref, :datatype) + cache[d] = tags[Symbol(d[:tag])](applychildren!(x -> raise_recursive(x, cache, init), d), init) + else + cache[d] = tags[Symbol(d[:tag])](applychildren!(x -> raise_recursive(x, cache, init), d)) + end else cache[d] = d - applychildren!(x -> raise_recursive(x, cache), d) + applychildren!(x -> raise_recursive(x, cache, init), d) end end -function raise_recursive(d::AbstractDict, cache) +function raise_recursive(d::AbstractDict, cache, init) haskey(cache, d) && return cache[d] - haskey(d, :tag) && haskey(raise, Symbol(d[:tag])) && return raise[Symbol(d[:tag])](d, cache) - _raise_recursive(d::AbstractDict, cache) + haskey(d, :tag) && haskey(raise, Symbol(d[:tag])) && return raise[Symbol(d[:tag])](d, cache, init) + _raise_recursive(d::AbstractDict, cache, init) end -function raise_recursive(v::BSONArray, cache) +function raise_recursive(v::BSONArray, cache, init) cache[v] = v - applychildren!(x -> raise_recursive(x, cache), v) + applychildren!(x -> raise_recursive(x, cache, init), v) end -raise_recursive(x, cache) = x +raise_recursive(x, cache, init) = x -raise_recursive(x) = raise_recursive(x, IdDict()) +raise_recursive(x, init) = raise_recursive(x, IdDict(), init) parse(io::IO) = backrefs!(parse_doc(io)) parse(path::String) = open(parse, path) -load(x) = raise_recursive(parse(x)) +load(x, init=Main) = raise_recursive(parse(x), init) function roundtrip(x) buf = IOBuffer() From 32d8417e770293b4c73a4870542ac96e0422125a Mon Sep 17 00:00:00 2001 From: Timo Larson <44177396+TimoLarson@users.noreply.github.com> Date: Thu, 21 Feb 2019 09:19:27 -0500 Subject: [PATCH 2/2] Pass module for resolving names through anonymous function handling --- src/anonymous.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/anonymous.jl b/src/anonymous.jl index 596dda2..2e328cd 100644 --- a/src/anonymous.jl +++ b/src/anonymous.jl @@ -38,14 +38,14 @@ end baremodule __deserialized_types__ end -function newstruct_raw(cache, ::Type{TypeName}, d) - name = raise_recursive(d[:data][2], cache) +function newstruct_raw(cache, ::Type{TypeName}, d, init) + name = raise_recursive(d[:data][2], cache, init) name = isdefined(__deserialized_types__, name) ? gensym() : name tn = ccall(:jl_new_typename_in, Ref{Core.TypeName}, (Any, Any), name, __deserialized_types__) cache[d] = tn names, super, parameters, types, has_instance, - abstr, mutabl, ninitialized = map(x -> raise_recursive(x, cache), d[:data][3:end-1]) + abstr, mutabl, ninitialized = map(x -> raise_recursive(x, cache, init), d[:data][3:end-1]) tn.names = names ndt = ccall(:jl_new_datatype, Any, (Any, Any, Any, Any, Any, Any, Cint, Cint, Cint), tn, tn.module, super, parameters, names, types, @@ -56,7 +56,7 @@ function newstruct_raw(cache, ::Type{TypeName}, d) # use setfield! directly to avoid `fieldtype` lowering expecting to see a Singleton object already on ty Core.setfield!(ty, :instance, ccall(:jl_new_struct, Any, (Any, Any...), ty)) end - mt = raise_recursive(d[:data][end], cache) + mt = raise_recursive(d[:data][end], cache, init) if mt != nothing mtname, defs, maxa, kwsorter = mt tn.mt = ccall(:jl_new_method_table, Any, (Any, Any), name, tn.module)