summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb5
-rw-r--r--yjit/src/codegen.rs6
-rw-r--r--yjit/src/stats.rs1
3 files changed, 12 insertions, 0 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index f79f047928..68b738477b 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -3579,3 +3579,8 @@ assert_equal 'true', %q{
def a.test = :test
a.is_a?(a.singleton_class)
}
+
+# Test send with splat to a cfunc
+assert_equal 'true', %q{
+ 1.send(:==, 1, *[])
+}
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index e4cfe16e73..6643247989 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -4929,6 +4929,12 @@ fn gen_send_cfunc(
// push_splat_args does stack manipulation so we can no longer side exit
if flags & VM_CALL_ARGS_SPLAT != 0 {
+ if flags & VM_CALL_OPT_SEND != 0 {
+ // FIXME: This combination is buggy.
+ // For example `1.send(:==, 1, *[])` fails to adjust the stack properly
+ gen_counter_incr!(asm, send_cfunc_splat_send);
+ return CantCompile;
+ }
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 {
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index 666816b2e9..583e82527d 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -192,6 +192,7 @@ make_counters! {
send_cfunc_tracing,
send_cfunc_kwargs,
send_cfunc_splat_with_kw,
+ send_cfunc_splat_send,
send_attrset_kwargs,
send_iseq_tailcall,
send_iseq_arity_error,