Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions lib/fiddle/ffi_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ class Error < StandardError; end
class DLError < Error; end
class ClearedReferenceError < Error; end

# Pointer isn't thread safe for now
class Pointer
attr_reader :ffi_ptr
extend FFI::DataConverter
native_type FFI::Type::Builtin::POINTER

Expand Down Expand Up @@ -285,15 +285,15 @@ def []=(*args, value)
value = value.to_str(args[1])
end

@ffi_ptr.put_bytes(args[0], value, 0, args[1])
ffi_ptr.put_bytes(args[0], value, 0, args[1])
elsif args.size == 1
if value.is_a?(Fiddle::Pointer)
value = value.to_str(args[0] + 1)
else
value = value.chr
end

@ffi_ptr.put_bytes(args[0], value, 0, 1)
ffi_ptr.put_bytes(args[0], value, 0, 1)
end
rescue FFI::NullPointerError
raise DLError.new("NULL pointer access")
Expand Down Expand Up @@ -332,9 +332,14 @@ def initialize(addr, size = nil, free = nil)
end
@free = free
@ffi_ptr = ptr
@addr_ptr = nil
@freed = false
end

def ffi_ptr
@addr_ptr ? @addr_ptr.get_pointer(0) : @ffi_ptr
end

module LibC
extend FFI::Library
ffi_lib FFI::Library::LIBC
Expand Down Expand Up @@ -363,11 +368,11 @@ def self.malloc(size, free = nil)
end

def null?
@ffi_ptr.null?
ffi_ptr.null?
end

def to_ptr
@ffi_ptr
ffi_ptr
end

def size
Expand All @@ -386,9 +391,9 @@ def call_free
return if @free.nil?
return if @freed
if @free == RUBY_FREE
LibC::FREE.call(@ffi_ptr)
LibC::FREE.call(ffi_ptr)
else
@free.call(@ffi_ptr)
@free.call(ffi_ptr)
end
@freed = true
end
Expand Down Expand Up @@ -492,10 +497,8 @@ def -@
end

def ref
cptr = Pointer.malloc(FFI::Type::POINTER.size, RUBY_FREE)
cptr.ffi_ptr.put_pointer(0, ffi_ptr)
cptr.size = 0
cptr
@addr_ptr ||= FFI::MemoryPointer.new(:pointer).put_pointer(0, @ffi_ptr)
Pointer.new(@addr_ptr, 0)
end
end

Expand Down
13 changes: 13 additions & 0 deletions test/fiddle/test_pointer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@ def test_cmp
assert_nil(ptr <=> 10, '10 should not be comparable')
end

def test_ref
ptr = Fiddle::Pointer["hello"]
ref = ptr.ref
assert_equal(0, ref.size)
assert_nil(ref.free)
assert_equal(ptr, ref.ptr)

ptr2 = Fiddle::Pointer["world"]
ptr.ref[0, Fiddle::SIZEOF_VOIDP] = ptr2.ref
assert_equal("world", ptr.to_s)
assert_equal(ptr.to_i, ptr2.to_i)
end

def test_ref_ptr
if ffi_backend?
omit("Fiddle.dlwrap([]) isn't supported with FFI backend")
Expand Down