summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb13
-rw-r--r--yjit/src/codegen.rs24
2 files changed, 20 insertions, 17 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 568cc583b1..b064bcdde7 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -3585,7 +3585,7 @@ assert_equal 'true', %q{
1.send(:==, 1, *[])
}
-# Test send with splat to a cfunc
+# Test empty splat with cfunc
assert_equal '2', %q{
def foo
Integer.sqrt(4, *[])
@@ -3594,3 +3594,14 @@ assert_equal '2', %q{
foo
foo
}
+
+# Test non-empty splat with cfunc
+assert_equal 'Hello World', %q{
+ def bar
+ args = ["Hello "]
+ greeting = "World"
+ greeting.insert(0, *args)
+ greeting
+ end
+ bar
+}
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 9d4f51f8df..3cfce12c34 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -4864,6 +4864,7 @@ fn gen_send_cfunc(
// push_splat_args does stack manipulation so we can no longer side exit
if flags & VM_CALL_ARGS_SPLAT != 0 {
+ assert!(cfunc_argc >= 0);
let required_args : u32 = (cfunc_argc as u32).saturating_sub(argc as u32 - 1);
// + 1 because we pass self
if required_args + 1 >= C_ARG_OPNDS.len() as u32 {
@@ -4871,22 +4872,13 @@ fn gen_send_cfunc(
return CantCompile;
}
- if required_args == 0 {
- // The splat is not going to supply us any arguments
- // so we set the argc to the number of arguments
- // the cfunc expects.
- // We still need to do all the splat logic because someone
- // could pass in a non-zero sized array and we need to
- // exit to error.
- argc = cfunc_argc;
- passed_argc = argc;
- } else {
- // We are going to assume that the splat fills
- // all the remaining arguments. In the generated code
- // we test if this is true and if not side exit.
- argc = required_args as i32;
- passed_argc = argc;
- }
+ // We are going to assume that the splat fills
+ // all the remaining arguments. So the number of args
+ // should just equal the number of args the cfunc takes.
+ // In the generated code we test if this is true
+ // and if not side exit.
+ argc = cfunc_argc;
+ passed_argc = argc;
push_splat_args(required_args, ctx, asm, ocb, side_exit)
}