Skip to content

Commit 6a46ca3

Browse files
tekknolagiXrXr
authored andcommitted
ZJIT: Add codegen for uncached getinstancevariable
I didn't know `rb_ivar_get` existed until @XrXr pointed me to it. Thanks, Alan!
1 parent 2eb0a1a commit 6a46ca3

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

test/ruby/test_zjit.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,20 @@ def minus(a)
545545
}
546546
end
547547

548+
def test_getinstancevariable
549+
assert_compiles 'nil', %q{
550+
def test() = @foo
551+
552+
test()
553+
}
554+
assert_compiles '3', %q{
555+
@foo = 3
556+
def test() = @foo
557+
558+
test()
559+
}
560+
end
561+
548562
# tool/ruby_vm/views/*.erb relies on the zjit instructions a) being contiguous and
549563
# b) being reliably ordered after all the other instructions.
550564
def test_instruction_order

zjit/src/codegen.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
274274
Insn::GuardBitEquals { val, expected, state } => gen_guard_bit_equals(jit, asm, opnd!(val), *expected, &function.frame_state(*state))?,
275275
Insn::PatchPoint(_) => return Some(()), // For now, rb_zjit_bop_redefined() panics. TODO: leave a patch point and fix rb_zjit_bop_redefined()
276276
Insn::CCall { cfun, args, name: _, return_type: _, elidable: _ } => gen_ccall(jit, asm, *cfun, args)?,
277+
Insn::GetIvar { self_val, id, state: _ } => gen_getivar(asm, opnd!(self_val), *id),
277278
_ => {
278279
debug!("ZJIT: gen_function: unexpected insn {:?}", insn);
279280
return None;
@@ -297,6 +298,15 @@ fn gen_ccall(jit: &mut JITState, asm: &mut Assembler, cfun: *const u8, args: &[I
297298
Some(asm.ccall(cfun, lir_args))
298299
}
299300

301+
/// Emit an uncached instance variable lookup
302+
fn gen_getivar(asm: &mut Assembler, recv: Opnd, id: ID) -> Opnd {
303+
asm_comment!(asm, "call rb_ivar_get");
304+
asm.ccall(
305+
rb_ivar_get as *const u8,
306+
vec![recv, Opnd::UImm(id.0)],
307+
)
308+
}
309+
300310
/// Compile an interpreter entry block to be inserted into an ISEQ
301311
fn gen_entry_prologue(asm: &mut Assembler, iseq: IseqPtr) {
302312
asm_comment!(asm, "ZJIT entry point: {}", iseq_get_location(iseq, 0));

0 commit comments

Comments
 (0)