diff options
-rw-r--r-- | test/ruby/test_yjit.rb | 5 | ||||
-rw-r--r-- | vm_insnhelper.c | 12 | ||||
-rw-r--r-- | yjit_codegen.c | 27 |
3 files changed, 44 insertions, 0 deletions
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index e00f15ecf5..d7dd599205 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -8,6 +8,11 @@ return unless YJIT.enabled? # Tests for YJIT with assertions on compilation and side exits # insipired by the MJIT tests in test/ruby/test_jit.rb class TestYJIT < Test::Unit::TestCase + def test_compile_getclassvariable + script = 'class Foo; @@foo = 1; def self.foo; @@foo; end; end; Foo.foo' + assert_compiles(script, insns: %i[getclassvariable], result: 1) + end + def test_compile_putnil assert_compiles('nil', insns: %i[putnil], result: nil) end diff --git a/vm_insnhelper.c b/vm_insnhelper.c index a33f6b5ea3..1f591b8323 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -835,6 +835,12 @@ vm_get_cref(const VALUE *ep) } } +rb_cref_t * +rb_vm_get_cref(const VALUE *ep) +{ + return vm_get_cref(ep); +} + static rb_cref_t * vm_ec_cref(const rb_execution_context_t *ec) { @@ -1336,6 +1342,12 @@ vm_getclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_contr return update_classvariable_cache(iseq, klass, id, ic); } +VALUE +rb_vm_getclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_control_frame_t *cfp, ID id, ICVARC ic) +{ + return vm_getclassvariable(iseq, cref, cfp, id, ic); +} + static inline void vm_setclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic) { diff --git a/yjit_codegen.c b/yjit_codegen.c index 9cc643654b..f6973b5a81 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -4110,6 +4110,32 @@ gen_getspecial(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb) } } +VALUE +rb_vm_getclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_control_frame_t *cfp, ID id, ICVARC ic); + +rb_cref_t * +rb_vm_get_cref(const VALUE *ep); + +static codegen_status_t +gen_getclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb) +{ + mov(cb, C_ARG_REGS[0], member_opnd(REG_CFP, rb_control_frame_t, ep)); + call_ptr(cb, REG0, (void *)rb_vm_get_cref); + + mov(cb, C_ARG_REGS[0], member_opnd(REG_CFP, rb_control_frame_t, iseq)); + mov(cb, C_ARG_REGS[1], RAX); + mov(cb, C_ARG_REGS[2], REG_CFP); + mov(cb, C_ARG_REGS[3], imm_opnd(jit_get_arg(jit, 0))); + mov(cb, C_ARG_REGS[4], imm_opnd(jit_get_arg(jit, 1))); + + call_ptr(cb, REG0, (void *)rb_vm_getclassvariable); + + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); + mov(cb, stack_top, RAX); + + return YJIT_KEEP_COMPILING; +} + static codegen_status_t gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb) { @@ -4500,6 +4526,7 @@ yjit_init_codegen(void) yjit_reg_op(BIN(tostring), gen_tostring); yjit_reg_op(BIN(toregexp), gen_toregexp); yjit_reg_op(BIN(getspecial), gen_getspecial); + yjit_reg_op(BIN(getclassvariable), gen_getclassvariable); yjit_method_codegen_table = st_init_numtable(); |