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:
parent
dd5082d7ca
commit
2ba090a1f9
3 changed files with 48 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue