summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy Miller <jimmy.miller@shopify.com>2023-01-30 15:51:55 -0500
committerGitHub <noreply@github.com>2023-01-30 15:51:55 -0500
commitb32e1169c948f0e4cd63f2c75929516106942594 (patch)
tree6e7da779bd6f2becc15ce3789376ec8b8ca7e51a
parentc4cc3be195825e47a66c7b919454c520e49ea307 (diff)
YJIT: Initial implementation of splat with optional params (#7166)
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
-rw-r--r--yjit/src/codegen.rs21
1 files changed, 13 insertions, 8 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index bfac557a4c..b6aa75953e 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -5147,12 +5147,6 @@ fn gen_send_iseq(
let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) };
let opts_missing: i32 = opt_num - opts_filled;
-
- if opt_num > 0 && flags & VM_CALL_ARGS_SPLAT != 0 {
- gen_counter_incr!(asm, send_iseq_splat_with_opt);
- return CantCompile;
- }
-
if doing_kw_call && flags & VM_CALL_ARGS_SPLAT != 0 {
gen_counter_incr!(asm, send_iseq_splat_with_kw);
return CantCompile;
@@ -5198,13 +5192,24 @@ fn gen_send_iseq(
return CantCompile;
}
- if opt_num > 0 {
+ if opt_num > 0 && flags & VM_CALL_ARGS_SPLAT == 0 {
num_params -= opts_missing as u32;
unsafe {
let opt_table = get_iseq_body_param_opt_table(iseq);
start_pc_offset = (*opt_table.offset(opts_filled as isize)).as_u32();
}
- }
+ } else if opt_num > 0 && flags & VM_CALL_ARGS_SPLAT != 0 {
+ // We are going to assume that args_splat fills all of the optional arguments.
+ // We should actually get the array length instead at compile time.
+ // We don't set num_params here because we use it for the splat.
+ // If our assumption is wrong, we will exit early in the splat code.
+ // We could do that a bit smarter and not exit but instead change
+ // the offset we jump to. But we aren't currently doing that.
+ unsafe {
+ let opt_table = get_iseq_body_param_opt_table(iseq);
+ start_pc_offset = (*opt_table.offset(opt_num as isize)).as_u32();
+ };
+ };
if doing_kw_call {
// Here we're calling a method with keyword arguments and specifying