ffi 1.0.7 → 1.0.9

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.

Files changed (37) hide show
  1. data/Rakefile +3 -3
  2. data/ext/ffi_c/AbstractMemory.c +40 -3
  3. data/ext/ffi_c/AbstractMemory.h +2 -2
  4. data/ext/ffi_c/Buffer.c +28 -0
  5. data/ext/ffi_c/DynamicLibrary.c +17 -6
  6. data/ext/ffi_c/Function.c +20 -10
  7. data/ext/ffi_c/MemoryPointer.c +17 -27
  8. data/ext/ffi_c/Platform.c +17 -7
  9. data/ext/ffi_c/Pointer.c +103 -12
  10. data/ext/ffi_c/Pointer.h +9 -0
  11. data/ext/ffi_c/Struct.c +43 -1
  12. data/ext/ffi_c/StructLayout.c +2 -1
  13. data/lib/ffi/enum.rb +1 -3
  14. data/lib/ffi/platform.rb +1 -1
  15. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  16. data/lib/ffi/platform/i386-linux/types.conf +100 -0
  17. data/lib/ffi/platform/i386-openbsd/types.conf +126 -0
  18. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  19. data/lib/ffi/platform/i386-windows/types.conf +105 -0
  20. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  21. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  22. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  23. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  24. data/lib/ffi/platform/x86_64-darwin/types.conf +100 -0
  25. data/lib/ffi/platform/x86_64-linux/types.conf +100 -0
  26. data/lib/ffi/platform/x86_64-openbsd/types.conf +126 -0
  27. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  28. data/lib/ffi/struct.rb +1 -1
  29. data/lib/ffi/tools/generator.rb +1 -1
  30. data/lib/ffi/types.rb +2 -1
  31. data/spec/ffi/dup_spec.rb +65 -0
  32. data/spec/ffi/enum_spec.rb +28 -0
  33. data/spec/ffi/strptr_spec.rb +11 -2
  34. data/spec/ffi/struct_spec.rb +2 -2
  35. data/tasks/extension.rake +1 -1
  36. metadata +33 -24
  37. data/lib/ffi_c.bundle +0 -0
data/Rakefile CHANGED
@@ -75,7 +75,7 @@ PROJ.name = 'ffi'
75
75
  PROJ.authors = 'Wayne Meissner'
76
76
  PROJ.email = 'wmeissner@gmail.com'
77
77
  PROJ.url = 'http://wiki.github.com/ffi/ffi'
78
- PROJ.version = '1.0.7'
78
+ PROJ.version = '1.0.9'
79
79
  PROJ.rubyforge.name = 'ffi'
80
80
  PROJ.readme_file = 'README.rdoc'
81
81
 
@@ -93,7 +93,7 @@ PROJ.gem.platform = Gem::Platform::RUBY
93
93
  #PROJ.gem.required_ruby_version = ">= 1.9.2"
94
94
 
95
95
  # Override Mr. Bones autogenerated extensions and force ours in
96
- PROJ.gem.extras['extensions'] = %w(ext/ffi_c/extconf.rb gen/Rakefile)
96
+ PROJ.gem.extras['extensions'] = %w(ext/ffi_c/extconf.rb)
97
97
  #PROJ.gem.extras['required_ruby_version'] = ">= 1.9.2"
98
98
 
99
99
  # RDoc
@@ -110,7 +110,7 @@ PROJ.spec.opts << '--color' << '-fs'
110
110
 
111
111
  # Dependencies
112
112
 
113
- depend_on 'rake', '>=0.8.7'
113
+ #depend_on 'rake', '>=0.8.7'
114
114
 
115
115
  TEST_DEPS = [ LIBTEST ]
116
116
  if RUBY_PLATFORM == "java"
@@ -165,7 +165,7 @@ SWAPU16(uint16_t x)
165
165
  return bswap16(x);
166
166
  }
167
167
 
168
- #if !defined(__GNUC__) || __GNUC__ < 4
168
+ #if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
169
169
  #define bswap32(x) \
170
170
  (((x << 24) & 0xff000000) | \
171
171
  ((x << 8) & 0x00ff0000) | \
@@ -243,7 +243,7 @@ get_pointer_value(VALUE value)
243
243
  } else if (type == T_NIL) {
244
244
  return NULL;
245
245
  } else if (type == T_FIXNUM) {
246
- return (void *) (uintptr_t) FIX2INT(value);
246
+ return (void *) (uintptr_t) FIX2ULONG(value);
247
247
  } else if (type == T_BIGNUM) {
248
248
  return (void *) (uintptr_t) NUM2ULL(value);
249
249
  } else if (rb_respond_to(value, id_to_ptr)) {
@@ -333,6 +333,21 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
333
333
  return retVal;
334
334
  }
335
335
 
336
+ static VALUE
337
+ memory_read_array_of_string(int argc, VALUE* argv, VALUE self)
338
+ {
339
+ VALUE* rargv = ALLOCA_N(VALUE, argc + 1);
340
+ int i;
341
+
342
+ rargv[0] = INT2FIX(0);
343
+ for (i = 0; i < argc; i++) {
344
+ rargv[i + 1] = argv[i];
345
+ }
346
+
347
+ return memory_get_array_of_string(argc + 1, rargv, self);
348
+ }
349
+
350
+
336
351
  static VALUE
337
352
  memory_put_string(VALUE self, VALUE offset, VALUE str)
338
353
  {
@@ -406,6 +421,26 @@ memory_put_bytes(int argc, VALUE* argv, VALUE self)
406
421
  return self;
407
422
  }
408
423
 
424
+ static VALUE
425
+ memory_read_bytes(VALUE self, VALUE length)
426
+ {
427
+ return memory_get_bytes(self, INT2FIX(0), length);
428
+ }
429
+
430
+ static VALUE
431
+ memory_write_bytes(int argc, VALUE* argv, VALUE self)
432
+ {
433
+ VALUE* wargv = ALLOCA_N(VALUE, argc + 1);
434
+ int i;
435
+
436
+ wargv[0] = INT2FIX(0);
437
+ for (i = 0; i < argc; i++) {
438
+ wargv[i + 1] = argv[i];
439
+ }
440
+
441
+ return memory_put_bytes(argc + 1, wargv, self);
442
+ }
443
+
409
444
  static VALUE
410
445
  memory_type_size(VALUE self)
411
446
  {
@@ -495,7 +530,7 @@ MemoryOps rbffi_AbstractMemoryOps = {
495
530
  .int64 = &memory_op_int64,
496
531
  .uint64 = &memory_op_uint64,
497
532
  .slong = &memory_op_long,
498
- .ulong = &memory_op_ulong,
533
+ .uslong = &memory_op_ulong,
499
534
  .float32 = &memory_op_float32,
500
535
  .float64 = &memory_op_float64,
501
536
  .pointer = &memory_op_pointer,
@@ -599,6 +634,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
599
634
  rb_define_method(classMemory, "put_string", memory_put_string, 2);
600
635
  rb_define_method(classMemory, "get_bytes", memory_get_bytes, 2);
601
636
  rb_define_method(classMemory, "put_bytes", memory_put_bytes, -1);
637
+ rb_define_method(classMemory, "read_bytes", memory_read_bytes, 1);
638
+ rb_define_method(classMemory, "write_bytes", memory_write_bytes, -1);
602
639
  rb_define_method(classMemory, "get_array_of_string", memory_get_array_of_string, -1);
603
640
 
604
641
  rb_define_method(classMemory, "clear", memory_clear, 0);
@@ -55,7 +55,7 @@ typedef struct {
55
55
  MemoryOp* int64;
56
56
  MemoryOp* uint64;
57
57
  MemoryOp* slong;
58
- MemoryOp* ulong;
58
+ MemoryOp* uslong;
59
59
  MemoryOp* float32;
60
60
  MemoryOp* float64;
61
61
  MemoryOp* pointer;
@@ -127,7 +127,7 @@ get_memory_op(Type* type)
127
127
  case NATIVE_LONG:
128
128
  return rbffi_AbstractMemoryOps.slong;
129
129
  case NATIVE_ULONG:
130
- return rbffi_AbstractMemoryOps.ulong;
130
+ return rbffi_AbstractMemoryOps.uslong;
131
131
  case NATIVE_FLOAT32:
132
132
  return rbffi_AbstractMemoryOps.float32;
133
133
  case NATIVE_FLOAT64:
@@ -97,6 +97,33 @@ buffer_initialize(int argc, VALUE* argv, VALUE self)
97
97
  return self;
98
98
  }
99
99
 
100
+ static VALUE
101
+ buffer_initialize_copy(VALUE self, VALUE other)
102
+ {
103
+ AbstractMemory* src;
104
+ Buffer* dst;
105
+
106
+ Data_Get_Struct(self, Buffer, dst);
107
+ src = rbffi_AbstractMemory_Cast(other, BufferClass);
108
+ if (dst->storage != NULL) {
109
+ xfree(dst->storage);
110
+ }
111
+ dst->storage = xmalloc(src->size + 7);
112
+ if (dst->storage == NULL) {
113
+ rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
114
+ return Qnil;
115
+ }
116
+
117
+ dst->memory.address = (void *) (((uintptr_t) dst->storage + 0x7) & (uintptr_t) ~0x7UL);
118
+ dst->memory.size = src->size;
119
+ dst->memory.typeSize = src->typeSize;
120
+
121
+ // finally, copy the actual buffer contents
122
+ memcpy(dst->memory.address, src->address, src->size);
123
+
124
+ return self;
125
+ }
126
+
100
127
  static VALUE
101
128
  buffer_alloc_inout(int argc, VALUE* argv, VALUE klass)
102
129
  {
@@ -235,6 +262,7 @@ rbffi_Buffer_Init(VALUE moduleFFI)
235
262
  rb_define_alias(rb_singleton_class(BufferClass), "new_inout", "alloc_inout");
236
263
 
237
264
  rb_define_method(BufferClass, "initialize", buffer_initialize, -1);
265
+ rb_define_method(BufferClass, "initialize_copy", buffer_initialize_copy, 1);
238
266
  rb_define_method(BufferClass, "order", buffer_order, -1);
239
267
  rb_define_method(BufferClass, "inspect", buffer_inspect, 0);
240
268
  rb_define_alias(BufferClass, "length", "total");
@@ -37,7 +37,7 @@
37
37
  #include "DynamicLibrary.h"
38
38
 
39
39
  typedef struct LibrarySymbol_ {
40
- AbstractMemory memory;
40
+ Pointer base;
41
41
  VALUE library;
42
42
  VALUE name;
43
43
  } LibrarySymbol;
@@ -163,20 +163,29 @@ symbol_allocate(VALUE klass)
163
163
  VALUE obj = Data_Make_Struct(klass, LibrarySymbol, NULL, -1, sym);
164
164
  sym->name = Qnil;
165
165
  sym->library = Qnil;
166
+ sym->base.rbParent = Qnil;
166
167
 
167
168
  return obj;
168
169
  }
169
170
 
171
+
172
+ static VALUE
173
+ symbol_initialize_copy(VALUE self, VALUE other)
174
+ {
175
+ rb_raise(rb_eRuntimeError, "cannot duplicate symbol");
176
+ return Qnil;
177
+ }
178
+
170
179
  static VALUE
171
180
  symbol_new(VALUE library, void* address, VALUE name)
172
181
  {
173
182
  LibrarySymbol* sym;
174
183
  VALUE obj = Data_Make_Struct(SymbolClass, LibrarySymbol, symbol_mark, -1, sym);
175
184
 
176
- sym->memory.address = address;
177
- sym->memory.size = LONG_MAX;
178
- sym->memory.typeSize = 1;
179
- sym->memory.flags = MEM_RD | MEM_WR;
185
+ sym->base.memory.address = address;
186
+ sym->base.memory.size = LONG_MAX;
187
+ sym->base.memory.typeSize = 1;
188
+ sym->base.memory.flags = MEM_RD | MEM_WR;
180
189
  sym->library = library;
181
190
  sym->name = name;
182
191
 
@@ -198,7 +207,7 @@ symbol_inspect(VALUE self)
198
207
 
199
208
  Data_Get_Struct(self, LibrarySymbol, sym);
200
209
  snprintf(buf, sizeof(buf), "#<FFI::Library::Symbol name=%s address=%p>",
201
- StringValueCStr(sym->name), sym->memory.address);
210
+ StringValueCStr(sym->name), sym->base.memory.address);
202
211
  return rb_str_new2(buf);
203
212
  }
204
213
 
@@ -224,6 +233,8 @@ rbffi_DynamicLibrary_Init(VALUE moduleFFI)
224
233
  rb_define_alloc_func(SymbolClass, symbol_allocate);
225
234
  rb_undef_method(SymbolClass, "new");
226
235
  rb_define_method(SymbolClass, "inspect", symbol_inspect, 0);
236
+ rb_define_method(SymbolClass, "initialize_copy", symbol_initialize_copy, 1);
237
+
227
238
 
228
239
  #define DEF(x) rb_define_const(LibraryClass, "RTLD_" #x, UINT2NUM(RTLD_##x))
229
240
  DEF(LAZY);
@@ -53,7 +53,7 @@
53
53
  #include "Thread.h"
54
54
 
55
55
  typedef struct Function_ {
56
- AbstractMemory memory;
56
+ Pointer base;
57
57
  FunctionType* info;
58
58
  MethodHandle* methodHandle;
59
59
  bool autorelease;
@@ -131,8 +131,8 @@ function_allocate(VALUE klass)
131
131
 
132
132
  obj = Data_Make_Struct(klass, Function, function_mark, function_free, fn);
133
133
 
134
- fn->memory.flags = MEM_RD;
135
-
134
+ fn->base.memory.flags = MEM_RD;
135
+ fn->base.rbParent = Qnil;
136
136
  fn->rbProc = Qnil;
137
137
  fn->rbFunctionInfo = Qnil;
138
138
  fn->autorelease = true;
@@ -143,6 +143,7 @@ function_allocate(VALUE klass)
143
143
  static void
144
144
  function_mark(Function *fn)
145
145
  {
146
+ rb_gc_mark(fn->base.rbParent);
146
147
  rb_gc_mark(fn->rbProc);
147
148
  rb_gc_mark(fn->rbFunctionInfo);
148
149
  }
@@ -201,6 +202,13 @@ function_initialize(int argc, VALUE* argv, VALUE self)
201
202
  return self;
202
203
  }
203
204
 
205
+ static VALUE
206
+ function_initialize_copy(VALUE self, VALUE other)
207
+ {
208
+ rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
209
+ return Qnil;
210
+ }
211
+
204
212
  VALUE
205
213
  rbffi_Function_NewInstance(VALUE rbFunctionInfo, VALUE rbProc)
206
214
  {
@@ -254,9 +262,10 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
254
262
  Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info);
255
263
 
256
264
  if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
257
- AbstractMemory* memory;
258
- Data_Get_Struct(rbProc, AbstractMemory, memory);
259
- fn->memory = *memory;
265
+ Pointer* orig;
266
+ Data_Get_Struct(rbProc, Pointer, orig);
267
+ fn->base.memory = orig->memory;
268
+ fn->base.rbParent = rbProc;
260
269
 
261
270
  } else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) {
262
271
  if (fn->info->closurePool == NULL) {
@@ -280,8 +289,8 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
280
289
 
281
290
  fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
282
291
  fn->closure->info = fn;
283
- fn->memory.address = fn->closure->code;
284
- fn->memory.size = sizeof(*fn->closure);
292
+ fn->base.memory.address = fn->closure->code;
293
+ fn->base.memory.size = sizeof(*fn->closure);
285
294
  fn->autorelease = true;
286
295
 
287
296
  } else {
@@ -301,7 +310,7 @@ function_call(int argc, VALUE* argv, VALUE self)
301
310
 
302
311
  Data_Get_Struct(self, Function, fn);
303
312
 
304
- return (*fn->info->invoke)(argc, argv, fn->memory.address, fn->info);
313
+ return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
305
314
  }
306
315
 
307
316
  static VALUE
@@ -323,7 +332,7 @@ function_attach(VALUE self, VALUE module, VALUE name)
323
332
  }
324
333
 
325
334
  if (fn->methodHandle == NULL) {
326
- fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->memory.address);
335
+ fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
327
336
  }
328
337
 
329
338
  //
@@ -819,6 +828,7 @@ rbffi_Function_Init(VALUE moduleFFI)
819
828
  rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
820
829
 
821
830
  rb_define_method(rbffi_FunctionClass, "initialize", function_initialize, -1);
831
+ rb_define_method(rbffi_FunctionClass, "initialize_copy", function_initialize_copy, 1);
822
832
  rb_define_method(rbffi_FunctionClass, "call", function_call, -1);
823
833
  rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
824
834
  rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
@@ -28,15 +28,10 @@
28
28
  #include "Pointer.h"
29
29
  #include "MemoryPointer.h"
30
30
 
31
- typedef struct MemoryPointer {
32
- AbstractMemory memory;
33
- char* storage; /* start of malloc area */
34
- bool autorelease;
35
- bool allocated;
36
- } MemoryPointer;
37
31
 
38
32
  static VALUE memptr_allocate(VALUE klass);
39
- static void memptr_release(MemoryPointer* ptr);
33
+ static void memptr_mark(Pointer* ptr);
34
+ static void memptr_release(Pointer* ptr);
40
35
  static VALUE memptr_malloc(VALUE self, long size, long count, bool clear);
41
36
  static VALUE memptr_free(VALUE self);
42
37
 
@@ -53,8 +48,9 @@ rbffi_MemoryPointer_NewInstance(long size, long count, bool clear)
53
48
  static VALUE
54
49
  memptr_allocate(VALUE klass)
55
50
  {
56
- MemoryPointer* p;
57
- VALUE obj = Data_Make_Struct(klass, MemoryPointer, NULL, memptr_release, p);
51
+ Pointer* p;
52
+ VALUE obj = Data_Make_Struct(klass, Pointer, NULL, memptr_release, p);
53
+ p->rbParent = Qnil;
58
54
  p->memory.flags = MEM_RD | MEM_WR;
59
55
 
60
56
  return obj;
@@ -79,10 +75,10 @@ memptr_initialize(int argc, VALUE* argv, VALUE self)
79
75
  static VALUE
80
76
  memptr_malloc(VALUE self, long size, long count, bool clear)
81
77
  {
82
- MemoryPointer* p;
78
+ Pointer* p;
83
79
  unsigned long msize;
84
80
 
85
- Data_Get_Struct(self, MemoryPointer, p);
81
+ Data_Get_Struct(self, Pointer, p);
86
82
 
87
83
  msize = size * count;
88
84
 
@@ -108,9 +104,9 @@ memptr_malloc(VALUE self, long size, long count, bool clear)
108
104
  static VALUE
109
105
  memptr_free(VALUE self)
110
106
  {
111
- MemoryPointer* ptr;
107
+ Pointer* ptr;
112
108
 
113
- Data_Get_Struct(self, MemoryPointer, ptr);
109
+ Data_Get_Struct(self, Pointer, ptr);
114
110
 
115
111
  if (ptr->allocated) {
116
112
  if (ptr->storage != NULL) {
@@ -123,19 +119,8 @@ memptr_free(VALUE self)
123
119
  return self;
124
120
  }
125
121
 
126
- static VALUE
127
- memptr_autorelease(VALUE self, VALUE autorelease)
128
- {
129
- MemoryPointer* ptr;
130
-
131
- Data_Get_Struct(self, MemoryPointer, ptr);
132
- ptr->autorelease = autorelease == Qtrue;
133
-
134
- return autorelease;
135
- }
136
-
137
122
  static void
138
- memptr_release(MemoryPointer* ptr)
123
+ memptr_release(Pointer* ptr)
139
124
  {
140
125
  if (ptr->autorelease && ptr->allocated && ptr->storage != NULL) {
141
126
  xfree(ptr->storage);
@@ -144,6 +129,13 @@ memptr_release(MemoryPointer* ptr)
144
129
  xfree(ptr);
145
130
  }
146
131
 
132
+ static void
133
+ memptr_mark(Pointer* ptr)
134
+ {
135
+ rb_gc_mark(ptr->rbParent);
136
+ }
137
+
138
+
147
139
  void
148
140
  rbffi_MemoryPointer_Init(VALUE moduleFFI)
149
141
  {
@@ -152,7 +144,5 @@ rbffi_MemoryPointer_Init(VALUE moduleFFI)
152
144
 
153
145
  rb_define_alloc_func(rbffi_MemoryPointerClass, memptr_allocate);
154
146
  rb_define_method(rbffi_MemoryPointerClass, "initialize", memptr_initialize, -1);
155
- rb_define_method(rbffi_MemoryPointerClass, "autorelease=", memptr_autorelease, 1);
156
- rb_define_method(rbffi_MemoryPointerClass, "free", memptr_free, 0);
157
147
  }
158
148
 
@@ -34,14 +34,17 @@ static VALUE PlatformModule = Qnil;
34
34
  * system installed ruby incorrectly reports 'host_cpu' as 'powerpc' when running
35
35
  * on intel.
36
36
  */
37
- #ifdef __i386__
37
+ #if defined(__x86_64__) || defined(__x86_64) || defined(__amd64)
38
+ # define CPU "x86_64"
39
+
40
+ #elif defined(__i386__) || defined(__i386)
38
41
  # define CPU "i386"
39
42
 
40
- #elif defined(__ppc__) || defined(__powerpc__)
41
- # define CPU "powerpc"
43
+ #elif defined(__ppc64__) || defined(__powerpc64__)
44
+ # define CPU "ppc64"
42
45
 
43
- #elif defined(__x86_64__)
44
- # define CPU "x86_64"
46
+ #elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc)
47
+ # define CPU "ppc"
45
48
 
46
49
  /* Need to check for __sparcv9 first, because __sparc will be defined either way. */
47
50
  #elif defined(__sparcv9__) || defined(__sparcv9)
@@ -50,10 +53,17 @@ static VALUE PlatformModule = Qnil;
50
53
  #elif defined(__sparc__) || defined(__sparc)
51
54
  # define CPU "sparc"
52
55
 
53
- #elif defined(__arm__)
56
+ #elif defined(__arm__) || defined(__arm)
54
57
  # define CPU "arm"
58
+
59
+ #elif defined(__mips__) || defined(__mips)
60
+ # define CPU "mips"
61
+
62
+ #elif defined(__s390__)
63
+ # define CPU "s390"
64
+
55
65
  #else
56
- # error "Unknown cpu type"
66
+ # define CPU "unknown"
57
67
  #endif
58
68
 
59
69
  static void