ffi 1.2.0.dev → 1.2.0.dev2

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.

data/Rakefile CHANGED
@@ -72,7 +72,7 @@ LIBTEST = "build/libtest.#{LIBEXT}"
72
72
  BUILD_DIR = "build"
73
73
  BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
74
74
 
75
- gem_spec = eval(IO.read('ffi.gemspec'))
75
+ gem_spec = Gem::Specification.load('ffi.gemspec')
76
76
 
77
77
  Gem::PackageTask.new(gem_spec) do |pkg|
78
78
  pkg.need_zip = true
@@ -431,11 +431,6 @@ memory_put_string(VALUE self, VALUE offset, VALUE str)
431
431
 
432
432
  checkWrite(ptr);
433
433
  checkBounds(ptr, off, len + 1);
434
-
435
- if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
436
- rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
437
- return Qnil;
438
- }
439
434
 
440
435
  memcpy(ptr->address + off, RSTRING_PTR(str), len);
441
436
  *((char *) ptr->address + off + len) = '\0';
@@ -651,25 +646,24 @@ memory_op_put_strptr(AbstractMemory* ptr, long offset, VALUE value)
651
646
 
652
647
  static MemoryOp memory_op_strptr = { memory_op_get_strptr, memory_op_put_strptr };
653
648
 
654
- //static MemoryOp memory_op_pointer = { memory_op_get_pointer, memory_op_put_pointer };
655
649
 
656
650
  MemoryOps rbffi_AbstractMemoryOps = {
657
- &memory_op_int8, //.int8
658
- &memory_op_uint8, //.uint8
659
- &memory_op_int16, //.int16
660
- &memory_op_uint16, //.uint16
661
- &memory_op_int32, //.int32
662
- &memory_op_uint32, //.uint32
663
- &memory_op_int64, //.int64
664
- &memory_op_uint64, //.uint64
665
- &memory_op_long, //.slong
666
- &memory_op_ulong, //.uslong
667
- &memory_op_float32, //.float32
668
- &memory_op_float64, //.float64
669
- &memory_op_longdouble, //.longdouble
670
- &memory_op_pointer, //.pointer
671
- &memory_op_strptr, //.strptr
672
- &memory_op_bool //.boolOp
651
+ &memory_op_int8, /*.int8 */
652
+ &memory_op_uint8, /* .uint8 */
653
+ &memory_op_int16, /* .int16 */
654
+ &memory_op_uint16, /* .uint16 */
655
+ &memory_op_int32, /* .int32 */
656
+ &memory_op_uint32, /* .uint32 */
657
+ &memory_op_int64, /* .int64 */
658
+ &memory_op_uint64, /* .uint64 */
659
+ &memory_op_long, /* .slong */
660
+ &memory_op_ulong, /* .uslong */
661
+ &memory_op_float32, /* .float32 */
662
+ &memory_op_float64, /* .float64 */
663
+ &memory_op_longdouble, /* .longdouble */
664
+ &memory_op_pointer, /* .pointer */
665
+ &memory_op_strptr, /* .strptr */
666
+ &memory_op_bool /* .boolOp */
673
667
  };
674
668
 
675
669
  void
@@ -70,7 +70,7 @@ typedef struct {
70
70
  } MemoryOps;
71
71
 
72
72
  struct AbstractMemory_ {
73
- char* address; // Use char* instead of void* to ensure adding to it works correctly
73
+ char* address; /* Use char* instead of void* to ensure adding to it works correctly */
74
74
  long size;
75
75
  int flags;
76
76
  int typeSize;
@@ -41,7 +41,7 @@ typedef struct Buffer {
41
41
  union {
42
42
  VALUE rbParent; /* link to parent buffer */
43
43
  char* storage; /* start of malloc area */
44
- long embed[BUFFER_EMBED_MAXLEN / sizeof(long)]; // storage for tiny allocations
44
+ long embed[BUFFER_EMBED_MAXLEN / sizeof(long)]; /* storage for tiny allocations */
45
45
  } data;
46
46
  } Buffer;
47
47
 
@@ -151,7 +151,7 @@ buffer_initialize_copy(VALUE self, VALUE other)
151
151
  dst->memory.size = src->size;
152
152
  dst->memory.typeSize = src->typeSize;
153
153
 
154
- // finally, copy the actual buffer contents
154
+ /* finally, copy the actual buffer contents */
155
155
  memcpy(dst->memory.address, src->address, src->size);
156
156
 
157
157
  return self;
@@ -314,8 +314,10 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
314
314
  if (unlikely(fnInfo->blocking)) {
315
315
  BlockingCall* bc;
316
316
 
317
- // due to the way thread switching works on older ruby variants, we
318
- // cannot allocate anything passed to the blocking function on the stack
317
+ /*
318
+ * due to the way thread switching works on older ruby variants, we
319
+ * cannot allocate anything passed to the blocking function on the stack
320
+ */
319
321
  ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
320
322
  params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
321
323
  bc = ALLOC_N(BlockingCall, 1);
@@ -375,10 +377,7 @@ getPointer(VALUE value, int type)
375
377
  return memory != NULL ? memory->address : NULL;
376
378
 
377
379
  } else if (type == T_STRING) {
378
-
379
- if (rb_safe_level() >= 1 && OBJ_TAINTED(value)) {
380
- rb_raise(rb_eSecurityError, "Unsafe string parameter");
381
- }
380
+
382
381
  return StringValuePtr(value);
383
382
 
384
383
  } else if (type == T_NIL) {
@@ -432,14 +431,13 @@ callback_param(VALUE proc, VALUE cbInfo)
432
431
  return NULL ;
433
432
  }
434
433
 
435
- // Handle Function pointers here
434
+ /* Handle Function pointers here */
436
435
  if (rb_obj_is_kind_of(proc, rbffi_FunctionClass)) {
437
436
  AbstractMemory* ptr;
438
437
  Data_Get_Struct(proc, AbstractMemory, ptr);
439
438
  return ptr->address;
440
439
  }
441
440
 
442
- //callback = rbffi_NativeCallback_ForProc(proc, cbInfo);
443
441
  callback = rbffi_Function_ForProc(cbInfo, proc);
444
442
  RB_GC_GUARD(callback);
445
443
 
@@ -206,7 +206,7 @@ rbffi_Closure_Free(Closure* closure)
206
206
  if (closure != NULL) {
207
207
  ClosurePool* pool = closure->pool;
208
208
  long refcnt;
209
- // Just push it on the front of the free list
209
+ /* Just push it on the front of the free list */
210
210
  closure->next = pool->list;
211
211
  pool->list = closure;
212
212
  refcnt = --(pool->refcnt);
@@ -155,7 +155,7 @@ library_dlerror(VALUE self)
155
155
  static void
156
156
  library_free(Library* library)
157
157
  {
158
- // dlclose() on MacOS tends to segfault - avoid it
158
+ /* dlclose() on MacOS tends to segfault - avoid it */
159
159
  #ifndef __APPLE__
160
160
  if (library->handle != NULL) {
161
161
  dl_close(library->handle);
@@ -270,7 +270,7 @@ rbffi_DynamicLibrary_Init(VALUE moduleFFI)
270
270
  * Document-const: FFI::NativeLibrary
271
271
  * Backward compatibility for FFI::DynamicLibrary
272
272
  */
273
- rb_define_const(moduleFFI, "NativeLibrary", LibraryClass); // backwards compat library
273
+ rb_define_const(moduleFFI, "NativeLibrary", LibraryClass); /* backwards compat library */
274
274
  rb_define_alloc_func(LibraryClass, library_allocate);
275
275
  rb_define_singleton_method(LibraryClass, "open", library_open, 2);
276
276
  rb_define_singleton_method(LibraryClass, "last_error", library_dlerror, 0);
@@ -199,11 +199,11 @@ function_initialize(int argc, VALUE* argv, VALUE self)
199
199
 
200
200
  nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);
201
201
 
202
- //
203
- // Callback with block,
204
- // e.g. Function.new(:int, [ :int ]) { |i| blah }
205
- // or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
206
- //
202
+ /*
203
+ * Callback with block,
204
+ * e.g. Function.new(:int, [ :int ]) { |i| blah }
205
+ * or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
206
+ */
207
207
  if (rb_block_given_p()) {
208
208
  if (nargs > 3) {
209
209
  rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
@@ -211,11 +211,12 @@ function_initialize(int argc, VALUE* argv, VALUE self)
211
211
  rbOptions = rbProc;
212
212
  rbProc = rb_block_proc();
213
213
  } else {
214
- // Callback with proc, or Function with address
215
- // e.g. Function.new(:int, [ :int ], Proc.new { |i| })
216
- // Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
217
- // Function.new(:int, [ :int ], addr)
218
- // Function.new(:int, [ :int ], addr, { :convention => :stdcall })
214
+ /* Callback with proc, or Function with address
215
+ * e.g. Function.new(:int, [ :int ], Proc.new { |i| })
216
+ * Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
217
+ * Function.new(:int, [ :int ], addr)
218
+ * Function.new(:int, [ :int ], addr, { :convention => :stdcall })
219
+ */
219
220
  }
220
221
 
221
222
  infoArgv[0] = rbReturnType;
@@ -381,9 +382,9 @@ function_attach(VALUE self, VALUE module, VALUE name)
381
382
  fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
382
383
  }
383
384
 
384
- //
385
- // Stash the Function in a module variable so it does not get garbage collected
386
- //
385
+ /*
386
+ * Stash the Function in a module variable so it does not get garbage collected
387
+ */
387
388
  snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
388
389
  rb_cv_set(module, var, self);
389
390
 
@@ -470,7 +471,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
470
471
  pthread_mutex_init(&cb.async_mutex, NULL);
471
472
  pthread_cond_init(&cb.async_cond, NULL);
472
473
 
473
- // Now signal the async callback thread
474
+ /* Now signal the async callback thread */
474
475
  pthread_mutex_lock(&async_cb_mutex);
475
476
  empty = async_cb_list == NULL;
476
477
  cb.next = async_cb_list;
@@ -478,7 +479,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
478
479
  pthread_mutex_unlock(&async_cb_mutex);
479
480
 
480
481
  #if !defined(HAVE_RB_THREAD_BLOCKING_REGION)
481
- // Only signal if the list was empty
482
+ /* Only signal if the list was empty */
482
483
  if (empty) {
483
484
  char c;
484
485
  write(async_cb_pipe[1], &c, 1);
@@ -487,7 +488,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
487
488
  pthread_cond_signal(&async_cb_cond);
488
489
  #endif
489
490
 
490
- // Wait for the thread executing the ruby callback to signal it is done
491
+ /* Wait for the thread executing the ruby callback to signal it is done */
491
492
  pthread_mutex_lock(&cb.async_mutex);
492
493
  while (!cb.done) {
493
494
  pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
@@ -502,7 +503,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
502
503
 
503
504
  cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
504
505
 
505
- // Now signal the async callback thread
506
+ /* Now signal the async callback thread */
506
507
  EnterCriticalSection(&async_cb_lock);
507
508
  empty = async_cb_list == NULL;
508
509
  cb.next = async_cb_list;
@@ -510,7 +511,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
510
511
  LeaveCriticalSection(&async_cb_lock);
511
512
 
512
513
  #if !defined(HAVE_RB_THREAD_BLOCKING_REGION)
513
- // Only signal if the list was empty
514
+ /* Only signal if the list was empty */
514
515
  if (empty) {
515
516
  char c;
516
517
  write(async_cb_pipe[1], &c, 1);
@@ -519,7 +520,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
519
520
  SetEvent(async_cb_cond);
520
521
  #endif
521
522
 
522
- // Wait for the thread executing the ruby callback to signal it is done
523
+ /* Wait for the thread executing the ruby callback to signal it is done */
523
524
  WaitForSingleObject(cb.async_event, INFINITE);
524
525
  CloseHandle(cb.async_event);
525
526
  #endif
@@ -545,7 +546,7 @@ async_cb_event(void* unused)
545
546
  while (!w.stop) {
546
547
  rb_thread_blocking_region(async_cb_wait, &w, async_cb_stop, &w);
547
548
  if (w.cb != NULL) {
548
- // Start up a new ruby thread to run the ruby callback
549
+ /* Start up a new ruby thread to run the ruby callback */
549
550
  rb_thread_create(async_cb_call, w.cb);
550
551
  }
551
552
  }
@@ -574,7 +575,7 @@ async_cb_event(void* unused)
574
575
 
575
576
  while (cb != NULL) {
576
577
  struct gvl_callback* next = cb->next;
577
- // Start up a new ruby thread to run the ruby callback
578
+ /* Start up a new ruby thread to run the ruby callback */
578
579
  rb_thread_create(async_cb_call, cb);
579
580
  cb = next;
580
581
  }
@@ -606,7 +607,7 @@ async_cb_event(void* unused)
606
607
 
607
608
  while (cb != NULL) {
608
609
  struct gvl_callback* next = cb->next;
609
- // Start up a new ruby thread to run the ruby callback
610
+ /* Start up a new ruby thread to run the ruby callback */
610
611
  rb_thread_create(async_cb_call, cb);
611
612
  cb = next;
612
613
  }
@@ -696,7 +697,7 @@ async_cb_call(void *data)
696
697
 
697
698
  callback_with_gvl(cb);
698
699
 
699
- // Signal the original native thread that the ruby code has completed
700
+ /* Signal the original native thread that the ruby code has completed */
700
701
  #ifdef _WIN32
701
702
  SetEvent(cb->async_event);
702
703
  #else
@@ -799,7 +800,7 @@ callback_with_gvl(void* data)
799
800
  break;
800
801
  }
801
802
 
802
- // Convert the native value into a custom ruby value
803
+ /* Convert the native value into a custom ruby value */
803
804
  if (unlikely(cbInfo->parameterTypes[i]->nativeType == NATIVE_MAPPED)) {
804
805
  VALUE values[] = { param, Qnil };
805
806
  param = rb_funcall2(((MappedType *) cbInfo->parameterTypes[i])->rbConverter, id_from_native, 2, values);
@@ -853,7 +854,7 @@ callback_with_gvl(void* data)
853
854
  if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
854
855
  *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
855
856
  } else {
856
- // Default to returning NULL if not a value pointer object. handles nil case as well
857
+ /* Default to returning NULL if not a value pointer object. handles nil case as well */
857
858
  *((void **) retval) = NULL;
858
859
  }
859
860
  break;
@@ -41,7 +41,7 @@ typedef struct FunctionType_ FunctionType;
41
41
  #include "ClosurePool.h"
42
42
 
43
43
  struct FunctionType_ {
44
- Type type; // The native type of a FunctionInfo object
44
+ Type type; /* The native type of a FunctionInfo object */
45
45
  VALUE rbReturnType;
46
46
  VALUE rbParameterTypes;
47
47
 
@@ -144,8 +144,9 @@ memptr_mark(Pointer* ptr)
144
144
  }
145
145
 
146
146
  static VALUE
147
- memptr_s_from_string(VALUE klass, VALUE s)
147
+ memptr_s_from_string(VALUE klass, VALUE to_str)
148
148
  {
149
+ VALUE s = StringValue(to_str);
149
150
  VALUE args[] = { INT2FIX(1), LONG2NUM(RSTRING_LEN(s) + 1), Qfalse };
150
151
  VALUE obj = rb_class_new_instance(3, args, klass);
151
152
  rb_funcall(obj, rb_intern("put_string"), 2, INT2FIX(0), s);
@@ -311,7 +311,7 @@ prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t er
311
311
  caddr_t ptr = (caddr_t) code;
312
312
 
313
313
  memcpy(ptr, &ffi_trampoline, trampoline_size());
314
- // Patch the context and function addresses into the stub code
314
+ /* Patch the context and function addresses into the stub code */
315
315
  *(intptr_t *)(ptr + trampoline_ctx_offset) = (intptr_t) closure;
316
316
  *(intptr_t *)(ptr + trampoline_func_offset) = (intptr_t) custom_trampoline;
317
317
 
@@ -181,7 +181,7 @@ ptr_initialize_copy(VALUE self, VALUE other)
181
181
  dst->memory.size = src->size;
182
182
  dst->memory.typeSize = src->typeSize;
183
183
 
184
- // finally, copy the actual memory contents
184
+ /* finally, copy the actual memory contents */
185
185
  memcpy(dst->memory.address, src->address, src->size);
186
186
 
187
187
  return self;
@@ -139,11 +139,11 @@ struct_initialize_copy(VALUE self, VALUE other)
139
139
  dst->rbLayout = src->rbLayout;
140
140
  dst->layout = src->layout;
141
141
 
142
- //
143
- // A new MemoryPointer instance is allocated here instead of just calling
144
- // #dup on rbPointer, since the Pointer may not know its length, or may
145
- // be longer than just this struct.
146
- //
142
+ /*
143
+ * A new MemoryPointer instance is allocated here instead of just calling
144
+ * #dup on rbPointer, since the Pointer may not know its length, or may
145
+ * be longer than just this struct.
146
+ */
147
147
  if (src->pointer->address != NULL) {
148
148
  dst->rbPointer = rbffi_MemoryPointer_NewInstance(1, src->layout->size, false);
149
149
  dst->pointer = MEMORY(dst->rbPointer);
@@ -87,7 +87,7 @@ sbv_initialize(VALUE self, VALUE rbStructClass)
87
87
  sbv->rbStructClass = rbStructClass;
88
88
  sbv->rbStructLayout = rbLayout;
89
89
 
90
- // We can just use everything from the ffi_type directly
90
+ /* We can just use everything from the ffi_type directly */
91
91
  *sbv->base.ffiType = *layout->base.ffiType;
92
92
 
93
93
  return self;
@@ -281,7 +281,7 @@ array_field_put(VALUE self, VALUE pointer, VALUE value)
281
281
  rb_raise(rb_eIndexError, "array too large");
282
282
  }
283
283
 
284
- // clear the contents in case of a short write
284
+ /* clear the contents in case of a short write */
285
285
  checkWrite(memory);
286
286
  checkBounds(memory, f->offset, f->type->ffiType->size);
287
287
  if (count < array->length) {
@@ -289,7 +289,7 @@ array_field_put(VALUE self, VALUE pointer, VALUE value)
289
289
  0, (array->length - count) * array->componentType->ffiType->size);
290
290
  }
291
291
 
292
- // now copy each element in
292
+ /* now copy each element in */
293
293
  if ((op = get_memory_op(array->componentType)) != NULL) {
294
294
 
295
295
  for (i = 0; i < count; ++i) {
@@ -357,7 +357,7 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
357
357
  layout->fieldCount = (int) RARRAY_LEN(fields);
358
358
  layout->rbFieldMap = rb_hash_new();
359
359
  layout->rbFieldNames = rb_ary_new2(layout->fieldCount);
360
- layout->size = FFI_ALIGN(NUM2INT(size), NUM2INT(align));
360
+ layout->size = (int) FFI_ALIGN(NUM2INT(size), NUM2INT(align));
361
361
  layout->align = NUM2INT(align);
362
362
  layout->fields = xcalloc(layout->fieldCount, sizeof(StructField *));
363
363
  layout->ffiTypes = xcalloc(layout->fieldCount + 1, sizeof(ffi_type *));
@@ -423,7 +423,7 @@ struct_layout_union_bang(VALUE self)
423
423
 
424
424
  for (i = 0; alignment_types[i] != NULL; ++i) {
425
425
  if (alignment_types[i]->alignment == layout->align) {
426
- t = alignment_types[i];
426
+ t = (ffi_type *) alignment_types[i];
427
427
  break;
428
428
  }
429
429
  }
@@ -432,7 +432,7 @@ struct_layout_union_bang(VALUE self)
432
432
  return Qnil;
433
433
  }
434
434
 
435
- count = layout->size / t->size;
435
+ count = (int) layout->size / t->size;
436
436
  xfree(layout->ffiTypes);
437
437
  layout->ffiTypes = xcalloc(count + 1, sizeof(ffi_type *));
438
438
  layout->base.ffiType->elements = layout->ffiTypes;
@@ -76,7 +76,7 @@ rbffi_thread_has_gvl_p(void)
76
76
  return rbffi_active_thread.valid && pthread_equal(rbffi_active_thread.id, pthread_self());
77
77
  #endif
78
78
  }
79
- #endif // HAVE_RUBY_THREAD_HAS_GVL_P
79
+ #endif /* HAVE_RUBY_THREAD_HAS_GVL_P */
80
80
 
81
81
  #ifndef HAVE_RB_THREAD_BLOCKING_REGION
82
82
 
@@ -322,5 +322,5 @@ rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(voi
322
322
 
323
323
  #endif /* !_WIN32 */
324
324
 
325
- #endif // HAVE_RB_THREAD_BLOCKING_REGION
325
+ #endif /* HAVE_RB_THREAD_BLOCKING_REGION */
326
326
 
@@ -193,7 +193,7 @@ rbffi_type_size(VALUE type)
193
193
  }
194
194
  }
195
195
 
196
- // Not found - call up to the ruby version to resolve
196
+ /* Not found - call up to the ruby version to resolve */
197
197
  return NUM2INT(rb_funcall2(rbffi_FFIModule, id_type_size, 1, &type));
198
198
 
199
199
  } else {
@@ -321,14 +321,14 @@ rbffi_Type_Init(VALUE moduleFFI)
321
321
  rb_define_method(rbffi_TypeClass, "alignment", type_alignment, 0);
322
322
  rb_define_method(rbffi_TypeClass, "inspect", type_inspect, 0);
323
323
 
324
- // Make Type::Builtin non-allocatable
324
+ /* Make Type::Builtin non-allocatable */
325
325
  rb_undef_method(CLASS_OF(classBuiltinType), "new");
326
326
  rb_define_method(classBuiltinType, "inspect", builtin_type_inspect, 0);
327
327
 
328
328
  rb_global_variable(&rbffi_TypeClass);
329
329
  rb_global_variable(&classBuiltinType);
330
330
 
331
- // Define all the builtin types
331
+ /* Define all the builtin types */
332
332
  #define T(x, ffiType) do { \
333
333
  VALUE t = Qnil; \
334
334
  rb_define_const(rbffi_TypeClass, #x, t = builtin_type_new(classBuiltinType, NATIVE_##x, ffiType, #x)); \
@@ -98,8 +98,10 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr)
98
98
  }
99
99
 
100
100
  case NATIVE_MAPPED: {
101
- // For mapped types, first convert to the real native type, then upcall to
102
- // ruby to convert to the expected return type
101
+ /*
102
+ * For mapped types, first convert to the real native type, then upcall to
103
+ * ruby to convert to the expected return type
104
+ */
103
105
  MappedType* m = (MappedType *) type;
104
106
  VALUE values[2], rbReturnValue;
105
107
 
@@ -69,10 +69,6 @@ typedef enum {
69
69
  #include <ffi.h>
70
70
  #include "Type.h"
71
71
 
72
- #ifndef FFI_STDCALL
73
- #define FFI_STDCALL FFI_DEFAULT_ABI
74
- #endif
75
-
76
72
  VALUE rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr);
77
73
  void rbffi_Types_Init(VALUE moduleFFI);
78
74
 
@@ -219,7 +219,11 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
219
219
  if (ffiReturnType == NULL) {
220
220
  rb_raise(rb_eArgError, "Invalid return type");
221
221
  }
222
+ #ifdef HAVE_FFI_PREP_CIF_VAR
223
+ ffiStatus = ffi_prep_cif_var(&cif, invoker->abi, paramCount, paramCount, ffiReturnType, ffiParamTypes);
224
+ #else
222
225
  ffiStatus = ffi_prep_cif(&cif, invoker->abi, paramCount, ffiReturnType, ffiParamTypes);
226
+ #endif
223
227
  switch (ffiStatus) {
224
228
  case FFI_BAD_ABI:
225
229
  rb_raise(rb_eArgError, "Invalid ABI specified");
@@ -21,6 +21,7 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
21
21
  have_func('rb_thread_blocking_region')
22
22
  have_func('ruby_native_thread_p')
23
23
  have_func('rb_thread_call_with_gvl')
24
+ have_func('ffi_prep_cif_var')
24
25
 
25
26
  $defs << "-DHAVE_EXTCONF_H" if $defs.empty? # needed so create_header works
26
27
  $defs << "-DUSE_INTERNAL_LIBFFI" unless libffi_ok
@@ -59,7 +59,7 @@ Init_ffi_c(void) {
59
59
  rb_global_variable(&moduleFFI);
60
60
 
61
61
 
62
- // FFI::Type needs to be initialized before most other classes
62
+ /* FFI::Type needs to be initialized before most other classes */
63
63
  rbffi_Type_Init(moduleFFI);
64
64
 
65
65
  rbffi_DataConverter_Init(moduleFFI);
@@ -25,7 +25,7 @@ ifeq ($(strip $(ARCHES)),)
25
25
  LIBFFI_BUILD_DIR = $(BUILD_DIR)/libffi-$(arch)
26
26
  # Just build the one (default) architecture
27
27
  $(LIBFFI):
28
- @mkdir -p "$(LIBFFI_BUILD_DIR)"
28
+ @mkdir -p "$(LIBFFI_BUILD_DIR)" "$(@D)"
29
29
  @if [ ! -f "$(LIBFFI_BUILD_DIR)"/Makefile ]; then \
30
30
  echo "Configuring libffi"; \
31
31
  cd "$(LIBFFI_BUILD_DIR)" && \
@@ -66,7 +66,7 @@ endif
66
66
 
67
67
  $(LIBFFI): $(LIBTARGETS)
68
68
  # Assemble into a FAT (x86_64, i386, ppc) library
69
- @mkdir -p "$(BUILD_DIR)"/libffi/.libs
69
+ @mkdir -p "$(@D)"
70
70
  /usr/bin/libtool -static -o $@ \
71
71
  $(foreach arch, $(ARCHES),"$(BUILD_DIR)"/libffi-$(arch)/.libs/libffi_convenience.a)
72
72
  @mkdir -p "$(LIBFFI_BUILD_DIR)"/include
@@ -3,7 +3,7 @@
3
3
  include ${srcdir}/libffi.gnu.mk
4
4
 
5
5
  $(LIBFFI):
6
- @mkdir -p "$(LIBFFI_BUILD_DIR)"
6
+ @mkdir -p "$(LIBFFI_BUILD_DIR)" "$@(D)"
7
7
  @if [ ! -f "$(LIBFFI_BUILD_DIR)"/Makefile ]; then \
8
8
  echo "Configuring libffi"; \
9
9
  cd "$(LIBFFI_BUILD_DIR)" && \
data/gen/log ADDED
@@ -0,0 +1 @@
1
+ /Users/wayne/src/ruby-ffi/lib/ffi/platform/x86_64-darwin/types.conf
@@ -16,6 +16,10 @@ describe "MemoryPointer" do
16
16
  m.type_size.should eq 1
17
17
  end
18
18
 
19
+ it "does not make a pointer from non-strings" do
20
+ expect { FFI::MemoryPointer.from_string(nil) }.to raise_error(TypeError)
21
+ end
22
+
19
23
  it "makes a pointer from a string with multibyte characters" do
20
24
  m = FFI::MemoryPointer.from_string("ぱんだ")
21
25
  m.total.should eq 10
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi
3
3
  version: !ruby/object:Gem::Version
4
- hash: 286533929
4
+ hash: -4076106022
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
9
  - 0
10
10
  - dev
11
- version: 1.2.0.dev
11
+ - 2
12
+ version: 1.2.0.dev2
12
13
  platform: ruby
13
14
  authors:
14
15
  - Wayne Meissner
@@ -16,7 +17,7 @@ autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2012-07-29 00:00:00 +10:00
20
+ date: 2012-08-12 00:00:00 +10:00
20
21
  default_executable:
21
22
  dependencies:
22
23
  - !ruby/object:Gem::Dependency
@@ -49,6 +50,20 @@ dependencies:
49
50
  version: 0.6.0
50
51
  type: :development
51
52
  version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
52
67
  description: Ruby FFI library
53
68
  email: wmeissner@gmail.com
54
69
  executables: []
@@ -389,6 +404,7 @@ files:
389
404
  - ext/ffi_c/Types.h
390
405
  - ext/ffi_c/Variadic.c
391
406
  - ext/ffi_c/win32/stdint.h
407
+ - gen/log
392
408
  - gen/Rakefile
393
409
  - lib/ffi/autopointer.rb
394
410
  - lib/ffi/buffer.rb