1
- # This is part of JRuby's FFI-based fiddle implementation.
1
+ # This is based on JRuby's FFI-based fiddle implementation.
2
2
3
3
require 'ffi'
4
4
@@ -74,7 +74,7 @@ module Types
74
74
75
75
WINDOWS = FFI ::Platform . windows?
76
76
77
- module JRuby
77
+ module FFIBackend
78
78
FFITypes = {
79
79
'c' => FFI ::Type ::INT8 ,
80
80
'h' => FFI ::Type ::INT16 ,
@@ -104,16 +104,16 @@ module JRuby
104
104
Types ::VARIADIC => FFI ::Type ::Builtin ::VARARGS ,
105
105
}
106
106
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 )
110
110
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
113
113
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
117
117
ffi_type
118
118
end
119
119
end
@@ -133,8 +133,8 @@ def initialize(ptr, args, return_type, abi = DEFAULT, kwargs = nil)
133
133
@ptr , @args , @return_type , @abi = ptr , args , return_type , abi
134
134
raise TypeError . new "invalid argument types" unless args . is_a? ( Array )
135
135
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 ) }
138
138
pointer = FFI ::Pointer . new ( ptr . to_i )
139
139
options = { convention : @abi }
140
140
if ffi_args . last == FFI ::Type ::Builtin ::VARARGS
@@ -149,14 +149,25 @@ def initialize(ptr, args, return_type, abi = DEFAULT, kwargs = nil)
149
149
end
150
150
end
151
151
152
- def call ( *args , &block ) ;
152
+ def call ( *args , &block )
153
153
if @function . is_a? ( FFI ::VariadicInvoker )
154
154
n_fixed_args = @args . size - 1
155
155
n_fixed_args . step ( args . size - 1 , 2 ) do |i |
156
156
if args [ i ] == :const_string || args [ i ] == Types ::CONST_STRING
157
157
args [ i + 1 ] = String . try_convert ( args [ i + 1 ] ) || args [ i + 1 ]
158
158
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
160
171
end
161
172
end
162
173
result = @function . call ( *args , &block )
@@ -170,19 +181,21 @@ def initialize(ret, args, abi = Function::DEFAULT)
170
181
raise TypeError . new "invalid argument types" unless args . is_a? ( Array )
171
182
172
183
@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 ) }
174
185
if ffi_args . size == 1 && ffi_args [ 0 ] == FFI ::Type ::Builtin ::VOID
175
186
ffi_args = [ ]
176
187
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 )
183
192
@freed = false
184
193
end
185
194
195
+ def to_ptr
196
+ @function
197
+ end
198
+
186
199
def to_i
187
200
@function . to_i
188
201
end
@@ -550,51 +563,51 @@ def cleared?
550
563
RUBY_FREE = Fiddle ::Pointer ::LibC ::FREE . address
551
564
NULL = Fiddle ::Pointer . new ( 0 )
552
565
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
567
580
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
595
608
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
600
613
end
0 commit comments