summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb16
-rw-r--r--yjit/src/codegen.rs122
2 files changed, 77 insertions, 61 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 2f8c6a8f18..b8374746f7 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -3087,3 +3087,19 @@ assert_equal 'foo', %q{
foo = Foo.new
foo.foo
}
+
+# anytostring, intern
+assert_equal 'true', %q{
+ def foo()
+ :"#{true}"
+ end
+ foo()
+}
+
+# toregexp
+assert_equal '/true/', %q{
+ def foo()
+ /#{true}/
+ end
+ foo().inspect
+}
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index ee52800699..36cdd55573 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -5338,31 +5338,28 @@ fn gen_setglobal(
KeepCompiling
}
-/*
fn gen_anytostring(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Save the PC and SP since we might call #to_s
- jit_prepare_routine_call(jit, ctx, cb, REG0);
+ jit_prepare_routine_call(jit, ctx, asm);
let str = ctx.stack_pop(1);
let val = ctx.stack_pop(1);
- mov(cb, C_ARG_REGS[0], str);
- mov(cb, C_ARG_REGS[1], val);
-
- call_ptr(cb, REG0, rb_obj_as_string_result as *const u8);
+ let val = asm.ccall(rb_obj_as_string_result as *const u8, vec![str, val]);
// Push the return value
let stack_ret = ctx.stack_push(Type::TString);
- mov(cb, stack_ret, RAX);
+ asm.mov(stack_ret, val);
KeepCompiling
}
+/*
fn gen_objtostring(
jit: &mut JITState,
ctx: &mut Context,
@@ -5399,25 +5396,23 @@ fn gen_objtostring(
gen_send_general(jit, ctx, cb, ocb, cd, None)
}
}
+*/
fn gen_intern(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Save the PC and SP because we might allocate
- jit_prepare_routine_call(jit, ctx, cb, REG0);
+ jit_prepare_routine_call(jit, ctx, asm);
let str = ctx.stack_pop(1);
-
- mov(cb, C_ARG_REGS[0], str);
-
- call_ptr(cb, REG0, rb_str_intern as *const u8);
+ let sym = asm.ccall(rb_str_intern as *const u8, vec![str]);
// Push the return value
let stack_ret = ctx.stack_push(Type::Unknown);
- mov(cb, stack_ret, RAX);
+ asm.mov(stack_ret, sym);
KeepCompiling
}
@@ -5425,7 +5420,7 @@ fn gen_intern(
fn gen_toregexp(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
let opt = jit_get_arg(jit, 0).as_i64();
@@ -5433,34 +5428,43 @@ fn gen_toregexp(
// Save the PC and SP because this allocates an object and could
// raise an exception.
- jit_prepare_routine_call(jit, ctx, cb, REG0);
+ jit_prepare_routine_call(jit, ctx, asm);
let values_ptr = ctx.sp_opnd(-((SIZEOF_VALUE as isize) * (cnt as isize)));
ctx.stack_pop(cnt);
- mov(cb, C_ARG_REGS[0], imm_opnd(0));
- mov(cb, C_ARG_REGS[1], imm_opnd(cnt.try_into().unwrap()));
- lea(cb, C_ARG_REGS[2], values_ptr);
- call_ptr(cb, REG0, rb_ary_tmp_new_from_values as *const u8);
+ let ary = asm.ccall(
+ rb_ary_tmp_new_from_values as *const u8,
+ vec![
+ Opnd::Imm(0),
+ Opnd::UImm(jit_get_arg(jit, 1).as_u64()),
+ values_ptr,
+ ]
+ );
// 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, rb_reg_new_ary as *const u8);
+ asm.cpush(ary);
+ asm.cpush(ary); // Alignment
+
+ let val = asm.ccall(
+ rb_reg_new_ary as *const u8,
+ vec![
+ ary,
+ Opnd::Imm(opt),
+ ]
+ );
// 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]);
+ let ary = asm.cpop(); // Alignment
+ asm.cpop_into(ary);
// The value we want to push on the stack is in RAX right now
let stack_ret = ctx.stack_push(Type::Unknown);
- mov(cb, stack_ret, RAX);
+ asm.mov(stack_ret, val);
// Clear the temp array.
- call_ptr(cb, REG0, rb_ary_clear as *const u8);
+ asm.ccall(rb_ary_clear as *const u8, vec![ary]);
KeepCompiling
}
@@ -5468,7 +5472,7 @@ fn gen_toregexp(
fn gen_getspecial(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// This takes two arguments, key and type
@@ -5484,65 +5488,63 @@ fn gen_getspecial(
// Fetch a "special" backref based on a char encoded by shifting by 1
// Can raise if matchdata uninitialized
- jit_prepare_routine_call(jit, ctx, cb, REG0);
+ jit_prepare_routine_call(jit, ctx, asm);
// call rb_backref_get()
- add_comment(cb, "rb_backref_get");
- call_ptr(cb, REG0, rb_backref_get as *const u8);
- mov(cb, C_ARG_REGS[0], RAX);
+ asm.comment("rb_backref_get");
+ let backref = asm.ccall(rb_backref_get as *const u8, vec![]);
let rt_u8: u8 = (rtype >> 1).try_into().unwrap();
- match rt_u8.into() {
+ let val = match rt_u8.into() {
'&' => {
- add_comment(cb, "rb_reg_last_match");
- call_ptr(cb, REG0, rb_reg_last_match as *const u8);
+ asm.comment("rb_reg_last_match");
+ asm.ccall(rb_reg_last_match as *const u8, vec![backref])
}
'`' => {
- add_comment(cb, "rb_reg_match_pre");
- call_ptr(cb, REG0, rb_reg_match_pre as *const u8);
+ asm.comment("rb_reg_match_pre");
+ asm.ccall(rb_reg_match_pre as *const u8, vec![backref])
}
'\'' => {
- add_comment(cb, "rb_reg_match_post");
- call_ptr(cb, REG0, rb_reg_match_post as *const u8);
+ asm.comment("rb_reg_match_post");
+ asm.ccall(rb_reg_match_post as *const u8, vec![backref])
}
'+' => {
- add_comment(cb, "rb_reg_match_last");
- call_ptr(cb, REG0, rb_reg_match_last as *const u8);
+ asm.comment("rb_reg_match_last");
+ asm.ccall(rb_reg_match_last as *const u8, vec![backref])
}
_ => panic!("invalid back-ref"),
- }
+ };
let stack_ret = ctx.stack_push(Type::Unknown);
- mov(cb, stack_ret, RAX);
+ asm.mov(stack_ret, val);
KeepCompiling
} else {
// Fetch the N-th match from the last backref based on type shifted by 1
// Can raise if matchdata uninitialized
- jit_prepare_routine_call(jit, ctx, cb, REG0);
+ jit_prepare_routine_call(jit, ctx, asm);
// call rb_backref_get()
- add_comment(cb, "rb_backref_get");
- call_ptr(cb, REG0, rb_backref_get as *const u8);
+ asm.comment("rb_backref_get");
+ let backref = asm.ccall(rb_backref_get as *const u8, vec![]);
// rb_reg_nth_match((int)(type >> 1), backref);
- add_comment(cb, "rb_reg_nth_match");
- mov(
- cb,
- C_ARG_REGS[0],
- imm_opnd((rtype >> 1).try_into().unwrap()),
+ asm.comment("rb_reg_nth_match");
+ let val = asm.ccall(
+ rb_reg_nth_match as *const u8,
+ vec![
+ Opnd::Imm((rtype >> 1).try_into().unwrap()),
+ backref,
+ ]
);
- mov(cb, C_ARG_REGS[1], RAX);
- call_ptr(cb, REG0, rb_reg_nth_match as *const u8);
let stack_ret = ctx.stack_push(Type::Unknown);
- mov(cb, stack_ret, RAX);
+ asm.mov(stack_ret, val);
KeepCompiling
}
}
-*/
fn gen_getclassvariable(
jit: &mut JITState,
@@ -6052,13 +6054,11 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_getglobal => Some(gen_getglobal),
YARVINSN_setglobal => Some(gen_setglobal),
- /*
YARVINSN_anytostring => Some(gen_anytostring),
- YARVINSN_objtostring => Some(gen_objtostring),
+ //YARVINSN_objtostring => Some(gen_objtostring),
YARVINSN_intern => Some(gen_intern),
YARVINSN_toregexp => Some(gen_toregexp),
YARVINSN_getspecial => Some(gen_getspecial),
- */
YARVINSN_getclassvariable => Some(gen_getclassvariable),
YARVINSN_setclassvariable => Some(gen_setclassvariable),