ffi 1.0.9 → 1.0.10
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 +4 -4
- data/ext/ffi_c/AbstractMemory.c +367 -14
- data/ext/ffi_c/AbstractMemory.h +4 -0
- data/ext/ffi_c/ArrayType.c +28 -0
- data/ext/ffi_c/Buffer.c +101 -25
- data/ext/ffi_c/Call.c +8 -5
- data/ext/ffi_c/ClosurePool.c +9 -8
- data/ext/ffi_c/DataConverter.c +29 -0
- data/ext/ffi_c/DynamicLibrary.c +64 -1
- data/ext/ffi_c/Function.c +111 -10
- data/ext/ffi_c/FunctionInfo.c +13 -1
- data/ext/ffi_c/LastError.c +16 -0
- data/ext/ffi_c/MappedType.c +22 -0
- data/ext/ffi_c/MemoryPointer.c +11 -1
- data/ext/ffi_c/MethodHandle.c +18 -11
- data/ext/ffi_c/Platform.c +9 -3
- data/ext/ffi_c/Pointer.c +98 -0
- data/ext/ffi_c/Struct.c +4 -4
- data/ext/ffi_c/Struct.h +2 -1
- data/ext/ffi_c/StructLayout.c +2 -2
- data/ext/ffi_c/Thread.c +124 -1
- data/ext/ffi_c/Type.c +108 -17
- data/ext/ffi_c/Types.c +9 -2
- data/ext/ffi_c/Variadic.c +5 -4
- data/ext/ffi_c/compat.h +8 -0
- data/ext/ffi_c/endian.h +7 -1
- data/ext/ffi_c/extconf.rb +46 -35
- data/ext/ffi_c/ffi.c +5 -0
- data/ext/ffi_c/libffi.darwin.mk +15 -15
- data/ext/ffi_c/libffi.gnu.mk +3 -3
- data/ext/ffi_c/libffi.mk +4 -4
- data/lib/ffi.rb +13 -9
- data/lib/ffi/autopointer.rb +88 -26
- data/lib/ffi/enum.rb +42 -0
- data/lib/ffi/errno.rb +6 -1
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/io.rb +13 -2
- data/lib/ffi/library.rb +212 -19
- data/lib/ffi/memorypointer.rb +1 -33
- data/lib/ffi/platform.rb +23 -7
- data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
- data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
- data/lib/ffi/platform/x86_64-freebsd/types.conf +126 -0
- data/lib/ffi/platform/x86_64-netbsd/types.conf +126 -0
- data/lib/ffi/pointer.rb +44 -0
- data/lib/ffi/struct.rb +1 -1
- data/lib/ffi/struct_layout_builder.rb +2 -1
- data/lib/ffi/tools/const_generator.rb +72 -17
- data/lib/ffi/types.rb +21 -1
- data/spec/ffi/rbx/memory_pointer_spec.rb +4 -2
- data/spec/ffi/struct_spec.rb +10 -0
- data/spec/ffi/typedef_spec.rb +11 -0
- data/tasks/extension.rake +0 -1
- data/tasks/gem.rake +0 -1
- data/tasks/yard.rake +11 -0
- metadata +15 -8
data/ext/ffi_c/AbstractMemory.h
CHANGED
@@ -37,6 +37,7 @@ extern "C" {
|
|
37
37
|
#define MEM_WR 0x02
|
38
38
|
#define MEM_CODE 0x04
|
39
39
|
#define MEM_SWAP 0x08
|
40
|
+
#define MEM_EMBED 0x10
|
40
41
|
|
41
42
|
typedef struct AbstractMemory_ AbstractMemory;
|
42
43
|
|
@@ -60,6 +61,7 @@ typedef struct {
|
|
60
61
|
MemoryOp* float64;
|
61
62
|
MemoryOp* pointer;
|
62
63
|
MemoryOp* strptr;
|
64
|
+
MemoryOp* boolOp;
|
63
65
|
} MemoryOps;
|
64
66
|
|
65
67
|
struct AbstractMemory_ {
|
@@ -136,6 +138,8 @@ get_memory_op(Type* type)
|
|
136
138
|
return rbffi_AbstractMemoryOps.pointer;
|
137
139
|
case NATIVE_STRING:
|
138
140
|
return rbffi_AbstractMemoryOps.strptr;
|
141
|
+
case NATIVE_BOOL:
|
142
|
+
return rbffi_AbstractMemoryOps.boolOp;
|
139
143
|
default:
|
140
144
|
return NULL;
|
141
145
|
}
|
data/ext/ffi_c/ArrayType.c
CHANGED
@@ -62,6 +62,13 @@ array_type_free(ArrayType *array)
|
|
62
62
|
}
|
63
63
|
|
64
64
|
|
65
|
+
/*
|
66
|
+
* call-seq: initialize(component_type, length)
|
67
|
+
* @param [Type] component_type
|
68
|
+
* @param [Numeric] length
|
69
|
+
* @return [self]
|
70
|
+
* A new instance of ArrayType.
|
71
|
+
*/
|
65
72
|
static VALUE
|
66
73
|
array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength)
|
67
74
|
{
|
@@ -86,6 +93,11 @@ array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength)
|
|
86
93
|
return self;
|
87
94
|
}
|
88
95
|
|
96
|
+
/*
|
97
|
+
* call-seq: length
|
98
|
+
* @return [Numeric]
|
99
|
+
* Get array's length
|
100
|
+
*/
|
89
101
|
static VALUE
|
90
102
|
array_type_length(VALUE self)
|
91
103
|
{
|
@@ -96,6 +108,11 @@ array_type_length(VALUE self)
|
|
96
108
|
return UINT2NUM(array->length);
|
97
109
|
}
|
98
110
|
|
111
|
+
/*
|
112
|
+
* call-seq: element_type
|
113
|
+
* @return [Type]
|
114
|
+
* Get element type.
|
115
|
+
*/
|
99
116
|
static VALUE
|
100
117
|
array_type_element_type(VALUE self)
|
101
118
|
{
|
@@ -109,8 +126,19 @@ array_type_element_type(VALUE self)
|
|
109
126
|
void
|
110
127
|
rbffi_ArrayType_Init(VALUE moduleFFI)
|
111
128
|
{
|
129
|
+
/*
|
130
|
+
* Document-class: FFI::ArrayType < FFI::Type
|
131
|
+
*
|
132
|
+
* This is a typed array. The type is a {NativeType native type}.
|
133
|
+
*/
|
112
134
|
rbffi_ArrayTypeClass = rb_define_class_under(moduleFFI, "ArrayType", rbffi_TypeClass);
|
135
|
+
/*
|
136
|
+
* Document-variable: FFI::ArrayType
|
137
|
+
*/
|
113
138
|
rb_global_variable(&rbffi_ArrayTypeClass);
|
139
|
+
/*
|
140
|
+
* Document-constant: FFI::Type::Array
|
141
|
+
*/
|
114
142
|
rb_define_const(rbffi_TypeClass, "Array", rbffi_ArrayTypeClass);
|
115
143
|
|
116
144
|
rb_define_alloc_func(rbffi_ArrayTypeClass, array_type_s_allocate);
|
data/ext/ffi_c/Buffer.c
CHANGED
@@ -26,10 +26,15 @@
|
|
26
26
|
#include "endian.h"
|
27
27
|
#include "AbstractMemory.h"
|
28
28
|
|
29
|
+
#define BUFFER_EMBED_MAXLEN (8)
|
29
30
|
typedef struct Buffer {
|
30
31
|
AbstractMemory memory;
|
31
|
-
|
32
|
-
|
32
|
+
|
33
|
+
union {
|
34
|
+
VALUE rbParent; /* link to parent buffer */
|
35
|
+
char* storage; /* start of malloc area */
|
36
|
+
long embed[BUFFER_EMBED_MAXLEN / sizeof(long)]; // storage for tiny allocations
|
37
|
+
} data;
|
33
38
|
} Buffer;
|
34
39
|
|
35
40
|
static VALUE buffer_allocate(VALUE klass);
|
@@ -47,7 +52,7 @@ buffer_allocate(VALUE klass)
|
|
47
52
|
VALUE obj;
|
48
53
|
|
49
54
|
obj = Data_Make_Struct(klass, Buffer, NULL, buffer_release, buffer);
|
50
|
-
buffer->rbParent = Qnil;
|
55
|
+
buffer->data.rbParent = Qnil;
|
51
56
|
buffer->memory.flags = MEM_RD | MEM_WR;
|
52
57
|
|
53
58
|
return obj;
|
@@ -56,14 +61,23 @@ buffer_allocate(VALUE klass)
|
|
56
61
|
static void
|
57
62
|
buffer_release(Buffer* ptr)
|
58
63
|
{
|
59
|
-
if (ptr->storage != NULL) {
|
60
|
-
xfree(ptr->storage);
|
61
|
-
ptr->storage = NULL;
|
64
|
+
if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) {
|
65
|
+
xfree(ptr->data.storage);
|
66
|
+
ptr->data.storage = NULL;
|
62
67
|
}
|
63
68
|
|
64
69
|
xfree(ptr);
|
65
70
|
}
|
66
71
|
|
72
|
+
/*
|
73
|
+
* call-seq: initialize(size, count=1, clear=false)
|
74
|
+
* @param [Integer, Symbol, #size] Type or size in bytes of a buffer cell
|
75
|
+
* @param [Fixnum] count number of cell in the Buffer
|
76
|
+
* @param [Boolean] clear if true, set the buffer to all-zero
|
77
|
+
* @return [self]
|
78
|
+
* @raise {NoMemoryError} if failed to allocate memory for Buffer
|
79
|
+
* A new instance of Buffer.
|
80
|
+
*/
|
67
81
|
static VALUE
|
68
82
|
buffer_initialize(int argc, VALUE* argv, VALUE self)
|
69
83
|
{
|
@@ -77,17 +91,23 @@ buffer_initialize(int argc, VALUE* argv, VALUE self)
|
|
77
91
|
p->memory.typeSize = rbffi_type_size(rbSize);
|
78
92
|
p->memory.size = p->memory.typeSize * (nargs > 1 ? NUM2LONG(rbCount) : 1);
|
79
93
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
94
|
+
if (p->memory.size > BUFFER_EMBED_MAXLEN) {
|
95
|
+
p->data.storage = xmalloc(p->memory.size + 7);
|
96
|
+
if (p->data.storage == NULL) {
|
97
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory size=%lu bytes", p->memory.size);
|
98
|
+
return Qnil;
|
99
|
+
}
|
85
100
|
|
86
|
-
|
87
|
-
|
101
|
+
/* ensure the memory is aligned on at least a 8 byte boundary */
|
102
|
+
p->memory.address = (void *) (((uintptr_t) p->data.storage + 0x7) & (uintptr_t) ~0x7UL);
|
103
|
+
|
104
|
+
if (p->memory.size > 0 && (nargs < 3 || RTEST(rbClear))) {
|
105
|
+
memset(p->memory.address, 0, p->memory.size);
|
106
|
+
}
|
88
107
|
|
89
|
-
|
90
|
-
|
108
|
+
} else {
|
109
|
+
p->memory.flags |= MEM_EMBED;
|
110
|
+
p->memory.address = (void *) &p->data.embed[0];
|
91
111
|
}
|
92
112
|
|
93
113
|
if (rb_block_given_p()) {
|
@@ -97,6 +117,11 @@ buffer_initialize(int argc, VALUE* argv, VALUE self)
|
|
97
117
|
return self;
|
98
118
|
}
|
99
119
|
|
120
|
+
/*
|
121
|
+
* call-seq: initialize_copy(other)
|
122
|
+
* @return [self]
|
123
|
+
* DO NOT CALL THIS METHOD.
|
124
|
+
*/
|
100
125
|
static VALUE
|
101
126
|
buffer_initialize_copy(VALUE self, VALUE other)
|
102
127
|
{
|
@@ -105,16 +130,16 @@ buffer_initialize_copy(VALUE self, VALUE other)
|
|
105
130
|
|
106
131
|
Data_Get_Struct(self, Buffer, dst);
|
107
132
|
src = rbffi_AbstractMemory_Cast(other, BufferClass);
|
108
|
-
if (dst->storage != NULL) {
|
109
|
-
xfree(dst->storage);
|
133
|
+
if ((dst->memory.flags & MEM_EMBED) == 0 && dst->data.storage != NULL) {
|
134
|
+
xfree(dst->data.storage);
|
110
135
|
}
|
111
|
-
dst->storage = xmalloc(src->size + 7);
|
112
|
-
if (dst->storage == NULL) {
|
136
|
+
dst->data.storage = xmalloc(src->size + 7);
|
137
|
+
if (dst->data.storage == NULL) {
|
113
138
|
rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
|
114
139
|
return Qnil;
|
115
140
|
}
|
116
141
|
|
117
|
-
dst->memory.address = (void *) (((uintptr_t) dst->storage + 0x7) & (uintptr_t) ~0x7UL);
|
142
|
+
dst->memory.address = (void *) (((uintptr_t) dst->data.storage + 0x7) & (uintptr_t) ~0x7UL);
|
118
143
|
dst->memory.size = src->size;
|
119
144
|
dst->memory.typeSize = src->typeSize;
|
120
145
|
|
@@ -145,11 +170,17 @@ slice(VALUE self, long offset, long len)
|
|
145
170
|
result->memory.size = len;
|
146
171
|
result->memory.flags = ptr->memory.flags;
|
147
172
|
result->memory.typeSize = ptr->memory.typeSize;
|
148
|
-
result->rbParent = self;
|
173
|
+
result->data.rbParent = self;
|
149
174
|
|
150
175
|
return obj;
|
151
176
|
}
|
152
177
|
|
178
|
+
/*
|
179
|
+
* call-seq: + offset
|
180
|
+
* @param [Numeric] offset
|
181
|
+
* @return [Buffer] a new instance of Buffer pointing from offset until end of previous buffer.
|
182
|
+
* Add a Buffer with an offset
|
183
|
+
*/
|
153
184
|
static VALUE
|
154
185
|
buffer_plus(VALUE self, VALUE rbOffset)
|
155
186
|
{
|
@@ -161,12 +192,24 @@ buffer_plus(VALUE self, VALUE rbOffset)
|
|
161
192
|
return slice(self, offset, ptr->memory.size - offset);
|
162
193
|
}
|
163
194
|
|
195
|
+
/*
|
196
|
+
* call-seq: slice(offset, length)
|
197
|
+
* @param [Numeric] offset
|
198
|
+
* @param [Numeric] length
|
199
|
+
* @return [Buffer] a new instance of Buffer
|
200
|
+
* Slice an existing Buffer.
|
201
|
+
*/
|
164
202
|
static VALUE
|
165
203
|
buffer_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
|
166
204
|
{
|
167
205
|
return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
|
168
206
|
}
|
169
207
|
|
208
|
+
/*
|
209
|
+
* call-seq: inspect
|
210
|
+
* @return [String]
|
211
|
+
* Inspect a Buffer.
|
212
|
+
*/
|
170
213
|
static VALUE
|
171
214
|
buffer_inspect(VALUE self)
|
172
215
|
{
|
@@ -187,6 +230,16 @@ buffer_inspect(VALUE self)
|
|
187
230
|
# define SWAPPED_ORDER LITTLE_ENDIAN
|
188
231
|
#endif
|
189
232
|
|
233
|
+
/*
|
234
|
+
* Set or get endianness of Buffer.
|
235
|
+
* @overload order
|
236
|
+
* @return [:big, :little]
|
237
|
+
* Get endianness of Buffer.
|
238
|
+
* @overload order(order)
|
239
|
+
* @param [:big, :little, :network] order
|
240
|
+
* @return [self]
|
241
|
+
* Set endinaness of Buffer (+:network+ is an alias for +:big+).
|
242
|
+
*/
|
190
243
|
static VALUE
|
191
244
|
buffer_order(int argc, VALUE* argv, VALUE self)
|
192
245
|
{
|
@@ -232,9 +285,9 @@ buffer_free(VALUE self)
|
|
232
285
|
Buffer* ptr;
|
233
286
|
|
234
287
|
Data_Get_Struct(self, Buffer, ptr);
|
235
|
-
if (ptr->storage != NULL) {
|
236
|
-
xfree(ptr->storage);
|
237
|
-
ptr->storage = NULL;
|
288
|
+
if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) {
|
289
|
+
xfree(ptr->data.storage);
|
290
|
+
ptr->data.storage = NULL;
|
238
291
|
}
|
239
292
|
|
240
293
|
return self;
|
@@ -243,19 +296,42 @@ buffer_free(VALUE self)
|
|
243
296
|
static void
|
244
297
|
buffer_mark(Buffer* ptr)
|
245
298
|
{
|
246
|
-
rb_gc_mark(ptr->rbParent);
|
299
|
+
rb_gc_mark(ptr->data.rbParent);
|
247
300
|
}
|
248
301
|
|
249
302
|
void
|
250
303
|
rbffi_Buffer_Init(VALUE moduleFFI)
|
251
304
|
{
|
305
|
+
/*
|
306
|
+
* Document-class: FFI::Buffer < FFI::AbstractMemory
|
307
|
+
*
|
308
|
+
* A Buffer is a function argument type. It should be use with functions playing with C arrays.
|
309
|
+
*/
|
252
310
|
BufferClass = rb_define_class_under(moduleFFI, "Buffer", rbffi_AbstractMemoryClass);
|
253
311
|
|
312
|
+
/*
|
313
|
+
* Document-variable: FFI::Buffer
|
314
|
+
*/
|
254
315
|
rb_global_variable(&BufferClass);
|
255
316
|
rb_define_alloc_func(BufferClass, buffer_allocate);
|
256
317
|
|
318
|
+
/*
|
319
|
+
* Document-method: alloc_inout
|
320
|
+
* call-seq: alloc_inout(*args)
|
321
|
+
* Create a new Buffer for in and out arguments (alias : <i>new_inout</i>).
|
322
|
+
*/
|
257
323
|
rb_define_singleton_method(BufferClass, "alloc_inout", buffer_alloc_inout, -1);
|
324
|
+
/*
|
325
|
+
* Document-method: alloc_out
|
326
|
+
* call-seq: alloc_out(*args)
|
327
|
+
* Create a new Buffer for out arguments (alias : <i>new_out</i>).
|
328
|
+
*/
|
258
329
|
rb_define_singleton_method(BufferClass, "alloc_out", buffer_alloc_inout, -1);
|
330
|
+
/*
|
331
|
+
* Document-method: alloc_in
|
332
|
+
* call-seq: alloc_in(*args)
|
333
|
+
* Create a new Buffer for in arguments (alias : <i>new_in</i>).
|
334
|
+
*/
|
259
335
|
rb_define_singleton_method(BufferClass, "alloc_in", buffer_alloc_inout, -1);
|
260
336
|
rb_define_alias(rb_singleton_class(BufferClass), "new_in", "alloc_in");
|
261
337
|
rb_define_alias(rb_singleton_class(BufferClass), "new_out", "alloc_out");
|
data/ext/ffi_c/Call.c
CHANGED
@@ -288,7 +288,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
288
288
|
void** ffiValues;
|
289
289
|
FFIStorage* params;
|
290
290
|
VALUE rbReturnValue;
|
291
|
-
|
291
|
+
|
292
292
|
#if !defined(HAVE_RUBY_THREAD_HAS_GVL_P)
|
293
293
|
rbffi_thread_t oldThread;
|
294
294
|
#endif
|
@@ -329,7 +329,6 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
329
329
|
oldThread = rbffi_active_thread;
|
330
330
|
rbffi_active_thread = rbffi_thread_self();
|
331
331
|
#endif
|
332
|
-
retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
333
332
|
ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues);
|
334
333
|
|
335
334
|
#if !defined(HAVE_RUBY_THREAD_HAS_GVL_P)
|
@@ -339,9 +338,12 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
339
338
|
|
340
339
|
if (unlikely(!fnInfo->ignoreErrno)) {
|
341
340
|
rbffi_save_errno();
|
342
|
-
}
|
343
|
-
|
344
|
-
|
341
|
+
}
|
342
|
+
|
343
|
+
RB_GC_GUARD(rbReturnValue) = rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval);
|
344
|
+
RB_GC_GUARD(fnInfo->rbReturnType);
|
345
|
+
|
346
|
+
return rbReturnValue;
|
345
347
|
}
|
346
348
|
|
347
349
|
static inline void*
|
@@ -423,6 +425,7 @@ callback_param(VALUE proc, VALUE cbInfo)
|
|
423
425
|
|
424
426
|
//callback = rbffi_NativeCallback_ForProc(proc, cbInfo);
|
425
427
|
callback = rbffi_Function_ForProc(cbInfo, proc);
|
428
|
+
RB_GC_GUARD(callback);
|
426
429
|
|
427
430
|
return ((AbstractMemory *) DATA_PTR(callback))->address;
|
428
431
|
}
|
data/ext/ffi_c/ClosurePool.c
CHANGED
@@ -28,6 +28,7 @@
|
|
28
28
|
#ifndef _WIN32
|
29
29
|
# include <unistd.h>
|
30
30
|
#else
|
31
|
+
# define _WINSOCKAPI_
|
31
32
|
# include <windows.h>
|
32
33
|
#endif
|
33
34
|
#include <errno.h>
|
@@ -68,7 +69,7 @@ struct ClosurePool_ {
|
|
68
69
|
long refcnt;
|
69
70
|
};
|
70
71
|
|
71
|
-
static
|
72
|
+
static long pageSize;
|
72
73
|
|
73
74
|
static void* allocatePage(void);
|
74
75
|
static bool freePage(void *);
|
@@ -102,15 +103,14 @@ cleanup_closure_pool(ClosurePool* pool)
|
|
102
103
|
free(memory);
|
103
104
|
memory = next;
|
104
105
|
}
|
105
|
-
|
106
|
+
xfree(pool);
|
106
107
|
}
|
107
108
|
|
108
109
|
void
|
109
110
|
rbffi_ClosurePool_Free(ClosurePool* pool)
|
110
111
|
{
|
111
112
|
if (pool != NULL) {
|
112
|
-
|
113
|
-
refcnt = --(pool->refcnt);
|
113
|
+
long refcnt = --(pool->refcnt);
|
114
114
|
if (refcnt == 0) {
|
115
115
|
cleanup_closure_pool(pool);
|
116
116
|
}
|
@@ -124,7 +124,8 @@ rbffi_Closure_Alloc(ClosurePool* pool)
|
|
124
124
|
Memory* block = NULL;
|
125
125
|
caddr_t code = NULL;
|
126
126
|
char errmsg[256];
|
127
|
-
int nclosures
|
127
|
+
int nclosures;
|
128
|
+
long trampolineSize;
|
128
129
|
int i;
|
129
130
|
|
130
131
|
if (pool->list != NULL) {
|
@@ -136,7 +137,7 @@ rbffi_Closure_Alloc(ClosurePool* pool)
|
|
136
137
|
}
|
137
138
|
|
138
139
|
trampolineSize = roundup(pool->closureSize, 8);
|
139
|
-
nclosures = pageSize / trampolineSize;
|
140
|
+
nclosures = (int) (pageSize / trampolineSize);
|
140
141
|
block = calloc(1, sizeof(*block));
|
141
142
|
list = calloc(nclosures, sizeof(*list));
|
142
143
|
code = allocatePage();
|
@@ -192,7 +193,7 @@ rbffi_Closure_Free(Closure* closure)
|
|
192
193
|
{
|
193
194
|
if (closure != NULL) {
|
194
195
|
ClosurePool* pool = closure->pool;
|
195
|
-
|
196
|
+
long refcnt;
|
196
197
|
// Just push it on the front of the free list
|
197
198
|
closure->next = pool->list;
|
198
199
|
pool->list = closure;
|
@@ -210,7 +211,7 @@ rbffi_Closure_CodeAddress(Closure* handle)
|
|
210
211
|
}
|
211
212
|
|
212
213
|
|
213
|
-
static
|
214
|
+
static long
|
214
215
|
getPageSize()
|
215
216
|
{
|
216
217
|
#if defined(_WIN32) || defined(__WIN32__)
|
data/ext/ffi_c/DataConverter.c
CHANGED
@@ -11,6 +11,15 @@
|
|
11
11
|
VALUE rbffi_DataConverterClass = Qnil;
|
12
12
|
static ID id_native_type_ivar;
|
13
13
|
|
14
|
+
/*
|
15
|
+
* Get native type.
|
16
|
+
* @overload native_type(type)
|
17
|
+
* @param [String, Symbol, Type] type
|
18
|
+
* @return [Type]
|
19
|
+
* Get native type from +type+.
|
20
|
+
* @overload native_type
|
21
|
+
* @raise {NotImplementedError} This method must be overriden.
|
22
|
+
*/
|
14
23
|
static VALUE
|
15
24
|
conv_native_type(int argc, VALUE* argv, VALUE self)
|
16
25
|
{
|
@@ -33,12 +42,26 @@ conv_native_type(int argc, VALUE* argv, VALUE self)
|
|
33
42
|
}
|
34
43
|
}
|
35
44
|
|
45
|
+
/*
|
46
|
+
* call-seq: to_native(value, ctx)
|
47
|
+
* @param value
|
48
|
+
* @param ctx
|
49
|
+
* @return [value]
|
50
|
+
* Convert to a native type.
|
51
|
+
*/
|
36
52
|
static VALUE
|
37
53
|
conv_to_native(VALUE self, VALUE value, VALUE ctx)
|
38
54
|
{
|
39
55
|
return value;
|
40
56
|
}
|
41
57
|
|
58
|
+
/*
|
59
|
+
* call-seq: from_native(value, ctx)
|
60
|
+
* @param value
|
61
|
+
* @param ctx
|
62
|
+
* @return [value]
|
63
|
+
* Convert from a native type.
|
64
|
+
*/
|
42
65
|
static VALUE
|
43
66
|
conv_from_native(VALUE self, VALUE value, VALUE ctx)
|
44
67
|
{
|
@@ -50,6 +73,12 @@ conv_from_native(VALUE self, VALUE value, VALUE ctx)
|
|
50
73
|
void
|
51
74
|
rbffi_DataConverter_Init(VALUE moduleFFI)
|
52
75
|
{
|
76
|
+
/*
|
77
|
+
* Document-module: FFI::DataConverter
|
78
|
+
* This module is used to extend somes classes and give then a common API.
|
79
|
+
*
|
80
|
+
* Most of methods defined here must be overriden.
|
81
|
+
*/
|
53
82
|
rbffi_DataConverterClass = rb_define_module_under(moduleFFI, "DataConverter");
|
54
83
|
|
55
84
|
rb_define_method(rbffi_DataConverterClass, "native_type", conv_native_type, -1);
|