Skip to content

Commit e4f5794

Browse files
committed
Merge remote-tracking branch 'upstream/master' into Ractor-Local-GC-version-3
2 parents bd0bb40 + 43683e1 commit e4f5794

File tree

289 files changed

+5814
-3544
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

289 files changed

+5814
-3544
lines changed

.github/workflows/spec_guards.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ jobs:
4141
# Specs from ruby/spec should still run on all supported Ruby versions.
4242
# This also ensures the needed ruby_version_is guards are there, see spec/README.md.
4343
ruby:
44-
- ruby-3.0
4544
- ruby-3.1
4645
- ruby-3.2
4746
- ruby-3.3

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ Note that each entry is kept to a minimum, see links for details.
77

88
## Language changes
99

10+
* `*nil` no longer calls `nil.to_a`, similar to how `**nil` does
11+
not call `nil.to_hash`. [[Feature #21047]]
12+
1013
## Core classes updates
1114

1215
Note: We're only listing outstanding class updates.
@@ -84,4 +87,5 @@ The following bundled gems are updated.
8487
## JIT
8588

8689
[Feature #19908]: https://bugs.ruby-lang.org/issues/19908
90+
[Feature #21047]: https://bugs.ruby-lang.org/issues/21047
8791
[Bug #21049]: https://bugs.ruby-lang.org/issues/21049

benchmark/nilclass.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
prelude: |
2+
def a = nil
13
benchmark:
24
to_i: |
35
nil.to_i
46
to_f: |
57
nil.to_f
8+
splat: |
9+
a(*nil)
610
loop_count: 100000

bootstraptest/test_literal.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@
117117
assert_equal 'true', 'a = [obj = Object.new]; a[0] == obj'
118118
assert_equal '5', 'a = [1,2,3]; a[1] = 5; a[1]'
119119
assert_equal 'bar', '[*:foo];:bar'
120-
assert_equal '[1, 2]', 'def nil.to_a; [2]; end; [1, *nil]'
121-
assert_equal '[1, 2]', 'def nil.to_a; [1, 2]; end; [*nil]'
120+
assert_equal '[]', 'def nil.to_a; [1, 2]; end; [*nil]'
121+
assert_equal '[1]', 'def nil.to_a; [2]; end; [1, *nil]'
122122
assert_equal '[0, 1, {2 => 3}]', '[0, *[1], 2=>3]', "[ruby-dev:31592]"
123123

124124

bootstraptest/test_ractor.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,28 @@ def /(other)
13611361
Ractor.shareable?(pr)
13621362
}
13631363

1364+
# Ractor.make_shareable(a_proc) makes inner structure shareable and freezes it
1365+
assert_equal 'true,true,true,true', %q{
1366+
class Proc
1367+
attr_reader :obj
1368+
def initialize
1369+
@obj = Object.new
1370+
end
1371+
end
1372+
1373+
pr = Ractor.current.instance_eval do
1374+
Proc.new {}
1375+
end
1376+
1377+
results = []
1378+
Ractor.make_shareable(pr)
1379+
results << Ractor.shareable?(pr)
1380+
results << pr.frozen?
1381+
results << Ractor.shareable?(pr.obj)
1382+
results << pr.obj.frozen?
1383+
results.map(&:to_s).join(',')
1384+
}
1385+
13641386
# Ractor.shareable?(recursive_objects)
13651387
assert_equal '[false, false]', %q{
13661388
y = []
@@ -1389,6 +1411,21 @@ module M; end
13891411
Ractor.make_shareable(ary = [C, M])
13901412
}
13911413

1414+
# Ractor.make_shareable with curried proc checks isolation of original proc
1415+
assert_equal 'isolation error', %q{
1416+
a = Object.new
1417+
orig = proc { a }
1418+
curried = orig.curry
1419+
1420+
begin
1421+
Ractor.make_shareable(curried)
1422+
rescue Ractor::IsolationError
1423+
'isolation error'
1424+
else
1425+
'no error'
1426+
end
1427+
}
1428+
13921429
# define_method() can invoke different Ractor's proc if the proc is shareable.
13931430
assert_equal '1', %q{
13941431
class C

ext/json/fbuffer/fbuffer.h

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "ruby.h"
55
#include "ruby/encoding.h"
6+
#include "../vendor/jeaiii-ltoa.h"
67

78
/* shims */
89
/* This is the fallback definition from Ruby 3.4 */
@@ -150,6 +151,13 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
150151
}
151152
}
152153

154+
/* Appends a character into a buffer. The buffer needs to have sufficient capacity, via fbuffer_inc_capa(...). */
155+
static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr)
156+
{
157+
fb->ptr[fb->len] = chr;
158+
fb->len += 1;
159+
}
160+
153161
static void fbuffer_append_str(FBuffer *fb, VALUE str)
154162
{
155163
const char *newstr = StringValuePtr(str);
@@ -167,25 +175,48 @@ static inline void fbuffer_append_char(FBuffer *fb, char newchr)
167175
fb->len++;
168176
}
169177

170-
static long fltoa(long number, char *buf)
178+
static inline char *fbuffer_cursor(FBuffer *fb)
179+
{
180+
return fb->ptr + fb->len;
181+
}
182+
183+
static inline void fbuffer_advance_to(FBuffer *fb, char *end)
171184
{
172-
static const char digits[] = "0123456789";
173-
long sign = number;
174-
char* tmp = buf;
175-
176-
if (sign < 0) number = -number;
177-
do *tmp-- = digits[number % 10]; while (number /= 10);
178-
if (sign < 0) *tmp-- = '-';
179-
return buf - tmp;
185+
fb->len = end - fb->ptr;
180186
}
181187

182-
#define LONG_BUFFER_SIZE 20
188+
/*
189+
* Appends the decimal string representation of \a number into the buffer.
190+
*/
183191
static void fbuffer_append_long(FBuffer *fb, long number)
184192
{
185-
char buf[LONG_BUFFER_SIZE];
186-
char *buffer_end = buf + LONG_BUFFER_SIZE;
187-
long len = fltoa(number, buffer_end - 1);
188-
fbuffer_append(fb, buffer_end - len, len);
193+
/*
194+
* The jeaiii_ultoa() function produces digits left-to-right,
195+
* allowing us to write directly into the buffer, but we don't know
196+
* the number of resulting characters.
197+
*
198+
* We do know, however, that the `number` argument is always in the
199+
* range 0xc000000000000000 to 0x3fffffffffffffff, or, in decimal,
200+
* -4611686018427387904 to 4611686018427387903. The max number of chars
201+
* generated is therefore 20 (including a potential sign character).
202+
*/
203+
204+
static const int MAX_CHARS_FOR_LONG = 20;
205+
206+
fbuffer_inc_capa(fb, MAX_CHARS_FOR_LONG);
207+
208+
if (number < 0) {
209+
fbuffer_append_reserved_char(fb, '-');
210+
211+
/*
212+
* Since number is always > LONG_MIN, `-number` will not overflow
213+
* and is always the positive abs() value.
214+
*/
215+
number = -number;
216+
}
217+
218+
char *end = jeaiii_ultoa(fbuffer_cursor(fb), number);
219+
fbuffer_advance_to(fb, end);
189220
}
190221

191222
static VALUE fbuffer_finalize(FBuffer *fb)

ext/json/generator/depend

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,6 @@ generator.o: $(hdrdir)/ruby/st.h
178178
generator.o: $(hdrdir)/ruby/subst.h
179179
generator.o: $(srcdir)/../fbuffer/fbuffer.h
180180
generator.o: $(srcdir)/../vendor/fpconv.c
181+
generator.o: $(srcdir)/../vendor/jeaiii-ltoa.h
181182
generator.o: generator.c
182183
# AUTOGENERATED DEPENDENCIES END

ext/json/lib/json/common.rb

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ def generator=(generator) # :nodoc:
7070
end
7171
self.state = generator::State
7272
const_set :State, self.state
73-
const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby
74-
const_set :FAST_STATE_PROTOTYPE, create_fast_state
75-
const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state
7673
ensure
7774
$VERBOSE = old
7875
end
@@ -101,6 +98,29 @@ def create_pretty_state
10198

10299
# Sets or Returns the JSON generator state class that is used by JSON.
103100
attr_accessor :state
101+
102+
private
103+
104+
def deprecated_singleton_attr_accessor(*attrs)
105+
args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
106+
attrs.each do |attr|
107+
singleton_class.class_eval <<~RUBY
108+
def #{attr}
109+
warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
110+
@#{attr}
111+
end
112+
113+
def #{attr}=(val)
114+
warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
115+
@#{attr} = val
116+
end
117+
118+
def _#{attr}
119+
@#{attr}
120+
end
121+
RUBY
122+
end
123+
end
104124
end
105125

106126
# Sets create identifier, which is used to decide if the _json_create_
@@ -334,13 +354,6 @@ def generate(obj, opts = nil)
334354
end
335355
end
336356

337-
# :stopdoc:
338-
# I want to deprecate these later, so I'll first be silent about them, and
339-
# later delete them.
340-
alias unparse generate
341-
module_function :unparse
342-
# :startdoc:
343-
344357
# :call-seq:
345358
# JSON.fast_generate(obj, opts) -> new_string
346359
#
@@ -363,12 +376,6 @@ def fast_generate(obj, opts = nil)
363376
state.generate(obj)
364377
end
365378

366-
# :stopdoc:
367-
# I want to deprecate these later, so I'll first be silent about them, and later delete them.
368-
alias fast_unparse fast_generate
369-
module_function :fast_unparse
370-
# :startdoc:
371-
372379
# :call-seq:
373380
# JSON.pretty_generate(obj, opts = nil) -> new_string
374381
#
@@ -418,34 +425,26 @@ def pretty_generate(obj, opts = nil)
418425
state.generate(obj)
419426
end
420427

421-
# :stopdoc:
422-
# I want to deprecate these later, so I'll first be silent about them, and later delete them.
423-
alias pretty_unparse pretty_generate
424-
module_function :pretty_unparse
425-
# :startdoc:
428+
# Sets or returns default options for the JSON.unsafe_load method.
429+
# Initially:
430+
# opts = JSON.load_default_options
431+
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
432+
deprecated_singleton_attr_accessor :unsafe_load_default_options
426433

427-
class << self
428-
# Sets or returns default options for the JSON.unsafe_load method.
429-
# Initially:
430-
# opts = JSON.load_default_options
431-
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
432-
attr_accessor :unsafe_load_default_options
433-
end
434-
self.unsafe_load_default_options = {
434+
@unsafe_load_default_options = {
435435
:max_nesting => false,
436436
:allow_nan => true,
437437
:allow_blank => true,
438438
:create_additions => true,
439439
}
440440

441-
class << self
442-
# Sets or returns default options for the JSON.load method.
443-
# Initially:
444-
# opts = JSON.load_default_options
445-
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
446-
attr_accessor :load_default_options
447-
end
448-
self.load_default_options = {
441+
# Sets or returns default options for the JSON.load method.
442+
# Initially:
443+
# opts = JSON.load_default_options
444+
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
445+
deprecated_singleton_attr_accessor :load_default_options
446+
447+
@load_default_options = {
449448
:allow_nan => true,
450449
:allow_blank => true,
451450
:create_additions => nil,
@@ -581,9 +580,9 @@ class << self
581580
#
582581
def unsafe_load(source, proc = nil, options = nil)
583582
opts = if options.nil?
584-
unsafe_load_default_options
583+
_unsafe_load_default_options
585584
else
586-
unsafe_load_default_options.merge(options)
585+
_unsafe_load_default_options.merge(options)
587586
end
588587

589588
unless source.is_a?(String)
@@ -741,9 +740,9 @@ def unsafe_load(source, proc = nil, options = nil)
741740
#
742741
def load(source, proc = nil, options = nil)
743742
opts = if options.nil?
744-
load_default_options
743+
_load_default_options
745744
else
746-
load_default_options.merge(options)
745+
_load_default_options.merge(options)
747746
end
748747

749748
unless source.is_a?(String)
@@ -778,17 +777,12 @@ def recurse_proc(result, &proc) # :nodoc:
778777
end
779778
end
780779

781-
alias restore load
782-
module_function :restore
783-
784-
class << self
785-
# Sets or returns the default options for the JSON.dump method.
786-
# Initially:
787-
# opts = JSON.dump_default_options
788-
# opts # => {:max_nesting=>false, :allow_nan=>true}
789-
attr_accessor :dump_default_options
790-
end
791-
self.dump_default_options = {
780+
# Sets or returns the default options for the JSON.dump method.
781+
# Initially:
782+
# opts = JSON.dump_default_options
783+
# opts # => {:max_nesting=>false, :allow_nan=>true}
784+
deprecated_singleton_attr_accessor :dump_default_options
785+
@dump_default_options = {
792786
:max_nesting => false,
793787
:allow_nan => true,
794788
}
@@ -841,7 +835,7 @@ def dump(obj, anIO = nil, limit = nil, kwargs = nil)
841835
end
842836
end
843837

844-
opts = JSON.dump_default_options
838+
opts = JSON._dump_default_options
845839
opts = opts.merge(:max_nesting => limit) if limit
846840
opts = opts.merge(kwargs) if kwargs
847841

0 commit comments

Comments
 (0)