summaryrefslogtreecommitdiff
path: root/test/fiddle
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2020-08-02 14:26:40 -0700
committerSutou Kouhei <kou@cozmixng.org>2020-11-18 09:05:13 +0900
commit307388ea19f5c9d1c8c417d1979c40d970b420a2 (patch)
treefbf713aa94ddc4314fbe755c6bdc7541d10a6925 /test/fiddle
parente2dfc0c26b1f3d3517002ca2645d1b67847fe518 (diff)
[ruby/fiddle] Add a "pinning" reference (#44)
* 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. https://github.com/ruby/fiddle/commit/ac52d00223
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3780
Diffstat (limited to 'test/fiddle')
-rw-r--r--test/fiddle/test_pinned.rb27
1 files changed, 27 insertions, 0 deletions
diff --git a/test/fiddle/test_pinned.rb b/test/fiddle/test_pinned.rb
new file mode 100644
index 0000000000..5bfae2172a
--- /dev/null
+++ b/test/fiddle/test_pinned.rb
@@ -0,0 +1,27 @@
+# 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
+