Skip to content

Commit

Permalink
Port class variable instructions (#346)
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Aug 25, 2022
1 parent 2b951ea commit c293e2c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 22 deletions.
22 changes: 22 additions & 0 deletions bootstraptest/test_yjit_new_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,29 @@ def foo()
$foo
}

# getclassvariable
assert_equal 'foo', %q{
class Foo
@@foo = "foo"
def self.foo
@@foo
end
end
Foo.foo
}

# setclassvariable
assert_equal 'foo', %q{
class Foo
def self.foo
@@foo = "foo"
end
end
Foo.foo
}



Expand Down
50 changes: 28 additions & 22 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5525,51 +5525,57 @@ fn gen_getspecial(
KeepCompiling
}
}
*/

fn gen_getclassvariable(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// rb_vm_getclassvariable can raise exceptions.
jit_prepare_routine_call(jit, ctx, cb, REG0);
let cfp_iseq_opnd = mem_opnd(64, REG_CFP, RUBY_OFFSET_CFP_ISEQ);
mov(cb, C_ARG_REGS[0], cfp_iseq_opnd);
mov(cb, C_ARG_REGS[1], REG_CFP);
mov(cb, C_ARG_REGS[2], uimm_opnd(jit_get_arg(jit, 0).as_u64()));
mov(cb, C_ARG_REGS[3], uimm_opnd(jit_get_arg(jit, 1).as_u64()));
jit_prepare_routine_call(jit, ctx, asm);

call_ptr(cb, REG0, rb_vm_getclassvariable as *const u8);
let val_opnd = asm.ccall(
rb_vm_getclassvariable as *const u8,
vec![
Opnd::mem(64, CFP, RUBY_OFFSET_CFP_ISEQ),
CFP,
Opnd::UImm(jit_get_arg(jit, 0).as_u64()),
Opnd::UImm(jit_get_arg(jit, 1).as_u64()),
],
);

let stack_top = ctx.stack_push(Type::Unknown);
mov(cb, stack_top, RAX);
let top = ctx.stack_push(Type::Unknown);
asm.mov(top, val_opnd);

KeepCompiling
}

fn gen_setclassvariable(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// rb_vm_setclassvariable can raise exceptions.
jit_prepare_routine_call(jit, ctx, cb, REG0);
let cfp_iseq_opnd = mem_opnd(64, REG_CFP, RUBY_OFFSET_CFP_ISEQ);
mov(cb, C_ARG_REGS[0], cfp_iseq_opnd);
mov(cb, C_ARG_REGS[1], REG_CFP);
mov(cb, C_ARG_REGS[2], uimm_opnd(jit_get_arg(jit, 0).as_u64()));
mov(cb, C_ARG_REGS[3], ctx.stack_pop(1));
mov(cb, C_ARG_REGS[4], uimm_opnd(jit_get_arg(jit, 1).as_u64()));
jit_prepare_routine_call(jit, ctx, asm);

call_ptr(cb, REG0, rb_vm_setclassvariable as *const u8);
asm.ccall(
rb_vm_setclassvariable as *const u8,
vec![
Opnd::mem(64, CFP, RUBY_OFFSET_CFP_ISEQ),
CFP,
Opnd::UImm(jit_get_arg(jit, 0).as_u64()),
ctx.stack_pop(1),
Opnd::UImm(jit_get_arg(jit, 1).as_u64()),
],
);

KeepCompiling
}

/*
fn gen_opt_getinlinecache(
jit: &mut JITState,
ctx: &mut Context,
Expand Down Expand Up @@ -6035,9 +6041,9 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_intern => Some(gen_intern),
YARVINSN_toregexp => Some(gen_toregexp),
YARVINSN_getspecial => Some(gen_getspecial),
*/
YARVINSN_getclassvariable => Some(gen_getclassvariable),
YARVINSN_setclassvariable => Some(gen_setclassvariable),
*/

// Unimplemented opcode, YJIT won't generate code for this yet
_ => None,
Expand Down

0 comments on commit c293e2c

Please sign in to comment.