ffi 0.3.0 → 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 +47 -28
  3. data/ext/ffi_c/AbstractMemory.c +149 -65
  4. data/ext/ffi_c/AbstractMemory.h +34 -4
  5. data/ext/ffi_c/AutoPointer.c +15 -18
  6. data/ext/ffi_c/AutoPointer.h +2 -2
  7. data/ext/ffi_c/Buffer.c +79 -44
  8. data/ext/ffi_c/Callback.c +133 -62
  9. data/ext/ffi_c/Callback.h +11 -5
  10. data/ext/ffi_c/{NativeLibrary.c → DynamicLibrary.c} +88 -24
  11. data/ext/ffi_c/{NativeLibrary.h → DynamicLibrary.h} +1 -1
  12. data/ext/ffi_c/Invoker.c +154 -190
  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 +30 -20
  16. data/ext/ffi_c/MemoryPointer.h +3 -3
  17. data/ext/ffi_c/NullPointer.c +67 -28
  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 +67 -30
  21. data/ext/ffi_c/Pointer.h +8 -6
  22. data/ext/ffi_c/Struct.c +202 -267
  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,21 +20,26 @@ 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
34
36
  memptr_allocate(VALUE klass)
35
37
  {
36
38
  MemoryPointer* p;
37
- return Data_Make_Struct(klass, MemoryPointer, NULL, memptr_release, p);
39
+ VALUE obj = Data_Make_Struct(klass, MemoryPointer, NULL, memptr_release, p);
40
+ p->memory.ops = &rbffi_AbstractMemoryOps;
41
+
42
+ return obj;
38
43
  }
39
44
 
40
45
  static VALUE
@@ -42,12 +47,14 @@ memptr_initialize(int argc, VALUE* argv, VALUE self)
42
47
  {
43
48
  VALUE size = Qnil, count = Qnil, clear = Qnil;
44
49
  int nargs = rb_scan_args(argc, argv, "12", &size, &count, &clear);
45
- memptr_malloc(self, rb_FFI_type_size(size), nargs > 1 ? NUM2LONG(count) : 1,
46
- nargs > 2 && RTEST(clear));
50
+
51
+ memptr_malloc(self, rbffi_type_size(size), nargs > 1 ? NUM2LONG(count) : 1,
52
+ RTEST(clear) || clear == Qnil);
47
53
 
48
54
  if (rb_block_given_p()) {
49
- return rb_rescue(rb_yield, self, memptr_free, self);
55
+ return rb_ensure(rb_yield, self, memptr_free, self);
50
56
  }
57
+
51
58
  return self;
52
59
  }
53
60
 
@@ -97,7 +104,7 @@ memptr_aref(VALUE self, VALUE which)
97
104
  {
98
105
  MemoryPointer* ptr = MEMPTR(self);
99
106
  VALUE offset = INT2NUM(ptr->type_size * NUM2INT(which));
100
- return rb_funcall2(self, rb_intern("+"), 1, &offset);
107
+ return rb_funcall2(self, plus_id, 1, &offset);
101
108
  }
102
109
 
103
110
  static VALUE
@@ -132,15 +139,18 @@ memptr_release(MemoryPointer* ptr)
132
139
  }
133
140
 
134
141
  void
135
- rb_FFI_MemoryPointer_Init()
142
+ rbffi_MemoryPointer_Init(VALUE moduleFFI)
136
143
  {
137
- VALUE moduleFFI = rb_define_module("FFI");
138
- rb_FFI_MemoryPointer_class = classMemoryPointer = rb_define_class_under(moduleFFI, "MemoryPointer", rb_FFI_Pointer_class);
139
- rb_define_alloc_func(classMemoryPointer, memptr_allocate);
140
- rb_define_method(classMemoryPointer, "initialize", memptr_initialize, -1);
141
- rb_define_method(classMemoryPointer, "inspect", memptr_inspect, 0);
142
- rb_define_method(classMemoryPointer, "autorelease=", memptr_autorelease, 1);
143
- rb_define_method(classMemoryPointer, "free", memptr_free, 0);
144
- rb_define_method(classMemoryPointer, "type_size", memptr_type_size, 0);
145
- 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("+");
146
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,13 +7,13 @@
7
7
  #include "AbstractMemory.h"
8
8
  #include "Pointer.h"
9
9
 
10
- static VALUE NullPointerError;
11
- static VALUE classNullPointer;
12
- VALUE rb_FFI_NullPointer_class;
13
- VALUE rb_FFI_NullPointer_singleton;
10
+ static VALUE NullPointerErrorClass;
14
11
 
15
- VALUE
16
- rb_FFI_NullPointer_allocate(VALUE klass)
12
+ VALUE rbffi_NullPointerClass;
13
+ VALUE rbffi_NullPointerSingleton;
14
+
15
+ static VALUE
16
+ nullptr_allocate(VALUE klass)
17
17
  {
18
18
  AbstractMemory* p;
19
19
  VALUE retval;
@@ -21,13 +21,29 @@ rb_FFI_NullPointer_allocate(VALUE klass)
21
21
  retval = Data_Make_Struct(klass, AbstractMemory, NULL, -1, p);
22
22
  p->address = 0;
23
23
  p->size = 0;
24
+ p->ops = &rbffi_NullPointerOps;
25
+
24
26
  return retval;
25
27
  }
26
28
 
27
29
  static VALUE
28
30
  nullptr_op(int argc, VALUE* argv, VALUE self)
29
31
  {
30
- rb_raise(NullPointerError, "NULL Pointer access attempted");
32
+ rb_raise(NullPointerErrorClass, "NULL Pointer access attempted");
33
+ return Qnil;
34
+ }
35
+
36
+ static VALUE
37
+ nullptr_op_get(AbstractMemory* ptr, long offset)
38
+ {
39
+ rb_raise(NullPointerErrorClass, "NULL Pointer access attempted");
40
+ return Qnil;
41
+ }
42
+
43
+ static void
44
+ nullptr_op_put(AbstractMemory* ptr, long offset, VALUE value)
45
+ {
46
+ rb_raise(NullPointerErrorClass, "NULL Pointer access attempted");
31
47
  }
32
48
 
33
49
  static VALUE
@@ -46,10 +62,13 @@ static VALUE
46
62
  nullptr_equals(VALUE self, VALUE other)
47
63
  {
48
64
  AbstractMemory* p2;
49
- if (!rb_obj_is_kind_of(other, rb_FFI_Pointer_class)) {
65
+
66
+ if (!rb_obj_is_kind_of(other, rbffi_PointerClass)) {
50
67
  rb_raise(rb_eArgError, "Comparing Pointer with non Pointer");
51
68
  }
69
+
52
70
  Data_Get_Struct(other, AbstractMemory, p2);
71
+
53
72
  return p2->address == 0 ? Qtrue : Qfalse;
54
73
  }
55
74
 
@@ -59,25 +78,44 @@ nullptr_address(VALUE self)
59
78
  return INT2NUM(0);
60
79
  }
61
80
 
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
+ };
62
97
 
63
98
  void
64
- rb_FFI_NullPointer_Init()
99
+ rbffi_NullPointer_Init(VALUE moduleFFI)
65
100
  {
66
- VALUE moduleFFI = rb_define_module("FFI");
67
- rb_FFI_NullPointer_class = classNullPointer = rb_define_class_under(moduleFFI, "NullPointer", rb_FFI_Pointer_class);
68
- NullPointerError = rb_define_class_under(moduleFFI, "NullPointerError", rb_eRuntimeError);
69
- rb_define_alloc_func(classNullPointer, rb_FFI_NullPointer_allocate);
70
- rb_define_method(classNullPointer, "inspect", nullptr_inspect, 0);
71
- rb_define_method(classNullPointer, "+", nullptr_op, -1);
72
- rb_define_method(classNullPointer, "null?", nullptr_null_p, 0);
73
- rb_define_method(classNullPointer, "address", nullptr_address, 0);
74
- 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);
75
113
 
76
114
  #define NOP(name) \
77
- rb_define_method(classNullPointer, "get_" #name, nullptr_op, -1); \
78
- rb_define_method(classNullPointer, "put_" #name, nullptr_op, -1); \
79
- rb_define_method(classNullPointer, "get_array_of_" #name, nullptr_op, -1); \
80
- 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); \
81
119
 
82
120
 
83
121
  NOP(int8); NOP(uint8); NOP(int16); NOP(uint16);
@@ -89,16 +127,17 @@ rb_FFI_NullPointer_Init()
89
127
 
90
128
  #undef NOP
91
129
  #define NOP(name) \
92
- rb_define_method(classNullPointer, "get_" #name, nullptr_op, -1); \
93
- 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);
94
132
 
95
133
  NOP(string); NOP(bytes); NOP(pointer); NOP(callback);
96
134
 
97
- rb_define_method(classNullPointer, "clear", nullptr_op, -1); \
98
- 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);
99
137
 
100
138
  // Create a singleton instance of NullPointer that can be shared
101
- rb_FFI_NullPointer_singleton = rb_FFI_NullPointer_allocate(classNullPointer);
102
- 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);
103
142
  }
104
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,35 +11,73 @@ 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
- static void ptr_free(Pointer* ptr);
20
18
 
21
19
  VALUE
22
- rb_FFI_Pointer_new(void* addr)
20
+ rbffi_Pointer_NewInstance(void* addr)
23
21
  {
24
22
  Pointer* p;
25
- VALUE retval;
23
+ VALUE obj;
24
+
26
25
  if (addr == NULL) {
27
- return rb_FFI_NullPointer_singleton;
26
+ return rbffi_NullPointerSingleton;
28
27
  }
29
- retval = Data_Make_Struct(classPointer, Pointer, NULL, ptr_free, p);
28
+
29
+ obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
30
30
  p->memory.address = addr;
31
31
  p->memory.size = LONG_MAX;
32
+ p->memory.ops = &rbffi_AbstractMemoryOps;
32
33
  p->parent = Qnil;
33
- return retval;
34
+
35
+ return obj;
34
36
  }
35
37
 
36
38
  static VALUE
37
39
  ptr_allocate(VALUE klass)
38
40
  {
39
41
  Pointer* p;
40
- return Data_Make_Struct(classPointer, Pointer, NULL, ptr_free, p);
42
+ VALUE obj;
43
+
44
+ obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
45
+ p->parent = Qnil;
46
+ p->memory.ops = &rbffi_AbstractMemoryOps;
47
+
48
+ return obj;
41
49
  }
42
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
+
43
81
  static VALUE
44
82
  ptr_plus(VALUE self, VALUE offset)
45
83
  {
@@ -51,10 +89,11 @@ ptr_plus(VALUE self, VALUE offset)
51
89
  Data_Get_Struct(self, AbstractMemory, ptr);
52
90
  checkBounds(ptr, off, 1);
53
91
 
54
- retval = Data_Make_Struct(classPointer, Pointer, ptr_mark, ptr_free, p);
92
+ retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p);
55
93
 
56
94
  p->memory.address = ptr->address + off;
57
95
  p->memory.size = ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off;
96
+ p->memory.ops = &rbffi_AbstractMemoryOps;
58
97
  p->parent = self;
59
98
 
60
99
  return retval;
@@ -76,7 +115,9 @@ static VALUE
76
115
  ptr_null_p(VALUE self)
77
116
  {
78
117
  Pointer* ptr;
118
+
79
119
  Data_Get_Struct(self, Pointer, ptr);
120
+
80
121
  return ptr->memory.address == NULL ? Qtrue : Qfalse;
81
122
  }
82
123
 
@@ -84,6 +125,7 @@ static VALUE
84
125
  ptr_equals(VALUE self, VALUE other)
85
126
  {
86
127
  Pointer* ptr;
128
+
87
129
  Data_Get_Struct(self, Pointer, ptr);
88
130
 
89
131
  return ptr->memory.address == POINTER(other)->address ? Qtrue : Qfalse;
@@ -93,6 +135,7 @@ static VALUE
93
135
  ptr_address(VALUE self)
94
136
  {
95
137
  Pointer* ptr;
138
+
96
139
  Data_Get_Struct(self, Pointer, ptr);
97
140
 
98
141
  return ULL2NUM((uintptr_t) ptr->memory.address);
@@ -101,27 +144,21 @@ ptr_address(VALUE self)
101
144
  static void
102
145
  ptr_mark(Pointer* ptr)
103
146
  {
104
- if (ptr->parent != Qnil) {
105
- rb_gc_mark(ptr->parent);
106
- }
107
- }
108
-
109
- static void
110
- ptr_free(Pointer* ptr)
111
- {
112
- xfree(ptr);
147
+ rb_gc_mark(ptr->parent);
113
148
  }
114
149
 
115
150
  void
116
- rb_FFI_Pointer_Init()
151
+ rbffi_Pointer_Init(VALUE moduleFFI)
117
152
  {
118
- VALUE moduleFFI = rb_define_module("FFI");
119
- rb_FFI_Pointer_class = classPointer = rb_define_class_under(moduleFFI, "Pointer", rb_FFI_AbstractMemory_class);
120
-
121
- rb_define_alloc_func(classPointer, ptr_allocate);
122
- rb_define_method(classPointer, "inspect", ptr_inspect, 0);
123
- rb_define_method(classPointer, "+", ptr_plus, 1);
124
- rb_define_method(classPointer, "null?", ptr_null_p, 0);
125
- rb_define_method(classPointer, "address", ptr_address, 0);
126
- 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);
127
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
  }