ffi 1.0.5 → 1.0.6

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
@@ -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.5'
78
+ PROJ.version = '1.0.6'
79
79
  PROJ.rubyforge.name = 'ffi'
80
80
  PROJ.readme_file = 'README.rdoc'
81
81
 
@@ -52,9 +52,11 @@ typedef struct InlineArray_ {
52
52
 
53
53
 
54
54
  static void struct_mark(Struct *);
55
+ static void struct_free(Struct *);
55
56
  static VALUE struct_class_layout(VALUE klass);
56
57
  static void struct_malloc(Struct* s);
57
58
  static void inline_array_mark(InlineArray *);
59
+ static void store_reference_value(StructField* f, Struct* s, VALUE value);
58
60
 
59
61
  VALUE rbffi_StructClass = Qnil;
60
62
 
@@ -74,7 +76,7 @@ static VALUE
74
76
  struct_allocate(VALUE klass)
75
77
  {
76
78
  Struct* s;
77
- VALUE obj = Data_Make_Struct(klass, Struct, struct_mark, -1, s);
79
+ VALUE obj = Data_Make_Struct(klass, Struct, struct_mark, struct_free, s);
78
80
 
79
81
  s->rbPointer = Qnil;
80
82
  s->rbLayout = Qnil;
@@ -183,8 +185,37 @@ struct_mark(Struct *s)
183
185
  {
184
186
  rb_gc_mark(s->rbPointer);
185
187
  rb_gc_mark(s->rbLayout);
188
+ if (s->rbReferences != NULL) {
189
+ rb_gc_mark_locations(&s->rbReferences[0], &s->rbReferences[s->layout->referenceFieldCount]);
190
+ }
191
+ }
192
+
193
+ static void
194
+ struct_free(Struct* s)
195
+ {
196
+ xfree(s->rbReferences);
186
197
  }
187
198
 
199
+
200
+ static void
201
+ store_reference_value(StructField* f, Struct* s, VALUE value)
202
+ {
203
+ if (unlikely(f->referenceIndex == -1)) {
204
+ rb_raise(rb_eRuntimeError, "put_reference_value called for non-reference type");
205
+ return;
206
+ }
207
+ if (s->rbReferences == NULL) {
208
+ int i;
209
+ s->rbReferences = ALLOC_N(VALUE, s->layout->referenceFieldCount);
210
+ for (i = 0; i < s->layout->referenceFieldCount; ++i) {
211
+ s->rbReferences[i] = Qnil;
212
+ }
213
+ }
214
+
215
+ s->rbReferences[f->referenceIndex] = value;
216
+ }
217
+
218
+
188
219
  static VALUE
189
220
  struct_field(Struct* s, VALUE fieldName)
190
221
  {
@@ -255,6 +286,10 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
255
286
  argv[1] = value;
256
287
  rb_funcall2(rbField, id_put, 2, argv);
257
288
  }
289
+
290
+ if (f->referenceRequired) {
291
+ store_reference_value(f, s, value);
292
+ }
258
293
 
259
294
  return value;
260
295
  }
@@ -44,6 +44,9 @@ extern "C" {
44
44
  Type* type;
45
45
  unsigned int offset;
46
46
 
47
+ int referenceIndex;
48
+
49
+ bool referenceRequired;
47
50
  VALUE rbType;
48
51
  VALUE rbName;
49
52
 
@@ -61,6 +64,10 @@ extern "C" {
61
64
  int align;
62
65
  ffi_type** ffiTypes;
63
66
  struct st_table* fieldSymbolTable;
67
+
68
+ /** The number of reference tracking fields in this struct */
69
+ int referenceFieldCount;
70
+
64
71
  VALUE rbFieldNames;
65
72
  VALUE rbFieldMap;
66
73
  VALUE rbFields;
@@ -69,6 +76,8 @@ extern "C" {
69
76
  struct Struct_ {
70
77
  StructLayout* layout;
71
78
  AbstractMemory* pointer;
79
+ VALUE* rbReferences;
80
+
72
81
  VALUE rbLayout;
73
82
  VALUE rbPointer;
74
83
  };
@@ -36,6 +36,7 @@
36
36
  #include "Struct.h"
37
37
  #include "StructByValue.h"
38
38
  #include "ArrayType.h"
39
+ #include "MappedType.h"
39
40
 
40
41
  #define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
41
42
 
@@ -99,7 +100,23 @@ struct_field_initialize(int argc, VALUE* argv, VALUE self)
99
100
  field->rbType = rbType;
100
101
  Data_Get_Struct(field->rbType, Type, field->type);
101
102
  field->memoryOp = get_memory_op(field->type);
102
-
103
+ field->referenceIndex = -1;
104
+
105
+ switch (field->type->nativeType == NATIVE_MAPPED ? ((MappedType *) field->type)->type->nativeType : field->type->nativeType) {
106
+ case NATIVE_FUNCTION:
107
+ case NATIVE_CALLBACK:
108
+ case NATIVE_POINTER:
109
+ field->referenceRequired = true;
110
+ break;
111
+
112
+ default:
113
+ field->referenceRequired = (rb_respond_to(self, rb_intern("reference_required?"))
114
+ && RTEST(rb_funcall2(self, rb_intern("reference_required?"), 0, NULL)))
115
+ || (rb_respond_to(rbType, rb_intern("reference_required?"))
116
+ && RTEST(rb_funcall2(rbType, rb_intern("reference_required?"), 0, NULL)));
117
+ break;
118
+ }
119
+
103
120
  return self;
104
121
  }
105
122
 
@@ -339,6 +356,7 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
339
356
  layout->fields = xcalloc(layout->fieldCount, sizeof(StructField *));
340
357
  layout->ffiTypes = xcalloc(layout->fieldCount + 1, sizeof(ffi_type *));
341
358
  layout->rbFields = rb_ary_new2(layout->fieldCount);
359
+ layout->referenceFieldCount = 0;
342
360
  layout->base.ffiType->elements = layout->ffiTypes;
343
361
  layout->base.ffiType->size = layout->size;
344
362
  layout->base.ffiType->alignment = layout->align;
@@ -367,6 +385,10 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
367
385
  rb_raise(rb_eTypeError, "type of field %d has zero size", i);
368
386
  }
369
387
 
388
+ if (field->referenceRequired) {
389
+ field->referenceIndex = layout->referenceFieldCount++;
390
+ }
391
+
370
392
  layout->ffiTypes[i] = ftype;
371
393
  st_insert(layout->fieldSymbolTable, rbName, rbField);
372
394
  rb_hash_aset(layout->rbFieldMap, rbName, rbField);
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 6
10
+ version: 1.0.6
5
11
  platform: ruby
6
12
  authors:
7
13
  - Wayne Meissner
@@ -9,19 +15,25 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2011-01-13 00:00:00 +10:00
18
+ date: 2011-02-21 00:00:00 +10:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rake
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 49
30
+ segments:
31
+ - 0
32
+ - 8
33
+ - 7
23
34
  version: 0.8.7
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  description: |-
26
38
  Ruby-FFI is a ruby extension for programmatically loading dynamic
27
39
  libraries, binding functions within them, and calling those functions
@@ -422,21 +434,27 @@ require_paths:
422
434
  - lib
423
435
  - ext
424
436
  required_ruby_version: !ruby/object:Gem::Requirement
437
+ none: false
425
438
  requirements:
426
439
  - - ">="
427
440
  - !ruby/object:Gem::Version
441
+ hash: 3
442
+ segments:
443
+ - 0
428
444
  version: "0"
429
- version:
430
445
  required_rubygems_version: !ruby/object:Gem::Requirement
446
+ none: false
431
447
  requirements:
432
448
  - - ">="
433
449
  - !ruby/object:Gem::Version
450
+ hash: 3
451
+ segments:
452
+ - 0
434
453
  version: "0"
435
- version:
436
454
  requirements: []
437
455
 
438
456
  rubyforge_project: ffi
439
- rubygems_version: 1.3.5
457
+ rubygems_version: 1.3.7
440
458
  signing_key:
441
459
  specification_version: 3
442
460
  summary: Ruby-FFI is a ruby extension for programmatically loading dynamic libraries, binding functions within them, and calling those functions from Ruby code