ffi 1.9.10 → 1.9.11

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e9c8839adf7b6a689045d90707bdaa36c7cc526
4
- data.tar.gz: 33adbf317d8e7beed7d821f014577168a9620af6
3
+ metadata.gz: cd5a2a6512c110a9b389f35fc72dc8cdaa750726
4
+ data.tar.gz: e245890dfe6d77d2c7377a0e7e397fd6603b1dde
5
5
  SHA512:
6
- metadata.gz: 745d43b045e9f04d1b8de34828855cf1b0a779c0f837c793e4ab647d1d3cf8a263c0698fbaa362a951443a40e316cbb97ef1a09f8de6f3d275b8d59d1e1a7779
7
- data.tar.gz: f06ee223a8b8f0ccca9612d126f34c04fd4a718a1c86cc8d57b9e8c59157c4ff974a1686317df939a171e9ee17f000806469acaa1c152b9d00954e788d2b9781
6
+ metadata.gz: 628b2b63ee4f4ddc196dbb169d68613e72b7710b00219f3c4001aa9b62c997f0540d92b6649aae09cb2d6937d5d3b2a2fc746c1ca3c571c8771602405ed143dc
7
+ data.tar.gz: f459df3bd97f90de497d6acf4c5e631e02a6e88287c09328873def76ea3f91f9aa87adf6271265626a6567169e16855954288b91058b84b36a40f7bdbfc83852
data/Rakefile CHANGED
@@ -93,13 +93,13 @@ task :package => 'gem:package'
93
93
 
94
94
  CLOBBER.include 'lib/ffi/types.conf'
95
95
  CLOBBER.include 'pkg'
96
+ CLOBBER.include 'log'
96
97
 
97
98
  CLEAN.include 'build'
98
99
  CLEAN.include 'conftest.dSYM'
99
100
  CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
100
101
  CLEAN.include 'spec/ffi/fixtures/*.o'
101
- CLEAN.include "pkg/ffi-#{FFI::VERSION}-*-mingw32"
102
- CLEAN.include "pkg/ffi-#{FFI::VERSION}-java"
102
+ CLEAN.include "pkg/ffi-*-{mingw32,java}"
103
103
  CLEAN.include 'lib/1.*'
104
104
  CLEAN.include 'lib/2.*'
105
105
  CLEAN.include 'bin'
@@ -138,7 +138,7 @@ end
138
138
  task 'spec:run' => TEST_DEPS
139
139
  task 'spec:specdoc' => TEST_DEPS
140
140
 
141
- task :default => :specs
141
+ task :default => :spec
142
142
 
143
143
  namespace 'java' do
144
144
 
@@ -175,15 +175,16 @@ if USE_RAKE_COMPILER
175
175
  ext.cross_platform = %w[i386-mingw32 x64-mingw32] # forces the Windows platform instead of the default one
176
176
  end
177
177
 
178
- ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3:2.0.0:2.1.5:2.2.1'
178
+ ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3:2.0.0:2.1.6:2.2.2:2.3.0'
179
179
 
180
+ # To reduce the gem file size strip mingw32 dlls before packaging
180
181
  ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
181
- task "copy:ffi_c:i386-mingw32:#{ruby_version}" do |t|
182
- sh "i686-w64-mingw32-strip -S #{BUILD_DIR}/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
182
+ task "build/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so" do |t|
183
+ sh "i686-w64-mingw32-strip -S build/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
183
184
  end
184
185
 
185
- task "copy:ffi_c:x64-mingw32:#{ruby_version}" do |t|
186
- sh "x86_64-w64-mingw32-strip -S #{BUILD_DIR}/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
186
+ task "build/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so" do |t|
187
+ sh "x86_64-w64-mingw32-strip -S build/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
187
188
  end
188
189
  end
189
190
 
@@ -194,6 +195,27 @@ if USE_RAKE_COMPILER
194
195
  end
195
196
  end
196
197
 
198
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
199
+ require 'ffi/platform'
200
+ types_conf = File.expand_path(File.join(FFI::Platform::CONF_DIR, 'types.conf'))
201
+ logfile = File.join(File.dirname(__FILE__), 'types_log')
202
+
203
+ file types_conf => File.join("lib", "ffi", "version.rb") do |task|
204
+ require 'fileutils'
205
+ require 'ffi/tools/types_generator'
206
+ options = {}
207
+ FileUtils.mkdir_p(File.dirname(task.name), { :mode => 0755 })
208
+ File.open(task.name, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
209
+ f.puts FFI::TypesGenerator.generate(options)
210
+ end
211
+ File.open(logfile, 'w') do |log|
212
+ log.puts(types_conf)
213
+ end
214
+ end
215
+
216
+ task :types_conf => types_conf do
217
+ end
218
+
197
219
  Gem::Tasks.new do |t|
198
220
  t.scm.tag.format = '%s'
199
221
  end
@@ -497,7 +497,7 @@ memory_put_bytes(int argc, VALUE* argv, VALUE self)
497
497
  off = NUM2LONG(offset);
498
498
  idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
499
499
  if (idx < 0) {
500
- rb_raise(rb_eRangeError, "index canot be less than zero");
500
+ rb_raise(rb_eRangeError, "index cannot be less than zero");
501
501
  return Qnil;
502
502
  }
503
503
  len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
@@ -253,7 +253,7 @@ buffer_inspect(VALUE self)
253
253
  * @overload order(order)
254
254
  * @param [:big, :little, :network] order
255
255
  * @return [self]
256
- * Set endinaness of Buffer (+:network+ is an alias for +:big+).
256
+ * Set endianness of Buffer (+:network+ is an alias for +:big+).
257
257
  */
258
258
  static VALUE
259
259
  buffer_order(int argc, VALUE* argv, VALUE self)
@@ -338,40 +338,27 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
338
338
  }
339
339
  }
340
340
 
341
-
342
- typedef struct BlockingCall_ {
343
- rbffi_frame_t* frame;
344
- void* function;
345
- FunctionType* info;
346
- void **ffiValues;
347
- void* retval;
348
- void* params;
349
- #if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
350
- void* stkretval;
351
- #endif
352
- } BlockingCall;
353
-
354
341
  static VALUE
355
342
  call_blocking_function(void* data)
356
343
  {
357
- BlockingCall* b = (BlockingCall *) data;
344
+ rbffi_blocking_call_t* b = (rbffi_blocking_call_t *) data;
358
345
  b->frame->has_gvl = false;
359
- ffi_call(&b->info->ffi_cif, FFI_FN(b->function), b->retval, b->ffiValues);
346
+ ffi_call(&b->cif, FFI_FN(b->function), b->retval, b->ffiValues);
360
347
  b->frame->has_gvl = true;
361
348
 
362
349
  return Qnil;
363
350
  }
364
351
 
365
- static VALUE
366
- do_blocking_call(void *data)
352
+ VALUE
353
+ rbffi_do_blocking_call(void *data)
367
354
  {
368
355
  rbffi_thread_blocking_region(call_blocking_function, data, (void *) -1, NULL);
369
356
 
370
357
  return Qnil;
371
358
  }
372
359
 
373
- static VALUE
374
- save_frame_exception(void *data, VALUE exc)
360
+ VALUE
361
+ rbffi_save_frame_exception(void *data, VALUE exc)
375
362
  {
376
363
  rbffi_frame_t* frame = (rbffi_frame_t *) data;
377
364
  frame->exc = exc;
@@ -390,7 +377,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
390
377
  retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
391
378
 
392
379
  if (unlikely(fnInfo->blocking)) {
393
- BlockingCall* bc;
380
+ rbffi_blocking_call_t* bc;
394
381
 
395
382
  /*
396
383
  * due to the way thread switching works on older ruby variants, we
@@ -399,16 +386,16 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
399
386
  #if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
400
387
  ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
401
388
  params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
402
- bc = ALLOCA_N(BlockingCall, 1);
389
+ bc = ALLOCA_N(rbffi_blocking_call_t, 1);
403
390
  bc->retval = retval;
404
391
  #else
405
392
  ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
406
393
  params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
407
- bc = ALLOC_N(BlockingCall, 1);
394
+ bc = ALLOC_N(rbffi_blocking_call_t, 1);
408
395
  bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
409
396
  bc->stkretval = retval;
410
397
  #endif
411
- bc->info = fnInfo;
398
+ bc->cif = fnInfo->ffi_cif;
412
399
  bc->function = function;
413
400
  bc->ffiValues = ffiValues;
414
401
  bc->params = params;
@@ -419,11 +406,11 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
419
406
  fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
420
407
 
421
408
  rbffi_frame_push(&frame);
422
- rb_rescue2(do_blocking_call, (VALUE) bc, save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
409
+ rb_rescue2(rbffi_do_blocking_call, (VALUE) bc, rbffi_save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
423
410
  rbffi_frame_pop(&frame);
424
411
 
425
412
  #if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
426
- memcpy(bc->stkretval, bc->retval, MAX(bc->info->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
413
+ memcpy(bc->stkretval, bc->retval, MAX(bc->cif.rtype->size, FFI_SIZEOF_ARG));
427
414
  xfree(bc->params);
428
415
  xfree(bc->ffiValues);
429
416
  xfree(bc->retval);
@@ -33,6 +33,8 @@
33
33
  #ifndef RBFFI_CALL_H
34
34
  #define RBFFI_CALL_H
35
35
 
36
+ #include "Thread.h"
37
+
36
38
  #ifdef __cplusplus
37
39
  extern "C" {
38
40
  #endif
@@ -85,6 +87,21 @@ Invoker rbffi_GetInvoker(struct FunctionType_* fnInfo);
85
87
  extern VALUE rbffi_GetEnumValue(VALUE enums, VALUE value);
86
88
  extern int rbffi_GetSignedIntValue(VALUE value, int type, int minValue, int maxValue, const char* typeName, VALUE enums);
87
89
 
90
+ typedef struct rbffi_blocking_call {
91
+ rbffi_frame_t* frame;
92
+ void* function;
93
+ ffi_cif cif;
94
+ void **ffiValues;
95
+ void* retval;
96
+ void* params;
97
+ #if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
98
+ void* stkretval;
99
+ #endif
100
+ } rbffi_blocking_call_t;
101
+
102
+ VALUE rbffi_do_blocking_call(void* data);
103
+ VALUE rbffi_save_frame_exception(void *data, VALUE exc);
104
+
88
105
  #ifdef __cplusplus
89
106
  }
90
107
  #endif
@@ -202,7 +202,7 @@ function_free(Function *fn)
202
202
  static VALUE
203
203
  function_initialize(int argc, VALUE* argv, VALUE self)
204
204
  {
205
-
205
+
206
206
  VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
207
207
  VALUE rbFunctionInfo = Qnil;
208
208
  VALUE infoArgv[3];
@@ -229,14 +229,14 @@ function_initialize(int argc, VALUE* argv, VALUE self)
229
229
  * Function.new(:int, [ :int ], addr, { :convention => :stdcall })
230
230
  */
231
231
  }
232
-
232
+
233
233
  infoArgv[0] = rbReturnType;
234
234
  infoArgv[1] = rbParamTypes;
235
235
  infoArgv[2] = rbOptions;
236
236
  rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
237
237
 
238
238
  function_init(self, rbFunctionInfo, rbProc);
239
-
239
+
240
240
  return self;
241
241
  }
242
242
 
@@ -272,12 +272,12 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
272
272
  return cbref;
273
273
  }
274
274
  }
275
-
275
+
276
276
  cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
277
277
  if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
278
278
  return callback;
279
279
  }
280
-
280
+
281
281
  /* No existing function for the proc with that signature, create a new one and cache it */
282
282
  callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
283
283
  if (cbref == Qnil) {
@@ -297,7 +297,7 @@ static VALUE
297
297
  function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
298
298
  {
299
299
  Function* fn = NULL;
300
-
300
+
301
301
  Data_Get_Struct(self, Function, fn);
302
302
 
303
303
  fn->rbFunctionInfo = rbFunctionInfo;
@@ -342,7 +342,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
342
342
  rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
343
343
  rb_obj_classname(rbProc));
344
344
  }
345
-
345
+
346
346
  fn->rbProc = rbProc;
347
347
 
348
348
  return self;
@@ -402,7 +402,7 @@ function_attach(VALUE self, VALUE module, VALUE name)
402
402
  rb_define_singleton_method(module, StringValueCStr(name),
403
403
  rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
404
404
 
405
-
405
+
406
406
  rb_define_method(module, StringValueCStr(name),
407
407
  rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
408
408
 
@@ -452,10 +452,10 @@ function_release(VALUE self)
452
452
  if (fn->closure == NULL) {
453
453
  rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
454
454
  }
455
-
455
+
456
456
  rbffi_Closure_Free(fn->closure);
457
457
  fn->closure = NULL;
458
-
458
+
459
459
  return self;
460
460
  }
461
461
 
@@ -463,13 +463,13 @@ static void
463
463
  callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
464
464
  {
465
465
  struct gvl_callback cb = { 0 };
466
-
466
+
467
467
  cb.closure = (Closure *) user_data;
468
468
  cb.retval = retval;
469
469
  cb.parameters = parameters;
470
470
  cb.done = false;
471
471
  cb.frame = rbffi_frame_current();
472
-
472
+
473
473
  if (cb.frame != NULL) cb.frame->exc = Qnil;
474
474
  if (cb.frame != NULL && cb.frame->has_gvl) {
475
475
  callback_with_gvl(&cb);
@@ -651,14 +651,14 @@ async_cb_wait(void *data)
651
651
  WaitForSingleObject(async_cb_cond, INFINITE);
652
652
  EnterCriticalSection(&async_cb_lock);
653
653
  }
654
-
654
+
655
655
  if (async_cb_list != NULL) {
656
656
  w->cb = async_cb_list;
657
657
  async_cb_list = async_cb_list->next;
658
658
  }
659
659
 
660
660
  LeaveCriticalSection(&async_cb_lock);
661
-
661
+
662
662
  return Qnil;
663
663
  }
664
664
 
@@ -686,14 +686,14 @@ async_cb_wait(void *data)
686
686
  while (!w->stop && async_cb_list == NULL) {
687
687
  pthread_cond_wait(&async_cb_cond, &async_cb_mutex);
688
688
  }
689
-
689
+
690
690
  if (async_cb_list != NULL) {
691
691
  w->cb = async_cb_list;
692
692
  async_cb_list = async_cb_list->next;
693
693
  }
694
694
 
695
695
  pthread_mutex_unlock(&async_cb_mutex);
696
-
696
+
697
697
  return Qnil;
698
698
  }
699
699
 
@@ -713,9 +713,9 @@ static VALUE
713
713
  async_cb_call(void *data)
714
714
  {
715
715
  struct gvl_callback* cb = (struct gvl_callback *) data;
716
-
716
+
717
717
  callback_with_gvl(data);
718
-
718
+
719
719
  /* Signal the original native thread that the ruby code has completed */
720
720
  #ifdef _WIN32
721
721
  SetEvent(cb->async_event);
@@ -835,8 +835,7 @@ invoke_callback(void* data)
835
835
  }
836
836
 
837
837
  rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
838
- RB_GC_GUARD_PTR(rbParams);
839
-
838
+
840
839
  if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
841
840
  VALUE values[] = { rbReturnValue, Qnil };
842
841
  rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
@@ -915,7 +914,7 @@ invoke_callback(void* data)
915
914
  } else {
916
915
  memset(retval, 0, returnType->ffiType->size);
917
916
  }
918
-
917
+
919
918
  } else {
920
919
  memset(retval, 0, returnType->ffiType->size);
921
920
  }
@@ -929,14 +928,14 @@ invoke_callback(void* data)
929
928
  return Qnil;
930
929
  }
931
930
 
932
- static VALUE
931
+ static VALUE
933
932
  save_callback_exception(void* data, VALUE exc)
934
933
  {
935
934
  struct gvl_callback* cb = (struct gvl_callback *) data;
936
-
935
+
937
936
  memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
938
937
  if (cb->frame != NULL) cb->frame->exc = exc;
939
-
938
+
940
939
  return Qnil;
941
940
  }
942
941
 
@@ -963,7 +962,7 @@ rbffi_Function_Init(VALUE moduleFFI)
963
962
  * Document-class: FFI::Function < FFI::Pointer
964
963
  */
965
964
  rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
966
-
965
+
967
966
  rb_global_variable(&rbffi_FunctionClass);
968
967
  rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
969
968
 
@@ -997,4 +996,3 @@ rbffi_Function_Init(VALUE moduleFFI)
997
996
  async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
998
997
  #endif
999
998
  }
1000
-
@@ -228,9 +228,8 @@ custom_trampoline(int argc, VALUE* argv, VALUE self, Closure* handle)
228
228
  {
229
229
  FunctionType* fnInfo = (FunctionType *) handle->info;
230
230
  VALUE rbReturnValue;
231
-
231
+
232
232
  RB_GC_GUARD(rbReturnValue) = (*fnInfo->invoke)(argc, argv, handle->function, fnInfo);
233
- RB_GC_GUARD_PTR(argv);
234
233
  RB_GC_GUARD(self);
235
234
 
236
235
  return rbReturnValue;
@@ -243,10 +242,10 @@ static VALUE custom_trampoline(caddr_t args, Closure*);
243
242
  #define TRAMPOLINE_FUN_MAGIC (0xbeefcafe)
244
243
 
245
244
  /*
246
- * This is a hand-coded trampoline to speedup entry from ruby to the FFI translation
245
+ * This is a hand-coded trampoline to speed-up entry from ruby to the FFI translation
247
246
  * layer for i386 arches.
248
247
  *
249
- * This does not make a discernable difference vs a raw closure, so for now,
248
+ * This does not make a discernible difference vs a raw closure, so for now,
250
249
  * it is not enabled.
251
250
  */
252
251
  __asm__(
@@ -357,4 +356,3 @@ rbffi_MethodHandle_Init(VALUE module)
357
356
 
358
357
  #endif
359
358
  }
360
-
@@ -89,7 +89,7 @@ ptr_allocate(VALUE klass)
89
89
  * @overload initialize(type, address)
90
90
  * @param [Type] type type for pointer
91
91
  * @param [Integer] address base address for pointer
92
- * Create a new pointer from a {Type} and a base adresse
92
+ * Create a new pointer from a {Type} and a base address
93
93
  * @return [self]
94
94
  * A new instance of Pointer.
95
95
  */
@@ -146,11 +146,11 @@ ptr_initialize(int argc, VALUE* argv, VALUE self)
146
146
  * call-seq: ptr.initialize_copy(other)
147
147
  * @param [Pointer] other source for cloning or dupping
148
148
  * @return [self]
149
- * @raise {RuntimeError} if +other+ is an unbounded memory area, or is unreable/unwritable
149
+ * @raise {RuntimeError} if +other+ is an unbounded memory area, or is unreadable/unwritable
150
150
  * @raise {NoMemError} if failed to allocate memory for new object
151
151
  * DO NOT CALL THIS METHOD.
152
152
  *
153
- * This method is internally used by #dup and #clone. Memory contents is copied from +other+.
153
+ * This method is internally used by #dup and #clone. Memory content is copied from +other+.
154
154
  */
155
155
  static VALUE
156
156
  ptr_initialize_copy(VALUE self, VALUE other)