summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb10
-rw-r--r--vm_insnhelper.c10
-rw-r--r--yjit/src/codegen.rs25
-rw-r--r--yjit/src/cruby.rs1
4 files changed, 46 insertions, 0 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 89d7c9a038..364ed7094b 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -3245,3 +3245,13 @@ assert_equal 'foo', %q{
end
foo { "foo" }.call
}
+
+assert_equal '[1, 2]', %q{
+ def foo
+ x = [2]
+ [1, *x]
+ end
+
+ foo
+ foo
+}
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 3c41adcdc9..ab1394c7ca 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -4380,6 +4380,14 @@ vm_concat_array(VALUE ary1, VALUE ary2st)
return rb_ary_concat(tmp1, tmp2);
}
+// YJIT implementation is using the C function
+// and needs to call a non-static function
+VALUE
+rb_vm_concat_array(VALUE ary1, VALUE ary2st)
+{
+ return vm_concat_array(ary1, ary2st);
+}
+
static VALUE
vm_splat_array(VALUE flag, VALUE ary)
{
@@ -4395,6 +4403,8 @@ vm_splat_array(VALUE flag, VALUE ary)
}
}
+// YJIT implementation is using the C function
+// and needs to call a non-static function
VALUE
rb_vm_splat_array(VALUE flag, VALUE ary)
{
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 3428466297..a6473842f8 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -1256,6 +1256,30 @@ fn gen_splatarray(
KeepCompiling
}
+// concat two arrays
+fn gen_concatarray(
+ jit: &mut JITState,
+ ctx: &mut Context,
+ asm: &mut Assembler,
+ _ocb: &mut OutlinedCb,
+) -> CodegenStatus {
+ // Save the PC and SP because the callee may allocate
+ // Note that this modifies REG_SP, which is why we do it first
+ jit_prepare_routine_call(jit, ctx, asm);
+
+ // Get the operands from the stack
+ let ary2st_opnd = ctx.stack_pop(1);
+ let ary1_opnd = ctx.stack_pop(1);
+
+ // Call rb_vm_concat_array(ary1, ary2st)
+ let ary = asm.ccall(rb_vm_concat_array as *const u8, vec![ary1_opnd, ary2st_opnd]);
+
+ let stack_ret = ctx.stack_push(Type::Array);
+ asm.mov(stack_ret, ary);
+
+ KeepCompiling
+}
+
// new range initialized from top 2 values
fn gen_newrange(
jit: &mut JITState,
@@ -5862,6 +5886,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_opt_str_freeze => Some(gen_opt_str_freeze),
YARVINSN_opt_str_uminus => Some(gen_opt_str_uminus),
YARVINSN_splatarray => Some(gen_splatarray),
+ YARVINSN_concatarray => Some(gen_concatarray),
YARVINSN_newrange => Some(gen_newrange),
YARVINSN_putstring => Some(gen_putstring),
YARVINSN_expandarray => Some(gen_expandarray),
diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs
index 2cf5134e81..2f823e1b61 100644
--- a/yjit/src/cruby.rs
+++ b/yjit/src/cruby.rs
@@ -112,6 +112,7 @@ pub use autogened::*;
#[cfg_attr(test, allow(unused))] // We don't link against C code when testing
extern "C" {
pub fn rb_vm_splat_array(flag: VALUE, ary: VALUE) -> VALUE;
+ pub fn rb_vm_concat_array(ary1: VALUE, ary2st: VALUE) -> VALUE;
pub fn rb_vm_defined(
ec: EcPtr,
reg_cfp: CfpPtr,