253 Commits

Author SHA1 Message Date
Nobuyoshi Nakada
b67f6129e3
[Misc #22206] Add dependency updater to mkmf
Allow extension projects to update marked dependency sections after
`create_makefile` has resolved their source and object lists.

Share the dependency scanner with `tool/mkdepend.rb` so bundled and
upstream extensions can generate the same dependency files.
2026-07-24 17:45:58 +09:00
Nobuyoshi Nakada
7d4461e162
[Misc #22206] Generate dependencies without compiler builds
Replace `tool/update-deps` with a Ruby source scanner so dependency
updates no longer require GNU make, a configured build, or compiler
preprocessor output.

Keep compact source mappings and scanner declarations in dependency
files, and expand complete rules into the build directory.  Avoid the
temporary fixture headers required by the compiler-driven prototype.

Use the generated rules from GNU make, BSD make, and NMake builds.
Support out-of-tree and read-only source trees, and retain expanded
dependencies shipped in release archives when baseruby is unavailable.
2026-07-23 00:04:47 +09:00
Scott Myron
7c69f93d53 [ruby/json] Add a sort_keys option to the generator.
Fix: https://github.com/ruby/json/issues/976

https://github.com/ruby/json/commit/ea008e82fe

Co-Authored-By: Jean Boussier <byroot@ruby-lang.org>
2026-07-02 09:24:35 +00:00
Jean Boussier
a746dd8374 [ruby/json] Declare types as RUBY_TYPED_THREAD_SAFE_FREE
Ref: https://github.com/ruby/ruby/pull/17395

https://github.com/ruby/json/commit/fa69e94b66
2026-06-25 06:37:32 +00:00
Jean Boussier
9ac37cd626 [ruby/json] generator.c: don't start with a stack buffer in IO case
It was never intended to be initialized with a stack buffer
in that case, as when dumping into an IO we want larger chunks.

https://github.com/ruby/json/commit/996bac686d
2026-06-11 18:46:57 +00:00
Jean Boussier
cfc13d2e89 [ruby/json] Fix memsize function for embedded types
We shouldn't report the size of the embedded struct.

https://github.com/ruby/json/commit/b1a0891cc3
2026-06-05 07:55:36 +00:00
Jean Boussier
8fefa5537c [ruby/json] Integrate with Ruby 4.1 ruby_sized_xfree
Ensure that buffer sizes have been properly tracked when running
in debug mode, and appease the GC slightly when running in release
mode.

Ref: https://bugs.ruby-lang.org/issues/21861

https://github.com/ruby/json/commit/90354007ea
2026-06-03 07:33:28 +00:00
Jean Boussier
49c9046fa0 [ruby/json] Handle invalid types passed as max_nesting option
https://github.com/ruby/json/commit/be8d068a8e

Co-Authored-By: Yuhang Wu <yuhang@depthfirst.com>
2026-05-29 06:41:06 +00:00
Jean Boussier
bed68bc9c8 [ruby/json] generator.c: trigger write barriers in cState_init_copy
Reported-By: Yuhang Wu <yuhang@depthfirst.com>

https://github.com/ruby/json/commit/dba1d885ea
2026-05-28 08:02:29 +00:00
Jean Boussier
255a3a07b7 [ruby/json] Further validate generator depth config
https://github.com/ruby/json/commit/e8800cb0c5

Co-Authored-By: Yuhang Wu <yuhang@depthfirst.com>
2026-05-28 07:43:09 +00:00
Scott Myron
c568944b8f [ruby/json] Force ensure_valid_encoding to be inlined.
And move the encoding convertion logic in another function with NOINLINE.

The overwelming majority of strings are correctly encoded, so we
want to inline the very cheap check, however we don't want to
inline the much larger piece of code required to re-encode the string.

https://github.com/ruby/json/commit/cfbe356b4f

Co-Authored-By: Jean Boussier <jean.boussier@gmail.com>
2026-04-20 12:56:53 +00:00
Scott Myron
8f02f644eb [ruby/json] Use RB_ENC_CODERANGE to first check the cached coderange before calling rb_enc_str_coderange if the coderange is unknown.
https://github.com/ruby/json/commit/4ef7a45654
2026-04-19 02:14:12 +00:00
Jean Boussier
60116d5ee1 [ruby/json] Use embeddable types
Ref: https://bugs.ruby-lang.org/issues/21853

Introduced in Ruby 3.3, will officially be public API in 4.1,
but can be used sooner by checking the existence of RUBY_TYPED_EMBEDDABLE

https://github.com/ruby/json/commit/101f7342cd
2026-03-24 07:35:33 +00:00
Jean Boussier
e832057ad3 [ruby/json] Revert use of RUBY_TYPED_EMBEDDABLE
https://github.com/ruby/json/commit/8364dbd491
2026-03-23 21:27:51 +00:00
Jean Boussier
f23ffd5bef [ruby/json] Use embeddable types
Ref: https://bugs.ruby-lang.org/issues/21853

Introduced in Ruby 3.3, will officially be public API in 4.1,
but can be used sooner by checking the existence of RUBY_TYPED_EMBEDDABLE

https://github.com/ruby/json/commit/89fe63069d
2026-03-23 20:39:05 +00:00
thesmartshadow
f56310de4a [ruby/json] Reject negative depth; add overflow guards to prevent hang/crash
https://github.com/ruby/json/commit/de993aa766
2026-03-06 07:48:59 +00:00
Jean Boussier
858c96c568 [ruby/json] Reimplement to_json methods in Ruby
https://github.com/ruby/json/commit/3f32c47de4
2026-03-05 08:28:55 +00:00
Jean Boussier
c0eca60eba [ruby/json] Remove codepaths under !RUBY_INTEGER_UNIFICATION
This was for pre Ruby 2.4 support which we dropped a while ago.

https://github.com/ruby/json/commit/b11ce01ca6
2026-02-03 07:50:19 +00:00
Jean Boussier
41238ccd85 [ruby/json] fbuffer_append_str: assume string
https://github.com/ruby/json/commit/fff25c9f4b
2026-02-03 07:24:37 +00:00
Jean Boussier
066332465b [ruby/json] Ensure Generator::State is kept on the stack
Fix: https://github.com/ruby/json/issues/929

When calling `cState_partial_generate` from `mHash_to_json` or other
`to_json` funcs, `VState` becomes unreachable very quickly, hence the
compiler may optimize it out of the stack, and make it invisible to
the GC stack scanning. This is particularly liekly given how aggressively
we inline.

Repro:

```ruby
require 'json'

test_data = {
  "flag" => true,
  "data" => 10000.times.map { [1.0] },
  :flag => false,
}

10.times do
  test_data.to_json
end
```

But in practice the cause was just that the issued warning calls
Hash#inspect on a big hash, which triggers GC.

So it can be triggered even more reliably with:

```ruby
require 'json'

module JSON
  module Common
    def self.on_mixed_keys_hash(...)
      GC.start
    end
  end
end

test_data = {
  "flag" => true,
  "data" => 10000.times.map { [1.0] },
  :flag => false,
}

test_data.to_json
```

https://github.com/ruby/json/commit/79b6e168ba
2026-02-03 07:24:29 +00:00
Jean Boussier
3164d4e8a2 [ruby/json] Extract json_fast_memcpy16 for readability
https://github.com/ruby/json/commit/1b276c8623
2026-01-16 17:52:54 +00:00
Scott Myron
456ef9140a [ruby/json] Use __builtin_memcpy, if available, to copy overlapping byte ranges in copy_remaining_bytes to avoid a branch to MEMCPY. Additionally use a space as padding byte instead of an 'X' so it can be represented diretly on AArch64 with a single instruction.
https://github.com/ruby/json/commit/643ee11fed
2026-01-16 17:52:54 +00:00
Nobuyoshi Nakada
b8566faca5
[ruby/json] Remove trailing spaces [ci skip]
https://github.com/ruby/json/commit/15eb40dbdf
2026-01-14 21:30:19 +09:00
Scott Myron
a650c90fab [ruby/json] initialize search.chunk_end to silence a warning about it being potentially uninitialized
https://github.com/ruby/json/commit/73818b80c8
2026-01-14 07:59:32 +00:00
Scott Myron
24ad90d3e0 [ruby/json] use a conditional to select SIMD implementation rather than pointer
https://github.com/ruby/json/commit/86a5cce405
2026-01-14 07:59:32 +00:00
Étienne Barrié
208271e372 [ruby/json] Fix handling of depth
https://github.com/ruby/json/commit/ccca602274
2025-12-03 15:21:08 +00:00
Étienne Barrié
54a73a57a2 [ruby/json] Test and restore behavior around to_json changing depth
When serializing an Array, and one of the elements of the Array requires
calling `to_json`, if the depth is changed, it will be used for the next
entries, which wasn't the case before
https://github.com/ruby/json/commit/5abd43490714, and is not the case with
TruffleRuby and JRuby.

Additionally, with TruffleRuby and JRuby the state's depth after the
`to_json` call is used to close the Array, which isn't the case with
CRuby.

https://github.com/ruby/json/commit/386b36fde5
2025-12-03 13:49:05 +00:00
Nobuyoshi Nakada
28d9493b98 [ruby/json] Fix macro arguments
`ALWAYS_INLINE()` and `NOINLINE()` are defined with one argument.

https://github.com/ruby/json/commit/8fb727901e
2025-12-03 02:19:06 +00:00
Étienne Barrié
2f192c73cc [ruby/json] Respect Coder depth when generating
https://github.com/ruby/json/commit/9c36681b17
2025-11-27 13:01:57 +00:00
Étienne Barrié
ab3b79ea3d [ruby/json] Don't copy JSON_Generator_State in generate_new
Now that the state isn't mutated in generate_new, we no longer need to
copy the struct, we can just use it.

https://github.com/ruby/json/commit/d7964f8892
2025-11-26 14:47:27 +00:00
Étienne Barrié
98a9667736 [ruby/json] Don't write depth to JSON_Generator_State in some cases
For `JSON.generate` and `JSON::State#generate_new`, don't copy
generate_json_data::depth to JSON_Generator_State::depth.

In `JSON.generate`, the JSON_Generator_State is on the stack and
discarded anyway. In `JSON::State#generate_new`, we copy the struct to
avoid mutating the original one.

https://github.com/ruby/json/commit/873b29ea34
2025-11-26 14:47:27 +00:00
Étienne Barrié
4b8ec8c9fc [ruby/json] Add depth to struct generate_json_data
Instead of incrementing JSON_Generator_State::depth, we now increment
generate_json_data::depth, and only copied at the end.

https://github.com/ruby/json/commit/5abd434907
2025-11-26 14:47:27 +00:00
Étienne Barrié
ffa105c27f [ruby/json] Move RUBY_TYPED_FROZEN_SHAREABLE macro to json.h
https://github.com/ruby/json/commit/2a4ebe8250
2025-11-21 16:12:35 +00:00
Étienne Barrié
bdca2a9975 [ruby/json] Ractor-shareable JSON::Coder
https://github.com/ruby/json/commit/58d60d6b76
2025-11-21 16:12:35 +00:00
Étienne Barrié
48027256cf [ruby/json] Remove unused symbols
https://github.com/ruby/json/commit/9364d0c761
2025-11-20 17:23:37 +00:00
Scott Myron
f272aabb5c [ruby/json] Use #if instead of #ifdef when checking for JSON_DEBUG so debugging code is not generated when JSON_DEBUG=0.
https://github.com/ruby/json/commit/4f1adb10d3
2025-11-18 08:20:51 +00:00
Jean Boussier
2f9e0d355e [ruby/json] Fix duplicate 'inline' declaration specifier
Followup: https://github.com/ruby/json/pull/889

https://github.com/ruby/json/commit/591510392a
2025-11-03 15:56:38 +00:00
Takashi Kokubun
4740b3d7aa [ruby/json] Fix check_dependency 2025-11-03 07:39:00 -08:00
Jean Boussier
35a5e55133 [ruby/json] Centralize macro definitions
https://github.com/ruby/json/commit/1576ea7d47
2025-11-03 09:22:40 +00:00
Jean Boussier
5153a2dcb3 [ruby/json] Invoke as_json callback for strings with invalid encoding
Fix: https://github.com/ruby/json/issues/873

This allow users to encode binary strings if they so wish.
e.g. they can use Base64 or similar, or chose to replace invalid
characters with something else.

https://github.com/ruby/json/commit/b1b16c416f
2025-11-02 14:48:33 +00:00
Kazuki Yamaguchi
6bdb2027f6 [ruby/json] Fix memory leak when exception is raised during JSON generation part 2
Commit https://github.com/ruby/json/commit/44df509dc2de fixed it for StandardError, but other exceptions and
jumps are also possible. Use rb_ensure() to release FBuffer instead of
rb_rescue().

A reproducer:

    o = Object.new
    def o.to_json(a) = throw :a
    a = ["make heap allocation"*100, o]

    10.times do
      100_000.times do
        catch(:a) { JSON(a) }
      end

      puts `ps -o rss= -p #{$$}`
    end

https://github.com/ruby/json/commit/9b7b648ecd
2025-10-31 16:02:26 +00:00
Jean Boussier
317f102cbb [ruby/json] Fix GeneratorError messages to be UTF-8 encoded
https://github.com/ruby/json/commit/965ba6c5d4
2025-10-30 10:34:06 +00:00
Jean Boussier
8e8e327870 [ruby/json] Fix concurrent usage of JSON::Coder#dump
Fix: 90616277e3 (r168784389)

Because the `depth` counter is inside `JSON::State` it can't be used
concurrently, and in case of a circular reference the counter may be
left at the max value.

The depth counter should be moved outside `JSON_Generator_State` and
into `struct generate_json_data`, but it's a larger refactor.

In the meantime, `JSON::Coder` calls `State#generate_new` so I changed
that method so that it first copy the state on the stack.

https://github.com/ruby/json/commit/aefa671eca
2025-10-25 08:57:48 +00:00
Jean Boussier
1042a0bdd8 JSON::Coder callback now recieve a second argument to mark object keys
e.g.
```ruby
{ 1 => 2 }
```

The callback will be invoked for `1` as while it has a native JSON
equivalent, it's not legal as an object name.
2025-09-19 19:30:10 +09:00
Jean Boussier
dc406e9b5b [ruby/json] Avoid scientific notation before exponent 15
Fix: https://github.com/ruby/json/issues/861

It's not incorrect to use scientific notation, but it tend
to throw people off a bit, so it's best to keep it for very large
numbers.

https://github.com/ruby/json/commit/1566cd01a6
2025-09-19 19:30:10 +09:00
Jean Boussier
794e4a3a26 [ruby/json] Fix a -Wreturn-type warning
Fix: https://github.com/ruby/json/pull/843

https://github.com/ruby/json/commit/d3f7f0452b

Co-Authored-By: Takashi Kokubun <takashikkbn@gmail.com>
2025-09-03 23:38:37 +09:00
Jean Boussier
d9e9a667a8
JSON.generate: warn or raise on duplicated key
Because both strings and symbols keys are serialized the same,
it always has been possible to generate documents with duplicated
keys:

```ruby
>> puts JSON.generate({ foo: 1, "foo" => 2 })
{"foo":1,"foo":2}
```

This is pretty much always a mistake and can cause various
issues because it's not guaranteed how various JSON parsers
will handle this.

Until now I didn't think it was possible to catch such case without
tanking performance, hence why I only made the parser more strict.

But I finally found a way to check for duplicated keys cheaply enough.
2025-08-27 10:01:52 +09:00
Jean Boussier
0e0f0dfd07
Fix JSON::Coder to cast non-string keys. 2025-08-27 10:01:52 +09:00
Jean Boussier
c3a80ca582
Fix JSON.generate strict: true mode to also restrict hash keys 2025-08-27 10:01:52 +09:00
Jean Boussier
4d6b1241f6
[ruby/json] Extract fbuffer_append_str_repeat function
https://github.com/ruby/json/commit/12656777dc
2025-08-27 10:01:52 +09:00