Skip to content

Commit 220409f

Browse files
byrootetiennebarrie
authored andcommitted
[ruby/json] Refactor JSON::Ext::Parser to split configuration and parsing state
Ref: ruby/json#718 The existing `Parser` interface is pretty bad, as it forces to instantiate a new instance for each document. Instead it's preferable to only take the config and do all the initialization needed, and then keep the parsing state on the stack on in ephemeral memory. This refactor makes the `JSON::Coder` pull request much easier to implement in a performant way. ruby/json@c8d5236a92 Co-Authored-By: Étienne Barrié <[email protected]>
1 parent 61d3f9a commit 220409f

File tree

5 files changed

+419
-599
lines changed

5 files changed

+419
-599
lines changed

ext/json/lib/json/common.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,13 @@ def parse(source, opts = nil)
232232
# - Option +max_nesting+, if not provided, defaults to +false+,
233233
# which disables checking for nesting depth.
234234
# - Option +allow_nan+, if not provided, defaults to +true+.
235-
def parse!(source, opts = {})
236-
opts = {
235+
def parse!(source, opts = nil)
236+
options = {
237237
:max_nesting => false,
238238
:allow_nan => true
239-
}.merge(opts)
240-
Parser.new(source, **(opts||{})).parse
239+
}
240+
options.merge!(opts) if opts
241+
Parser.new(source, options).parse
241242
end
242243

243244
# :call-seq:
@@ -258,7 +259,7 @@ def load_file(filespec, opts = nil)
258259
# JSON.parse!(File.read(path, opts))
259260
#
260261
# See method #parse!
261-
def load_file!(filespec, opts = {})
262+
def load_file!(filespec, opts = nil)
262263
parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
263264
end
264265

ext/json/lib/json/ext.rb

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,36 @@ module JSON
66
# This module holds all the modules/classes that implement JSON's
77
# functionality as C extensions.
88
module Ext
9+
class Parser
10+
class << self
11+
def parse(...)
12+
new(...).parse
13+
end
14+
end
15+
16+
def initialize(source, opts = nil)
17+
@source = source
18+
@config = Config.new(opts)
19+
end
20+
21+
def source
22+
@source.dup
23+
end
24+
25+
def parse
26+
@config.parse(@source)
27+
end
28+
end
29+
30+
require 'json/ext/parser'
31+
Ext::Parser::Config = Ext::ParserConfig
32+
JSON.parser = Ext::Parser
33+
934
if RUBY_ENGINE == 'truffleruby'
10-
require 'json/ext/parser'
1135
require 'json/truffle_ruby/generator'
12-
JSON.parser = Parser
1336
JSON.generator = ::JSON::TruffleRuby::Generator
1437
else
15-
require 'json/ext/parser'
1638
require 'json/ext/generator'
17-
JSON.parser = Parser
1839
JSON.generator = Generator
1940
end
2041
end

0 commit comments

Comments
 (0)