From cbdabd5890e3cc07d66f53ad47e5beacd82172b6 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Mon, 12 Feb 2024 15:57:37 -0500 Subject: [PATCH] YJIT: Fix kwrest calls setting SP with uninit values We did stack_push() and then saved the SP without writing to the slots of the new values first, which caused the GC to mark uninitialized values. Should fix crashes like https://github.com/ruby/ruby/actions/runs/7877298133/job/21493179294 --- yjit/src/codegen.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index b15980fd2d..9b84a41104 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -6996,13 +6996,8 @@ fn gen_send_iseq( let mut unspecified_bits = 0; - // Start by ensuring the stack is large enough for the callee - for _ in caller_keyword_len..callee_kw_count { - argc += 1; - asm.stack_push(Type::Unknown); - } - // Now this is the stack_opnd() index to the 0th keyword argument. - let kwargs_stack_base = kwargs_order.len() as i32 - 1; + // The stack_opnd() index to the 0th keyword argument. + let kwargs_stack_base = caller_keyword_len_i32 - 1; // Build the keyword rest parameter hash before we make any changes to the order of // the supplied keyword arguments @@ -7089,6 +7084,14 @@ fn gen_send_iseq( } } + // Ensure the stack is large enough for the callee + for _ in caller_keyword_len..callee_kw_count { + argc += 1; + asm.stack_push(Type::Unknown); + } + // Now this is the stack_opnd() index to the 0th keyword argument. + let kwargs_stack_base = kwargs_order.len() as i32 - 1; + // Next, we're going to loop through every keyword that was // specified by the caller and make sure that it's in the correct // place. If it's not we're going to swap it around with another one.