diff options
-rw-r--r-- | bootstraptest/test_yjit.rb | 13 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 24 |
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) } |