From 374dd451b04db29dde8bb6f59e627d102010efb3 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Mon, 14 Aug 2023 11:12:01 -0400 Subject: [PATCH] YJIT: Compile splat calls to iseqs with rest params Test interactions with optional parameters. --- bootstraptest/test_yjit.rb | 34 ++++++++++++++++++++++++++++++++++ yjit/src/codegen.rs | 6 ------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 741e0c631ff3ad..65cdc322cda098 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,3 +1,37 @@ +# test splat filling required and feeding rest +assert_equal '[0, 1, 2, [3, 4]]', %q{ + public def lead_rest(a, b, *rest) + [self, a, b, rest] + end + + def call(args) = 0.lead_rest(*args) + + call([1, 2, 3, 4]) +} + +# test missing opts are nil initialized +assert_equal '[[0, 1, nil, 3], [0, 1, nil, 3], [0, 1, nil, 3, []], [0, 1, nil, 3, []]]', %q{ + public def lead_opts(a, b=binding.local_variable_get(:c), c=3) + [self, a, b, c] + end + + public def opts_rest(a=raise, b=binding.local_variable_get(:c), c=3, *rest) + [self, a, b, c, rest] + end + + def call(args) + [ + 0.lead_opts(1), + 0.lead_opts(*args), + + 0.opts_rest(1), + 0.opts_rest(*args), + ] + end + + call([1]) +} + # test filled optionals with unspecified keyword param assert_equal 'ok', %q{ def opt_rest_opt_kw(_=1, *, k: :ok) = k diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 6c59b1d86f23c3..0bb7a31d86f824 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -5665,7 +5665,6 @@ fn gen_send_iseq( exit_if_has_kwrest(asm, iseq)?; exit_if_splat_and_ruby2_keywords(asm, jit, flags)?; exit_if_has_rest_and_captured(asm, iseq_has_rest, captured_opnd)?; - exit_if_has_rest_and_splat(asm, iseq_has_rest, flags)?; exit_if_has_rest_and_supplying_kws(asm, iseq_has_rest, iseq, supplying_kws)?; exit_if_supplying_kw_and_has_no_kw(asm, supplying_kws, iseq)?; exit_if_supplying_kws_and_accept_no_kwargs(asm, supplying_kws, iseq)?; @@ -6426,11 +6425,6 @@ fn exit_if_has_rest_and_captured(asm: &mut Assembler, iseq_has_rest: bool, captu exit_if(asm, iseq_has_rest && captured_opnd.is_some(), Counter::send_iseq_has_rest_and_captured) } -#[must_use] -fn exit_if_has_rest_and_splat( asm: &mut Assembler, iseq_has_rest: bool, flags: u32) -> Option<()> { - exit_if(asm, iseq_has_rest && flags & VM_CALL_ARGS_SPLAT != 0, Counter::send_iseq_has_rest_and_splat) -} - #[must_use] fn exit_if_has_rest_and_supplying_kws(asm: &mut Assembler, iseq_has_rest: bool, iseq: *const rb_iseq_t, supplying_kws: bool) -> Option<()> { exit_if(