Implement getspecial
This commit is contained in:
parent
cc2aa1221f
commit
44214e8ad9
@ -205,6 +205,15 @@ class TestYJIT < Test::Unit::TestCase
|
|||||||
RUBY
|
RUBY
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_getspecial_backref
|
||||||
|
assert_compiles("'foo' =~ /(o)./; $&", insns: %i[getspecial], result: "oo")
|
||||||
|
assert_compiles("'foo' =~ /(o)./; $`", insns: %i[getspecial], result: "f")
|
||||||
|
assert_compiles("'foo' =~ /(o)./; $'", insns: %i[getspecial], result: "")
|
||||||
|
assert_compiles("'foo' =~ /(o)./; $+", insns: %i[getspecial], result: "o")
|
||||||
|
assert_compiles("'foo' =~ /(o)./; $1", insns: %i[getspecial], result: "o")
|
||||||
|
assert_compiles("'foo' =~ /(o)./; $2", insns: %i[getspecial], result: nil)
|
||||||
|
end
|
||||||
|
|
||||||
def test_compile_opt_getinlinecache
|
def test_compile_opt_getinlinecache
|
||||||
assert_compiles(<<~RUBY, insns: %i[opt_getinlinecache], result: 123, min_calls: 2)
|
assert_compiles(<<~RUBY, insns: %i[opt_getinlinecache], result: 123, min_calls: 2)
|
||||||
def get_foo
|
def get_foo
|
||||||
|
@ -3911,6 +3911,70 @@ gen_toregexp(jitstate_t* jit, ctx_t* ctx)
|
|||||||
return YJIT_KEEP_COMPILING;
|
return YJIT_KEEP_COMPILING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static codegen_status_t
|
||||||
|
gen_getspecial(jitstate_t *jit, ctx_t *ctx)
|
||||||
|
{
|
||||||
|
rb_num_t key = jit_get_arg(jit, 0);
|
||||||
|
rb_num_t type = jit_get_arg(jit, 1);
|
||||||
|
|
||||||
|
if (type == 0) {
|
||||||
|
// not yet implemented
|
||||||
|
return YJIT_CANT_COMPILE;
|
||||||
|
} else if (type & 0x01) {
|
||||||
|
// Can raise if matchdata uninitialized
|
||||||
|
jit_prepare_routine_call(jit, ctx, REG0);
|
||||||
|
|
||||||
|
// call rb_backref_get()
|
||||||
|
ADD_COMMENT(cb, "rb_backref_get");
|
||||||
|
call_ptr(cb, REG0, (void *)rb_backref_get);
|
||||||
|
mov(cb, C_ARG_REGS[0], RAX);
|
||||||
|
|
||||||
|
switch (type >> 1) {
|
||||||
|
case '&':
|
||||||
|
ADD_COMMENT(cb, "rb_reg_last_match");
|
||||||
|
call_ptr(cb, REG0, (void *)rb_reg_last_match);
|
||||||
|
break;
|
||||||
|
case '`':
|
||||||
|
ADD_COMMENT(cb, "rb_reg_match_pre");
|
||||||
|
call_ptr(cb, REG0, (void *)rb_reg_match_pre);
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
ADD_COMMENT(cb, "rb_reg_match_post");
|
||||||
|
call_ptr(cb, REG0, (void *)rb_reg_match_post);
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
ADD_COMMENT(cb, "rb_reg_match_last");
|
||||||
|
call_ptr(cb, REG0, (void *)rb_reg_match_last);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rb_bug("invalid back-ref");
|
||||||
|
}
|
||||||
|
|
||||||
|
x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
|
||||||
|
mov(cb, stack_ret, RAX);
|
||||||
|
|
||||||
|
return YJIT_KEEP_COMPILING;
|
||||||
|
} else {
|
||||||
|
// Can raise if matchdata uninitialized
|
||||||
|
jit_prepare_routine_call(jit, ctx, REG0);
|
||||||
|
|
||||||
|
// call rb_backref_get()
|
||||||
|
ADD_COMMENT(cb, "rb_backref_get");
|
||||||
|
call_ptr(cb, REG0, (void *)rb_backref_get);
|
||||||
|
|
||||||
|
// rb_reg_nth_match((int)(type >> 1), backref);
|
||||||
|
ADD_COMMENT(cb, "rb_reg_nth_match");
|
||||||
|
mov(cb, C_ARG_REGS[0], imm_opnd(type >> 1));
|
||||||
|
mov(cb, C_ARG_REGS[1], RAX);
|
||||||
|
call_ptr(cb, REG0, (void *)rb_reg_nth_match);
|
||||||
|
|
||||||
|
x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
|
||||||
|
mov(cb, stack_ret, RAX);
|
||||||
|
|
||||||
|
return YJIT_KEEP_COMPILING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static codegen_status_t
|
static codegen_status_t
|
||||||
gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx)
|
gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx)
|
||||||
{
|
{
|
||||||
@ -4261,6 +4325,7 @@ yjit_init_codegen(void)
|
|||||||
yjit_reg_op(BIN(setglobal), gen_setglobal);
|
yjit_reg_op(BIN(setglobal), gen_setglobal);
|
||||||
yjit_reg_op(BIN(tostring), gen_tostring);
|
yjit_reg_op(BIN(tostring), gen_tostring);
|
||||||
yjit_reg_op(BIN(toregexp), gen_toregexp);
|
yjit_reg_op(BIN(toregexp), gen_toregexp);
|
||||||
|
yjit_reg_op(BIN(getspecial), gen_getspecial);
|
||||||
|
|
||||||
yjit_method_codegen_table = st_init_numtable();
|
yjit_method_codegen_table = st_init_numtable();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user