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
96 changes: 16 additions & 80 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -2167,12 +2167,12 @@ rb_ary_rfind(int argc, VALUE *argv, VALUE ary)

/*
* call-seq:
* find_index(object, offset: 0) -> integer or nil
* find_index(object) -> integer or nil
* find_index {|element| ... } -> integer or nil
* find_index(offset: 0) -> new_enumerator
* index(object, offset: 0) -> integer or nil
* find_index -> new_enumerator
* index(object) -> integer or nil
* index {|element| ... } -> integer or nil
* index(offset: 0) -> new_enumerator
* index -> new_enumerator
*
* Returns the zero-based integer index of a specified element, or +nil+.
*
Expand All @@ -2194,20 +2194,6 @@ rb_ary_rfind(int argc, VALUE *argv, VALUE ary)
*
* Returns +nil+ if the block never returns a truthy value.
*
* When +offset+ is non-negative, begins the search at position +offset+;
* the returned index is relative to the beginning of +self+:
*
* a = [:foo, 'bar', 2, 'bar']
* a.index('bar', offset: 1) # => 1
* a.index('bar', offset: 2) # => 3
* a.index('bar', offset: 4) # => nil
*
* With negative integer argument +offset+, selects the search position by counting backward
* from the end of +self+:
*
* a = [:foo, 'bar', 2, 'bar']
* a.index('bar', offset: -2) # => 3
*
* With neither an argument nor a block given, returns a new Enumerator.
*
* Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
Expand All @@ -2216,8 +2202,7 @@ rb_ary_rfind(int argc, VALUE *argv, VALUE ary)
static VALUE
rb_ary_index(int argc, VALUE *argv, VALUE ary)
{
VALUE val, opts = Qnil, initpos = Qnil;
long pos = 0;
VALUE val;
long i;

if (argc == 0) {
Expand All @@ -2229,24 +2214,11 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
}
return Qnil;
}
rb_check_arity(argc, 0, 2);
rb_scan_args(argc, argv, "1:", &val, &opts);
if (!NIL_P(opts)) {
static ID keywords[1];
if (!keywords[0]) {
keywords[0] = rb_intern_const("offset");
}
rb_get_kwargs(opts, keywords, 0, 1, &initpos);
if (!UNDEF_P(initpos))
pos = NUM2LONG(initpos);
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
rb_warn("given block not used");
if (pos < 0)
pos += RARRAY_LEN(ary);
if (pos < 0)
return Qnil;
for (i=pos; i<RARRAY_LEN(ary); i++) {
for (i=0; i<RARRAY_LEN(ary); i++) {
VALUE e = RARRAY_AREF(ary, i);
if (rb_equal(e, val)) {
return LONG2NUM(i);
Expand All @@ -2257,9 +2229,9 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)

/*
* call-seq:
* rindex(object, offset: nil) -> integer or nil
* rindex(object) -> integer or nil
* rindex {|element| ... } -> integer or nil
* rindex(offset: nil) -> new_enumerator
* rindex -> new_enumerator
*
* Returns the index of the last element for which <tt>object == element</tt>.
*
Expand All @@ -2278,23 +2250,6 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
*
* Returns +nil+ if the block never returns a truthy value.
*
* When +offset+ is non-negative, it specifies the maximum starting position in the
* array to end the search:
*
* a = [:foo, 'bar', 2, 'bar']
* a.rindex('bar', offset: 0) # => 3
* a.rindex(2, offset: 1) # => 2
* a.rindex(2, offset: 3) # => nil
*
* With negative integer argument +offset+,
* selects the search position by counting backward from the end of +self+:
*
* a = [:foo, 'bar', 2, 'bar']
* a.rindex('bar', -1) # => 3
* a.rindex('bar', -2) # => 1
* a.rindex('bar', -3) # => 1
* a.rindex('bar', -4) # => nil
*
* When neither an argument nor a block is given, returns a new Enumerator.
*
* Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
Expand All @@ -2303,44 +2258,25 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
static VALUE
rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
{
VALUE val, opts = Qnil, offset_arg = Qnil;
long i = RARRAY_LEN(ary) - 1, len, end_pos = 0, offset;
VALUE val;
long i = RARRAY_LEN(ary), len;

if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
while (i >= 0) {
while (i--) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
return LONG2NUM(i);
if (i > (len = RARRAY_LEN(ary))) {
i = len;
}
i--;
}
return Qnil;
}
rb_check_arity(argc, 0, 2);
rb_scan_args(argc, argv, "1:", &val, &opts);
if (!NIL_P(opts)) {
static ID keywords[1];
if (!keywords[0]) {
keywords[0] = rb_intern_const("offset");
}
rb_get_kwargs(opts, keywords, 0, 1, &offset_arg);
if (!UNDEF_P(offset_arg)){
offset = NUM2LONG(offset_arg);
if (offset < 0) {
i += offset + 1;
}
else {
end_pos = offset;
}
}
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
rb_warn("given block not used");
if (i < 0 || end_pos >= RARRAY_LEN(ary))
return Qnil;
for (; i >= end_pos; i--) {
while (i--) {
VALUE e = RARRAY_AREF(ary, i);
if (rb_equal(e, val)) {
return LONG2NUM(i);
Expand Down
4 changes: 0 additions & 4 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@
/* internal/symbol.h */
#define rb_sym_intern_ascii_cstr(...) rb_nonexistent_symbol(__VA_ARGS__)

/* internal/vm.h */
#define rb_funcallv(...) rb_nonexistent_symbol(__VA_ARGS__)
#define rb_method_basic_definition_p(...) rb_nonexistent_symbol(__VA_ARGS__)


/* MRI debug support */

Expand Down
3 changes: 2 additions & 1 deletion io_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,8 @@ rb_io_buffer_readonly_p(VALUE self)
* If the buffer is <i>read only</i>, meaning the buffer cannot be modified using
* #set_value, #set_string or #copy and similar.
*
* Frozen strings and read-only files create read-only buffers.
* A buffer created by IO::Buffer.for without a block is read-only, as is one
* backed by a frozen string or a read-only file.
*/
static VALUE
io_buffer_readonly_p(VALUE self)
Expand Down
15 changes: 0 additions & 15 deletions test/ruby/test_array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1162,14 +1162,7 @@ def test_index
assert_nil(a.index('ca'))
assert_nil(a.index([1,2]))

assert_equal(1, a.index(99, offset: 0))
assert_equal(3, a.index(99, offset: 2))
assert_equal(2, a.index(/a/, offset: -4))
assert_nil(a.index(99, offset: a.size))
assert_nil(a.index(99, offset: -a.size - 1))

assert_equal(1, assert_warn(/given block not used/) {a.index(99) {|x| x == 'cat' }})
assert_equal(3, assert_warn(/given block not used/) {a.index(99, offset: 2) {|x| x == 'cat' }})
end

def test_values_at
Expand Down Expand Up @@ -1544,15 +1537,7 @@ def test_rindex
assert_nil(a.rindex('ca'))
assert_nil(a.rindex([1,2]))

assert_equal(3, a.rindex(99, offset: 0))
assert_equal(3, a.rindex(99, offset: 2))
assert_equal(1, a.rindex(99, offset: -3))
assert_nil(a.rindex(/a/, offset: -4))
assert_nil(a.index(99, offset: a.size))
assert_nil(a.index(99, offset: -a.size - 1))

assert_equal(3, assert_warning(/given block not used/) {a.rindex(99) {|x| x == [1,2,3] }})
assert_equal(3, assert_warning(/given block not used/) {a.rindex(99, offset: 2) {|x| x == [1,2,3] }})

bug15951 = "[Bug #15951]"
o2 = Object.new
Expand Down
31 changes: 28 additions & 3 deletions test/ruby/test_yjit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,27 @@ def jit_method
RUBY
end

def test_forwarding_callee_does_not_map_arguments_to_locals
assert_compiles(
<<~'RUBY', call_threshold: 1, code_gc: true, result: [:ok, :ok], verify_ctx: true
class ForwardingReceiver
def foo(...) = :ok
end

def delegate(...)
receiver = ForwardingReceiver.new
if defined?(receiver.foo)
receiver.foo(...)
else
receiver.__send__(:foo, ...)
end
end

2.times.map { delegate(nil, "string") }
RUBY
)
end

def test_send_block
# Setlocal_wc_0 sometimes side-exits on write barrier
assert_compiles(<<~'RUBY', result: "b:n/b:y/b:y/b:n")
Expand Down Expand Up @@ -1996,7 +2017,8 @@ def assert_compiles(
frozen_string_literal: nil,
mem_size: nil,
code_gc: false,
no_send_fallbacks: false
no_send_fallbacks: false,
verify_ctx: false
)
reset_stats = <<~RUBY
RubyVM::YJIT.runtime_stats
Expand Down Expand Up @@ -2031,7 +2053,7 @@ def collect_insns(iseq)
#{write_results}
RUBY

status, out, err, stats = eval_with_jit(script, call_threshold:, mem_size:, code_gc:)
status, out, err, stats = eval_with_jit(script, call_threshold:, mem_size:, code_gc:, verify_ctx:)

assert status.success?, "exited with status #{status.to_i}, stderr:\n#{err}"

Expand Down Expand Up @@ -2096,14 +2118,17 @@ def script_shell_encode(s)
s.chars.map { |c| c.ascii_only? ? c : "\\u%x" % c.codepoints[0] }.join
end

def eval_with_jit(script, call_threshold: 1, timeout: 1000, mem_size: nil, code_gc: false)
def eval_with_jit(
script, call_threshold: 1, timeout: 1000, mem_size: nil, code_gc: false, verify_ctx: false
)
args = [
"--disable-gems",
"--yjit-call-threshold=#{call_threshold}",
"--yjit-stats=quiet"
]
args << "--yjit-exec-mem-size=#{mem_size}" if mem_size
args << "--yjit-code-gc" if code_gc
args << "--yjit-verify-ctx" if verify_ctx
args << "-e" << script_shell_encode(script)
stats_r, stats_w = IO.pipe
# Separate thread so we don't deadlock when
Expand Down
19 changes: 8 additions & 11 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8290,17 +8290,14 @@ fn gen_send_iseq(
callee_ctx.set_inline_block(iseq);
}

// Set the argument types in the callee's context
for arg_idx in 0..argc {
let stack_offs: u8 = (argc - arg_idx - 1).try_into().unwrap();
let arg_type = asm.ctx.get_opnd_type(StackOpnd(stack_offs));
callee_ctx.set_local_type(arg_idx.try_into().unwrap(), arg_type);
}

// If we're in a forwarding callee, there will be one unknown type
// written in to the local table (the caller's CI object)
if forwarding {
callee_ctx.set_local_type(0, Type::Unknown)
// Forwarding callees store a callinfo object rather than arguments in
// their local table, so their argument types do not map to local types.
if !forwarding {
for arg_idx in 0..argc {
let stack_offs: u8 = (argc - arg_idx - 1).try_into().unwrap();
let arg_type = asm.ctx.get_opnd_type(StackOpnd(stack_offs));
callee_ctx.set_local_type(arg_idx.try_into().unwrap(), arg_type);
}
}

// Set the receiver type in the callee's context
Expand Down