diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2023-02-24 18:42:53 -0500 |
---|---|---|
committer | Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> | 2023-02-27 11:12:22 -0500 |
commit | 55a24f9b08ac2217accb720e29232d56aed2e5a4 (patch) | |
tree | 6234081c0702392137f4a6d3b5fae9c522cc3f07 | |
parent | ea830ab29d856bd0bf7bd4f1edffaff6ba4816ef (diff) | |
download | ruby-55a24f9b08ac2217accb720e29232d56aed2e5a4.tar.gz |
YJIT: Reject __send__ with splat to cfunc for now
`make test-spec` revealed this issue after applying an unrelated bug
fix. A crashing case is included, though I suspect there are other
scenarios where it misbehaves. Don't compile for now.
Note that this is *not* an issue on the 3.2.x series; it has
`send_args_splat_non_iseq` which already rejects all splats to cfuncs,
including sends with splats.
-rw-r--r-- | bootstraptest/test_yjit.rb | 5 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 6 | ||||
-rw-r--r-- | yjit/src/stats.rs | 1 |
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, |