diff options
author | Jeremy Evans <code@jeremyevans.net> | 2022-04-01 07:22:49 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2022-04-01 07:22:49 -0700 |
commit | d1d48cb690fdad855da94b2a2d11721428bc06ba (patch) | |
tree | 156fcb356f2b4206a93f374c281449a7f3fe41c2 /bootstraptest | |
parent | d8352ff3ac6960f029e3c9253f527f6e4a845645 (diff) |
Revert "Raise RuntimeError if Kernel#binding is called from a non-Ruby frame"
This reverts commit 343ea9967e4a6b279eed6bd8e81ad0bdc747f254.
This causes an assertion failure with -DRUBY_DEBUG=1 -DRGENGC_CHECK_MODE=2
Diffstat (limited to 'bootstraptest')
-rw-r--r-- | bootstraptest/test_yjit.rb | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index a84a9e035a..d124d180d1 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,3 +1,34 @@ +assert_equal '2022', %q{ + def contrivance(hash, key) + # Expect this to compile to an `opt_aref`. + hash[key] + + # The [] call above tracks that the `hash` local has a VALUE that + # is a heap pointer and the guard for the Kernel#itself call below + # doesn't check that it's a heap pointer VALUE. + # + # As you can see from the crash, the call to rb_hash_aref() can set the + # `hash` local, making eliding the heap object guard unsound. + hash.itself + end + + # This is similar to ->(recv, mid) { send(recv, mid).local_variable_set(...) }. + # By composing we avoid creating new Ruby frames and so sending :binding + # captures the environment of the frame that does the missing key lookup. + # We use it to capture the environment inside of `contrivance`. + cap_then_set = + Kernel.instance_method(:send).method(:bind_call).to_proc >> + ->(binding) { binding.local_variable_set(:hash, 2022) } + special_missing = Hash.new(&cap_then_set) + + # Make YJIT speculate that it's a hash and generate code + # that calls rb_hash_aref(). + contrivance({}, :warmup) + contrivance({}, :warmup) + + contrivance(special_missing, :binding) +} + assert_equal '18374962167983112447', %q{ # regression test for incorrectly discarding 32 bits of a pointer when it # comes to default values. |