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
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ bf01f6ae89a95d8f5572e050facfe311c8c28aaf
7480cd8d37fd71a41ce12b759090051c7e14fb5a
c0a526dd97b22f462f49a2a0062420523303769d
9ee713a92c2fe8bf5aac4c2f5b0c4c7e6b475b47
a925c74bd239398b97112e24f952c377345c5bff
92ce852366a8ba90b28254f4df36fc3f6b3b12eb

# Win32: EOL code of batch files
23f9a0d655c4d405bb2397a147a1523436205486
Expand Down
5 changes: 3 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ They are still available on rubygems.org and can be installed with
### The following default gems are updated.

* RubyGems 4.1.0.beta1
* 4.0.3 to [v4.0.4][RubyGems-v4.0.4], [v4.0.5][RubyGems-v4.0.5], [v4.0.6][RubyGems-v4.0.6], [v4.0.7][RubyGems-v4.0.7], [v4.0.8][RubyGems-v4.0.8], [v4.0.9][RubyGems-v4.0.9], [v4.0.10][RubyGems-v4.0.10], [v4.0.11][RubyGems-v4.0.11], [v4.0.12][RubyGems-v4.0.12], [v4.0.13][RubyGems-v4.0.13], [v4.0.14][RubyGems-v4.0.14], [v4.0.15][RubyGems-v4.0.15], [v4.0.16][RubyGems-v4.0.16], [v4.0.17][RubyGems-v4.0.17], [v4.0.18][RubyGems-v4.0.18], [v4.0.19][RubyGems-v4.0.19], [v4.0.20][RubyGems-v4.0.20]
* 4.0.3 to [v4.0.4][RubyGems-v4.0.4], [v4.0.5][RubyGems-v4.0.5], [v4.0.6][RubyGems-v4.0.6], [v4.0.7][RubyGems-v4.0.7], [v4.0.8][RubyGems-v4.0.8], [v4.0.9][RubyGems-v4.0.9], [v4.0.10][RubyGems-v4.0.10], [v4.0.11][RubyGems-v4.0.11], [v4.0.12][RubyGems-v4.0.12], [v4.0.13][RubyGems-v4.0.13], [v4.0.14][RubyGems-v4.0.14], [v4.0.15][RubyGems-v4.0.15], [v4.0.16][RubyGems-v4.0.16], [v4.0.17][RubyGems-v4.0.17], [v4.0.18][RubyGems-v4.0.18], [v4.0.19][RubyGems-v4.0.19], [v4.0.20][RubyGems-v4.0.20], [v4.1.0.beta1][RubyGems-v4.1.0.beta1]
* bundler 4.1.0.beta1
* 4.0.3 to [v4.0.4][bundler-v4.0.4], [v4.0.5][bundler-v4.0.5], [v4.0.6][bundler-v4.0.6], [v4.0.7][bundler-v4.0.7], [v4.0.8][bundler-v4.0.8], [v4.0.9][bundler-v4.0.9], [v4.0.10][bundler-v4.0.10], [v4.0.11][bundler-v4.0.11], [v4.0.12][bundler-v4.0.12], [v4.0.13][bundler-v4.0.13], [v4.0.14][bundler-v4.0.14], [v4.0.15][bundler-v4.0.15], [v4.0.16][bundler-v4.0.16], [v4.0.17][bundler-v4.0.17]
* erb 6.0.7
Expand Down Expand Up @@ -226,7 +226,7 @@ They are still available on rubygems.org and can be installed with
* 0.6.2 to [v0.6.3][net-imap-v0.6.3], [v0.6.4][net-imap-v0.6.4], [v0.6.4.1][net-imap-v0.6.4.1], [v0.6.5][net-imap-v0.6.5], [v0.6.6][net-imap-v0.6.6]
* rbs 4.2.0
* 3.10.0 to [v3.10.1][rbs-v3.10.1], [v3.10.2][rbs-v3.10.2], [v3.10.3][rbs-v3.10.3], [v3.10.4][rbs-v3.10.4], [v4.0.0.dev.1][rbs-v4.0.0.dev.1], [v4.0.0.dev.2][rbs-v4.0.0.dev.2], [v4.0.0.dev.3][rbs-v4.0.0.dev.3], [v4.0.0.dev.4][rbs-v4.0.0.dev.4], [v4.0.0.dev.5][rbs-v4.0.0.dev.5], [v4.0.0][rbs-v4.0.0], [v4.0.1.dev.1][rbs-v4.0.1.dev.1], [v4.0.1.dev.2][rbs-v4.0.1.dev.2], [v4.0.1][rbs-v4.0.1], [v4.0.2][rbs-v4.0.2], [v4.0.3][rbs-v4.0.3], [v4.1.0.pre.1][rbs-v4.1.0.pre.1], [v4.1.0.pre.2][rbs-v4.1.0.pre.2], [v4.1.0][rbs-v4.1.0], [v4.1.1.pre.1][rbs-v4.1.1.pre.1], [v4.1.1][rbs-v4.1.1], [v4.1.2][rbs-v4.1.2], [v4.1.3][rbs-v4.1.3], [v4.2.0.pre.1][rbs-v4.2.0.pre.1], [v4.2.0][rbs-v4.2.0]
* typeprof 0.33.0
* typeprof 0.33.1
* mutex_m 0.3.0
* bigdecimal 4.1.2
* 4.0.1 to [v4.1.0][bigdecimal-v4.1.0], [v4.1.1][bigdecimal-v4.1.1], [v4.1.2][bigdecimal-v4.1.2]
Expand Down Expand Up @@ -448,6 +448,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[RubyGems-v4.0.18]: https://github.com/rubygems/rubygems/releases/tag/v4.0.18
[RubyGems-v4.0.19]: https://github.com/rubygems/rubygems/releases/tag/v4.0.19
[RubyGems-v4.0.20]: https://github.com/rubygems/rubygems/releases/tag/v4.0.20
[RubyGems-v4.1.0.beta1]: https://github.com/rubygems/rubygems/releases/tag/v4.1.0.beta1
[bundler-v4.0.4]: https://github.com/rubygems/rubygems/releases/tag/bundler-v4.0.4
[bundler-v4.0.5]: https://github.com/rubygems/rubygems/releases/tag/bundler-v4.0.5
[bundler-v4.0.6]: https://github.com/rubygems/rubygems/releases/tag/bundler-v4.0.6
Expand Down
17 changes: 16 additions & 1 deletion class.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "internal/box.h"
#include "internal/class.h"
#include "internal/eval.h"
#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/object.h"
#include "internal/string.h"
Expand Down Expand Up @@ -2261,6 +2262,9 @@ rb_mod_descendants(VALUE mod)
*
* Raises an TypeError if the class is not a singleton class.
*
* Raises a Ractor::IsolationError if the attached object is not shareable and
* belongs to another Ractor.
*
* class Foo; end
*
* Foo.singleton_class.attached_object #=> Foo
Expand All @@ -2277,7 +2281,18 @@ rb_class_attached_object(VALUE klass)
rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass);
}

return RCLASS_ATTACHED_OBJECT(klass);
const VALUE obj = RCLASS_ATTACHED_OBJECT(klass);

/* A singleton class is shareable whatever it is attached to, so another Ractor can
* hold one attached to an unshareable object. Returning it would share it. */
if (rb_objspace_foreign_object_p(obj) && !RB_OBJ_SHAREABLE_P(obj)) {
/* No klass in the message: naming a singleton class inspects the very object we
* must not touch from here. */
rb_raise(rb_eRactorIsolationError,
"can not get an unshareable attached object from another Ractor");
}

return obj;
}

static void
Expand Down
15 changes: 15 additions & 0 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,21 @@ ELEM_SWAP(LINK_ELEMENT *first, LINK_ELEMENT *second)

second->prev = first->prev;
first->prev = second;

if (IS_INSN(first) && IS_INSN(second)) {
INSN *first_insn = (INSN*)first;
INSN *second_insn = (INSN*)second;

// [Bug #22299] If both instructions are on the same line and the first one carries
// a line event we need to swap the event as well.
if (first_insn->insn_info.line_no == second_insn->insn_info.line_no) {
rb_event_flag_t mask = (RUBY_EVENT_LINE | RUBY_EVENT_COVERAGE_LINE);
rb_event_flag_t first_events = first_insn->insn_info.events & mask;
rb_event_flag_t second_events = second_insn->insn_info.events & mask;
first_insn->insn_info.events = (first_insn->insn_info.events & ~mask) | second_events;
second_insn->insn_info.events = (second_insn->insn_info.events & ~mask) | first_events;
}
}
}

static LINK_ELEMENT *
Expand Down
2 changes: 1 addition & 1 deletion ext/erb/escape/escape.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ find_next_neon(search_state *search)
#endif // HAVE_SIMD_NEON

#ifndef find_next
#define find_next_basic
#define find_next find_next_basic
#endif

static VALUE
Expand Down
38 changes: 20 additions & 18 deletions ext/erb/escape/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@
else
have_func("rb_ext_ractor_safe", "ruby.h")

case RbConfig::CONFIG['host_cpu']
when /^(arm|aarch64)/
# Try to compile a small program using NEON instructions
header, type, init, extra = 'arm_neon.h', 'uint8x16_t', 'vdupq_n_u8(32)', nil
when /^(x86_64|x64)/
header, type, init, extra = 'x86intrin.h', '__m128i', '_mm_set1_epi8(32)', 'if (__builtin_cpu_supports("sse2")) { printf("OK"); }'
end
if header
if have_header(header) && try_compile(<<~SRC, '-Werror=implicit-function-declaration')
#{cpp_include(header)}
int main(int argc, char **argv) {
#{type} test = #{init};
#{extra}
if (argc > 100000) printf("%p", &test);
return 0;
}
SRC
$defs.push("-DERB_ENABLE_SIMD")
unless ENV["ERB_DISABLE_SIMD"]
case RbConfig::CONFIG['host_cpu']
when /^(arm|aarch64)/
# Try to compile a small program using NEON instructions
header, type, init, extra = 'arm_neon.h', 'uint8x16_t', 'vdupq_n_u8(32)', nil
when /^(x86_64|x64)/
header, type, init, extra = 'x86intrin.h', '__m128i', '_mm_set1_epi8(32)', 'if (__builtin_cpu_supports("sse2")) { printf("OK"); }'
end
if header
if have_header(header) && try_compile(<<~SRC, '-Werror=implicit-function-declaration')
#{cpp_include(header)}
int main(int argc, char **argv) {
#{type} test = #{init};
#{extra}
if (argc > 100000) printf("%p", &test);
return 0;
}
SRC
$defs.push("-DERB_ENABLE_SIMD")
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion gems/bundled_gems
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ net-smtp 0.5.1 https://github.com/ruby/net-smtp
matrix 0.4.3 https://github.com/ruby/matrix
prime 0.1.4 https://github.com/ruby/prime
rbs 4.2.0 https://github.com/ruby/rbs
typeprof 0.33.0 https://github.com/ruby/typeprof
typeprof 0.33.1 https://github.com/ruby/typeprof
debug 1.11.1 https://github.com/ruby/debug 6510cfbc7496c55ebbefa437a25c17ca58f7c5eb
racc 1.8.1 https://github.com/ruby/racc
mutex_m 0.3.0 https://github.com/ruby/mutex_m
Expand Down
13 changes: 13 additions & 0 deletions spec/ruby/core/data/initialize_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@ def initialize(*, **)
ScratchPad.recorded.should == [:initialize, [], {amount: 42, unit: "m"}]
end

it "receives the block passed to .new" do
klass = Data.define(:amount) do
def initialize(amount:, &block)
super(amount: block.call(amount))
end
end

klass.new(1) { |amount| amount * 2 }.amount.should == 2
klass.new(amount: 1) { |amount| amount * 2 }.amount.should == 2
klass[1] { |amount| amount * 2 }.amount.should == 2
klass[amount: 1] { |amount| amount * 2 }.amount.should == 2
end

it "accepts positional arguments with empty keyword arguments" do
data = DataSpecs::SingleWithOverriddenName.new(42, **{})

Expand Down
4 changes: 4 additions & 0 deletions spec/ruby/core/encoding/find_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def to_str; @encoding_name; end
-> { Encoding.find('dh2dh278d') }.should.raise(ArgumentError, 'unknown encoding name - dh2dh278d')
end

it "raises an ArgumentError when the name is in a non-ASCII-compatible encoding" do
-> { Encoding.find("utf-8".encode("utf-16be")) }.should.raise(ArgumentError, "invalid encoding name (non ASCII)")
end

# Not sure how to do a better test, since locale depends on weird platform-specific stuff
it "supports the 'locale' encoding alias" do
enc = Encoding.find('locale')
Expand Down
4 changes: 4 additions & 0 deletions spec/ruby/core/enumerator/size_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
Enumerator.new(100) {}.size.should == 100
end

it "returns 0 if set size is 0" do
Enumerator.new(0) {}.size.should == 0
end

it "returns nil if set size is nil" do
Enumerator.new(nil) {}.size.should == nil
end
Expand Down
85 changes: 85 additions & 0 deletions spec/ruby/core/fiber/current_scheduler_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require_relative '../../spec_helper'
require_relative 'fixtures/scheduler'

describe "Fiber.current_scheduler" do
it "returns nil when no scheduler is set" do
Fiber.scheduler.should == nil
Fiber.current_scheduler.should == nil
end

describe "when a scheduler is set" do
before :each do
@scheduler = FiberSpecs::LoggingScheduler.new
Fiber.set_scheduler(@scheduler)
end

after :each do
Fiber.set_scheduler(nil)
end

it "returns nil on the root Fiber, which is blocking" do
Fiber.current_scheduler.should == nil
end

it "returns the scheduler inside a non-blocking Fiber" do
seen = nil
Fiber.new(blocking: false) { seen = Fiber.current_scheduler }.resume
seen.should.equal?(@scheduler)
end

it "returns nil inside a blocking Fiber, where Fiber.scheduler still returns the scheduler" do
seen = nil
Fiber.new(blocking: true) { seen = [Fiber.scheduler, Fiber.current_scheduler] }.resume
seen.should == [@scheduler, nil]
end

it "returns nil inside a blocking Fiber nested in a non-blocking Fiber" do
seen = nil
Fiber.new(blocking: false) do
Fiber.new(blocking: true) { seen = Fiber.current_scheduler }.resume
end.resume
seen.should == nil
end

it "returns the scheduler inside a non-blocking Fiber nested in a blocking Fiber" do
seen = nil
Fiber.new(blocking: true) do
Fiber.new(blocking: false) { seen = Fiber.current_scheduler }.resume
end.resume
seen.should.equal?(@scheduler)
end

it "returns nil inside Fiber.blocking in a non-blocking Fiber" do
seen = nil
Fiber.new(blocking: false) { Fiber.blocking { seen = Fiber.current_scheduler } }.resume
seen.should == nil
end

it "returns the scheduler again after Fiber.blocking returns" do
seen = nil
Fiber.new(blocking: false) do
Fiber.blocking { }
seen = Fiber.current_scheduler
end.resume
seen.should.equal?(@scheduler)
end

it "returns nil on the root Fiber after a blocking Fiber has finished" do
Fiber.new(blocking: true) { }.resume
Fiber.current_scheduler.should == nil
end

it "returns nil on the root Fiber after a blocking Fiber has raised" do
fiber = Fiber.new(blocking: true) { raise "from the fiber" }
-> { fiber.resume }.should.raise(RuntimeError)
Fiber.current_scheduler.should == nil
end

it "returns nil on the root Fiber after a blocking Fiber has been killed" do
fiber = Fiber.new(blocking: true) { Fiber.yield }
fiber.resume
fiber.kill
Fiber.current_scheduler.should == nil
end
end
end
5 changes: 5 additions & 0 deletions spec/ruby/core/fiber/fixtures/scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ def block(*args)
Fiber.yield
end

def fiber(*args, &block)
@events << { event: :fiber, fiber: Fiber.current, args: args }
Fiber.new(blocking: false, &block).tap(&:resume)
end

def io_wait(*args)
@events << { event: :io_wait, fiber: Fiber.current, args: args }
Fiber.yield
Expand Down
69 changes: 69 additions & 0 deletions spec/ruby/core/fiber/schedule_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require_relative '../../spec_helper'
require_relative 'fixtures/scheduler'

describe "Fiber.schedule" do
describe "when no scheduler is set" do
it "raises a RuntimeError" do
Fiber.scheduler.should == nil

-> {
Fiber.schedule { }
}.should.raise(RuntimeError)
end
end

describe "when a scheduler is set" do
before :each do
@scheduler = FiberSpecs::LoggingScheduler.new
Fiber.set_scheduler(@scheduler)
end

after :each do
Fiber.set_scheduler(nil)
end

it "calls the scheduler's #fiber hook" do
Fiber.schedule { }
@scheduler.events.map { |event| event[:event] }.should == [:fiber]
end

it "returns the Fiber which runs the block" do
scheduled = nil
fiber = Fiber.schedule { scheduled = Fiber.current }
fiber.should.equal?(scheduled)
end

it "can be called from inside a non-blocking Fiber" do
inner = nil

outer = Fiber.new(blocking: false) do
inner = Fiber.schedule { }
end
outer.resume

inner.should.is_a?(Fiber)
end

it "uses the scheduler of the Thread owning the Fiber it is called from" do
seen = nil

outer = Fiber.new(blocking: false) do
Fiber.schedule { seen = Fiber.scheduler }
end
outer.resume

seen.should.equal?(@scheduler)
end

it "runs the block in a Fiber which sees the scheduler as its current scheduler" do
seen = nil

outer = Fiber.new(blocking: false) do
Fiber.schedule { seen = Fiber.current_scheduler }
end
outer.resume

seen.should.equal?(@scheduler)
end
end
end
17 changes: 16 additions & 1 deletion spec/ruby/core/file/open_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@
File.should.exist?(@file)
end

it "opens a file when use File::WRONLY|File::APPEND mode" do
it "opens a file in the read-write append mode when given mode File::RDWR|File::APPEND" do
File.open(@file, File::WRONLY) do |f|
f.puts("hello file")
end
Expand All @@ -399,6 +399,21 @@
end
end

it "opens a file in the append mode when given mode 'a'" do
File.write(@file, "hello")
File.open(@file, "a") { |f| f.write(" world") }
File.read(@file).should == "hello world"
end

it "opens a file in the read-write append mode when given mode 'a+'" do
File.write(@file, "hello")
File.open(@file, "a+") do |f|
f.read.should == "hello"
f.write(" world")
end
File.read(@file).should == "hello world"
end

it "raises an IOError if the file exists when open with File::RDONLY|File::APPEND" do
-> {
File.open(@file, File::RDONLY|File::APPEND) do |f|
Expand Down
Loading