mirror of
https://github.com/ruby/ruby.git
synced 2025-08-25 05:55:46 +02:00

* Add a "pinning" reference
A `Fiddle::Pinned` objects will prevent the objects they point to from
moving. This is useful in the case where you need to pass a reference
to a C extension that keeps the address in a global and needs the
address to be stable.
For example:
```ruby
class Foo
A = "hi" # this is an embedded string
some_c_function A # A might move!
end
```
If `A` moves, then the underlying string buffer may also move.
`Fiddle::Pinned` will prevent the object from moving:
```ruby
class Foo
A = "hi" # this is an embedded string
A_pinner = Fiddle::Pinned.new(A) # :nodoc:
some_c_function A # A can't move because of `Fiddle::Pinned`
end
```
This is a similar strategy to what Graal uses:
https://www.graalvm.org/sdk/javadoc/org/graalvm/nativeimage/PinnedObject.html#getObject--
* rename global to match exception name
* Introduce generic Fiddle::Error and rearrange error classes
Fiddle::Error is the generic exception base class for Fiddle exceptions.
This commit introduces the class and rearranges Fiddle exceptions to
inherit from it.
ac52d00223
27 lines
534 B
Ruby
27 lines
534 B
Ruby
# frozen_string_literal: true
|
|
begin
|
|
require_relative 'helper'
|
|
rescue LoadError
|
|
end
|
|
|
|
module Fiddle
|
|
class TestPinned < Fiddle::TestCase
|
|
def test_pin_object
|
|
x = Object.new
|
|
pinner = Pinned.new x
|
|
assert_same x, pinner.ref
|
|
end
|
|
|
|
def test_clear
|
|
pinner = Pinned.new Object.new
|
|
refute pinner.cleared?
|
|
pinner.clear
|
|
assert pinner.cleared?
|
|
ex = assert_raise(Fiddle::ClearedReferenceError) do
|
|
pinner.ref
|
|
end
|
|
assert_match "called on", ex.message
|
|
end
|
|
end
|
|
end
|
|
|