fiddle 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,13 @@
1
- http://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz \
1
+ ver = 3.2.1
2
+ pkg = libffi-$(ver)
3
+
4
+ https://ftp.osuosl.org/pub/blfs/conglomeration/libffi/$(pkg).tar.gz \
2
5
  md5:83b89587607e3eb65c70d361f13bab43 \
3
6
  sha512:980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 \
4
7
  #
5
- win32/libffi-3.2.1-mswin.patch -p0
8
+ win32/$(pkg)-mswin.patch -p0
9
+
10
+ $(pkg)/config.guess -> /tool/config.guess
11
+ $(pkg)/config.sub -> /tool/config.sub
12
+
13
+ ! chdir: $(pkg)| autoconf || exit 0
@@ -1,41 +1,11 @@
1
1
  #include <fiddle.h>
2
2
 
3
3
  VALUE mFiddle;
4
+ VALUE rb_eFiddleDLError;
4
5
  VALUE rb_eFiddleError;
5
6
 
6
- #ifndef TYPE_SSIZE_T
7
- # if SIZEOF_SIZE_T == SIZEOF_INT
8
- # define TYPE_SSIZE_T TYPE_INT
9
- # elif SIZEOF_SIZE_T == SIZEOF_LONG
10
- # define TYPE_SSIZE_T TYPE_LONG
11
- # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
12
- # define TYPE_SSIZE_T TYPE_LONG_LONG
13
- # endif
14
- #endif
15
- #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
16
-
17
- #ifndef TYPE_PTRDIFF_T
18
- # if SIZEOF_PTRDIFF_T == SIZEOF_INT
19
- # define TYPE_PTRDIFF_T TYPE_INT
20
- # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
21
- # define TYPE_PTRDIFF_T TYPE_LONG
22
- # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
23
- # define TYPE_PTRDIFF_T TYPE_LONG_LONG
24
- # endif
25
- #endif
26
-
27
- #ifndef TYPE_INTPTR_T
28
- # if SIZEOF_INTPTR_T == SIZEOF_INT
29
- # define TYPE_INTPTR_T TYPE_INT
30
- # elif SIZEOF_INTPTR_T == SIZEOF_LONG
31
- # define TYPE_INTPTR_T TYPE_LONG
32
- # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
33
- # define TYPE_INTPTR_T TYPE_LONG_LONG
34
- # endif
35
- #endif
36
- #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
37
-
38
7
  void Init_fiddle_pointer(void);
8
+ void Init_fiddle_pinned(void);
39
9
 
40
10
  /*
41
11
  * call-seq: Fiddle.malloc(size)
@@ -47,8 +17,7 @@ static VALUE
47
17
  rb_fiddle_malloc(VALUE self, VALUE size)
48
18
  {
49
19
  void *ptr;
50
-
51
- ptr = (void*)ruby_xmalloc(NUM2SIZET(size));
20
+ ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size));
52
21
  return PTR2NUM(ptr);
53
22
  }
54
23
 
@@ -163,12 +132,33 @@ Init_fiddle(void)
163
132
  */
164
133
  mFiddle = rb_define_module("Fiddle");
165
134
 
135
+ /*
136
+ * Document-class: Fiddle::Error
137
+ *
138
+ * Generic error class for Fiddle
139
+ */
140
+ rb_eFiddleError = rb_define_class_under(mFiddle, "Error", rb_eStandardError);
141
+
142
+ /*
143
+ * Ruby installed by RubyInstaller for Windows always require
144
+ * bundled Fiddle because ruby_installer/runtime/dll_directory.rb
145
+ * requires Fiddle. It's used by
146
+ * rubygems/defaults/operating_system.rb. It means that the
147
+ * bundled Fiddle is always required on initialization.
148
+ *
149
+ * We just remove existing Fiddle::DLError here to override
150
+ * the bundled Fiddle.
151
+ */
152
+ if (rb_const_defined(mFiddle, rb_intern("DLError"))) {
153
+ rb_const_remove(mFiddle, rb_intern("DLError"));
154
+ }
155
+
166
156
  /*
167
157
  * Document-class: Fiddle::DLError
168
158
  *
169
159
  * standard dynamic load exception
170
160
  */
171
- rb_eFiddleError = rb_define_class_under(mFiddle, "DLError", rb_eStandardError);
161
+ rb_eFiddleDLError = rb_define_class_under(mFiddle, "DLError", rb_eFiddleError);
172
162
 
173
163
  /* Document-const: TYPE_VOID
174
164
  *
@@ -226,6 +216,20 @@ Init_fiddle(void)
226
216
  */
227
217
  rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
228
218
 
219
+ #ifdef HAVE_FFI_PREP_CIF_VAR
220
+ /* Document-const: TYPE_VARIADIC
221
+ *
222
+ * C type - ...
223
+ */
224
+ rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC));
225
+ #endif
226
+
227
+ /* Document-const: TYPE_CONST_STRING
228
+ *
229
+ * C type - const char* ('\0' terminated const char*)
230
+ */
231
+ rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING));
232
+
229
233
  /* Document-const: TYPE_SIZE_T
230
234
  *
231
235
  * C type - size_t
@@ -426,6 +430,12 @@ Init_fiddle(void)
426
430
  */
427
431
  rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
428
432
 
433
+ /* Document-const: SIZEOF_CONST_STRING
434
+ *
435
+ * size of a const char*
436
+ */
437
+ rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
438
+
429
439
  /* Document-const: RUBY_FREE
430
440
  *
431
441
  * Address of the ruby_xfree() function
@@ -450,5 +460,6 @@ Init_fiddle(void)
450
460
  Init_fiddle_closure();
451
461
  Init_fiddle_handle();
452
462
  Init_fiddle_pointer();
463
+ Init_fiddle_pinned();
453
464
  }
454
465
  /* vim: set noet sws=4 sw=4: */
@@ -115,6 +115,40 @@
115
115
  #endif
116
116
  #define TYPE_FLOAT 7
117
117
  #define TYPE_DOUBLE 8
118
+ #define TYPE_VARIADIC 9
119
+ #define TYPE_CONST_STRING 10
120
+
121
+ #ifndef TYPE_SSIZE_T
122
+ # if SIZEOF_SIZE_T == SIZEOF_INT
123
+ # define TYPE_SSIZE_T TYPE_INT
124
+ # elif SIZEOF_SIZE_T == SIZEOF_LONG
125
+ # define TYPE_SSIZE_T TYPE_LONG
126
+ # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
127
+ # define TYPE_SSIZE_T TYPE_LONG_LONG
128
+ # endif
129
+ #endif
130
+ #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
131
+
132
+ #ifndef TYPE_PTRDIFF_T
133
+ # if SIZEOF_PTRDIFF_T == SIZEOF_INT
134
+ # define TYPE_PTRDIFF_T TYPE_INT
135
+ # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
136
+ # define TYPE_PTRDIFF_T TYPE_LONG
137
+ # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
138
+ # define TYPE_PTRDIFF_T TYPE_LONG_LONG
139
+ # endif
140
+ #endif
141
+
142
+ #ifndef TYPE_INTPTR_T
143
+ # if SIZEOF_INTPTR_T == SIZEOF_INT
144
+ # define TYPE_INTPTR_T TYPE_INT
145
+ # elif SIZEOF_INTPTR_T == SIZEOF_LONG
146
+ # define TYPE_INTPTR_T TYPE_LONG
147
+ # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
148
+ # define TYPE_INTPTR_T TYPE_LONG_LONG
149
+ # endif
150
+ #endif
151
+ #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
118
152
 
119
153
  #define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
120
154
 
@@ -130,7 +164,7 @@
130
164
  #define ALIGN_DOUBLE ALIGN_OF(double)
131
165
 
132
166
  extern VALUE mFiddle;
133
- extern VALUE rb_eFiddleError;
167
+ extern VALUE rb_eFiddleDLError;
134
168
 
135
169
  VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type);
136
170
 
@@ -1,6 +1,8 @@
1
1
  #include <fiddle.h>
2
2
  #include <ruby/thread.h>
3
3
 
4
+ #include <stdbool.h>
5
+
4
6
  #ifdef PRIsVALUE
5
7
  # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
6
8
  # define RB_OBJ_STRING(obj) (obj)
@@ -19,21 +21,21 @@ VALUE cFiddleFunction;
19
21
  #define Check_Max_Args_Long(name, len) \
20
22
  Check_Max_Args_(name, len, "l")
21
23
  #define Check_Max_Args_(name, len, fmt) \
22
- if ((size_t)(len) < MAX_ARGS) { \
23
- /* OK */ \
24
- } \
25
- else { \
26
- rb_raise(rb_eTypeError, \
27
- name" is so large that it can cause integer overflow (%"fmt"d)", \
28
- (len)); \
29
- }
24
+ do { \
25
+ if ((size_t)(len) >= MAX_ARGS) { \
26
+ rb_raise(rb_eTypeError, \
27
+ "%s is so large " \
28
+ "that it can cause integer overflow (%"fmt"d)", \
29
+ (name), (len)); \
30
+ } \
31
+ } while (0)
30
32
 
31
33
  static void
32
34
  deallocate(void *p)
33
35
  {
34
- ffi_cif *ptr = p;
35
- if (ptr->arg_types) xfree(ptr->arg_types);
36
- xfree(ptr);
36
+ ffi_cif *cif = p;
37
+ if (cif->arg_types) xfree(cif->arg_types);
38
+ xfree(cif);
37
39
  }
38
40
 
39
41
  static size_t
@@ -87,60 +89,91 @@ parse_keyword_arg_i(VALUE key, VALUE value, VALUE self)
87
89
  return ST_CONTINUE;
88
90
  }
89
91
 
92
+ static VALUE
93
+ normalize_argument_types(const char *name,
94
+ VALUE arg_types,
95
+ bool *is_variadic)
96
+ {
97
+ VALUE normalized_arg_types;
98
+ int i;
99
+ int n_arg_types;
100
+ *is_variadic = false;
101
+
102
+ Check_Type(arg_types, T_ARRAY);
103
+ n_arg_types = RARRAY_LENINT(arg_types);
104
+ Check_Max_Args(name, n_arg_types);
105
+
106
+ normalized_arg_types = rb_ary_new_capa(n_arg_types);
107
+ for (i = 0; i < n_arg_types; i++) {
108
+ VALUE arg_type = RARRAY_AREF(arg_types, i);
109
+ int c_arg_type;
110
+ arg_type = rb_fiddle_type_ensure(arg_type);
111
+ c_arg_type = NUM2INT(arg_type);
112
+ if (c_arg_type == TYPE_VARIADIC) {
113
+ if (i != n_arg_types - 1) {
114
+ rb_raise(rb_eArgError,
115
+ "Fiddle::TYPE_VARIADIC must be the last argument type: "
116
+ "%"PRIsVALUE,
117
+ arg_types);
118
+ }
119
+ *is_variadic = true;
120
+ break;
121
+ }
122
+ else {
123
+ (void)INT2FFI_TYPE(c_arg_type); /* raise */
124
+ }
125
+ rb_ary_push(normalized_arg_types, INT2FIX(c_arg_type));
126
+ }
127
+
128
+ /* freeze to prevent inconsistency at calling #to_int later */
129
+ OBJ_FREEZE(normalized_arg_types);
130
+ return normalized_arg_types;
131
+ }
132
+
90
133
  static VALUE
91
134
  initialize(int argc, VALUE argv[], VALUE self)
92
135
  {
93
136
  ffi_cif * cif;
94
- ffi_type **arg_types, *rtype;
95
- ffi_status result;
96
- VALUE ptr, args, ret_type, abi, kwds, ary;
97
- int i, len;
98
- int nabi;
137
+ VALUE ptr, arg_types, ret_type, abi, kwds;
138
+ int c_ret_type;
139
+ bool is_variadic = false;
140
+ ffi_abi c_ffi_abi;
99
141
  void *cfunc;
100
142
 
101
- rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds);
143
+ rb_scan_args(argc, argv, "31:", &ptr, &arg_types, &ret_type, &abi, &kwds);
144
+ rb_iv_set(self, "@closure", ptr);
145
+
102
146
  ptr = rb_Integer(ptr);
103
147
  cfunc = NUM2PTR(ptr);
104
148
  PTR2NUM(cfunc);
105
- nabi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
106
- abi = INT2FIX(nabi);
107
- i = NUM2INT(ret_type);
108
- rtype = INT2FFI_TYPE(i);
109
- ret_type = INT2FIX(i);
110
-
111
- Check_Type(args, T_ARRAY);
112
- len = RARRAY_LENINT(args);
113
- Check_Max_Args("args", len);
114
- ary = rb_ary_subseq(args, 0, len);
115
- for (i = 0; i < RARRAY_LEN(args); i++) {
116
- VALUE a = RARRAY_PTR(args)[i];
117
- int type = NUM2INT(a);
118
- (void)INT2FFI_TYPE(type); /* raise */
119
- if (INT2FIX(type) != a) rb_ary_store(ary, i, INT2FIX(type));
149
+ c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
150
+ abi = INT2FIX(c_ffi_abi);
151
+ ret_type = rb_fiddle_type_ensure(ret_type);
152
+ c_ret_type = NUM2INT(ret_type);
153
+ (void)INT2FFI_TYPE(c_ret_type); /* raise */
154
+ ret_type = INT2FIX(c_ret_type);
155
+
156
+ arg_types = normalize_argument_types("argument types",
157
+ arg_types,
158
+ &is_variadic);
159
+ #ifndef HAVE_FFI_PREP_CIF_VAR
160
+ if (is_variadic) {
161
+ rb_raise(rb_eNotImpError,
162
+ "ffi_prep_cif_var() is required in libffi "
163
+ "for variadic arguments");
120
164
  }
121
- OBJ_FREEZE(ary);
165
+ #endif
122
166
 
123
167
  rb_iv_set(self, "@ptr", ptr);
124
- rb_iv_set(self, "@args", args);
168
+ rb_iv_set(self, "@argument_types", arg_types);
125
169
  rb_iv_set(self, "@return_type", ret_type);
126
170
  rb_iv_set(self, "@abi", abi);
171
+ rb_iv_set(self, "@is_variadic", is_variadic ? Qtrue : Qfalse);
127
172
 
128
173
  if (!NIL_P(kwds)) rb_hash_foreach(kwds, parse_keyword_arg_i, self);
129
174
 
130
175
  TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
131
-
132
- arg_types = xcalloc(len + 1, sizeof(ffi_type *));
133
-
134
- for (i = 0; i < RARRAY_LEN(args); i++) {
135
- int type = NUM2INT(RARRAY_AREF(args, i));
136
- arg_types[i] = INT2FFI_TYPE(type);
137
- }
138
- arg_types[len] = NULL;
139
-
140
- result = ffi_prep_cif(cif, nabi, len, rtype, arg_types);
141
-
142
- if (result)
143
- rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
176
+ cif->arg_types = NULL;
144
177
 
145
178
  return self;
146
179
  }
@@ -167,54 +200,160 @@ function_call(int argc, VALUE argv[], VALUE self)
167
200
  {
168
201
  struct nogvl_ffi_call_args args = { 0 };
169
202
  fiddle_generic *generic_args;
170
- VALUE cfunc, types, cPointer;
203
+ VALUE cfunc;
204
+ VALUE abi;
205
+ VALUE arg_types;
206
+ VALUE cPointer;
207
+ VALUE is_variadic;
208
+ int n_arg_types;
209
+ int n_fixed_args = 0;
210
+ int n_call_args = 0;
171
211
  int i;
212
+ int i_call;
213
+ VALUE converted_args = Qnil;
172
214
  VALUE alloc_buffer = 0;
173
215
 
174
216
  cfunc = rb_iv_get(self, "@ptr");
175
- types = rb_iv_get(self, "@args");
217
+ abi = rb_iv_get(self, "@abi");
218
+ arg_types = rb_iv_get(self, "@argument_types");
176
219
  cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
177
-
178
- Check_Max_Args("number of arguments", argc);
179
- if (argc != (i = RARRAY_LENINT(types))) {
180
- rb_error_arity(argc, i, i);
220
+ is_variadic = rb_iv_get(self, "@is_variadic");
221
+
222
+ n_arg_types = RARRAY_LENINT(arg_types);
223
+ n_fixed_args = n_arg_types;
224
+ if (RTEST(is_variadic)) {
225
+ if (argc < n_arg_types) {
226
+ rb_error_arity(argc, n_arg_types, UNLIMITED_ARGUMENTS);
227
+ }
228
+ if (((argc - n_arg_types) % 2) != 0) {
229
+ rb_raise(rb_eArgError,
230
+ "variadic arguments must be type and value pairs: "
231
+ "%"PRIsVALUE,
232
+ rb_ary_new_from_values(argc, argv));
233
+ }
234
+ n_call_args = n_arg_types + ((argc - n_arg_types) / 2);
181
235
  }
236
+ else {
237
+ if (argc != n_arg_types) {
238
+ rb_error_arity(argc, n_arg_types, n_arg_types);
239
+ }
240
+ n_call_args = n_arg_types;
241
+ }
242
+ Check_Max_Args("the number of arguments", n_call_args);
182
243
 
183
244
  TypedData_Get_Struct(self, ffi_cif, &function_data_type, args.cif);
184
245
 
185
- if (rb_safe_level() >= 1) {
186
- for (i = 0; i < argc; i++) {
187
- VALUE src = argv[i];
188
- if (OBJ_TAINTED(src)) {
189
- rb_raise(rb_eSecurityError, "tainted parameter not allowed");
190
- }
191
- }
246
+ if (is_variadic && args.cif->arg_types) {
247
+ xfree(args.cif->arg_types);
248
+ args.cif->arg_types = NULL;
249
+ }
250
+
251
+ if (!args.cif->arg_types) {
252
+ VALUE fixed_arg_types = arg_types;
253
+ VALUE return_type;
254
+ int c_return_type;
255
+ ffi_type *ffi_return_type;
256
+ ffi_type **ffi_arg_types;
257
+ ffi_status result;
258
+
259
+ arg_types = rb_ary_dup(fixed_arg_types);
260
+ for (i = n_fixed_args; i < argc; i += 2) {
261
+ VALUE arg_type = argv[i];
262
+ int c_arg_type;
263
+ arg_type = rb_fiddle_type_ensure(arg_type);
264
+ c_arg_type = NUM2INT(arg_type);
265
+ (void)INT2FFI_TYPE(c_arg_type); /* raise */
266
+ rb_ary_push(arg_types, INT2FIX(c_arg_type));
267
+ }
268
+
269
+ return_type = rb_iv_get(self, "@return_type");
270
+ c_return_type = FIX2INT(return_type);
271
+ ffi_return_type = INT2FFI_TYPE(c_return_type);
272
+
273
+ ffi_arg_types = xcalloc(n_call_args + 1, sizeof(ffi_type *));
274
+ for (i_call = 0; i_call < n_call_args; i_call++) {
275
+ VALUE arg_type;
276
+ int c_arg_type;
277
+ arg_type = RARRAY_AREF(arg_types, i_call);
278
+ c_arg_type = FIX2INT(arg_type);
279
+ ffi_arg_types[i_call] = INT2FFI_TYPE(c_arg_type);
280
+ }
281
+ ffi_arg_types[i_call] = NULL;
282
+
283
+ if (is_variadic) {
284
+ #ifdef HAVE_FFI_PREP_CIF_VAR
285
+ result = ffi_prep_cif_var(args.cif,
286
+ FIX2INT(abi),
287
+ n_fixed_args,
288
+ n_call_args,
289
+ ffi_return_type,
290
+ ffi_arg_types);
291
+ #else
292
+ /* This code is never used because ffi_prep_cif_var()
293
+ * availability check is done in #initialize. */
294
+ result = FFI_BAD_TYPEDEF;
295
+ #endif
296
+ }
297
+ else {
298
+ result = ffi_prep_cif(args.cif,
299
+ FIX2INT(abi),
300
+ n_call_args,
301
+ ffi_return_type,
302
+ ffi_arg_types);
303
+ }
304
+ if (result != FFI_OK) {
305
+ xfree(ffi_arg_types);
306
+ args.cif->arg_types = NULL;
307
+ rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
308
+ }
192
309
  }
193
310
 
194
311
  generic_args = ALLOCV(alloc_buffer,
195
- (size_t)(argc + 1) * sizeof(void *) + (size_t)argc * sizeof(fiddle_generic));
312
+ sizeof(fiddle_generic) * n_call_args +
313
+ sizeof(void *) * (n_call_args + 1));
196
314
  args.values = (void **)((char *)generic_args +
197
- (size_t)argc * sizeof(fiddle_generic));
198
-
199
- for (i = 0; i < argc; i++) {
200
- VALUE type = RARRAY_AREF(types, i);
201
- VALUE src = argv[i];
202
- int argtype = FIX2INT(type);
203
-
204
- if (argtype == TYPE_VOIDP) {
205
- if(NIL_P(src)) {
206
- src = INT2FIX(0);
207
- } else if(cPointer != CLASS_OF(src)) {
208
- src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
209
- }
210
- src = rb_Integer(src);
211
- }
212
-
213
- VALUE2GENERIC(argtype, src, &generic_args[i]);
214
- args.values[i] = (void *)&generic_args[i];
315
+ sizeof(fiddle_generic) * n_call_args);
316
+
317
+ for (i = 0, i_call = 0;
318
+ i < argc && i_call < n_call_args;
319
+ i++, i_call++) {
320
+ VALUE arg_type;
321
+ int c_arg_type;
322
+ VALUE original_src;
323
+ VALUE src;
324
+ arg_type = RARRAY_AREF(arg_types, i_call);
325
+ c_arg_type = FIX2INT(arg_type);
326
+ if (i >= n_fixed_args) {
327
+ i++;
328
+ }
329
+ src = argv[i];
330
+
331
+ if (c_arg_type == TYPE_VOIDP) {
332
+ if (NIL_P(src)) {
333
+ src = INT2FIX(0);
334
+ }
335
+ else if (cPointer != CLASS_OF(src)) {
336
+ src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
337
+ if (NIL_P(converted_args)) {
338
+ converted_args = rb_ary_new();
339
+ }
340
+ rb_ary_push(converted_args, src);
341
+ }
342
+ src = rb_Integer(src);
343
+ }
344
+
345
+ original_src = src;
346
+ VALUE2GENERIC(c_arg_type, src, &generic_args[i_call]);
347
+ if (src != original_src) {
348
+ if (NIL_P(converted_args)) {
349
+ converted_args = rb_ary_new();
350
+ }
351
+ rb_ary_push(converted_args, src);
352
+ }
353
+ args.values[i_call] = (void *)&generic_args[i_call];
215
354
  }
216
- args.values[argc] = NULL;
217
- args.fn = NUM2PTR(cfunc);
355
+ args.values[i_call] = NULL;
356
+ args.fn = (void(*)(void))NUM2PTR(cfunc);
218
357
 
219
358
  (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
220
359