1- # This is part of JRuby's FFI-based fiddle implementation.
1+ # This is based on JRuby's FFI-based fiddle implementation.
22
33require 'ffi'
44
@@ -74,7 +74,7 @@ module Types
7474
7575 WINDOWS = FFI ::Platform . windows?
7676
77- module JRuby
77+ module FFIBackend
7878 FFITypes = {
7979 'c' => FFI ::Type ::INT8 ,
8080 'h' => FFI ::Type ::INT16 ,
@@ -104,16 +104,16 @@ module JRuby
104104 Types ::VARIADIC => FFI ::Type ::Builtin ::VARARGS ,
105105 }
106106
107- def self . __ffi_type__ ( dl_type )
108- if dl_type . is_a? ( Symbol )
109- dl_type = Types . const_get ( dl_type . to_s . upcase )
107+ def self . to_ffi_type ( fiddle_type )
108+ if fiddle_type . is_a? ( Symbol )
109+ fiddle_type = Types . const_get ( fiddle_type . to_s . upcase )
110110 end
111- if !dl_type . is_a? ( Integer ) && dl_type . respond_to? ( :to_int )
112- dl_type = dl_type . to_int
111+ if !fiddle_type . is_a? ( Integer ) && fiddle_type . respond_to? ( :to_int )
112+ fiddle_type = fiddle_type . to_int
113113 end
114- ffi_type = FFITypes [ dl_type ]
115- ffi_type = FFITypes [ -dl_type ] if ffi_type . nil? && dl_type . is_a? ( Integer ) && dl_type < 0
116- raise TypeError . new ( "cannot convert #{ dl_type } to ffi" ) unless ffi_type
114+ ffi_type = FFITypes [ fiddle_type ]
115+ ffi_type = FFITypes [ -fiddle_type ] if ffi_type . nil? && fiddle_type . is_a? ( Integer ) && fiddle_type < 0
116+ raise TypeError . new ( "cannot convert #{ fiddle_type } to ffi" ) unless ffi_type
117117 ffi_type
118118 end
119119 end
@@ -133,8 +133,8 @@ def initialize(ptr, args, return_type, abi = DEFAULT, kwargs = nil)
133133 @ptr , @args , @return_type , @abi = ptr , args , return_type , abi
134134 raise TypeError . new "invalid argument types" unless args . is_a? ( Array )
135135
136- ffi_return_type = Fiddle ::JRuby :: __ffi_type__ ( @return_type )
137- ffi_args = @args . map { |t | Fiddle ::JRuby . __ffi_type__ ( t ) }
136+ ffi_return_type = Fiddle ::FFIBackend . to_ffi_type ( @return_type )
137+ ffi_args = @args . map { |t | Fiddle ::FFIBackend . to_ffi_type ( t ) }
138138 pointer = FFI ::Pointer . new ( ptr . to_i )
139139 options = { convention : @abi }
140140 if ffi_args . last == FFI ::Type ::Builtin ::VARARGS
@@ -149,14 +149,25 @@ def initialize(ptr, args, return_type, abi = DEFAULT, kwargs = nil)
149149 end
150150 end
151151
152- def call ( *args , &block ) ;
152+ def call ( *args , &block )
153153 if @function . is_a? ( FFI ::VariadicInvoker )
154154 n_fixed_args = @args . size - 1
155155 n_fixed_args . step ( args . size - 1 , 2 ) do |i |
156156 if args [ i ] == :const_string || args [ i ] == Types ::CONST_STRING
157157 args [ i + 1 ] = String . try_convert ( args [ i + 1 ] ) || args [ i + 1 ]
158158 end
159- args [ i ] = Fiddle ::JRuby . __ffi_type__ ( args [ i ] )
159+ args [ i ] = Fiddle ::FFIBackend . to_ffi_type ( args [ i ] )
160+ end
161+ else
162+ args . map! do |arg |
163+ if arg . respond_to? ( :to_ptr )
164+ begin
165+ arg = arg . to_ptr
166+ end until arg . is_a? ( FFI ::Pointer ) || !arg . respond_to? ( :to_ptr )
167+ arg
168+ else
169+ arg
170+ end
160171 end
161172 end
162173 result = @function . call ( *args , &block )
@@ -170,19 +181,21 @@ def initialize(ret, args, abi = Function::DEFAULT)
170181 raise TypeError . new "invalid argument types" unless args . is_a? ( Array )
171182
172183 @ctype , @args = ret , args
173- ffi_args = @args . map { |t | Fiddle ::JRuby . __ffi_type__ ( t ) }
184+ ffi_args = @args . map { |t | Fiddle ::FFIBackend . to_ffi_type ( t ) }
174185 if ffi_args . size == 1 && ffi_args [ 0 ] == FFI ::Type ::Builtin ::VOID
175186 ffi_args = [ ]
176187 end
177- @function = FFI ::Function . new (
178- Fiddle ::JRuby . __ffi_type__ ( @ctype ) ,
179- ffi_args ,
180- self ,
181- :convention => abi
182- )
188+ return_type = Fiddle ::FFIBackend . to_ffi_type ( @ctype )
189+ raise "#{ self . class } must implement #call" unless respond_to? ( :call )
190+ callable = method ( :call )
191+ @function = FFI ::Function . new ( return_type , ffi_args , callable , convention : abi )
183192 @freed = false
184193 end
185194
195+ def to_ptr
196+ @function
197+ end
198+
186199 def to_i
187200 @function . to_i
188201 end
@@ -550,51 +563,51 @@ def cleared?
550563 RUBY_FREE = Fiddle ::Pointer ::LibC ::FREE . address
551564 NULL = Fiddle ::Pointer . new ( 0 )
552565
553- ALIGN_VOIDP = Fiddle ::JRuby ::FFITypes [ Types ::VOIDP ] . alignment
554- ALIGN_CHAR = Fiddle ::JRuby ::FFITypes [ Types ::CHAR ] . alignment
555- ALIGN_SHORT = Fiddle ::JRuby ::FFITypes [ Types ::SHORT ] . alignment
556- ALIGN_INT = Fiddle ::JRuby ::FFITypes [ Types ::INT ] . alignment
557- ALIGN_LONG = Fiddle ::JRuby ::FFITypes [ Types ::LONG ] . alignment
558- ALIGN_LONG_LONG = Fiddle ::JRuby ::FFITypes [ Types ::LONG_LONG ] . alignment
559- ALIGN_INT8_T = Fiddle ::JRuby ::FFITypes [ Types ::INT8_T ] . alignment
560- ALIGN_INT16_T = Fiddle ::JRuby ::FFITypes [ Types ::INT16_T ] . alignment
561- ALIGN_INT32_T = Fiddle ::JRuby ::FFITypes [ Types ::INT32_T ] . alignment
562- ALIGN_INT64_T = Fiddle ::JRuby ::FFITypes [ Types ::INT64_T ] . alignment
563- ALIGN_FLOAT = Fiddle ::JRuby ::FFITypes [ Types ::FLOAT ] . alignment
564- ALIGN_DOUBLE = Fiddle ::JRuby ::FFITypes [ Types ::DOUBLE ] . alignment
565- ALIGN_BOOL = Fiddle ::JRuby ::FFITypes [ Types ::BOOL ] . alignment
566- ALIGN_SIZE_T = Fiddle ::JRuby ::FFITypes [ Types ::SIZE_T ] . alignment
566+ ALIGN_VOIDP = Fiddle ::FFIBackend ::FFITypes [ Types ::VOIDP ] . alignment
567+ ALIGN_CHAR = Fiddle ::FFIBackend ::FFITypes [ Types ::CHAR ] . alignment
568+ ALIGN_SHORT = Fiddle ::FFIBackend ::FFITypes [ Types ::SHORT ] . alignment
569+ ALIGN_INT = Fiddle ::FFIBackend ::FFITypes [ Types ::INT ] . alignment
570+ ALIGN_LONG = Fiddle ::FFIBackend ::FFITypes [ Types ::LONG ] . alignment
571+ ALIGN_LONG_LONG = Fiddle ::FFIBackend ::FFITypes [ Types ::LONG_LONG ] . alignment
572+ ALIGN_INT8_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT8_T ] . alignment
573+ ALIGN_INT16_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT16_T ] . alignment
574+ ALIGN_INT32_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT32_T ] . alignment
575+ ALIGN_INT64_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT64_T ] . alignment
576+ ALIGN_FLOAT = Fiddle ::FFIBackend ::FFITypes [ Types ::FLOAT ] . alignment
577+ ALIGN_DOUBLE = Fiddle ::FFIBackend ::FFITypes [ Types ::DOUBLE ] . alignment
578+ ALIGN_BOOL = Fiddle ::FFIBackend ::FFITypes [ Types ::BOOL ] . alignment
579+ ALIGN_SIZE_T = Fiddle ::FFIBackend ::FFITypes [ Types ::SIZE_T ] . alignment
567580 ALIGN_SSIZE_T = ALIGN_SIZE_T
568- ALIGN_PTRDIFF_T = Fiddle ::JRuby ::FFITypes [ Types ::PTRDIFF_T ] . alignment
569- ALIGN_INTPTR_T = Fiddle ::JRuby ::FFITypes [ Types ::INTPTR_T ] . alignment
570- ALIGN_UINTPTR_T = Fiddle ::JRuby ::FFITypes [ Types ::UINTPTR_T ] . alignment
571-
572- SIZEOF_VOIDP = Fiddle ::JRuby ::FFITypes [ Types ::VOIDP ] . size
573- SIZEOF_CHAR = Fiddle ::JRuby ::FFITypes [ Types ::CHAR ] . size
574- SIZEOF_UCHAR = Fiddle ::JRuby ::FFITypes [ Types ::UCHAR ] . size
575- SIZEOF_SHORT = Fiddle ::JRuby ::FFITypes [ Types ::SHORT ] . size
576- SIZEOF_USHORT = Fiddle ::JRuby ::FFITypes [ Types ::USHORT ] . size
577- SIZEOF_INT = Fiddle ::JRuby ::FFITypes [ Types ::INT ] . size
578- SIZEOF_UINT = Fiddle ::JRuby ::FFITypes [ Types ::UINT ] . size
579- SIZEOF_LONG = Fiddle ::JRuby ::FFITypes [ Types ::LONG ] . size
580- SIZEOF_ULONG = Fiddle ::JRuby ::FFITypes [ Types ::ULONG ] . size
581- SIZEOF_LONG_LONG = Fiddle ::JRuby ::FFITypes [ Types ::LONG_LONG ] . size
582- SIZEOF_ULONG_LONG = Fiddle ::JRuby ::FFITypes [ Types ::ULONG_LONG ] . size
583- SIZEOF_INT8_T = Fiddle ::JRuby ::FFITypes [ Types ::INT8_T ] . size
584- SIZEOF_UINT8_T = Fiddle ::JRuby ::FFITypes [ Types ::UINT8_T ] . size
585- SIZEOF_INT16_T = Fiddle ::JRuby ::FFITypes [ Types ::INT16_T ] . size
586- SIZEOF_UINT16_T = Fiddle ::JRuby ::FFITypes [ Types ::UINT16_T ] . size
587- SIZEOF_INT32_T = Fiddle ::JRuby ::FFITypes [ Types ::INT32_T ] . size
588- SIZEOF_UINT32_T = Fiddle ::JRuby ::FFITypes [ Types ::UINT32_T ] . size
589- SIZEOF_INT64_T = Fiddle ::JRuby ::FFITypes [ Types ::INT64_T ] . size
590- SIZEOF_UINT64_T = Fiddle ::JRuby ::FFITypes [ Types ::UINT64_T ] . size
591- SIZEOF_FLOAT = Fiddle ::JRuby ::FFITypes [ Types ::FLOAT ] . size
592- SIZEOF_DOUBLE = Fiddle ::JRuby ::FFITypes [ Types ::DOUBLE ] . size
593- SIZEOF_BOOL = Fiddle ::JRuby ::FFITypes [ Types ::BOOL ] . size
594- SIZEOF_SIZE_T = Fiddle ::JRuby ::FFITypes [ Types ::SIZE_T ] . size
581+ ALIGN_PTRDIFF_T = Fiddle ::FFIBackend ::FFITypes [ Types ::PTRDIFF_T ] . alignment
582+ ALIGN_INTPTR_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INTPTR_T ] . alignment
583+ ALIGN_UINTPTR_T = Fiddle ::FFIBackend ::FFITypes [ Types ::UINTPTR_T ] . alignment
584+
585+ SIZEOF_VOIDP = Fiddle ::FFIBackend ::FFITypes [ Types ::VOIDP ] . size
586+ SIZEOF_CHAR = Fiddle ::FFIBackend ::FFITypes [ Types ::CHAR ] . size
587+ SIZEOF_UCHAR = Fiddle ::FFIBackend ::FFITypes [ Types ::UCHAR ] . size
588+ SIZEOF_SHORT = Fiddle ::FFIBackend ::FFITypes [ Types ::SHORT ] . size
589+ SIZEOF_USHORT = Fiddle ::FFIBackend ::FFITypes [ Types ::USHORT ] . size
590+ SIZEOF_INT = Fiddle ::FFIBackend ::FFITypes [ Types ::INT ] . size
591+ SIZEOF_UINT = Fiddle ::FFIBackend ::FFITypes [ Types ::UINT ] . size
592+ SIZEOF_LONG = Fiddle ::FFIBackend ::FFITypes [ Types ::LONG ] . size
593+ SIZEOF_ULONG = Fiddle ::FFIBackend ::FFITypes [ Types ::ULONG ] . size
594+ SIZEOF_LONG_LONG = Fiddle ::FFIBackend ::FFITypes [ Types ::LONG_LONG ] . size
595+ SIZEOF_ULONG_LONG = Fiddle ::FFIBackend ::FFITypes [ Types ::ULONG_LONG ] . size
596+ SIZEOF_INT8_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT8_T ] . size
597+ SIZEOF_UINT8_T = Fiddle ::FFIBackend ::FFITypes [ Types ::UINT8_T ] . size
598+ SIZEOF_INT16_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT16_T ] . size
599+ SIZEOF_UINT16_T = Fiddle ::FFIBackend ::FFITypes [ Types ::UINT16_T ] . size
600+ SIZEOF_INT32_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT32_T ] . size
601+ SIZEOF_UINT32_T = Fiddle ::FFIBackend ::FFITypes [ Types ::UINT32_T ] . size
602+ SIZEOF_INT64_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INT64_T ] . size
603+ SIZEOF_UINT64_T = Fiddle ::FFIBackend ::FFITypes [ Types ::UINT64_T ] . size
604+ SIZEOF_FLOAT = Fiddle ::FFIBackend ::FFITypes [ Types ::FLOAT ] . size
605+ SIZEOF_DOUBLE = Fiddle ::FFIBackend ::FFITypes [ Types ::DOUBLE ] . size
606+ SIZEOF_BOOL = Fiddle ::FFIBackend ::FFITypes [ Types ::BOOL ] . size
607+ SIZEOF_SIZE_T = Fiddle ::FFIBackend ::FFITypes [ Types ::SIZE_T ] . size
595608 SIZEOF_SSIZE_T = SIZEOF_SIZE_T
596- SIZEOF_PTRDIFF_T = Fiddle ::JRuby ::FFITypes [ Types ::PTRDIFF_T ] . size
597- SIZEOF_INTPTR_T = Fiddle ::JRuby ::FFITypes [ Types ::INTPTR_T ] . size
598- SIZEOF_UINTPTR_T = Fiddle ::JRuby ::FFITypes [ Types ::UINTPTR_T ] . size
599- SIZEOF_CONST_STRING = Fiddle ::JRuby ::FFITypes [ Types ::VOIDP ] . size
609+ SIZEOF_PTRDIFF_T = Fiddle ::FFIBackend ::FFITypes [ Types ::PTRDIFF_T ] . size
610+ SIZEOF_INTPTR_T = Fiddle ::FFIBackend ::FFITypes [ Types ::INTPTR_T ] . size
611+ SIZEOF_UINTPTR_T = Fiddle ::FFIBackend ::FFITypes [ Types ::UINTPTR_T ] . size
612+ SIZEOF_CONST_STRING = Fiddle ::FFIBackend ::FFITypes [ Types ::VOIDP ] . size
600613end
0 commit comments