summaryrefslogtreecommitdiff
path: root/bootstraptest
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2021-10-20 13:20:08 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:43 -0400
commitcffa1162758a67dd73da6cd911d593f67f05ea7b (patch)
treed0e8656f70ae2ba4ca9a735b158d42a5021182d7 /bootstraptest
parentc062028d3785d5d56deb1be6c4c5733f7f9f19ac (diff)
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 <kddnewton@gmail.com>
Diffstat (limited to 'bootstraptest')
-rw-r--r--bootstraptest/test_yjit.rb39
1 files changed, 39 insertions, 0 deletions
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
+}