ffi 0.4.0 → 0.5.0

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 (55) hide show
  1. data/README.rdoc +15 -15
  2. data/Rakefile +57 -8
  3. data/ext/ffi_c/AbstractMemory.c +101 -24
  4. data/ext/ffi_c/AbstractMemory.h +98 -6
  5. data/ext/ffi_c/ArrayType.c +129 -0
  6. data/ext/ffi_c/ArrayType.h +58 -0
  7. data/ext/ffi_c/AutoPointer.c +1 -0
  8. data/ext/ffi_c/Buffer.c +59 -43
  9. data/ext/ffi_c/Call.c +853 -0
  10. data/ext/ffi_c/Call.h +86 -0
  11. data/ext/ffi_c/ClosurePool.c +302 -0
  12. data/ext/ffi_c/ClosurePool.h +29 -0
  13. data/ext/ffi_c/DynamicLibrary.c +3 -0
  14. data/ext/ffi_c/Function.c +478 -0
  15. data/ext/ffi_c/Function.h +80 -0
  16. data/ext/ffi_c/FunctionInfo.c +221 -0
  17. data/ext/ffi_c/LastError.c +30 -6
  18. data/ext/ffi_c/MemoryPointer.c +50 -28
  19. data/ext/ffi_c/MethodHandle.c +346 -0
  20. data/ext/ffi_c/MethodHandle.h +53 -0
  21. data/ext/ffi_c/Pointer.c +73 -13
  22. data/ext/ffi_c/Pointer.h +31 -7
  23. data/ext/ffi_c/Struct.c +517 -224
  24. data/ext/ffi_c/Struct.h +60 -6
  25. data/ext/ffi_c/StructByValue.c +140 -0
  26. data/ext/ffi_c/StructByValue.h +53 -0
  27. data/ext/ffi_c/StructLayout.c +450 -0
  28. data/ext/ffi_c/Type.c +121 -22
  29. data/ext/ffi_c/Type.h +37 -8
  30. data/ext/ffi_c/Types.c +46 -61
  31. data/ext/ffi_c/Types.h +38 -7
  32. data/ext/ffi_c/Variadic.c +260 -0
  33. data/ext/ffi_c/compat.h +53 -3
  34. data/ext/ffi_c/extconf.rb +6 -7
  35. data/ext/ffi_c/ffi.c +45 -39
  36. data/ext/ffi_c/libffi.darwin.mk +2 -2
  37. data/ext/ffi_c/rbffi.h +3 -0
  38. data/lib/ffi/ffi.rb +7 -4
  39. data/lib/ffi/library.rb +34 -59
  40. data/lib/ffi/platform.rb +14 -4
  41. data/lib/ffi/struct.rb +110 -281
  42. data/lib/ffi/union.rb +4 -9
  43. data/lib/ffi/variadic.rb +1 -6
  44. data/spec/ffi/buffer_spec.rb +6 -0
  45. data/spec/ffi/callback_spec.rb +34 -3
  46. data/spec/ffi/function_spec.rb +73 -0
  47. data/spec/ffi/library_spec.rb +56 -52
  48. data/spec/ffi/pointer_spec.rb +3 -3
  49. data/spec/ffi/struct_callback_spec.rb +26 -3
  50. data/spec/ffi/struct_spec.rb +56 -3
  51. metadata +42 -11
  52. data/ext/ffi_c/Callback.c +0 -374
  53. data/ext/ffi_c/Callback.h +0 -47
  54. data/ext/ffi_c/Invoker.c +0 -962
  55. data/ext/ffi_c/NullPointer.c +0 -143
@@ -0,0 +1,260 @@
1
+ /*
2
+ * Copyright (c) 2008, 2009, Wayne Meissner
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * * Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright notice
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * * The name of the author or authors may not be used to endorse or promote
14
+ * products derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #include <sys/param.h>
29
+ #include <sys/types.h>
30
+
31
+ #include <stdio.h>
32
+ #include <stdint.h>
33
+ #include <stdbool.h>
34
+ #include <ruby.h>
35
+
36
+ #include <ffi.h>
37
+ #include "rbffi.h"
38
+ #include "compat.h"
39
+
40
+ #include "AbstractMemory.h"
41
+ #include "Pointer.h"
42
+ #include "Types.h"
43
+ #include "Type.h"
44
+ #include "LastError.h"
45
+ #include "MethodHandle.h"
46
+ #include "Call.h"
47
+
48
+ typedef struct VariadicInvoker_ {
49
+ VALUE rbAddress;
50
+ VALUE rbReturnType;
51
+ VALUE rbEnums;
52
+
53
+ Type* returnType;
54
+ ffi_abi abi;
55
+ void* function;
56
+ int paramCount;
57
+ } VariadicInvoker;
58
+
59
+
60
+ static VALUE variadic_allocate(VALUE klass);
61
+ static VALUE variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes,
62
+ VALUE rbReturnType, VALUE options);
63
+ static void variadic_mark(VariadicInvoker *);
64
+
65
+ static VALUE classVariadicInvoker = Qnil;
66
+
67
+
68
+ static VALUE
69
+ variadic_allocate(VALUE klass)
70
+ {
71
+ VariadicInvoker *invoker;
72
+ VALUE obj = Data_Make_Struct(klass, VariadicInvoker, variadic_mark, -1, invoker);
73
+
74
+ invoker->rbAddress = Qnil;
75
+ invoker->rbEnums = Qnil;
76
+ invoker->rbReturnType = Qnil;
77
+
78
+ return obj;
79
+ }
80
+
81
+ static void
82
+ variadic_mark(VariadicInvoker *invoker)
83
+ {
84
+ rb_gc_mark(invoker->rbEnums);
85
+ rb_gc_mark(invoker->rbAddress);
86
+ rb_gc_mark(invoker->rbReturnType);
87
+ }
88
+
89
+ static VALUE
90
+ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE rbReturnType, VALUE options)
91
+ {
92
+ VariadicInvoker* invoker = NULL;
93
+ VALUE retval = Qnil;
94
+ VALUE convention = Qnil;
95
+ VALUE fixed = Qnil;
96
+ int i;
97
+
98
+ Check_Type(options, T_HASH);
99
+ convention = rb_hash_aref(options, ID2SYM(rb_intern("convention")));
100
+
101
+ Data_Get_Struct(self, VariadicInvoker, invoker);
102
+ invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums")));
103
+ invoker->rbAddress = rbFunction;
104
+ invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address;
105
+
106
+ #if defined(_WIN32) || defined(__WIN32__)
107
+ VALUE rbConventionStr = rb_funcall2(convention, rb_intern("to_s"), 0, NULL);
108
+ invoker->abi = (RTEST(convention) && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
109
+ ? FFI_STDCALL : FFI_DEFAULT_ABI;
110
+ #else
111
+ invoker->abi = FFI_DEFAULT_ABI;
112
+ #endif
113
+
114
+ invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType);
115
+ if (!RTEST(invoker->rbReturnType)) {
116
+ VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
117
+ rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
118
+ }
119
+
120
+ Data_Get_Struct(rbReturnType, Type, invoker->returnType);
121
+
122
+ invoker->paramCount = -1;
123
+
124
+ fixed = rb_ary_new2(RARRAY_LEN(rbParameterTypes) - 1);
125
+ for (i = 0; i < RARRAY_LEN(rbParameterTypes); ++i) {
126
+ VALUE entry = rb_ary_entry(rbParameterTypes, i);
127
+ VALUE rbType = rbffi_Type_Lookup(entry);
128
+ Type* type;
129
+
130
+ if (!RTEST(rbType)) {
131
+ VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
132
+ rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
133
+ }
134
+ Data_Get_Struct(rbType, Type, type);
135
+ if (type->nativeType != NATIVE_VARARGS) {
136
+ rb_ary_push(fixed, entry);
137
+ }
138
+ }
139
+ /*
140
+ * @fixed and @type_map are used by the parameter mangling ruby code
141
+ */
142
+ rb_iv_set(self, "@fixed", fixed);
143
+ rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map"))));
144
+
145
+ return retval;
146
+ }
147
+
148
+
149
+ static inline VALUE
150
+ ffi_invoke(ffi_cif* cif, void* function, Type* returnType, void** ffiValues,
151
+ VALUE rbReturnType, VALUE rbEnums)
152
+ {
153
+ FFIStorage retval;
154
+
155
+ #ifdef USE_RAW
156
+ ffi_raw_call(cif, function, &retval, (ffi_raw *) ffiValues[0]);
157
+ #else
158
+ ffi_call(cif, function, &retval, ffiValues);
159
+ #endif
160
+ rbffi_save_errno();
161
+
162
+ return rbffi_NativeValue_ToRuby(returnType, rbReturnType, &retval, rbEnums);
163
+ }
164
+
165
+ static VALUE
166
+ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
167
+ {
168
+ VariadicInvoker* invoker;
169
+ FFIStorage* params;
170
+ ffi_cif cif;
171
+ void** ffiValues;
172
+ ffi_type** ffiParamTypes;
173
+ ffi_type* ffiReturnType;
174
+ NativeType* paramTypes;
175
+ VALUE* argv;
176
+ int paramCount = 0, i;
177
+ ffi_status ffiStatus;
178
+
179
+ Check_Type(parameterTypes, T_ARRAY);
180
+ Check_Type(parameterValues, T_ARRAY);
181
+
182
+ Data_Get_Struct(self, VariadicInvoker, invoker);
183
+ paramCount = RARRAY_LEN(parameterTypes);
184
+ paramTypes = ALLOCA_N(NativeType, paramCount);
185
+ ffiParamTypes = ALLOCA_N(ffi_type *, paramCount);
186
+ params = ALLOCA_N(FFIStorage, paramCount);
187
+ ffiValues = ALLOCA_N(void*, paramCount);
188
+ argv = ALLOCA_N(VALUE, paramCount);
189
+
190
+ for (i = 0; i < paramCount; ++i) {
191
+ VALUE entry = rb_ary_entry(parameterTypes, i);
192
+ int paramType = rbffi_Type_GetIntValue(entry);
193
+ Type* type;
194
+ Data_Get_Struct(entry, Type, type);
195
+
196
+ switch (paramType) {
197
+ case NATIVE_INT8:
198
+ case NATIVE_INT16:
199
+ case NATIVE_INT32:
200
+ case NATIVE_ENUM:
201
+ paramType = NATIVE_INT32;
202
+ ffiParamTypes[i] = &ffi_type_sint;
203
+ break;
204
+ case NATIVE_UINT8:
205
+ case NATIVE_UINT16:
206
+ case NATIVE_UINT32:
207
+ paramType = NATIVE_UINT32;
208
+ ffiParamTypes[i] = &ffi_type_uint;
209
+ break;
210
+ case NATIVE_FLOAT32:
211
+ paramType = NATIVE_FLOAT64;
212
+ ffiParamTypes[i] = &ffi_type_double;
213
+ break;
214
+ default:
215
+ ffiParamTypes[i] = type->ffiType;
216
+ break;
217
+ }
218
+ paramTypes[i] = paramType;
219
+ if (ffiParamTypes[i] == NULL) {
220
+ rb_raise(rb_eArgError, "Invalid parameter type #%x", paramType);
221
+ }
222
+ argv[i] = rb_ary_entry(parameterValues, i);
223
+ }
224
+
225
+ ffiReturnType = invoker->returnType->ffiType;
226
+ if (ffiReturnType == NULL) {
227
+ rb_raise(rb_eArgError, "Invalid return type");
228
+ }
229
+ ffiStatus = ffi_prep_cif(&cif, invoker->abi, paramCount, ffiReturnType, ffiParamTypes);
230
+ switch (ffiStatus) {
231
+ case FFI_BAD_ABI:
232
+ rb_raise(rb_eArgError, "Invalid ABI specified");
233
+ case FFI_BAD_TYPEDEF:
234
+ rb_raise(rb_eArgError, "Invalid argument type specified");
235
+ case FFI_OK:
236
+ break;
237
+ default:
238
+ rb_raise(rb_eArgError, "Unknown FFI error");
239
+ }
240
+
241
+ rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
242
+ ffiValues, NULL, 0, invoker->rbEnums);
243
+
244
+ return ffi_invoke(&cif, invoker->function, invoker->returnType,
245
+ ffiValues, invoker->rbReturnType, invoker->rbEnums);
246
+ }
247
+
248
+
249
+ void
250
+ rbffi_Variadic_Init(VALUE moduleFFI)
251
+ {
252
+ classVariadicInvoker = rb_define_class_under(moduleFFI, "VariadicInvoker", rb_cObject);
253
+ rb_global_variable(&classVariadicInvoker);
254
+
255
+ rb_define_alloc_func(classVariadicInvoker, variadic_allocate);
256
+
257
+ rb_define_method(classVariadicInvoker, "initialize", variadic_initialize, 4);
258
+ rb_define_method(classVariadicInvoker, "invoke", variadic_invoke, 2);
259
+ }
260
+
data/ext/ffi_c/compat.h CHANGED
@@ -1,22 +1,72 @@
1
- #ifndef FFI_COMPAT_H
2
- #define FFI_COMPAT_H
1
+ /*
2
+ * Copyright (c) 2008, 2009, Wayne Meissner
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * * Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright notice
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * * The name of the author or authors may not be used to endorse or promote
14
+ * products derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #ifndef RBFFI_COMPAT_H
29
+ #define RBFFI_COMPAT_H
3
30
 
4
31
  #include <ruby.h>
5
32
 
6
33
  #ifndef RARRAY_LEN
7
34
  # define RARRAY_LEN(ary) RARRAY(ary)->len
8
35
  #endif
36
+
9
37
  #ifndef RARRAY_PTR
10
38
  # define RARRAY_PTR(ary) RARRAY(ary)->ptr
11
39
  #endif
40
+
12
41
  #ifndef RSTRING_LEN
13
42
  # define RSTRING_LEN(s) RSTRING(s)->len
14
43
  #endif
44
+
15
45
  #ifndef RSTRING_PTR
16
46
  # define RSTRING_PTR(s) RSTRING(s)->ptr
17
47
  #endif
48
+
18
49
  #ifndef NUM2ULL
19
50
  # define NUM2ULL(x) rb_num2ull((VALUE)x)
20
51
  #endif
21
52
 
22
- #endif /* FFI_COMPAT_H */
53
+ #ifndef roundup
54
+ # define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
55
+ #endif
56
+
57
+ #ifdef __GNUC__
58
+ # define likely(x) __builtin_expect((x), 1)
59
+ # define unlikely(x) __builtin_expect((x), 0)
60
+ #else
61
+ # define likely(x) (x)
62
+ # define unlikely(x) (x)
63
+ #endif
64
+
65
+ #ifndef MAX
66
+ # define MAX(a, b) ((a) < (b) ? (b) : (a))
67
+ #endif
68
+ #ifndef MIN
69
+ # define MIN(a, b) ((a) < (b) ? (a) : (b))
70
+ #endif
71
+
72
+ #endif /* RBFFI_COMPAT_H */
data/ext/ffi_c/extconf.rb CHANGED
@@ -2,24 +2,23 @@
2
2
  require 'mkmf'
3
3
  require 'rbconfig'
4
4
  dir_config("ffi_c")
5
- #IS_MAC = Config::CONFIG['host_os'] =~ /^darwin/
6
- #if IS_MAC
7
- # $CPPFLAGS << " -DMACOSX"
8
- # find_header("ffi.h", "/usr/include/ffi")
9
- #end
5
+
6
+ IS_MAC = Config::CONFIG['host_os'] =~ /^darwin/
10
7
  have_closure_alloc = have_library("ffi", "ffi_closure_alloc", [ "ffi.h" ])
11
8
  $defs.push("-DHAVE_FFI_CLOSURE_ALLOC") if have_closure_alloc
12
- libffi_ok = have_closure_alloc
9
+ libffi_ok = have_closure_alloc && !IS_MAC
13
10
  $defs << "-DHAVE_LIBFFI" if libffi_ok
14
11
  $defs << "-DHAVE_EXTCONF_H" if $defs.empty? # needed so create_header works
15
12
 
13
+ have_func('rb_thread_blocking_region')
14
+
16
15
  create_makefile("ffi_c")
17
16
  create_header("extconf.h")
18
17
  File.open("Makefile", "a") do |mf|
19
18
  mf.puts "CPPFLAGS += -Werror -Wunused -Wformat -Wimplicit -Wreturn-type"
20
19
  unless libffi_ok
21
20
  mf.puts "LIBFFI_HOST=--host=#{Config::CONFIG['host_alias']}" if Config::CONFIG.has_key?("host_alias")
22
- mf.puts "FFI_MMAP_EXEC=-DFFI_MMAP_EXEC_WRIT=#{Config::CONFIG['host_os'] =~ /win/ ? 0 : 1}"
21
+ mf.puts "FFI_MMAP_EXEC=-DFFI_MMAP_EXEC_WRIT=#{Config::CONFIG['host_os'] =~ /(win32|mingw)/ ? 0 : 1}"
23
22
  if Config::CONFIG['host_os'].downcase =~ /darwin/
24
23
  mf.puts "include ${srcdir}/libffi.darwin.mk"
25
24
  elsif Config::CONFIG['host_os'].downcase =~ /bsd/
data/ext/ffi_c/ffi.c CHANGED
@@ -1,3 +1,30 @@
1
+ /*
2
+ * Copyright (c) 2008, 2009, Wayne Meissner
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * * Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright notice
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * * The name of the author or authors may not be used to endorse or promote
14
+ * products derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
1
28
  #include <sys/types.h>
2
29
  #include <stdio.h>
3
30
  #include <ruby.h>
@@ -10,67 +37,46 @@
10
37
  #include "MemoryPointer.h"
11
38
  #include "AutoPointer.h"
12
39
  #include "Struct.h"
13
- #include "Callback.h"
40
+ #include "StructByValue.h"
14
41
  #include "DynamicLibrary.h"
15
42
  #include "Platform.h"
16
43
  #include "Types.h"
17
44
  #include "LastError.h"
45
+ #include "Function.h"
46
+ #include "ClosurePool.h"
47
+ #include "MethodHandle.h"
48
+ #include "Call.h"
49
+ #include "ArrayType.h"
18
50
 
51
+ void Init_ffi_c(void);
19
52
 
20
- void Init_ffi_c();
53
+ VALUE rbffi_FFIModule = Qnil;
21
54
 
22
55
  static VALUE moduleFFI = Qnil;
23
- static VALUE typeMap = Qnil, sizeMap = Qnil;
24
- static ID type_size_id = 0, size_id;
25
-
26
- int
27
- rbffi_type_size(VALUE type)
28
- {
29
- int t = TYPE(type);
30
- if (t == T_FIXNUM || t == T_BIGNUM) {
31
- return NUM2INT(type);
32
- } else if (t == T_SYMBOL) {
33
- /*
34
- * Try looking up directly in the type and size maps
35
- */
36
- VALUE nType;
37
- if ((nType = rb_hash_aref(typeMap, type)) != Qnil) {
38
- VALUE nSize = rb_hash_aref(sizeMap, nType);
39
- if (TYPE(nSize) == T_FIXNUM) {
40
- return FIX2INT(nSize);
41
- }
42
- }
43
- // Not found - call up to the ruby version to resolve
44
- return NUM2INT(rb_funcall2(moduleFFI, type_size_id, 1, &type));
45
- } else {
46
- return NUM2INT(rb_funcall2(type, size_id, 0, NULL));
47
- }
48
- }
49
56
 
50
57
  void
51
- Init_ffi_c() {
52
- moduleFFI = rb_define_module("FFI");
58
+ Init_ffi_c(void) {
59
+ rbffi_FFIModule = moduleFFI = rb_define_module("FFI");
53
60
  rb_global_variable(&moduleFFI);
54
- rb_define_const(moduleFFI, "TypeDefs", typeMap = rb_hash_new());
55
- rb_define_const(moduleFFI, "SizeTypes", sizeMap = rb_hash_new());
56
- rb_global_variable(&typeMap);
57
- rb_global_variable(&sizeMap);
58
- type_size_id = rb_intern("type_size");
59
- size_id = rb_intern("size");
60
61
 
62
+ // FFI::Type needs to be initialized before most other classes
61
63
  rbffi_Type_Init(moduleFFI);
64
+ rbffi_ArrayType_Init(moduleFFI);
62
65
  rbffi_LastError_Init(moduleFFI);
66
+ rbffi_Call_Init(moduleFFI);
67
+ rbffi_ClosurePool_Init(moduleFFI);
68
+ rbffi_MethodHandle_Init(moduleFFI);
63
69
  rbffi_Platform_Init(moduleFFI);
64
70
  rbffi_AbstractMemory_Init(moduleFFI);
65
71
  rbffi_Pointer_Init(moduleFFI);
66
72
  rbffi_AutoPointer_Init(moduleFFI);
67
- rbffi_NullPointer_Init(moduleFFI);
73
+ rbffi_Function_Init(moduleFFI);
68
74
  rbffi_MemoryPointer_Init(moduleFFI);
69
75
  rbffi_Buffer_Init(moduleFFI);
70
- rbffi_Callback_Init(moduleFFI);
76
+ rbffi_StructByValue_Init(moduleFFI);
71
77
  rbffi_Struct_Init(moduleFFI);
72
78
  rbffi_DynamicLibrary_Init(moduleFFI);
73
- rbffi_Invoker_Init(moduleFFI);
79
+ rbffi_Variadic_Init(moduleFFI);
74
80
  rbffi_Types_Init(moduleFFI);
75
81
  }
76
82