diff --git a/doc/string.rb b/doc/string.rb index d68b40743b9d77..ad1abf29b7f55b 100644 --- a/doc/string.rb +++ b/doc/string.rb @@ -460,8 +460,7 @@ # # _Substitution_ # -# - #dump: Returns a copy of +self+ with all non-printing characters replaced by \xHH notation -# and all special characters escaped. +# - #dump: Returns a printable version of +self+, enclosed in double-quotes. # - #undump: Returns a copy of +self+ with all \xNN notations replaced by \uNNNN notations # and all escaped characters unescaped. # - #sub: Returns a copy of +self+ with the first substring matching a given pattern diff --git a/doc/string/each_byte.rdoc b/doc/string/each_byte.rdoc index 643118fea3e47e..1f1069863b264b 100644 --- a/doc/string/each_byte.rdoc +++ b/doc/string/each_byte.rdoc @@ -1,17 +1,18 @@ -Calls the given block with each successive byte from +self+; +With a block given, calls the block with each successive byte from +self+; returns +self+: - 'hello'.each_byte {|byte| print byte, ' ' } - print "\n" - 'тест'.each_byte {|byte| print byte, ' ' } - print "\n" - 'こんにちは'.each_byte {|byte| print byte, ' ' } - print "\n" + a = [] + 'hello'.each_byte {|byte| a.push(byte) } # Five 1-byte characters. + a # => [104, 101, 108, 108, 111] + a = [] + 'тест'.each_byte {|byte| a.push(byte) } # Four 2-byte characters. + a # => [209, 130, 208, 181, 209, 129, 209, 130] + a = [] + 'こんにちは'.each_byte {|byte| a.push(byte) } # Five 3-byte characters. + a # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] -Output: +With no block given, returns an enumerator. + +Related: see {Iterating}[rdoc-ref:String@Iterating]. - 104 101 108 108 111 - 209 130 208 181 209 129 209 130 - 227 129 147 227 130 147 227 129 171 227 129 161 227 129 175 -Returns an enumerator if no block is given. diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 54346e077806c4..fee6537c375d49 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -1,5 +1,6 @@ use std::cell::Cell; use std::rc::Rc; +use std::ffi::{c_int}; use crate::asm::Label; use crate::backend::current::{Reg, ALLOC_REGS}; @@ -446,8 +447,20 @@ fn gen_getlocal_with_ep(asm: &mut Assembler, local_ep_offset: u32, level: u32) - /// can't optimize the level=0 case using the SP register. fn gen_setlocal_with_ep(asm: &mut Assembler, val: Opnd, local_ep_offset: u32, level: u32) -> Option<()> { let ep = gen_get_ep(asm, level); - let offset = -(SIZEOF_VALUE_I32 * i32::try_from(local_ep_offset).ok()?); - asm.mov(Opnd::mem(64, ep, offset), val); + match val { + // If we're writing a constant, non-heap VALUE, do a raw memory write without + // running write barrier. + lir::Opnd::Value(const_val) if const_val.special_const_p() => { + let offset = -(SIZEOF_VALUE_I32 * i32::try_from(local_ep_offset).ok()?); + asm.mov(Opnd::mem(64, ep, offset), val); + } + // We're potentially writing a reference to an IMEMO/env object, + // so take care of the write barrier with a function. + _ => { + let local_index = c_int::try_from(local_ep_offset).ok().and_then(|idx| idx.checked_mul(-1))?; + asm_ccall!(asm, rb_vm_env_write, ep, local_index.into(), val); + } + } Some(()) }