diff options
author | Daniel Colson <[email protected]> | 2025-06-10 20:34:41 -0400 |
---|---|---|
committer | Max Bernstein <[email protected]> | 2025-06-17 08:20:07 +0900 |
commit | b1410c1c75518a54a2a32e0da2555840258ce228 () | |
tree | a9748df192025a515db01311dd4ca61ef854e55a | |
parent | 2956573b09ec78d7735a07fe3d7b2dcc907879fb (diff) |
ZJIT: Add codegen for StringCopy
Prior to this commit we compiled `putstring` and `putchilledstring` to `StringCopy`, but then failed to compile past HIR. This commit adds codegen for `StringCopy` to call `rb_ec_str_ressurrect` as the VM does for these instructions.
Notes: Merged: https://.com/ruby/ruby/pull/13625
-rw-r--r-- | test/ruby/test_zjit.rb | 14 | ||||
-rw-r--r-- | zjit/src/codegen.rs | 12 | ||||
-rw-r--r-- | zjit/src/hir.rs | 18 |
3 files changed, 37 insertions, 7 deletions
@@ -31,6 +31,20 @@ class TestZJIT < Test::Unit::TestCase } end def test_leave_param assert_compiles '5', %q{ def test(n) = n @@ -252,6 +252,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::NewArray { elements, state } => gen_new_array(jit, asm, elements, &function.frame_state(*state)), Insn::NewRange { low, high, flag, state } => gen_new_range(asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::ArrayDup { val, state } => gen_array_dup(asm, opnd!(val), &function.frame_state(*state)), Insn::Param { idx } => unreachable!("block.insns should not have Insn::Param({idx})"), Insn::Snapshot { .. } => return Some(()), // we don't need to do anything for this instruction at the moment Insn::Jump(branch) => return gen_jump(jit, asm, branch), @@ -611,6 +612,17 @@ fn gen_send_without_block_direct( Some(ret) } /// Compile an array duplication instruction fn gen_array_dup( asm: &mut Assembler, @@ -396,7 +396,7 @@ pub enum Insn { /// SSA block parameter. Also used for function parameters in the function's entry block. Param { idx: usize }, - StringCopy { val: InsnId }, StringIntern { val: InsnId }, /// Put special object (VMCORE, CBASE, etc.) based on value_type @@ -602,7 +602,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::ArraySet { array, idx, val } => { write!(f, "ArraySet {array}, {idx}, {val}") } Insn::ArrayDup { val, .. } => { write!(f, "ArrayDup {val}") } Insn::HashDup { val, .. } => { write!(f, "HashDup {val}") } - Insn::StringCopy { val } => { write!(f, "StringCopy {val}") } Insn::Test { val } => { write!(f, "Test {val}") } Insn::IsNil { val } => { write!(f, "IsNil {val}") } Insn::Jump(target) => { write!(f, "Jump {target}") } @@ -978,7 +978,7 @@ impl Function { } }, Return { val } => Return { val: find!(*val) }, - StringCopy { val } => StringCopy { val: find!(*val) }, StringIntern { val } => StringIntern { val: find!(*val) }, Test { val } => Test { val: find!(*val) }, &IsNil { val } => IsNil { val: find!(val) }, @@ -1623,7 +1623,7 @@ impl Function { worklist.push_back(high); worklist.push_back(state); } - Insn::StringCopy { val } | Insn::StringIntern { val } | Insn::Return { val } | Insn::Defined { v: val, .. } @@ -2142,10 +2142,14 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> { let value_type = SpecialObjectType::from(get_arg(pc, 0).as_u32()); state.stack_push(fun.push_insn(block, Insn::PutSpecialObject { value_type })); } - YARVINSN_putstring | YARVINSN_putchilledstring => { - // TODO(max): Do something different for chilled string let val = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) }); - let insn_id = fun.push_insn(block, Insn::StringCopy { val }); state.stack_push(insn_id); } YARVINSN_putself => { state.stack_push(self_param); } |