From cffa1162758a67dd73da6cd911d593f67f05ea7b Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 20 Oct 2021 13:20:08 -0400 Subject: Do kwarg shuffle after checking for interrupts Previously, we were shuffling keyword arguments before checking for interrupts. In the case that we side exit in the interrupt check, we left the interpreter with an already-shuffled argument list for the call, resulting in a double shuffle, leaving the locals in the wrong order for the callee. Do keyword shuffling after all the possible side exits. Co-authored-by: Kevin Newton --- bootstraptest/test_yjit.rb | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'bootstraptest') diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 765580a030..a58ff2d18f 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -2175,3 +2175,42 @@ assert_equal 'false', %q{ foo.failed? foo.failed? } + +# regression test for doing kwarg shuffle before checking for interrupts +assert_equal 'ok', %q{ + def new_media_drop(attributes:, product_drop:, context:, sources:) + nil.nomethod rescue nil # force YJIT to bail to side exit + + [attributes, product_drop, context, sources] + end + + def load_medias(product_drop: nil, raw_medias:, context:) + raw_medias.map do |raw_media| + case new_media_drop(context: context, attributes: raw_media, product_drop: product_drop, sources: []) + in [Hash, ProductDrop, Context, Array] + else + raise "bad shuffle" + end + end + end + + class Context; end + + class ProductDrop + attr_reader :title + def initialize(title) + @title = title + end + end + + # Make a thread so we have thread switching interrupts + th = Thread.new do + while true; end + end + 1_000.times do |i| + load_medias(product_drop: ProductDrop.new("foo"), raw_medias: [{}, {}], context: Context.new) + end + th.kill.join + + :ok +} -- cgit v1.2.3