ffi 0.5.4 → 0.6.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.
- data/LICENSE +1 -27
- data/Rakefile +2 -11
- data/ext/ffi_c/AbstractMemory.c +6 -8
- data/ext/ffi_c/AbstractMemory.h +23 -21
- data/ext/ffi_c/AutoPointer.c +0 -1
- data/ext/ffi_c/Buffer.c +23 -8
- data/ext/ffi_c/Call.c +28 -0
- data/ext/ffi_c/Call.h +5 -1
- data/ext/ffi_c/DynamicLibrary.c +0 -1
- data/ext/ffi_c/Function.c +19 -2
- data/ext/ffi_c/MemoryPointer.c +2 -3
- data/ext/ffi_c/Pointer.c +23 -9
- data/ext/ffi_c/Struct.c +142 -69
- data/ext/ffi_c/Struct.h +16 -7
- data/ext/ffi_c/StructLayout.c +92 -55
- data/ext/ffi_c/Type.c +5 -22
- data/ext/ffi_c/Type.h +1 -1
- data/ext/ffi_c/Types.c +8 -2
- data/ext/ffi_c/Types.h +2 -0
- data/ext/ffi_c/extconf.rb +11 -7
- data/ext/ffi_c/libffi/ChangeLog +900 -84
- data/ext/ffi_c/libffi/ChangeLog.libffi +311 -0
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/Makefile.am +14 -4
- data/ext/ffi_c/libffi/Makefile.in +362 -211
- data/ext/ffi_c/libffi/README +70 -92
- data/ext/ffi_c/libffi/aclocal.m4 +6068 -4586
- data/ext/ffi_c/libffi/config.guess +125 -143
- data/ext/ffi_c/libffi/config.sub +103 -27
- data/ext/ffi_c/libffi/configure +11364 -18497
- data/ext/ffi_c/libffi/configure.ac +43 -4
- data/ext/ffi_c/libffi/doc/libffi.info +15 -15
- data/ext/ffi_c/libffi/doc/libffi.texi +1 -1
- data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +24 -3
- data/ext/ffi_c/libffi/include/Makefile.am +1 -1
- data/ext/ffi_c/libffi/include/Makefile.in +97 -50
- data/ext/ffi_c/libffi/include/ffi.h.in +8 -2
- data/ext/ffi_c/libffi/include/ffi_common.h +24 -0
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/ltmain.sh +7346 -5870
- data/ext/ffi_c/libffi/m4/libtool.m4 +7360 -0
- data/ext/ffi_c/libffi/m4/ltoptions.m4 +368 -0
- data/ext/ffi_c/libffi/m4/ltsugar.m4 +123 -0
- data/ext/ffi_c/libffi/m4/ltversion.m4 +23 -0
- data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +92 -0
- data/ext/ffi_c/libffi/man/Makefile.in +115 -62
- data/ext/ffi_c/libffi/man/ffi_call.3 +3 -3
- data/ext/ffi_c/libffi/missing +15 -8
- data/ext/ffi_c/libffi/src/arm/sysv.S +15 -8
- data/ext/ffi_c/libffi/src/avr32/ffi.c +421 -0
- data/ext/ffi_c/libffi/src/avr32/ffitarget.h +50 -0
- data/ext/ffi_c/libffi/src/avr32/sysv.S +208 -0
- data/ext/ffi_c/libffi/src/closures.c +47 -10
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/java_raw_api.c +0 -3
- data/ext/ffi_c/libffi/src/mips/ffi.c +135 -32
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +37 -4
- data/ext/ffi_c/libffi/src/mips/n32.S +67 -10
- data/ext/ffi_c/libffi/src/mips/o32.S +8 -8
- data/ext/ffi_c/libffi/src/pa/ffi.c +7 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +163 -64
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +308 -112
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +20 -7
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +208 -80
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +11 -3
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +12 -23
- data/ext/ffi_c/libffi/src/s390/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/sh/sysv.S +9 -9
- data/ext/ffi_c/libffi/src/sh64/ffi.c +37 -22
- data/ext/ffi_c/libffi/src/sh64/sysv.S +23 -14
- data/ext/ffi_c/libffi/src/sparc/ffi.c +21 -6
- data/ext/ffi_c/libffi/src/sparc/v8.S +55 -14
- data/ext/ffi_c/libffi/src/x86/darwin.S +10 -9
- data/ext/ffi_c/libffi/src/x86/ffi.c +293 -86
- data/ext/ffi_c/libffi/src/x86/ffi64.c +73 -19
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +30 -0
- data/ext/ffi_c/libffi/src/x86/sysv.S +21 -4
- data/ext/ffi_c/libffi/src/x86/unix64.S +8 -4
- data/ext/ffi_c/libffi/src/x86/win32.S +633 -147
- data/ext/ffi_c/libffi/src/x86/win64.S +460 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.am +63 -54
- data/ext/ffi_c/libffi/testsuite/Makefile.in +112 -77
- data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +12 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +7 -14
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c +95 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +6 -14
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +134 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +117 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +11 -17
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +66 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +4 -13
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +105 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +74 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +140 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +8 -16
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +37 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +25 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +31 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +342 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +145 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +148 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +124 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +124 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +70 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +4 -5
- data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +17 -16
- data/ext/ffi_c/libffi/texinfo.tex +155 -427
- data/lib/ffi/autopointer.rb +79 -20
- data/lib/ffi/callback.rb +4 -10
- data/lib/ffi/enum.rb +28 -0
- data/lib/ffi/io.rb +28 -0
- data/lib/ffi/library.rb +237 -182
- data/lib/ffi/memorypointer.rb +28 -62
- data/lib/ffi/platform.rb +27 -0
- data/lib/ffi/pointer.rb +28 -0
- data/lib/ffi/struct.rb +55 -1
- data/lib/ffi/types.rb +29 -0
- data/lib/ffi/variadic.rb +29 -0
- data/spec/ffi/library_spec.rb +31 -5
- data/spec/ffi/rbx/attach_function_spec.rb +2 -1
- data/spec/ffi/rbx/memory_pointer_spec.rb +2 -1
- data/spec/ffi/spec_helper.rb +5 -1
- data/spec/ffi/struct_spec.rb +64 -0
- metadata +28 -8
- data/ext/ffi_c/libffi/TODO +0 -1
- data/ext/ffi_c/libffi/ltcf-c.sh +0 -861
- data/ext/ffi_c/libffi/ltcf-cxx.sh +0 -1069
- data/ext/ffi_c/libffi/ltcf-gcj.sh +0 -700
- data/ext/ffi_c/libffi/ltconfig +0 -2862
- data/ext/ffi_c/libffi/mkinstalldirs +0 -158
data/ext/ffi_c/Pointer.c
CHANGED
@@ -59,7 +59,6 @@ rbffi_Pointer_NewInstance(void* addr)
|
|
59
59
|
obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
|
60
60
|
p->memory.address = addr;
|
61
61
|
p->memory.size = LONG_MAX;
|
62
|
-
p->memory.ops = &rbffi_AbstractMemoryOps;
|
63
62
|
p->memory.access = (addr == NULL) ? 0 : (MEM_RD | MEM_WR);
|
64
63
|
p->memory.typeSize = 1;
|
65
64
|
p->parent = Qnil;
|
@@ -75,7 +74,6 @@ ptr_allocate(VALUE klass)
|
|
75
74
|
|
76
75
|
obj = Data_Make_Struct(klass, Pointer, NULL, -1, p);
|
77
76
|
p->parent = Qnil;
|
78
|
-
p->memory.ops = &rbffi_AbstractMemoryOps;
|
79
77
|
p->memory.access = MEM_RD | MEM_WR;
|
80
78
|
|
81
79
|
return obj;
|
@@ -132,21 +130,19 @@ ptr_initialize(int argc, VALUE* argv, VALUE self)
|
|
132
130
|
|
133
131
|
|
134
132
|
static VALUE
|
135
|
-
|
133
|
+
slice(VALUE self, long offset, long size)
|
136
134
|
{
|
137
135
|
AbstractMemory* ptr;
|
138
136
|
Pointer* p;
|
139
137
|
VALUE retval;
|
140
|
-
|
141
|
-
|
138
|
+
|
142
139
|
Data_Get_Struct(self, AbstractMemory, ptr);
|
143
|
-
checkBounds(ptr,
|
140
|
+
checkBounds(ptr, offset, 1);
|
144
141
|
|
145
142
|
retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p);
|
146
143
|
|
147
|
-
p->memory.address = ptr->address +
|
148
|
-
p->memory.size =
|
149
|
-
p->memory.ops = &rbffi_AbstractMemoryOps;
|
144
|
+
p->memory.address = ptr->address + offset;
|
145
|
+
p->memory.size = size;
|
150
146
|
p->memory.access = ptr->access;
|
151
147
|
p->memory.typeSize = ptr->typeSize;
|
152
148
|
p->parent = self;
|
@@ -154,6 +150,23 @@ ptr_plus(VALUE self, VALUE offset)
|
|
154
150
|
return retval;
|
155
151
|
}
|
156
152
|
|
153
|
+
static VALUE
|
154
|
+
ptr_plus(VALUE self, VALUE offset)
|
155
|
+
{
|
156
|
+
AbstractMemory* ptr;
|
157
|
+
long off = NUM2LONG(offset);
|
158
|
+
|
159
|
+
Data_Get_Struct(self, AbstractMemory, ptr);
|
160
|
+
|
161
|
+
return slice(self, off, ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off);
|
162
|
+
}
|
163
|
+
|
164
|
+
static VALUE
|
165
|
+
ptr_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
|
166
|
+
{
|
167
|
+
return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
|
168
|
+
}
|
169
|
+
|
157
170
|
static VALUE
|
158
171
|
ptr_inspect(VALUE self)
|
159
172
|
{
|
@@ -214,6 +227,7 @@ rbffi_Pointer_Init(VALUE moduleFFI)
|
|
214
227
|
rb_define_method(rbffi_PointerClass, "initialize", ptr_initialize, -1);
|
215
228
|
rb_define_method(rbffi_PointerClass, "inspect", ptr_inspect, 0);
|
216
229
|
rb_define_method(rbffi_PointerClass, "+", ptr_plus, 1);
|
230
|
+
rb_define_method(rbffi_PointerClass, "slice", ptr_slice, 2);
|
217
231
|
rb_define_method(rbffi_PointerClass, "null?", ptr_null_p, 0);
|
218
232
|
rb_define_method(rbffi_PointerClass, "address", ptr_address, 0);
|
219
233
|
rb_define_alias(rbffi_PointerClass, "to_i", "address");
|
data/ext/ffi_c/Struct.c
CHANGED
@@ -63,6 +63,8 @@ typedef struct InlineArray_ {
|
|
63
63
|
StructField* field;
|
64
64
|
MemoryOp *op;
|
65
65
|
Type* componentType;
|
66
|
+
ArrayType* arrayType;
|
67
|
+
unsigned int length;
|
66
68
|
} InlineArray;
|
67
69
|
|
68
70
|
|
@@ -77,6 +79,8 @@ VALUE rbffi_StructClass = Qnil;
|
|
77
79
|
static VALUE StructLayoutBuilderClass = Qnil;
|
78
80
|
|
79
81
|
VALUE rbffi_StructInlineArrayClass = Qnil;
|
82
|
+
VALUE rbffi_StructLayoutCharArrayClass = Qnil;
|
83
|
+
|
80
84
|
static ID id_pointer_ivar = 0, id_layout_ivar = 0;
|
81
85
|
static ID id_get = 0, id_put = 0, id_to_ptr = 0, id_to_s = 0, id_layout = 0;
|
82
86
|
|
@@ -132,11 +136,6 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
|
|
132
136
|
s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
|
133
137
|
}
|
134
138
|
|
135
|
-
if (s->pointer->ops == NULL) {
|
136
|
-
VALUE name = rb_class_name(CLASS_OF(s->rbPointer));
|
137
|
-
rb_raise(rb_eRuntimeError, "No memory ops set for %s", StringValueCStr(name));
|
138
|
-
}
|
139
|
-
|
140
139
|
return self;
|
141
140
|
}
|
142
141
|
|
@@ -171,19 +170,22 @@ struct_aref(VALUE self, VALUE fieldName)
|
|
171
170
|
Struct* s;
|
172
171
|
VALUE rbField;
|
173
172
|
StructField* f;
|
174
|
-
|
175
|
-
|
173
|
+
|
176
174
|
Data_Get_Struct(self, Struct, s);
|
177
175
|
rbField = struct_field(s, fieldName);
|
178
176
|
f = (StructField *) DATA_PTR(rbField);
|
179
177
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
}
|
178
|
+
if (f->get != NULL) {
|
179
|
+
return (*f->get)(f, s);
|
180
|
+
|
181
|
+
} else if (f->memoryOp != NULL) {
|
182
|
+
return (*f->memoryOp->get)(s->pointer, f->offset);
|
183
|
+
|
184
|
+
} else {
|
184
185
|
|
185
|
-
|
186
|
-
|
186
|
+
/* call up to the ruby code to fetch the value */
|
187
|
+
return rb_funcall2(rbField, id_get, 1, &s->rbPointer);
|
188
|
+
}
|
187
189
|
}
|
188
190
|
|
189
191
|
static VALUE
|
@@ -192,25 +194,27 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
|
|
192
194
|
Struct* s;
|
193
195
|
VALUE rbField;
|
194
196
|
StructField* f;
|
195
|
-
|
196
|
-
VALUE argv[2];
|
197
|
+
|
197
198
|
|
198
199
|
Data_Get_Struct(self, Struct, s);
|
199
200
|
rbField = struct_field(s, fieldName);
|
200
201
|
f = (StructField *) DATA_PTR(rbField);
|
202
|
+
if (f->put != NULL) {
|
203
|
+
(*f->put)(f, s, value);
|
201
204
|
|
202
|
-
|
203
|
-
|
204
|
-
(*
|
205
|
-
return self;
|
206
|
-
}
|
205
|
+
} else if (f->memoryOp != NULL) {
|
206
|
+
|
207
|
+
(*f->memoryOp->put)(s->pointer, f->offset, value);
|
207
208
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
209
|
+
} else {
|
210
|
+
/* call up to the ruby code to set the value */
|
211
|
+
VALUE argv[2];
|
212
|
+
argv[0] = s->rbPointer;
|
213
|
+
argv[1] = value;
|
214
|
+
rb_funcall2(rbField, id_put, 2, argv);
|
215
|
+
}
|
212
216
|
|
213
|
-
return
|
217
|
+
return value;
|
214
218
|
}
|
215
219
|
|
216
220
|
static VALUE
|
@@ -425,16 +429,32 @@ struct_layout_builder_add_field(int argc, VALUE* argv, VALUE self)
|
|
425
429
|
fargv[0] = rbName;
|
426
430
|
fargv[1] = UINT2NUM(offset);
|
427
431
|
fargv[2] = rbType;
|
432
|
+
|
428
433
|
if (rb_obj_is_kind_of(rbType, rbffi_FunctionTypeClass)) {
|
434
|
+
|
429
435
|
rbFieldClass = rbffi_StructLayoutFunctionFieldClass;
|
436
|
+
|
430
437
|
} else if (rb_obj_is_kind_of(rbType, rbffi_StructByValueClass)) {
|
431
|
-
|
438
|
+
|
439
|
+
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct"));
|
440
|
+
|
432
441
|
} else if (rb_obj_is_kind_of(rbType, rbffi_ArrayTypeClass)) {
|
442
|
+
|
433
443
|
rbFieldClass = rbffi_StructLayoutArrayFieldClass;
|
444
|
+
|
445
|
+
} else if (rb_obj_is_kind_of(rbType, rbffi_EnumTypeClass)) {
|
446
|
+
|
447
|
+
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("Enum"));
|
448
|
+
|
434
449
|
} else {
|
435
450
|
rbFieldClass = rbffi_StructLayoutFieldClass;
|
436
451
|
}
|
437
452
|
|
453
|
+
if (!RTEST(rbFieldClass)) {
|
454
|
+
rb_raise(rb_eTypeError, "invalid struct field type (%s)", rb_obj_classname(rbType));
|
455
|
+
return Qnil;
|
456
|
+
}
|
457
|
+
|
438
458
|
rbField = rb_class_new_instance(3, fargv, rbFieldClass);
|
439
459
|
} else {
|
440
460
|
rbField = rbType;
|
@@ -449,7 +469,8 @@ static VALUE
|
|
449
469
|
struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self)
|
450
470
|
{
|
451
471
|
StructLayoutBuilder* builder;
|
452
|
-
VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil
|
472
|
+
VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil;
|
473
|
+
VALUE rbFieldClass = Qnil, rbStructClass = Qnil;
|
453
474
|
VALUE fargv[3];
|
454
475
|
unsigned int size, alignment, offset;
|
455
476
|
int nargs;
|
@@ -472,7 +493,14 @@ struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self)
|
|
472
493
|
fargv[0] = rbName;
|
473
494
|
fargv[1] = UINT2NUM(offset);
|
474
495
|
fargv[2] = rbType;
|
475
|
-
|
496
|
+
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct"));
|
497
|
+
if (!RTEST(rbFieldClass)) {
|
498
|
+
rb_raise(rb_eRuntimeError, "could not locate StructLayout::InlineStruct");
|
499
|
+
return Qnil;
|
500
|
+
}
|
501
|
+
|
502
|
+
rbField = rb_class_new_instance(3, fargv, rbFieldClass);
|
503
|
+
|
476
504
|
store_field(builder, rbName, rbField, offset, size, alignment);
|
477
505
|
|
478
506
|
return self;
|
@@ -554,21 +582,18 @@ static VALUE
|
|
554
582
|
inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
|
555
583
|
{
|
556
584
|
InlineArray* array;
|
557
|
-
|
558
|
-
|
585
|
+
|
559
586
|
Data_Get_Struct(self, InlineArray, array);
|
560
587
|
array->rbMemory = rbMemory;
|
561
588
|
array->rbField = rbField;
|
562
589
|
|
563
590
|
Data_Get_Struct(rbMemory, AbstractMemory, array->memory);
|
564
591
|
Data_Get_Struct(rbField, StructField, array->field);
|
565
|
-
Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
|
566
|
-
Data_Get_Struct(arrayType->rbComponentType, Type, array->componentType);
|
592
|
+
Data_Get_Struct(array->field->rbType, ArrayType, array->arrayType);
|
593
|
+
Data_Get_Struct(array->arrayType->rbComponentType, Type, array->componentType);
|
567
594
|
|
568
|
-
array->op =
|
569
|
-
|
570
|
-
rb_raise(rb_eRuntimeError, "invalid memory ops");
|
571
|
-
}
|
595
|
+
array->op = get_memory_op(array->componentType);
|
596
|
+
array->length = array->arrayType->length;
|
572
597
|
|
573
598
|
return self;
|
574
599
|
}
|
@@ -584,8 +609,12 @@ inline_array_size(VALUE self)
|
|
584
609
|
}
|
585
610
|
|
586
611
|
static int
|
587
|
-
inline_array_offset(InlineArray* array,
|
612
|
+
inline_array_offset(InlineArray* array, int index)
|
588
613
|
{
|
614
|
+
if (index < 0 || index >= array->length) {
|
615
|
+
rb_raise(rb_eIndexError, "index %d out of bounds", index);
|
616
|
+
}
|
617
|
+
|
589
618
|
return array->field->offset + (index * array->componentType->ffiType->size);
|
590
619
|
}
|
591
620
|
|
@@ -596,7 +625,19 @@ inline_array_aref(VALUE self, VALUE rbIndex)
|
|
596
625
|
|
597
626
|
Data_Get_Struct(self, InlineArray, array);
|
598
627
|
|
599
|
-
|
628
|
+
if (array->op != NULL) {
|
629
|
+
return array->op->get(array->memory, inline_array_offset(array, NUM2INT(rbIndex)));
|
630
|
+
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
|
631
|
+
VALUE rbOffset = INT2NUM(inline_array_offset(array, NUM2INT(rbIndex)));
|
632
|
+
VALUE rbLength = INT2NUM(array->componentType->ffiType->size);
|
633
|
+
VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
|
634
|
+
|
635
|
+
return rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass);
|
636
|
+
} else {
|
637
|
+
|
638
|
+
rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(array->arrayType->rbComponentType));
|
639
|
+
return Qnil;
|
640
|
+
}
|
600
641
|
}
|
601
642
|
|
602
643
|
static VALUE
|
@@ -606,8 +647,34 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
|
|
606
647
|
|
607
648
|
Data_Get_Struct(self, InlineArray, array);
|
608
649
|
|
609
|
-
array->op
|
610
|
-
|
650
|
+
if (array->op != NULL) {
|
651
|
+
array->op->put(array->memory, inline_array_offset(array, NUM2INT(rbIndex)),
|
652
|
+
rbValue);
|
653
|
+
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
|
654
|
+
int offset = inline_array_offset(array, NUM2INT(rbIndex));
|
655
|
+
Struct* s;
|
656
|
+
|
657
|
+
if (!rb_obj_is_kind_of(rbValue, rbffi_StructClass)) {
|
658
|
+
rb_raise(rb_eTypeError, "argument not an instance of struct");
|
659
|
+
return Qnil;
|
660
|
+
}
|
661
|
+
|
662
|
+
checkWrite(array->memory);
|
663
|
+
checkBounds(array->memory, offset, array->componentType->ffiType->size);
|
664
|
+
|
665
|
+
Data_Get_Struct(rbValue, Struct, s);
|
666
|
+
checkRead(s->pointer);
|
667
|
+
checkBounds(s->pointer, 0, array->componentType->ffiType->size);
|
668
|
+
|
669
|
+
memcpy(array->memory->address + offset, s->pointer->address, array->componentType->ffiType->size);
|
670
|
+
|
671
|
+
} else {
|
672
|
+
ArrayType* arrayType;
|
673
|
+
Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
|
674
|
+
|
675
|
+
rb_raise(rb_eArgError, "set not supported for %s", rb_obj_classname(arrayType->rbComponentType));
|
676
|
+
return Qnil;
|
677
|
+
}
|
611
678
|
|
612
679
|
return rbValue;
|
613
680
|
}
|
@@ -616,16 +683,30 @@ static VALUE
|
|
616
683
|
inline_array_each(VALUE self)
|
617
684
|
{
|
618
685
|
InlineArray* array;
|
619
|
-
ArrayType* arrayType;
|
620
686
|
|
621
687
|
int i;
|
622
688
|
|
623
689
|
Data_Get_Struct(self, InlineArray, array);
|
624
|
-
|
690
|
+
|
691
|
+
if (array->op != NULL) {
|
692
|
+
for (i = 0; i < array->length; ++i) {
|
693
|
+
int offset = inline_array_offset(array, i);
|
694
|
+
rb_yield(array->op->get(array->memory, offset));
|
695
|
+
}
|
696
|
+
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
|
697
|
+
for (i = 0; i < array->length; ++i) {
|
698
|
+
VALUE rbOffset = UINT2NUM(inline_array_offset(array, i));
|
699
|
+
VALUE rbLength = UINT2NUM(array->componentType->ffiType->size);
|
700
|
+
VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
|
625
701
|
|
626
|
-
|
627
|
-
|
628
|
-
|
702
|
+
rb_yield(rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass));
|
703
|
+
}
|
704
|
+
} else {
|
705
|
+
ArrayType* arrayType;
|
706
|
+
Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
|
707
|
+
|
708
|
+
rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(arrayType->rbComponentType));
|
709
|
+
return Qnil;
|
629
710
|
}
|
630
711
|
|
631
712
|
return self;
|
@@ -635,16 +716,14 @@ static VALUE
|
|
635
716
|
inline_array_to_a(VALUE self)
|
636
717
|
{
|
637
718
|
InlineArray* array;
|
638
|
-
ArrayType* arrayType;
|
639
719
|
VALUE obj;
|
640
720
|
int i;
|
641
721
|
|
642
722
|
Data_Get_Struct(self, InlineArray, array);
|
643
|
-
|
644
|
-
obj = rb_ary_new2(arrayType->length);
|
723
|
+
obj = rb_ary_new2(array->length);
|
645
724
|
|
646
725
|
|
647
|
-
for (i = 0; i <
|
726
|
+
for (i = 0; i < array->length; ++i) {
|
648
727
|
int offset = inline_array_offset(array, i);
|
649
728
|
rb_ary_push(obj, array->op->get(array->memory, offset));
|
650
729
|
}
|
@@ -656,19 +735,17 @@ static VALUE
|
|
656
735
|
inline_array_to_s(VALUE self)
|
657
736
|
{
|
658
737
|
InlineArray* array;
|
659
|
-
ArrayType* arrayType;
|
660
738
|
VALUE argv[2];
|
661
739
|
|
662
740
|
Data_Get_Struct(self, InlineArray, array);
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
return Qnil;
|
741
|
+
|
742
|
+
if (array->componentType->nativeType != NATIVE_INT8 && array->componentType->nativeType != NATIVE_UINT8) {
|
743
|
+
VALUE dummy = Qnil;
|
744
|
+
return rb_call_super(0, &dummy);
|
668
745
|
}
|
669
746
|
|
670
747
|
argv[0] = UINT2NUM(array->field->offset);
|
671
|
-
argv[1] = UINT2NUM(
|
748
|
+
argv[1] = UINT2NUM(array->length);
|
672
749
|
|
673
750
|
return rb_funcall2(array->rbMemory, rb_intern("get_string"), 2, argv);
|
674
751
|
}
|
@@ -678,19 +755,11 @@ static VALUE
|
|
678
755
|
inline_array_to_ptr(VALUE self)
|
679
756
|
{
|
680
757
|
InlineArray* array;
|
681
|
-
AbstractMemory* ptr;
|
682
|
-
VALUE rbOffset, rbPointer;
|
683
|
-
|
684
|
-
Data_Get_Struct(self, InlineArray, array);
|
685
|
-
|
686
|
-
rbOffset = UINT2NUM(array->field->offset);
|
687
|
-
rbPointer = rb_funcall2(array->rbMemory, rb_intern("+"), 1, &rbOffset);
|
688
|
-
Data_Get_Struct(rbPointer, AbstractMemory, ptr);
|
689
758
|
|
690
|
-
|
691
|
-
ptr->size = MIN(ptr->size, array->field->type->ffiType->size);
|
759
|
+
Data_Get_Struct(self, InlineArray, array);
|
692
760
|
|
693
|
-
return
|
761
|
+
return rb_funcall(array->rbMemory, rb_intern("slice"), 2,
|
762
|
+
UINT2NUM(array->field->offset), UINT2NUM(array->arrayType->base.ffiType->size));
|
694
763
|
}
|
695
764
|
|
696
765
|
|
@@ -711,6 +780,9 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
711
780
|
rbffi_StructInlineArrayClass = rb_define_class_under(rbffi_StructClass, "InlineArray", rb_cObject);
|
712
781
|
rb_global_variable(&rbffi_StructInlineArrayClass);
|
713
782
|
|
783
|
+
rbffi_StructLayoutCharArrayClass = rb_define_class_under(rbffi_StructLayoutClass,
|
784
|
+
"CharArray", rbffi_StructInlineArrayClass);
|
785
|
+
rb_global_variable(&rbffi_StructLayoutCharArrayClass);
|
714
786
|
|
715
787
|
|
716
788
|
rb_define_alloc_func(StructClass, struct_allocate);
|
@@ -756,10 +828,11 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
756
828
|
rb_define_method(rbffi_StructInlineArrayClass, "each", inline_array_each, 0);
|
757
829
|
rb_define_method(rbffi_StructInlineArrayClass, "size", inline_array_size, 0);
|
758
830
|
rb_define_method(rbffi_StructInlineArrayClass, "to_a", inline_array_to_a, 0);
|
759
|
-
rb_define_method(rbffi_StructInlineArrayClass, "to_s", inline_array_to_s, 0);
|
760
|
-
rb_define_alias(rbffi_StructInlineArrayClass, "to_str", "to_s");
|
761
831
|
rb_define_method(rbffi_StructInlineArrayClass, "to_ptr", inline_array_to_ptr, 0);
|
762
832
|
|
833
|
+
rb_define_method(rbffi_StructLayoutCharArrayClass, "to_s", inline_array_to_s, 0);
|
834
|
+
rb_define_alias(rbffi_StructLayoutCharArrayClass, "to_str", "to_s");
|
835
|
+
|
763
836
|
id_pointer_ivar = rb_intern("@pointer");
|
764
837
|
id_layout_ivar = rb_intern("@layout");
|
765
838
|
id_layout = rb_intern("layout");
|