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.
- data/README.rdoc +51 -1
- data/Rakefile +38 -28
- data/ext/ffi_c/AbstractMemory.c +74 -70
- data/ext/ffi_c/AbstractMemory.h +8 -4
- data/ext/ffi_c/AutoPointer.c +8 -9
- data/ext/ffi_c/AutoPointer.h +2 -2
- data/ext/ffi_c/Buffer.c +42 -24
- data/ext/ffi_c/Callback.c +85 -33
- data/ext/ffi_c/Callback.h +11 -5
- data/ext/ffi_c/{NativeLibrary.c → DynamicLibrary.c} +83 -16
- data/ext/ffi_c/{NativeLibrary.h → DynamicLibrary.h} +1 -1
- data/ext/ffi_c/Invoker.c +152 -192
- data/ext/ffi_c/LastError.c +135 -0
- data/ext/ffi_c/LastError.h +18 -0
- data/ext/ffi_c/MemoryPointer.c +27 -20
- data/ext/ffi_c/MemoryPointer.h +3 -3
- data/ext/ffi_c/NullPointer.c +51 -47
- data/ext/ffi_c/Platform.c +9 -10
- data/ext/ffi_c/Platform.h +1 -1
- data/ext/ffi_c/Pointer.c +52 -21
- data/ext/ffi_c/Pointer.h +8 -6
- data/ext/ffi_c/Struct.c +70 -61
- data/ext/ffi_c/Struct.h +2 -2
- data/ext/ffi_c/Type.c +230 -0
- data/ext/ffi_c/Type.h +28 -0
- data/ext/ffi_c/Types.c +48 -6
- data/ext/ffi_c/Types.h +8 -2
- data/ext/ffi_c/endian.h +40 -0
- data/ext/ffi_c/extconf.rb +6 -5
- data/ext/ffi_c/ffi.c +21 -44
- data/ext/ffi_c/libffi.bsd.mk +34 -0
- data/ext/ffi_c/libffi.darwin.mk +30 -10
- data/ext/ffi_c/libffi.gnu.mk +29 -0
- data/ext/ffi_c/libffi.mk +4 -2
- data/ext/ffi_c/rbffi.h +6 -8
- data/gen/Rakefile +12 -0
- data/lib/ffi/autopointer.rb +1 -1
- data/lib/ffi/enum.rb +78 -0
- data/lib/ffi/ffi.rb +5 -6
- data/lib/ffi/io.rb +15 -1
- data/lib/ffi/library.rb +79 -18
- data/lib/ffi/pointer.rb +2 -2
- data/lib/ffi/struct.rb +68 -14
- data/lib/ffi/types.rb +6 -3
- data/lib/ffi/variadic.rb +2 -2
- data/lib/ffi.rb +10 -1
- data/spec/ffi/bool_spec.rb +24 -0
- data/spec/ffi/callback_spec.rb +217 -17
- data/spec/ffi/enum_spec.rb +164 -0
- data/spec/ffi/managed_struct_spec.rb +6 -1
- data/spec/ffi/number_spec.rb +30 -0
- data/spec/ffi/pointer_spec.rb +33 -8
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -6
- data/spec/ffi/spec_helper.rb +5 -1
- data/spec/ffi/string_spec.rb +65 -4
- data/spec/ffi/struct_callback_spec.rb +41 -0
- data/spec/ffi/struct_initialize_spec.rb +30 -0
- data/spec/ffi/struct_spec.rb +44 -21
- metadata +31 -69
- data/ext/ffi_c/ffi.mk +0 -23
- data/nbproject/Makefile-Default.mk +0 -57
- data/nbproject/Makefile-impl.mk +0 -123
- data/nbproject/Package-Default.bash +0 -72
- data/nbproject/configurations.xml +0 -293
- data/nbproject/private/configurations.xml +0 -22
- data/nbproject/private/private.xml +0 -7
- data/nbproject/project.properties +0 -0
- data/nbproject/project.xml +0 -15
- data/samples/getlogin.rb +0 -7
- data/samples/getpid.rb +0 -7
- data/samples/gettimeofday.rb +0 -17
- data/samples/hello.rb +0 -6
- data/samples/inotify.rb +0 -59
- data/samples/pty.rb +0 -75
- data/samples/qsort.rb +0 -20
- 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
|
+
|
data/ext/ffi_c/MemoryPointer.c
CHANGED
|
@@ -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
|
|
24
|
-
|
|
25
|
-
#define MEMPTR(obj) ((MemoryPointer *)
|
|
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
|
-
|
|
30
|
+
rbffi_MemoryPointer_NewInstance(long size, long count, bool clear)
|
|
29
31
|
{
|
|
30
|
-
return memptr_malloc(memptr_allocate(
|
|
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 = &
|
|
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
|
-
|
|
49
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
142
|
+
rbffi_MemoryPointer_Init(VALUE moduleFFI)
|
|
139
143
|
{
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
rb_define_method(
|
|
145
|
-
rb_define_method(
|
|
146
|
-
rb_define_method(
|
|
147
|
-
rb_define_method(
|
|
148
|
-
rb_define_method(
|
|
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
|
}
|
data/ext/ffi_c/MemoryPointer.h
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
extern "C" {
|
|
10
10
|
#endif
|
|
11
11
|
|
|
12
|
-
extern void
|
|
13
|
-
extern VALUE
|
|
14
|
-
extern VALUE
|
|
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
|
data/ext/ffi_c/NullPointer.c
CHANGED
|
@@ -7,15 +7,13 @@
|
|
|
7
7
|
#include "AbstractMemory.h"
|
|
8
8
|
#include "Pointer.h"
|
|
9
9
|
|
|
10
|
-
static VALUE
|
|
11
|
-
static VALUE classNullPointer;
|
|
12
|
-
static MemoryOps nullptr_ops;
|
|
10
|
+
static VALUE NullPointerErrorClass;
|
|
13
11
|
|
|
14
|
-
VALUE
|
|
15
|
-
VALUE
|
|
12
|
+
VALUE rbffi_NullPointerClass;
|
|
13
|
+
VALUE rbffi_NullPointerSingleton;
|
|
16
14
|
|
|
17
|
-
VALUE
|
|
18
|
-
|
|
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 = &
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
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
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.int8 = &
|
|
85
|
-
.uint8 = &
|
|
86
|
-
.int16 = &
|
|
87
|
-
.int16 = &
|
|
88
|
-
.int32 = &
|
|
89
|
-
.uint32 = &
|
|
90
|
-
.int64 = &
|
|
91
|
-
.uint64 = &
|
|
92
|
-
.float32 = &
|
|
93
|
-
.float64 = &
|
|
94
|
-
.pointer = &
|
|
95
|
-
.strptr = &
|
|
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
|
-
|
|
99
|
+
rbffi_NullPointer_Init(VALUE moduleFFI)
|
|
100
100
|
{
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
rb_define_method(
|
|
109
|
-
rb_define_method(
|
|
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(
|
|
113
|
-
rb_define_method(
|
|
114
|
-
rb_define_method(
|
|
115
|
-
rb_define_method(
|
|
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(
|
|
128
|
-
rb_define_method(
|
|
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(
|
|
133
|
-
rb_define_method(
|
|
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
|
-
|
|
137
|
-
|
|
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
|
|
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
|
-
|
|
51
|
+
rbffi_Platform_Init(VALUE moduleFFI)
|
|
51
52
|
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
rb_define_const(
|
|
55
|
-
rb_define_const(
|
|
56
|
-
rb_define_const(
|
|
57
|
-
|
|
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
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)
|
|
14
|
+
#define POINTER(obj) rbffi_AbstractMemory_Cast((obj), rbffi_PointerClass)
|
|
15
15
|
|
|
16
|
-
VALUE
|
|
17
|
-
static VALUE classPointer = Qnil;
|
|
16
|
+
VALUE rbffi_PointerClass;
|
|
18
17
|
static void ptr_mark(Pointer* ptr);
|
|
19
18
|
|
|
20
19
|
VALUE
|
|
21
|
-
|
|
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
|
|
26
|
+
return rbffi_NullPointerSingleton;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
obj = Data_Make_Struct(
|
|
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 = &
|
|
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(
|
|
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(
|
|
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 = &
|
|
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
|
-
|
|
151
|
+
rbffi_Pointer_Init(VALUE moduleFFI)
|
|
122
152
|
{
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
rb_define_method(
|
|
129
|
-
rb_define_method(
|
|
130
|
-
rb_define_method(
|
|
131
|
-
rb_define_method(
|
|
132
|
-
|
|
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
|
}
|