diff options
-rw-r--r-- | test/ruby/test_yjit.rb | 5 | ||||
-rw-r--r-- | vm_insnhelper.c | 6 | ||||
-rw-r--r-- | yjit_codegen.c | 21 |
3 files changed, 32 insertions, 0 deletions
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index a571432ccd..d951f79cfc 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -52,6 +52,11 @@ class TestYJIT < Test::Unit::TestCase assert_in_out_err([yjit_child_env, '-e p RubyVM::YJIT.enabled?'], '', ['true']) end + def test_compile_setclassvariable + script = 'class Foo; def self.foo; @@foo = 1; end; end; Foo.foo' + assert_compiles(script, insns: %i[setclassvariable], result: 1) + end + 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) diff --git a/vm_insnhelper.c b/vm_insnhelper.c index d1930d146c..348bfea5aa 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1367,6 +1367,12 @@ vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *reg_cfp, ID update_classvariable_cache(iseq, klass, id, ic); } +void +rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic) +{ + vm_setclassvariable(iseq, cfp, id, val, ic); +} + static inline VALUE vm_getinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, IVC ic) { diff --git a/yjit_codegen.c b/yjit_codegen.c index c34c56a972..add1e2012a 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -4488,6 +4488,26 @@ gen_getclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb) return YJIT_KEEP_COMPILING; } +VALUE +rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic); + +static codegen_status_t +gen_setclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb) +{ + // rb_vm_setclassvariable can raise exceptions. + jit_prepare_routine_call(jit, ctx, REG0); + + mov(cb, C_ARG_REGS[0], member_opnd(REG_CFP, rb_control_frame_t, iseq)); + mov(cb, C_ARG_REGS[1], REG_CFP); + mov(cb, C_ARG_REGS[2], imm_opnd(jit_get_arg(jit, 0))); + mov(cb, C_ARG_REGS[3], ctx_stack_pop(ctx, 1)); + mov(cb, C_ARG_REGS[4], imm_opnd(jit_get_arg(jit, 1))); + + call_ptr(cb, REG0, (void *)rb_vm_setclassvariable); + + return YJIT_KEEP_COMPILING; +} + static codegen_status_t gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb) { @@ -4886,6 +4906,7 @@ yjit_init_codegen(void) yjit_reg_op(BIN(toregexp), gen_toregexp); yjit_reg_op(BIN(getspecial), gen_getspecial); yjit_reg_op(BIN(getclassvariable), gen_getclassvariable); + yjit_reg_op(BIN(setclassvariable), gen_setclassvariable); yjit_method_codegen_table = st_init_numtable(); |