ffi 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/README.rdoc +51 -1
  2. data/Rakefile +38 -28
  3. data/ext/ffi_c/AbstractMemory.c +74 -70
  4. data/ext/ffi_c/AbstractMemory.h +8 -4
  5. data/ext/ffi_c/AutoPointer.c +8 -9
  6. data/ext/ffi_c/AutoPointer.h +2 -2
  7. data/ext/ffi_c/Buffer.c +42 -24
  8. data/ext/ffi_c/Callback.c +85 -33
  9. data/ext/ffi_c/Callback.h +11 -5
  10. data/ext/ffi_c/{NativeLibrary.c → DynamicLibrary.c} +83 -16
  11. data/ext/ffi_c/{NativeLibrary.h → DynamicLibrary.h} +1 -1
  12. data/ext/ffi_c/Invoker.c +152 -192
  13. data/ext/ffi_c/LastError.c +135 -0
  14. data/ext/ffi_c/LastError.h +18 -0
  15. data/ext/ffi_c/MemoryPointer.c +27 -20
  16. data/ext/ffi_c/MemoryPointer.h +3 -3
  17. data/ext/ffi_c/NullPointer.c +51 -47
  18. data/ext/ffi_c/Platform.c +9 -10
  19. data/ext/ffi_c/Platform.h +1 -1
  20. data/ext/ffi_c/Pointer.c +52 -21
  21. data/ext/ffi_c/Pointer.h +8 -6
  22. data/ext/ffi_c/Struct.c +70 -61
  23. data/ext/ffi_c/Struct.h +2 -2
  24. data/ext/ffi_c/Type.c +230 -0
  25. data/ext/ffi_c/Type.h +28 -0
  26. data/ext/ffi_c/Types.c +48 -6
  27. data/ext/ffi_c/Types.h +8 -2
  28. data/ext/ffi_c/endian.h +40 -0
  29. data/ext/ffi_c/extconf.rb +6 -5
  30. data/ext/ffi_c/ffi.c +21 -44
  31. data/ext/ffi_c/libffi.bsd.mk +34 -0
  32. data/ext/ffi_c/libffi.darwin.mk +30 -10
  33. data/ext/ffi_c/libffi.gnu.mk +29 -0
  34. data/ext/ffi_c/libffi.mk +4 -2
  35. data/ext/ffi_c/rbffi.h +6 -8
  36. data/gen/Rakefile +12 -0
  37. data/lib/ffi/autopointer.rb +1 -1
  38. data/lib/ffi/enum.rb +78 -0
  39. data/lib/ffi/ffi.rb +5 -6
  40. data/lib/ffi/io.rb +15 -1
  41. data/lib/ffi/library.rb +79 -18
  42. data/lib/ffi/pointer.rb +2 -2
  43. data/lib/ffi/struct.rb +68 -14
  44. data/lib/ffi/types.rb +6 -3
  45. data/lib/ffi/variadic.rb +2 -2
  46. data/lib/ffi.rb +10 -1
  47. data/spec/ffi/bool_spec.rb +24 -0
  48. data/spec/ffi/callback_spec.rb +217 -17
  49. data/spec/ffi/enum_spec.rb +164 -0
  50. data/spec/ffi/managed_struct_spec.rb +6 -1
  51. data/spec/ffi/number_spec.rb +30 -0
  52. data/spec/ffi/pointer_spec.rb +33 -8
  53. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -6
  54. data/spec/ffi/spec_helper.rb +5 -1
  55. data/spec/ffi/string_spec.rb +65 -4
  56. data/spec/ffi/struct_callback_spec.rb +41 -0
  57. data/spec/ffi/struct_initialize_spec.rb +30 -0
  58. data/spec/ffi/struct_spec.rb +44 -21
  59. metadata +31 -69
  60. data/ext/ffi_c/ffi.mk +0 -23
  61. data/nbproject/Makefile-Default.mk +0 -57
  62. data/nbproject/Makefile-impl.mk +0 -123
  63. data/nbproject/Package-Default.bash +0 -72
  64. data/nbproject/configurations.xml +0 -293
  65. data/nbproject/private/configurations.xml +0 -22
  66. data/nbproject/private/private.xml +0 -7
  67. data/nbproject/project.properties +0 -0
  68. data/nbproject/project.xml +0 -15
  69. data/samples/getlogin.rb +0 -7
  70. data/samples/getpid.rb +0 -7
  71. data/samples/gettimeofday.rb +0 -17
  72. data/samples/hello.rb +0 -6
  73. data/samples/inotify.rb +0 -59
  74. data/samples/pty.rb +0 -75
  75. data/samples/qsort.rb +0 -20
  76. data/samples/sample_helper.rb +0 -6
@@ -0,0 +1,135 @@
1
+ #include <sys/param.h>
2
+ #include <sys/types.h>
3
+ #include <stdio.h>
4
+ #include <stdint.h>
5
+ #include <stdbool.h>
6
+ #include <errno.h>
7
+ #include <ruby.h>
8
+
9
+ #include "LastError.h"
10
+
11
+ #if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
12
+ # include <pthread.h>
13
+ #endif
14
+
15
+ #if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
16
+ # define USE_PTHREAD_LOCAL
17
+ #endif
18
+
19
+ typedef struct ThreadData {
20
+ int td_errno;
21
+ } ThreadData;
22
+
23
+ #if defined(USE_PTHREAD_LOCAL)
24
+ static pthread_key_t threadDataKey;
25
+ #endif
26
+
27
+ static inline ThreadData* thread_data_get(void);
28
+
29
+ #if defined(USE_PTHREAD_LOCAL)
30
+
31
+ static ThreadData*
32
+ thread_data_init(void)
33
+ {
34
+ ThreadData* td = ALLOC_N(ThreadData, 1);
35
+
36
+ memset(td, 0, sizeof(*td));
37
+ pthread_setspecific(threadDataKey, td);
38
+
39
+ return td;
40
+ }
41
+
42
+
43
+ static inline ThreadData*
44
+ thread_data_get(void)
45
+ {
46
+ ThreadData* td = pthread_getspecific(threadDataKey);
47
+ return td != NULL ? td : thread_data_init();
48
+ }
49
+
50
+ static void
51
+ thread_data_free(void *ptr)
52
+ {
53
+ xfree(ptr);
54
+ }
55
+
56
+ #else
57
+ static ID id_thread_data;
58
+
59
+ static ThreadData*
60
+ thread_data_init(void)
61
+ {
62
+ ThreadData* td;
63
+ VALUE obj;
64
+
65
+ obj = Data_Make_Struct(rb_cObject, ThreadData, NULL, -1, td);
66
+ rb_thread_local_aset(rb_thread_current(), id_thread_data, obj);
67
+
68
+ return td;
69
+ }
70
+
71
+ static inline ThreadData*
72
+ thread_data_get()
73
+ {
74
+ VALUE obj = rb_thread_local_aref(rb_thread_current(), id_thread_data);
75
+
76
+ if (obj != Qnil && TYPE(obj) == T_DATA) {
77
+ return (ThreadData *) DATA_PTR(obj);
78
+ }
79
+
80
+ return thread_data_init();
81
+ }
82
+
83
+ #endif
84
+
85
+
86
+ static VALUE
87
+ get_last_error(VALUE self)
88
+ {
89
+ return INT2NUM(thread_data_get()->td_errno);
90
+ }
91
+
92
+
93
+ static VALUE
94
+ set_last_error(VALUE self, VALUE error)
95
+ {
96
+
97
+ #ifdef _WIN32
98
+ SetLastError(NUM2INT(error));
99
+ #else
100
+ errno = NUM2INT(error);
101
+ #endif
102
+
103
+ return Qnil;
104
+ }
105
+
106
+
107
+ void
108
+ rbffi_save_errno(void)
109
+ {
110
+ int error = 0;
111
+
112
+ #ifdef _WIN32
113
+ error = GetLastError();
114
+ #else
115
+ error = errno;
116
+ #endif
117
+
118
+ thread_data_get()->td_errno = error;
119
+ }
120
+
121
+
122
+ void
123
+ rbffi_LastError_Init(VALUE moduleFFI)
124
+ {
125
+ VALUE moduleError = rb_define_module_under(moduleFFI, "LastError");
126
+
127
+ rb_define_module_function(moduleError, "error", get_last_error, 0);
128
+ rb_define_module_function(moduleError, "error=", set_last_error, 1);
129
+
130
+ #if defined(USE_PTHREAD_LOCAL)
131
+ pthread_key_create(&threadDataKey, thread_data_free);
132
+ #else
133
+ id_thread_data = rb_intern("ffi_thread_local_data");
134
+ #endif /* USE_PTHREAD_LOCAL */
135
+ }
@@ -0,0 +1,18 @@
1
+ #ifndef RBFFI_LASTERROR_H
2
+ #define RBFFI_LASTERROR_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+
9
+ void rbffi_LastError_Init(VALUE moduleFFI);
10
+
11
+ void rbffi_save_errno(void);
12
+
13
+ #ifdef __cplusplus
14
+ }
15
+ #endif
16
+
17
+ #endif /* RBFFI_LASTERROR_H */
18
+
@@ -20,14 +20,16 @@ static void memptr_release(MemoryPointer* ptr);
20
20
  static VALUE memptr_malloc(VALUE self, long size, long count, bool clear);
21
21
  static VALUE memptr_free(VALUE self);
22
22
 
23
- VALUE rb_FFI_MemoryPointer_class;
24
- static VALUE classMemoryPointer = Qnil;
25
- #define MEMPTR(obj) ((MemoryPointer *) rb_FFI_AbstractMemory_cast(obj, rb_FFI_MemoryPointer_class))
23
+ VALUE rbffi_MemoryPointerClass;
24
+
25
+ #define MEMPTR(obj) ((MemoryPointer *) rbffi_AbstractMemory_Cast(obj, rbffi_MemoryPointerClass))
26
+
27
+ static ID plus_id = 0;
26
28
 
27
29
  VALUE
28
- rb_FFI_MemoryPointer_new(long size, long count, bool clear)
30
+ rbffi_MemoryPointer_NewInstance(long size, long count, bool clear)
29
31
  {
30
- return memptr_malloc(memptr_allocate(classMemoryPointer), size, count, clear);
32
+ return memptr_malloc(memptr_allocate(rbffi_MemoryPointerClass), size, count, clear);
31
33
  }
32
34
 
33
35
  static VALUE
@@ -35,7 +37,7 @@ memptr_allocate(VALUE klass)
35
37
  {
36
38
  MemoryPointer* p;
37
39
  VALUE obj = Data_Make_Struct(klass, MemoryPointer, NULL, memptr_release, p);
38
- p->memory.ops = &rb_FFI_AbstractMemory_ops;
40
+ p->memory.ops = &rbffi_AbstractMemoryOps;
39
41
 
40
42
  return obj;
41
43
  }
@@ -45,12 +47,14 @@ memptr_initialize(int argc, VALUE* argv, VALUE self)
45
47
  {
46
48
  VALUE size = Qnil, count = Qnil, clear = Qnil;
47
49
  int nargs = rb_scan_args(argc, argv, "12", &size, &count, &clear);
48
- memptr_malloc(self, rb_FFI_type_size(size), nargs > 1 ? NUM2LONG(count) : 1,
49
- nargs > 2 && RTEST(clear));
50
+
51
+ memptr_malloc(self, rbffi_type_size(size), nargs > 1 ? NUM2LONG(count) : 1,
52
+ RTEST(clear) || clear == Qnil);
50
53
 
51
54
  if (rb_block_given_p()) {
52
- return rb_rescue(rb_yield, self, memptr_free, self);
55
+ return rb_ensure(rb_yield, self, memptr_free, self);
53
56
  }
57
+
54
58
  return self;
55
59
  }
56
60
 
@@ -100,7 +104,7 @@ memptr_aref(VALUE self, VALUE which)
100
104
  {
101
105
  MemoryPointer* ptr = MEMPTR(self);
102
106
  VALUE offset = INT2NUM(ptr->type_size * NUM2INT(which));
103
- return rb_funcall2(self, rb_intern("+"), 1, &offset);
107
+ return rb_funcall2(self, plus_id, 1, &offset);
104
108
  }
105
109
 
106
110
  static VALUE
@@ -135,15 +139,18 @@ memptr_release(MemoryPointer* ptr)
135
139
  }
136
140
 
137
141
  void
138
- rb_FFI_MemoryPointer_Init()
142
+ rbffi_MemoryPointer_Init(VALUE moduleFFI)
139
143
  {
140
- VALUE moduleFFI = rb_define_module("FFI");
141
- rb_FFI_MemoryPointer_class = classMemoryPointer = rb_define_class_under(moduleFFI, "MemoryPointer", rb_FFI_Pointer_class);
142
- rb_define_alloc_func(classMemoryPointer, memptr_allocate);
143
- rb_define_method(classMemoryPointer, "initialize", memptr_initialize, -1);
144
- rb_define_method(classMemoryPointer, "inspect", memptr_inspect, 0);
145
- rb_define_method(classMemoryPointer, "autorelease=", memptr_autorelease, 1);
146
- rb_define_method(classMemoryPointer, "free", memptr_free, 0);
147
- rb_define_method(classMemoryPointer, "type_size", memptr_type_size, 0);
148
- rb_define_method(classMemoryPointer, "[]", memptr_aref, 1);
144
+ rbffi_MemoryPointerClass = rb_define_class_under(moduleFFI, "MemoryPointer", rbffi_PointerClass);
145
+ rb_global_variable(&rbffi_MemoryPointerClass);
146
+
147
+ rb_define_alloc_func(rbffi_MemoryPointerClass, memptr_allocate);
148
+ rb_define_method(rbffi_MemoryPointerClass, "initialize", memptr_initialize, -1);
149
+ rb_define_method(rbffi_MemoryPointerClass, "inspect", memptr_inspect, 0);
150
+ rb_define_method(rbffi_MemoryPointerClass, "autorelease=", memptr_autorelease, 1);
151
+ rb_define_method(rbffi_MemoryPointerClass, "free", memptr_free, 0);
152
+ rb_define_method(rbffi_MemoryPointerClass, "type_size", memptr_type_size, 0);
153
+ rb_define_method(rbffi_MemoryPointerClass, "[]", memptr_aref, 1);
154
+
155
+ plus_id = rb_intern("+");
149
156
  }
@@ -9,9 +9,9 @@
9
9
  extern "C" {
10
10
  #endif
11
11
 
12
- extern void rb_FFI_MemoryPointer_Init();
13
- extern VALUE rb_FFI_MemoryPointer_class;
14
- extern VALUE rb_FFI_MemoryPointer_new(long size, long count, bool clear);
12
+ extern void rbffi_MemoryPointer_Init(VALUE moduleFFI);
13
+ extern VALUE rbffi_MemoryPointerClass;
14
+ extern VALUE rbffi_MemoryPointer_NewInstance(long size, long count, bool clear);
15
15
  #ifdef __cplusplus
16
16
  }
17
17
  #endif
@@ -7,15 +7,13 @@
7
7
  #include "AbstractMemory.h"
8
8
  #include "Pointer.h"
9
9
 
10
- static VALUE NullPointerError;
11
- static VALUE classNullPointer;
12
- static MemoryOps nullptr_ops;
10
+ static VALUE NullPointerErrorClass;
13
11
 
14
- VALUE rb_FFI_NullPointer_class;
15
- VALUE rb_FFI_NullPointer_singleton;
12
+ VALUE rbffi_NullPointerClass;
13
+ VALUE rbffi_NullPointerSingleton;
16
14
 
17
- VALUE
18
- rb_FFI_NullPointer_allocate(VALUE klass)
15
+ static VALUE
16
+ nullptr_allocate(VALUE klass)
19
17
  {
20
18
  AbstractMemory* p;
21
19
  VALUE retval;
@@ -23,7 +21,7 @@ rb_FFI_NullPointer_allocate(VALUE klass)
23
21
  retval = Data_Make_Struct(klass, AbstractMemory, NULL, -1, p);
24
22
  p->address = 0;
25
23
  p->size = 0;
26
- p->ops = &nullptr_ops;
24
+ p->ops = &rbffi_NullPointerOps;
27
25
 
28
26
  return retval;
29
27
  }
@@ -31,19 +29,21 @@ rb_FFI_NullPointer_allocate(VALUE klass)
31
29
  static VALUE
32
30
  nullptr_op(int argc, VALUE* argv, VALUE self)
33
31
  {
34
- rb_raise(NullPointerError, "NULL Pointer access attempted");
32
+ rb_raise(NullPointerErrorClass, "NULL Pointer access attempted");
33
+ return Qnil;
35
34
  }
36
35
 
37
36
  static VALUE
38
37
  nullptr_op_get(AbstractMemory* ptr, long offset)
39
38
  {
40
- rb_raise(NullPointerError, "NULL Pointer access attempted");
39
+ rb_raise(NullPointerErrorClass, "NULL Pointer access attempted");
40
+ return Qnil;
41
41
  }
42
42
 
43
43
  static void
44
44
  nullptr_op_put(AbstractMemory* ptr, long offset, VALUE value)
45
45
  {
46
- rb_raise(NullPointerError, "NULL Pointer access attempted");
46
+ rb_raise(NullPointerErrorClass, "NULL Pointer access attempted");
47
47
  }
48
48
 
49
49
  static VALUE
@@ -63,7 +63,7 @@ nullptr_equals(VALUE self, VALUE other)
63
63
  {
64
64
  AbstractMemory* p2;
65
65
 
66
- if (!rb_obj_is_kind_of(other, rb_FFI_Pointer_class)) {
66
+ if (!rb_obj_is_kind_of(other, rbffi_PointerClass)) {
67
67
  rb_raise(rb_eArgError, "Comparing Pointer with non Pointer");
68
68
  }
69
69
 
@@ -78,41 +78,44 @@ nullptr_address(VALUE self)
78
78
  return INT2NUM(0);
79
79
  }
80
80
 
81
- static MemoryOp nullptr_memory_op = { nullptr_op_get, nullptr_op_put };
82
-
83
- static MemoryOps nullptr_ops = {
84
- .int8 = &nullptr_memory_op,
85
- .uint8 = &nullptr_memory_op,
86
- .int16 = &nullptr_memory_op,
87
- .int16 = &nullptr_memory_op,
88
- .int32 = &nullptr_memory_op,
89
- .uint32 = &nullptr_memory_op,
90
- .int64 = &nullptr_memory_op,
91
- .uint64 = &nullptr_memory_op,
92
- .float32 = &nullptr_memory_op,
93
- .float64 = &nullptr_memory_op,
94
- .pointer = &nullptr_memory_op,
95
- .strptr = &nullptr_memory_op,
81
+ static MemoryOp NullPointerMemoryOp = { nullptr_op_get, nullptr_op_put };
82
+
83
+ MemoryOps rbffi_NullPointerOps = {
84
+ .int8 = &NullPointerMemoryOp,
85
+ .uint8 = &NullPointerMemoryOp,
86
+ .int16 = &NullPointerMemoryOp,
87
+ .int16 = &NullPointerMemoryOp,
88
+ .int32 = &NullPointerMemoryOp,
89
+ .uint32 = &NullPointerMemoryOp,
90
+ .int64 = &NullPointerMemoryOp,
91
+ .uint64 = &NullPointerMemoryOp,
92
+ .float32 = &NullPointerMemoryOp,
93
+ .float64 = &NullPointerMemoryOp,
94
+ .pointer = &NullPointerMemoryOp,
95
+ .strptr = &NullPointerMemoryOp,
96
96
  };
97
97
 
98
98
  void
99
- rb_FFI_NullPointer_Init()
99
+ rbffi_NullPointer_Init(VALUE moduleFFI)
100
100
  {
101
- VALUE moduleFFI = rb_define_module("FFI");
102
- rb_FFI_NullPointer_class = classNullPointer = rb_define_class_under(moduleFFI, "NullPointer", rb_FFI_Pointer_class);
103
- NullPointerError = rb_define_class_under(moduleFFI, "NullPointerError", rb_eRuntimeError);
104
- rb_define_alloc_func(classNullPointer, rb_FFI_NullPointer_allocate);
105
- rb_define_method(classNullPointer, "inspect", nullptr_inspect, 0);
106
- rb_define_method(classNullPointer, "+", nullptr_op, -1);
107
- rb_define_method(classNullPointer, "null?", nullptr_null_p, 0);
108
- rb_define_method(classNullPointer, "address", nullptr_address, 0);
109
- rb_define_method(classNullPointer, "==", nullptr_equals, 1);
101
+ rbffi_NullPointerClass = rb_define_class_under(moduleFFI, "NullPointer", rbffi_PointerClass);
102
+ rb_global_variable(&rbffi_NullPointerClass);
103
+
104
+ NullPointerErrorClass = rb_define_class_under(moduleFFI, "NullPointerError", rb_eRuntimeError);
105
+ rb_global_variable(&NullPointerErrorClass);
106
+
107
+ rb_define_alloc_func(rbffi_NullPointerClass, nullptr_allocate);
108
+ rb_define_method(rbffi_NullPointerClass, "inspect", nullptr_inspect, 0);
109
+ rb_define_method(rbffi_NullPointerClass, "+", nullptr_op, -1);
110
+ rb_define_method(rbffi_NullPointerClass, "null?", nullptr_null_p, 0);
111
+ rb_define_method(rbffi_NullPointerClass, "address", nullptr_address, 0);
112
+ rb_define_method(rbffi_NullPointerClass, "==", nullptr_equals, 1);
110
113
 
111
114
  #define NOP(name) \
112
- rb_define_method(classNullPointer, "get_" #name, nullptr_op, -1); \
113
- rb_define_method(classNullPointer, "put_" #name, nullptr_op, -1); \
114
- rb_define_method(classNullPointer, "get_array_of_" #name, nullptr_op, -1); \
115
- rb_define_method(classNullPointer, "put_array_of_" #name, nullptr_op, -1); \
115
+ rb_define_method(rbffi_NullPointerClass, "get_" #name, nullptr_op, -1); \
116
+ rb_define_method(rbffi_NullPointerClass, "put_" #name, nullptr_op, -1); \
117
+ rb_define_method(rbffi_NullPointerClass, "get_array_of_" #name, nullptr_op, -1); \
118
+ rb_define_method(rbffi_NullPointerClass, "put_array_of_" #name, nullptr_op, -1); \
116
119
 
117
120
 
118
121
  NOP(int8); NOP(uint8); NOP(int16); NOP(uint16);
@@ -124,16 +127,17 @@ rb_FFI_NullPointer_Init()
124
127
 
125
128
  #undef NOP
126
129
  #define NOP(name) \
127
- rb_define_method(classNullPointer, "get_" #name, nullptr_op, -1); \
128
- rb_define_method(classNullPointer, "put_" #name, nullptr_op, -1);
130
+ rb_define_method(rbffi_NullPointerClass, "get_" #name, nullptr_op, -1); \
131
+ rb_define_method(rbffi_NullPointerClass, "put_" #name, nullptr_op, -1);
129
132
 
130
133
  NOP(string); NOP(bytes); NOP(pointer); NOP(callback);
131
134
 
132
- rb_define_method(classNullPointer, "clear", nullptr_op, -1); \
133
- rb_define_method(classNullPointer, "total", nullptr_op, -1);
135
+ rb_define_method(rbffi_NullPointerClass, "clear", nullptr_op, -1); \
136
+ rb_define_method(rbffi_NullPointerClass, "total", nullptr_op, -1);
134
137
 
135
138
  // Create a singleton instance of NullPointer that can be shared
136
- rb_FFI_NullPointer_singleton = rb_FFI_NullPointer_allocate(classNullPointer);
137
- rb_gc_register_address(&rb_FFI_NullPointer_singleton);
139
+ rbffi_NullPointerSingleton = nullptr_allocate(rbffi_NullPointerClass);
140
+ rb_global_variable(&rbffi_NullPointerSingleton);
141
+ rb_define_const(rbffi_PointerClass, "NULL", rbffi_NullPointerSingleton);
138
142
  }
139
143
 
data/ext/ffi_c/Platform.c CHANGED
@@ -4,9 +4,10 @@
4
4
  #include <stdbool.h>
5
5
  #include <ruby.h>
6
6
  #include <ctype.h>
7
+ #include "endian.h"
7
8
  #include "Platform.h"
8
9
 
9
- static VALUE modulePlatform = Qnil;
10
+ static VALUE PlatformModule = Qnil;
10
11
 
11
12
  /*
12
13
  * Determine the cpu type at compile time - useful for MacOSX where the the
@@ -47,14 +48,12 @@ export_primitive_types(VALUE module)
47
48
  }
48
49
 
49
50
  void
50
- rb_FFI_Platform_Init()
51
+ rbffi_Platform_Init(VALUE moduleFFI)
51
52
  {
52
- VALUE moduleFFI = rb_define_module("FFI");
53
- VALUE platform = rb_define_module_under(moduleFFI, "Platform");
54
- rb_define_const(platform, "BYTE_ORDER", INT2FIX(BYTE_ORDER));
55
- rb_define_const(platform, "LITTLE_ENDIAN", INT2FIX(LITTLE_ENDIAN));
56
- rb_define_const(platform, "BIG_ENDIAN", INT2FIX(BIG_ENDIAN));
57
- rb_define_const(platform, "CPU", rb_str_new2(CPU));
58
- export_primitive_types(platform);
59
- modulePlatform = platform;
53
+ PlatformModule = rb_define_module_under(moduleFFI, "Platform");
54
+ rb_define_const(PlatformModule, "BYTE_ORDER", INT2FIX(BYTE_ORDER));
55
+ rb_define_const(PlatformModule, "LITTLE_ENDIAN", INT2FIX(LITTLE_ENDIAN));
56
+ rb_define_const(PlatformModule, "BIG_ENDIAN", INT2FIX(BIG_ENDIAN));
57
+ rb_define_const(PlatformModule, "CPU", rb_str_new2(CPU));
58
+ export_primitive_types(PlatformModule);
60
59
  }
data/ext/ffi_c/Platform.h CHANGED
@@ -5,7 +5,7 @@
5
5
  extern "C" {
6
6
  #endif
7
7
 
8
- extern void rb_FFI_Platform_Init();
8
+ extern void rbffi_Platform_Init(VALUE moduleFFI);
9
9
 
10
10
 
11
11
  #ifdef __cplusplus
data/ext/ffi_c/Pointer.c CHANGED
@@ -11,26 +11,25 @@ typedef struct Pointer {
11
11
  VALUE parent;
12
12
  } Pointer;
13
13
 
14
- #define POINTER(obj) rb_FFI_AbstractMemory_cast((obj), rb_FFI_Pointer_class)
14
+ #define POINTER(obj) rbffi_AbstractMemory_Cast((obj), rbffi_PointerClass)
15
15
 
16
- VALUE rb_FFI_Pointer_class;
17
- static VALUE classPointer = Qnil;
16
+ VALUE rbffi_PointerClass;
18
17
  static void ptr_mark(Pointer* ptr);
19
18
 
20
19
  VALUE
21
- rb_FFI_Pointer_new(void* addr)
20
+ rbffi_Pointer_NewInstance(void* addr)
22
21
  {
23
22
  Pointer* p;
24
23
  VALUE obj;
25
24
 
26
25
  if (addr == NULL) {
27
- return rb_FFI_NullPointer_singleton;
26
+ return rbffi_NullPointerSingleton;
28
27
  }
29
28
 
30
- obj = Data_Make_Struct(classPointer, Pointer, NULL, -1, p);
29
+ obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
31
30
  p->memory.address = addr;
32
31
  p->memory.size = LONG_MAX;
33
- p->memory.ops = &rb_FFI_AbstractMemory_ops;
32
+ p->memory.ops = &rbffi_AbstractMemoryOps;
34
33
  p->parent = Qnil;
35
34
 
36
35
  return obj;
@@ -42,12 +41,43 @@ ptr_allocate(VALUE klass)
42
41
  Pointer* p;
43
42
  VALUE obj;
44
43
 
45
- obj = Data_Make_Struct(classPointer, Pointer, NULL, -1, p);
44
+ obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
46
45
  p->parent = Qnil;
46
+ p->memory.ops = &rbffi_AbstractMemoryOps;
47
47
 
48
48
  return obj;
49
49
  }
50
50
 
51
+ static VALUE
52
+ ptr_initialize(int argc, VALUE* argv, VALUE self)
53
+ {
54
+ Pointer* p;
55
+ VALUE type, address;
56
+
57
+ Data_Get_Struct(self, Pointer, p);
58
+
59
+ switch (rb_scan_args(argc, argv, "11", &type, &address)) {
60
+ case 1:
61
+ p->memory.address = (void*)(uintptr_t) NUM2LL(type);
62
+ // FIXME set type_size to 1
63
+ break;
64
+ case 2:
65
+ p->memory.address = (void*)(uintptr_t) NUM2LL(address);
66
+ // FIXME set type_size to rbffi_type_size(type)
67
+ break;
68
+ default:
69
+ rb_raise(rb_eArgError, "Invalid arguments");
70
+ }
71
+ if (p->memory.address == NULL) {
72
+ p->memory.ops = &rbffi_NullPointerOps;
73
+ }
74
+
75
+ p->memory.size = LONG_MAX;
76
+
77
+ return self;
78
+ }
79
+
80
+
51
81
  static VALUE
52
82
  ptr_plus(VALUE self, VALUE offset)
53
83
  {
@@ -59,11 +89,11 @@ ptr_plus(VALUE self, VALUE offset)
59
89
  Data_Get_Struct(self, AbstractMemory, ptr);
60
90
  checkBounds(ptr, off, 1);
61
91
 
62
- retval = Data_Make_Struct(classPointer, Pointer, ptr_mark, -1, p);
92
+ retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p);
63
93
 
64
94
  p->memory.address = ptr->address + off;
65
95
  p->memory.size = ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off;
66
- p->memory.ops = &rb_FFI_AbstractMemory_ops;
96
+ p->memory.ops = &rbffi_AbstractMemoryOps;
67
97
  p->parent = self;
68
98
 
69
99
  return retval;
@@ -118,16 +148,17 @@ ptr_mark(Pointer* ptr)
118
148
  }
119
149
 
120
150
  void
121
- rb_FFI_Pointer_Init()
151
+ rbffi_Pointer_Init(VALUE moduleFFI)
122
152
  {
123
- VALUE moduleFFI = rb_define_module("FFI");
124
- rb_FFI_Pointer_class = classPointer = rb_define_class_under(moduleFFI, "Pointer", rb_FFI_AbstractMemory_class);
125
- rb_global_variable(&rb_FFI_Pointer_class);
126
-
127
- rb_define_alloc_func(classPointer, ptr_allocate);
128
- rb_define_method(classPointer, "inspect", ptr_inspect, 0);
129
- rb_define_method(classPointer, "+", ptr_plus, 1);
130
- rb_define_method(classPointer, "null?", ptr_null_p, 0);
131
- rb_define_method(classPointer, "address", ptr_address, 0);
132
- rb_define_method(classPointer, "==", ptr_equals, 1);
153
+ rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", rbffi_AbstractMemoryClass);
154
+ rb_global_variable(&rbffi_PointerClass);
155
+
156
+ rb_define_alloc_func(rbffi_PointerClass, ptr_allocate);
157
+ rb_define_method(rbffi_PointerClass, "initialize", ptr_initialize, -1);
158
+ rb_define_method(rbffi_PointerClass, "inspect", ptr_inspect, 0);
159
+ rb_define_method(rbffi_PointerClass, "+", ptr_plus, 1);
160
+ rb_define_method(rbffi_PointerClass, "null?", ptr_null_p, 0);
161
+ rb_define_method(rbffi_PointerClass, "address", ptr_address, 0);
162
+ rb_define_alias(rbffi_PointerClass, "to_i", "address");
163
+ rb_define_method(rbffi_PointerClass, "==", ptr_equals, 1);
133
164
  }
data/ext/ffi_c/Pointer.h CHANGED
@@ -6,14 +6,16 @@
6
6
  extern "C" {
7
7
  #endif
8
8
 
9
+ #include "AbstractMemory.h"
9
10
 
11
+ extern void rbffi_Pointer_Init(VALUE moduleFFI);
12
+ extern void rbffi_NullPointer_Init(VALUE moduleFFI);
13
+ extern VALUE rbffi_Pointer_NewInstance(void* addr);
14
+ extern VALUE rbffi_PointerClass;
15
+ extern VALUE rbffi_NullPointerClass;
16
+ extern VALUE rbffi_NullPointerSingleton;
17
+ extern MemoryOps rbffi_NullPointerOps;
10
18
 
11
- extern void rb_FFI_Pointer_Init(void);
12
- extern void rb_FFI_NullPointer_Init();
13
- extern VALUE rb_FFI_Pointer_new(void* addr);
14
- extern VALUE rb_FFI_Pointer_class;
15
- extern VALUE rb_FFI_NullPointer_class;
16
- extern VALUE rb_FFI_NullPointer_singleton;
17
19
 
18
20
  #ifdef __cplusplus
19
21
  }