Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/lazy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -270,17 +270,19 @@ function applyobject(keyvalfunc, x::LazyValues)
b == UInt8('}') && return pos + 1
while true
# parsestring returns key as a PtrString
key, pos = @inline parsestring(LazyValue(buf, pos, JSONTypes.STRING, opts, false))
@nextbyte
if b != UInt8(':')
error = ExpectedColon
@goto invalid
GC.@preserve buf begin
key, pos = @inline parsestring(LazyValue(buf, pos, JSONTypes.STRING, opts, false))
@nextbyte
if b != UInt8(':')
error = ExpectedColon
@goto invalid
end
pos += 1
@nextbyte
# we're now positioned at the start of the value
val = _lazy(buf, pos, len, b, opts)
ret = keyvalfunc(key, val)
end
pos += 1
@nextbyte
# we're now positioned at the start of the value
val = _lazy(buf, pos, len, b, opts)
ret = keyvalfunc(key, val)
# if ret is an EarlyReturn, then we're short-circuiting
# parsing via e.g. selection syntax, so return immediately
ret isa StructUtils.EarlyReturn && return ret
Expand Down Expand Up @@ -732,8 +734,11 @@ function Base.show(io::IO, x::LazyValue)
show(io, MIME"text/plain"(), la)
end
elseif T == JSONTypes.STRING
str, _ = parsestring(x)
Base.print(io, "JSON.LazyValue(", repr(convert(String, str)), ")")
buf = getbuf(x)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since buf isn't explicitly used and getbuf is just an accessor, GC.@preserve x is probably more clear in this case. The main difference is that the other fields of x would also be preserved.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so GC.@preserve x will ensure the field is also preserved?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will assume the whole object is being used in some unknown way, which includes the field.

For mutable object, this implies the object address may be used (though there’s no requirement for that address to be allocated in the heap). For immutable object this only implies that the fields are all being used in some unknown way.

GC.@preserve buf begin
str, _ = parsestring(x)
Base.print(io, "JSON.LazyValue(", repr(convert(String, str)), ")")
end
elseif T == JSONTypes.NULL
Base.print(io, "JSON.LazyValue(nothing)")
else # bool/number
Expand Down
22 changes: 16 additions & 6 deletions src/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,11 @@ function applyvalue(f, x::LazyValues, null)
f(arr)
return pos
elseif type == JSONTypes.STRING
str, pos = parsestring(x)
f(convert(String, str))
buf = getbuf(x)
GC.@preserve buf begin
str, pos = parsestring(x)
f(convert(String, str))
end
return pos
elseif type == JSONTypes.NUMBER
num, pos = parsenumber(x)
Expand Down Expand Up @@ -343,9 +346,12 @@ end

function StructUtils.lift(style::StructStyle, ::Type{T}, x::LazyValues, tags=(;)) where {T}
type = gettype(x)
buf = getbuf(x)
if type == JSONTypes.STRING
ptrstr, pos = parsestring(x)
str, _ = StructUtils.lift(style, T, ptrstr, tags)
GC.@preserve buf begin
ptrstr, pos = parsestring(x)
str, _ = StructUtils.lift(style, T, ptrstr, tags)
end
return str, pos
elseif type == JSONTypes.NUMBER
num, pos = parsenumber(x)
Expand Down Expand Up @@ -448,7 +454,9 @@ end
Base.@nexprs $N i -> begin
if typ == JSONTypes.OBJECT
# consume key
_, pos = @inline parsestring(LazyValue(buf, pos, JSONTypes.STRING, opts, false))
GC.@preserve buf begin
_, pos = @inline parsestring(LazyValue(buf, pos, JSONTypes.STRING, opts, false))
end
@nextbyte
if b != UInt8(':')
error = ExpectedColon
Expand Down Expand Up @@ -483,7 +491,9 @@ end
while true
if typ == JSONTypes.OBJECT
# consume key
_, pos = @inline parsestring(LazyValue(buf, pos, JSONTypes.STRING, opts, false))
GC.@preserve buf begin
_, pos = @inline parsestring(LazyValue(buf, pos, JSONTypes.STRING, opts, false))
end
@nextbyte
if b != UInt8(':')
error = ExpectedColon
Expand Down
Loading