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
18 changes: 18 additions & 0 deletions bootstraptest/test_yjit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,24 @@ def jittable_method
jittable_method
}

# test getbyte on string class
assert_equal '[97, :nil, 97, :nil, :raised]', %q{
def getbyte(s, i)
byte = begin
s.getbyte(i)
rescue TypeError
:raised
end

byte || :nil
end

getbyte("a", 0)
getbyte("a", 0)

[getbyte("a", 0), getbyte("a", 1), getbyte("a", -1), getbyte("a", -2), getbyte("a", "a")]
} unless defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # Not yet working on RJIT

# Test << operator on string subclass
assert_equal 'abab', %q{
class MyString < String; end
Expand Down
29 changes: 29 additions & 0 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4702,6 +4702,34 @@ fn jit_rb_str_bytesize(
true
}

fn jit_rb_str_getbyte(
jit: &mut JITState,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
_ci: *const rb_callinfo,
_cme: *const rb_callable_method_entry_t,
_block: Option<BlockHandler>,
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
asm.comment("String#getbyte");
extern "C" {
fn rb_str_getbyte(str: VALUE, index: VALUE) -> VALUE;
}
// Raises when non-integers are passed in
jit_prepare_routine_call(jit, asm);

let index = asm.stack_pop(1);
let recv = asm.stack_pop(1);
let ret_opnd = asm.ccall(rb_str_getbyte as *const u8, vec![recv, index]);

// Can either return a FIXNUM or nil
let out_opnd = asm.stack_push(Type::UnknownImm);
asm.mov(out_opnd, ret_opnd);

true
}

// Codegen for rb_str_to_s()
// When String#to_s is called on a String instance, the method returns self and
// most of the overhead comes from setting up the method call. We observed that
Expand Down Expand Up @@ -8750,6 +8778,7 @@ impl CodegenGlobals {
self.yjit_reg_method(rb_cString, "to_s", jit_rb_str_to_s);
self.yjit_reg_method(rb_cString, "to_str", jit_rb_str_to_s);
self.yjit_reg_method(rb_cString, "bytesize", jit_rb_str_bytesize);
self.yjit_reg_method(rb_cString, "getbyte", jit_rb_str_getbyte);
self.yjit_reg_method(rb_cString, "<<", jit_rb_str_concat);
self.yjit_reg_method(rb_cString, "+@", jit_rb_str_uplus);

Expand Down