1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Add toregexp to yjit

The FIXME is there so we remember to investigate why insns clears the
temporary array. Is this necessary? If it's not we can remove it from
both.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commit is contained in:
eileencodes 2021-08-10 09:10:34 -04:00 committed by Alan Wu
parent dd5082d7ca
commit 2ba090a1f9
3 changed files with 48 additions and 0 deletions

View file

@ -16721,6 +16721,7 @@ yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/compilers.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/gc.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/imemo.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/object.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/re.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/serial.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/string.h

View file

@ -67,6 +67,10 @@ class TestYJIT < Test::Unit::TestCase
assert_no_exits('"i am a string #{true}"')
end
def test_compile_regexp
assert_no_exits('/#{true}/')
end
def test_getlocal_with_level
assert_compiles(<<~RUBY, insns: %i[getlocal opt_plus], result: [[7]])
def foo(foo, bar)

View file

@ -10,6 +10,7 @@
#include "internal/object.h"
#include "internal/string.h"
#include "internal/variable.h"
#include "internal/re.h"
#include "insns_info.inc"
#include "yjit.h"
#include "yjit_iface.h"
@ -3520,6 +3521,47 @@ gen_tostring(jitstate_t* jit, ctx_t* ctx)
return YJIT_KEEP_COMPILING;
}
static codegen_status_t
gen_toregexp(jitstate_t* jit, ctx_t* ctx)
{
rb_num_t opt = jit_get_arg(jit, 0);
rb_num_t cnt = jit_get_arg(jit, 1);
// Save the PC and SP because this allocates an object and could
// raise an exception.
jit_save_pc(jit, REG0);
jit_save_sp(jit, ctx);
x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(sizeof(VALUE) * (uint32_t)cnt));
ctx_stack_pop(ctx, cnt);
mov(cb, C_ARG_REGS[0], imm_opnd(0));
mov(cb, C_ARG_REGS[1], imm_opnd(cnt));
lea(cb, C_ARG_REGS[2], values_ptr);
call_ptr(cb, REG0, (void *)&rb_ary_tmp_new_from_values);
// Save the array so we can clear it later
push(cb, RAX);
push(cb, RAX); // Alignment
mov(cb, C_ARG_REGS[0], RAX);
mov(cb, C_ARG_REGS[1], imm_opnd(opt));
call_ptr(cb, REG0, (void *)&rb_reg_new_ary);
// The actual regex is in RAX now. Pop the temp array from
// rb_ary_tmp_new_from_values into C arg regs so we can clear it
pop(cb, REG1); // Alignment
pop(cb, C_ARG_REGS[0]);
// The value we want to push on the stack is in RAX right now
x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
mov(cb, stack_ret, RAX);
// Clear the temp array.
call_ptr(cb, REG0, (void *)&rb_ary_clear);
return YJIT_KEEP_COMPILING;
}
static codegen_status_t
gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx)
{
@ -3758,6 +3800,7 @@ yjit_init_codegen(void)
yjit_reg_op(BIN(getglobal), gen_getglobal);
yjit_reg_op(BIN(setglobal), gen_setglobal);
yjit_reg_op(BIN(tostring), gen_tostring);
yjit_reg_op(BIN(toregexp), gen_toregexp);
yjit_method_codegen_table = st_init_numtable();