ffi 0.5.4-x86-mingw32 → 0.6.3-x86-mingw32
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/History.txt +102 -0
- data/LICENSE +1 -27
- data/Rakefile +4 -12
- 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 +31 -3
- data/ext/ffi_c/Call.h +5 -1
- data/ext/ffi_c/DynamicLibrary.c +0 -1
- data/ext/ffi_c/Function.c +22 -4
- data/ext/ffi_c/MemoryPointer.c +2 -3
- data/ext/ffi_c/Pointer.c +23 -9
- data/ext/ffi_c/Struct.c +227 -79
- 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 +9 -3
- data/ext/ffi_c/Types.h +2 -0
- data/ext/ffi_c/extconf.rb +11 -7
- data/ext/ffi_c/libffi.gnu.mk +1 -1
- data/ext/ffi_c/libffi.mk +1 -1
- 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 +11340 -18473
- 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/gen/Rakefile +4 -2
- data/lib/1.8/ffi_c.so +0 -0
- data/lib/1.9/ffi_c.so +0 -0
- data/lib/ffi/autopointer.rb +79 -20
- data/lib/ffi/callback.rb +4 -10
- data/lib/ffi/enum.rb +28 -0
- data/lib/ffi/ffi.rb +1 -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 +82 -0
- data/tasks/ann.rake +80 -0
- data/tasks/extension.rake +25 -0
- data/tasks/gem.rake +200 -0
- data/tasks/git.rake +41 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +300 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +312 -279
- 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/Call.h
CHANGED
@@ -35,7 +35,9 @@
|
|
35
35
|
extern "C" {
|
36
36
|
#endif
|
37
37
|
|
38
|
-
#if defined(__i386__) &&
|
38
|
+
#if defined(__i386__) && \
|
39
|
+
(defined(HAVE_RAW_API) || defined(USE_INTERNAL_LIBFFI)) && \
|
40
|
+
!defined(_WIN32) && !defined(__WIN32__)
|
39
41
|
# define USE_RAW
|
40
42
|
#endif
|
41
43
|
|
@@ -57,6 +59,8 @@ typedef union {
|
|
57
59
|
#endif
|
58
60
|
signed long long i64;
|
59
61
|
unsigned long long u64;
|
62
|
+
signed long sl;
|
63
|
+
unsigned long ul;
|
60
64
|
void* ptr;
|
61
65
|
float f32;
|
62
66
|
double f64;
|
data/ext/ffi_c/DynamicLibrary.c
CHANGED
@@ -157,7 +157,6 @@ symbol_new(VALUE library, void* address, VALUE name)
|
|
157
157
|
sym->memory.size = LONG_MAX;
|
158
158
|
sym->memory.typeSize = 1;
|
159
159
|
sym->memory.access = MEM_RD | MEM_WR;
|
160
|
-
sym->memory.ops = &rbffi_AbstractMemoryOps;
|
161
160
|
sym->library = library;
|
162
161
|
sym->name = name;
|
163
162
|
|
data/ext/ffi_c/Function.c
CHANGED
@@ -81,7 +81,6 @@ function_allocate(VALUE klass)
|
|
81
81
|
obj = Data_Make_Struct(klass, Function, function_mark, function_free, fn);
|
82
82
|
|
83
83
|
fn->memory.access = MEM_RD;
|
84
|
-
fn->memory.ops = &rbffi_AbstractMemoryOps;
|
85
84
|
|
86
85
|
fn->rbProc = Qnil;
|
87
86
|
fn->rbFunctionInfo = Qnil;
|
@@ -250,7 +249,13 @@ function_attach(VALUE self, VALUE module, VALUE name)
|
|
250
249
|
Data_Get_Struct(self, Function, fn);
|
251
250
|
|
252
251
|
if (fn->info->parameterCount == -1) {
|
253
|
-
rb_raise(rb_eRuntimeError, "
|
252
|
+
rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
|
253
|
+
return Qnil;
|
254
|
+
}
|
255
|
+
|
256
|
+
if (!rb_obj_is_kind_of(module, rb_cModule)) {
|
257
|
+
rb_raise(rb_eRuntimeError, "trying to attach function to non-module");
|
258
|
+
return Qnil;
|
254
259
|
}
|
255
260
|
|
256
261
|
if (fn->methodHandle == NULL) {
|
@@ -350,6 +355,12 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
350
355
|
case NATIVE_UINT64:
|
351
356
|
param = ULL2NUM(*(uint64_t *) parameters[i]);
|
352
357
|
break;
|
358
|
+
case NATIVE_LONG:
|
359
|
+
param = LONG2NUM(*(long *) parameters[i]);
|
360
|
+
break;
|
361
|
+
case NATIVE_ULONG:
|
362
|
+
param = ULONG2NUM(*(unsigned long *) parameters[i]);
|
363
|
+
break;
|
353
364
|
case NATIVE_FLOAT32:
|
354
365
|
param = rb_float_new(*(float *) parameters[i]);
|
355
366
|
break;
|
@@ -363,7 +374,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
363
374
|
param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
|
364
375
|
break;
|
365
376
|
case NATIVE_BOOL:
|
366
|
-
param = (*(
|
377
|
+
param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
|
367
378
|
break;
|
368
379
|
|
369
380
|
case NATIVE_FUNCTION:
|
@@ -397,6 +408,12 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
397
408
|
case NATIVE_UINT64:
|
398
409
|
*((uint64_t *) retval) = NUM2ULL(rbReturnValue);
|
399
410
|
break;
|
411
|
+
case NATIVE_LONG:
|
412
|
+
*((ffi_sarg *) retval) = NUM2LONG(rbReturnValue);
|
413
|
+
break;
|
414
|
+
case NATIVE_ULONG:
|
415
|
+
*((ffi_arg *) retval) = NUM2ULONG(rbReturnValue);
|
416
|
+
break;
|
400
417
|
case NATIVE_FLOAT32:
|
401
418
|
*((float *) retval) = (float) NUM2DBL(rbReturnValue);
|
402
419
|
break;
|
@@ -411,8 +428,9 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
411
428
|
*((void **) retval) = NULL;
|
412
429
|
}
|
413
430
|
break;
|
431
|
+
|
414
432
|
case NATIVE_BOOL:
|
415
|
-
*((
|
433
|
+
*((ffi_arg *) retval) = rbReturnValue == Qtrue;
|
416
434
|
break;
|
417
435
|
|
418
436
|
case NATIVE_FUNCTION:
|
data/ext/ffi_c/MemoryPointer.c
CHANGED
@@ -63,7 +63,6 @@ memptr_allocate(VALUE klass)
|
|
63
63
|
{
|
64
64
|
MemoryPointer* p;
|
65
65
|
VALUE obj = Data_Make_Struct(klass, MemoryPointer, NULL, memptr_release, p);
|
66
|
-
p->memory.ops = &rbffi_AbstractMemoryOps;
|
67
66
|
p->memory.access = MEM_RD | MEM_WR;
|
68
67
|
|
69
68
|
return obj;
|
@@ -106,7 +105,7 @@ memptr_malloc(VALUE self, long size, long count, bool clear)
|
|
106
105
|
/* ensure the memory is aligned on at least a 8 byte boundary */
|
107
106
|
p->memory.address = (char *) (((uintptr_t) p->storage + 0x7) & (uintptr_t) ~0x7UL);;
|
108
107
|
p->allocated = true;
|
109
|
-
|
108
|
+
|
110
109
|
if (clear && p->memory.size > 0) {
|
111
110
|
memset(p->memory.address, 0, p->memory.size);
|
112
111
|
}
|
@@ -135,7 +134,7 @@ memptr_free(VALUE self)
|
|
135
134
|
|
136
135
|
if (ptr->allocated) {
|
137
136
|
if (ptr->storage != NULL) {
|
138
|
-
|
137
|
+
xfree(ptr->storage);
|
139
138
|
ptr->storage = NULL;
|
140
139
|
}
|
141
140
|
ptr->allocated = false;
|
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,12 +63,16 @@ 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
|
|
69
71
|
static void struct_mark(Struct *);
|
70
72
|
static void struct_layout_builder_mark(StructLayoutBuilder *);
|
71
73
|
static void struct_layout_builder_free(StructLayoutBuilder *);
|
74
|
+
static VALUE struct_class_layout(VALUE klass);
|
75
|
+
static void struct_malloc(Struct* s);
|
72
76
|
static void inline_array_mark(InlineArray *);
|
73
77
|
|
74
78
|
static inline int align(int offset, int align);
|
@@ -77,6 +81,8 @@ VALUE rbffi_StructClass = Qnil;
|
|
77
81
|
static VALUE StructLayoutBuilderClass = Qnil;
|
78
82
|
|
79
83
|
VALUE rbffi_StructInlineArrayClass = Qnil;
|
84
|
+
VALUE rbffi_StructLayoutCharArrayClass = Qnil;
|
85
|
+
|
80
86
|
static ID id_pointer_ivar = 0, id_layout_ivar = 0;
|
81
87
|
static ID id_get = 0, id_put = 0, id_to_ptr = 0, id_to_s = 0, id_layout = 0;
|
82
88
|
|
@@ -112,10 +118,8 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
|
|
112
118
|
/* Call up into ruby code to adjust the layout */
|
113
119
|
if (nargs > 1) {
|
114
120
|
s->rbLayout = rb_funcall2(CLASS_OF(self), id_layout, RARRAY_LEN(rest), RARRAY_PTR(rest));
|
115
|
-
} else if (rb_cvar_defined(klass, id_layout_ivar)) {
|
116
|
-
s->rbLayout = rb_cvar_get(klass, id_layout_ivar);
|
117
121
|
} else {
|
118
|
-
|
122
|
+
s->rbLayout = struct_class_layout(klass);
|
119
123
|
}
|
120
124
|
|
121
125
|
if (!rb_obj_is_kind_of(s->rbLayout, rbffi_StructLayoutClass)) {
|
@@ -128,16 +132,72 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
|
|
128
132
|
s->pointer = MEMORY(rbPointer);
|
129
133
|
s->rbPointer = rbPointer;
|
130
134
|
} else {
|
131
|
-
|
132
|
-
|
135
|
+
struct_malloc(s);
|
136
|
+
}
|
137
|
+
|
138
|
+
return self;
|
139
|
+
}
|
140
|
+
|
141
|
+
static VALUE
|
142
|
+
struct_class_layout(VALUE klass)
|
143
|
+
{
|
144
|
+
VALUE layout;
|
145
|
+
if (!rb_cvar_defined(klass, id_layout_ivar)) {
|
146
|
+
rb_raise(rb_eRuntimeError, "no Struct layout configured for %s", rb_class2name(klass));
|
133
147
|
}
|
134
148
|
|
135
|
-
|
136
|
-
|
137
|
-
rb_raise(rb_eRuntimeError, "
|
149
|
+
layout = rb_cvar_get(klass, id_layout_ivar);
|
150
|
+
if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
|
151
|
+
rb_raise(rb_eRuntimeError, "invalid Struct layout for %s", rb_class2name(klass));
|
138
152
|
}
|
139
153
|
|
140
|
-
return
|
154
|
+
return layout;
|
155
|
+
}
|
156
|
+
|
157
|
+
static StructLayout*
|
158
|
+
struct_layout(VALUE self)
|
159
|
+
{
|
160
|
+
Struct* s = (Struct *) DATA_PTR(self);
|
161
|
+
if (s->layout != NULL) {
|
162
|
+
return s->layout;
|
163
|
+
}
|
164
|
+
|
165
|
+
if (s->layout == NULL) {
|
166
|
+
s->rbLayout = struct_class_layout(CLASS_OF(self));
|
167
|
+
Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
|
168
|
+
}
|
169
|
+
|
170
|
+
return s->layout;
|
171
|
+
}
|
172
|
+
|
173
|
+
static Struct*
|
174
|
+
struct_validate(VALUE self)
|
175
|
+
{
|
176
|
+
Struct* s;
|
177
|
+
Data_Get_Struct(self, Struct, s);
|
178
|
+
|
179
|
+
if (struct_layout(self) == NULL) {
|
180
|
+
rb_raise(rb_eRuntimeError, "struct layout == null");
|
181
|
+
}
|
182
|
+
|
183
|
+
if (s->pointer == NULL) {
|
184
|
+
struct_malloc(s);
|
185
|
+
}
|
186
|
+
|
187
|
+
return s;
|
188
|
+
}
|
189
|
+
|
190
|
+
static void
|
191
|
+
struct_malloc(Struct* s)
|
192
|
+
{
|
193
|
+
if (s->rbPointer == Qnil) {
|
194
|
+
s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
|
195
|
+
|
196
|
+
} else if (!rb_obj_is_kind_of(s->rbPointer, rbffi_AbstractMemoryClass)) {
|
197
|
+
rb_raise(rb_eRuntimeError, "invalid pointer in struct");
|
198
|
+
}
|
199
|
+
|
200
|
+
s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
|
141
201
|
}
|
142
202
|
|
143
203
|
static void
|
@@ -152,9 +212,6 @@ struct_field(Struct* s, VALUE fieldName)
|
|
152
212
|
{
|
153
213
|
StructLayout* layout = s->layout;
|
154
214
|
VALUE rbField;
|
155
|
-
if (layout == NULL) {
|
156
|
-
rb_raise(rb_eRuntimeError, "layout not set for Struct");
|
157
|
-
}
|
158
215
|
|
159
216
|
rbField = rb_hash_aref(layout->rbFieldMap, fieldName);
|
160
217
|
if (rbField == Qnil) {
|
@@ -171,19 +228,23 @@ struct_aref(VALUE self, VALUE fieldName)
|
|
171
228
|
Struct* s;
|
172
229
|
VALUE rbField;
|
173
230
|
StructField* f;
|
174
|
-
MemoryOp* op;
|
175
231
|
|
176
|
-
|
232
|
+
s = struct_validate(self);
|
233
|
+
|
177
234
|
rbField = struct_field(s, fieldName);
|
178
235
|
f = (StructField *) DATA_PTR(rbField);
|
179
236
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
}
|
237
|
+
if (f->get != NULL) {
|
238
|
+
return (*f->get)(f, s);
|
239
|
+
|
240
|
+
} else if (f->memoryOp != NULL) {
|
241
|
+
return (*f->memoryOp->get)(s->pointer, f->offset);
|
242
|
+
|
243
|
+
} else {
|
184
244
|
|
185
|
-
|
186
|
-
|
245
|
+
/* call up to the ruby code to fetch the value */
|
246
|
+
return rb_funcall2(rbField, id_get, 1, &s->rbPointer);
|
247
|
+
}
|
187
248
|
}
|
188
249
|
|
189
250
|
static VALUE
|
@@ -192,37 +253,53 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
|
|
192
253
|
Struct* s;
|
193
254
|
VALUE rbField;
|
194
255
|
StructField* f;
|
195
|
-
MemoryOp* op;
|
196
|
-
VALUE argv[2];
|
197
256
|
|
198
|
-
|
257
|
+
|
258
|
+
s = struct_validate(self);
|
259
|
+
|
199
260
|
rbField = struct_field(s, fieldName);
|
200
261
|
f = (StructField *) DATA_PTR(rbField);
|
262
|
+
if (f->put != NULL) {
|
263
|
+
(*f->put)(f, s, value);
|
201
264
|
|
202
|
-
|
203
|
-
|
204
|
-
(*
|
205
|
-
return self;
|
206
|
-
}
|
265
|
+
} else if (f->memoryOp != NULL) {
|
266
|
+
|
267
|
+
(*f->memoryOp->put)(s->pointer, f->offset, value);
|
207
268
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
269
|
+
} else {
|
270
|
+
/* call up to the ruby code to set the value */
|
271
|
+
VALUE argv[2];
|
272
|
+
argv[0] = s->rbPointer;
|
273
|
+
argv[1] = value;
|
274
|
+
rb_funcall2(rbField, id_put, 2, argv);
|
275
|
+
}
|
212
276
|
|
213
|
-
return
|
277
|
+
return value;
|
214
278
|
}
|
215
279
|
|
216
280
|
static VALUE
|
217
281
|
struct_set_pointer(VALUE self, VALUE pointer)
|
218
282
|
{
|
219
283
|
Struct* s;
|
284
|
+
StructLayout* layout;
|
285
|
+
AbstractMemory* memory;
|
220
286
|
|
221
287
|
if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
|
222
|
-
rb_raise(
|
288
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected Pointer or Buffer)",
|
289
|
+
rb_obj_classname(pointer));
|
290
|
+
return Qnil;
|
223
291
|
}
|
224
292
|
|
293
|
+
|
225
294
|
Data_Get_Struct(self, Struct, s);
|
295
|
+
Data_Get_Struct(pointer, AbstractMemory, memory);
|
296
|
+
layout = struct_layout(self);
|
297
|
+
|
298
|
+
if (layout->base.ffiType->size > memory->size) {
|
299
|
+
rb_raise(rb_eArgError, "memory of %d bytes too small for struct %s (expected at least %d)",
|
300
|
+
memory->size, rb_obj_classname(self), layout->base.ffiType->size);
|
301
|
+
}
|
302
|
+
|
226
303
|
s->pointer = MEMORY(pointer);
|
227
304
|
s->rbPointer = pointer;
|
228
305
|
rb_ivar_set(self, id_pointer_ivar, pointer);
|
@@ -247,7 +324,9 @@ struct_set_layout(VALUE self, VALUE layout)
|
|
247
324
|
Data_Get_Struct(self, Struct, s);
|
248
325
|
|
249
326
|
if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
|
250
|
-
rb_raise(
|
327
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
328
|
+
rb_obj_classname(layout), rb_class2name(rbffi_StructLayoutClass));
|
329
|
+
return Qnil;
|
251
330
|
}
|
252
331
|
|
253
332
|
Data_Get_Struct(layout, StructLayout, s->layout);
|
@@ -425,16 +504,32 @@ struct_layout_builder_add_field(int argc, VALUE* argv, VALUE self)
|
|
425
504
|
fargv[0] = rbName;
|
426
505
|
fargv[1] = UINT2NUM(offset);
|
427
506
|
fargv[2] = rbType;
|
507
|
+
|
428
508
|
if (rb_obj_is_kind_of(rbType, rbffi_FunctionTypeClass)) {
|
509
|
+
|
429
510
|
rbFieldClass = rbffi_StructLayoutFunctionFieldClass;
|
511
|
+
|
430
512
|
} else if (rb_obj_is_kind_of(rbType, rbffi_StructByValueClass)) {
|
431
|
-
|
513
|
+
|
514
|
+
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct"));
|
515
|
+
|
432
516
|
} else if (rb_obj_is_kind_of(rbType, rbffi_ArrayTypeClass)) {
|
517
|
+
|
433
518
|
rbFieldClass = rbffi_StructLayoutArrayFieldClass;
|
519
|
+
|
520
|
+
} else if (rb_obj_is_kind_of(rbType, rbffi_EnumTypeClass)) {
|
521
|
+
|
522
|
+
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("Enum"));
|
523
|
+
|
434
524
|
} else {
|
435
525
|
rbFieldClass = rbffi_StructLayoutFieldClass;
|
436
526
|
}
|
437
527
|
|
528
|
+
if (!RTEST(rbFieldClass)) {
|
529
|
+
rb_raise(rb_eTypeError, "invalid struct field type (%s)", rb_obj_classname(rbType));
|
530
|
+
return Qnil;
|
531
|
+
}
|
532
|
+
|
438
533
|
rbField = rb_class_new_instance(3, fargv, rbFieldClass);
|
439
534
|
} else {
|
440
535
|
rbField = rbType;
|
@@ -449,7 +544,8 @@ static VALUE
|
|
449
544
|
struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self)
|
450
545
|
{
|
451
546
|
StructLayoutBuilder* builder;
|
452
|
-
VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil
|
547
|
+
VALUE rbName = Qnil, rbType = Qnil, rbOffset = Qnil, rbField = Qnil;
|
548
|
+
VALUE rbFieldClass = Qnil, rbStructClass = Qnil;
|
453
549
|
VALUE fargv[3];
|
454
550
|
unsigned int size, alignment, offset;
|
455
551
|
int nargs;
|
@@ -472,7 +568,14 @@ struct_layout_builder_add_struct(int argc, VALUE* argv, VALUE self)
|
|
472
568
|
fargv[0] = rbName;
|
473
569
|
fargv[1] = UINT2NUM(offset);
|
474
570
|
fargv[2] = rbType;
|
475
|
-
|
571
|
+
rbFieldClass = rb_const_get(rbffi_StructLayoutClass, rb_intern("InlineStruct"));
|
572
|
+
if (!RTEST(rbFieldClass)) {
|
573
|
+
rb_raise(rb_eRuntimeError, "could not locate StructLayout::InlineStruct");
|
574
|
+
return Qnil;
|
575
|
+
}
|
576
|
+
|
577
|
+
rbField = rb_class_new_instance(3, fargv, rbFieldClass);
|
578
|
+
|
476
579
|
store_field(builder, rbName, rbField, offset, size, alignment);
|
477
580
|
|
478
581
|
return self;
|
@@ -554,21 +657,18 @@ static VALUE
|
|
554
657
|
inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
|
555
658
|
{
|
556
659
|
InlineArray* array;
|
557
|
-
|
558
|
-
|
660
|
+
|
559
661
|
Data_Get_Struct(self, InlineArray, array);
|
560
662
|
array->rbMemory = rbMemory;
|
561
663
|
array->rbField = rbField;
|
562
664
|
|
563
665
|
Data_Get_Struct(rbMemory, AbstractMemory, array->memory);
|
564
666
|
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);
|
667
|
+
Data_Get_Struct(array->field->rbType, ArrayType, array->arrayType);
|
668
|
+
Data_Get_Struct(array->arrayType->rbComponentType, Type, array->componentType);
|
567
669
|
|
568
|
-
array->op =
|
569
|
-
|
570
|
-
rb_raise(rb_eRuntimeError, "invalid memory ops");
|
571
|
-
}
|
670
|
+
array->op = get_memory_op(array->componentType);
|
671
|
+
array->length = array->arrayType->length;
|
572
672
|
|
573
673
|
return self;
|
574
674
|
}
|
@@ -584,8 +684,12 @@ inline_array_size(VALUE self)
|
|
584
684
|
}
|
585
685
|
|
586
686
|
static int
|
587
|
-
inline_array_offset(InlineArray* array,
|
687
|
+
inline_array_offset(InlineArray* array, int index)
|
588
688
|
{
|
689
|
+
if (index < 0 || index >= array->length) {
|
690
|
+
rb_raise(rb_eIndexError, "index %d out of bounds", index);
|
691
|
+
}
|
692
|
+
|
589
693
|
return array->field->offset + (index * array->componentType->ffiType->size);
|
590
694
|
}
|
591
695
|
|
@@ -596,7 +700,19 @@ inline_array_aref(VALUE self, VALUE rbIndex)
|
|
596
700
|
|
597
701
|
Data_Get_Struct(self, InlineArray, array);
|
598
702
|
|
599
|
-
|
703
|
+
if (array->op != NULL) {
|
704
|
+
return array->op->get(array->memory, inline_array_offset(array, NUM2INT(rbIndex)));
|
705
|
+
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
|
706
|
+
VALUE rbOffset = INT2NUM(inline_array_offset(array, NUM2INT(rbIndex)));
|
707
|
+
VALUE rbLength = INT2NUM(array->componentType->ffiType->size);
|
708
|
+
VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
|
709
|
+
|
710
|
+
return rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass);
|
711
|
+
} else {
|
712
|
+
|
713
|
+
rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(array->arrayType->rbComponentType));
|
714
|
+
return Qnil;
|
715
|
+
}
|
600
716
|
}
|
601
717
|
|
602
718
|
static VALUE
|
@@ -606,8 +722,34 @@ inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
|
|
606
722
|
|
607
723
|
Data_Get_Struct(self, InlineArray, array);
|
608
724
|
|
609
|
-
array->op
|
610
|
-
|
725
|
+
if (array->op != NULL) {
|
726
|
+
array->op->put(array->memory, inline_array_offset(array, NUM2INT(rbIndex)),
|
727
|
+
rbValue);
|
728
|
+
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
|
729
|
+
int offset = inline_array_offset(array, NUM2INT(rbIndex));
|
730
|
+
Struct* s;
|
731
|
+
|
732
|
+
if (!rb_obj_is_kind_of(rbValue, rbffi_StructClass)) {
|
733
|
+
rb_raise(rb_eTypeError, "argument not an instance of struct");
|
734
|
+
return Qnil;
|
735
|
+
}
|
736
|
+
|
737
|
+
checkWrite(array->memory);
|
738
|
+
checkBounds(array->memory, offset, array->componentType->ffiType->size);
|
739
|
+
|
740
|
+
Data_Get_Struct(rbValue, Struct, s);
|
741
|
+
checkRead(s->pointer);
|
742
|
+
checkBounds(s->pointer, 0, array->componentType->ffiType->size);
|
743
|
+
|
744
|
+
memcpy(array->memory->address + offset, s->pointer->address, array->componentType->ffiType->size);
|
745
|
+
|
746
|
+
} else {
|
747
|
+
ArrayType* arrayType;
|
748
|
+
Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
|
749
|
+
|
750
|
+
rb_raise(rb_eArgError, "set not supported for %s", rb_obj_classname(arrayType->rbComponentType));
|
751
|
+
return Qnil;
|
752
|
+
}
|
611
753
|
|
612
754
|
return rbValue;
|
613
755
|
}
|
@@ -616,16 +758,30 @@ static VALUE
|
|
616
758
|
inline_array_each(VALUE self)
|
617
759
|
{
|
618
760
|
InlineArray* array;
|
619
|
-
ArrayType* arrayType;
|
620
761
|
|
621
762
|
int i;
|
622
763
|
|
623
764
|
Data_Get_Struct(self, InlineArray, array);
|
624
|
-
|
765
|
+
|
766
|
+
if (array->op != NULL) {
|
767
|
+
for (i = 0; i < array->length; ++i) {
|
768
|
+
int offset = inline_array_offset(array, i);
|
769
|
+
rb_yield(array->op->get(array->memory, offset));
|
770
|
+
}
|
771
|
+
} else if (array->componentType->nativeType == NATIVE_STRUCT) {
|
772
|
+
for (i = 0; i < array->length; ++i) {
|
773
|
+
VALUE rbOffset = UINT2NUM(inline_array_offset(array, i));
|
774
|
+
VALUE rbLength = UINT2NUM(array->componentType->ffiType->size);
|
775
|
+
VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
|
776
|
+
|
777
|
+
rb_yield(rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass));
|
778
|
+
}
|
779
|
+
} else {
|
780
|
+
ArrayType* arrayType;
|
781
|
+
Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
|
625
782
|
|
626
|
-
|
627
|
-
|
628
|
-
rb_yield(array->op->get(array->memory, offset));
|
783
|
+
rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(arrayType->rbComponentType));
|
784
|
+
return Qnil;
|
629
785
|
}
|
630
786
|
|
631
787
|
return self;
|
@@ -635,16 +791,14 @@ static VALUE
|
|
635
791
|
inline_array_to_a(VALUE self)
|
636
792
|
{
|
637
793
|
InlineArray* array;
|
638
|
-
ArrayType* arrayType;
|
639
794
|
VALUE obj;
|
640
795
|
int i;
|
641
796
|
|
642
797
|
Data_Get_Struct(self, InlineArray, array);
|
643
|
-
|
644
|
-
obj = rb_ary_new2(arrayType->length);
|
798
|
+
obj = rb_ary_new2(array->length);
|
645
799
|
|
646
800
|
|
647
|
-
for (i = 0; i <
|
801
|
+
for (i = 0; i < array->length; ++i) {
|
648
802
|
int offset = inline_array_offset(array, i);
|
649
803
|
rb_ary_push(obj, array->op->get(array->memory, offset));
|
650
804
|
}
|
@@ -656,19 +810,17 @@ static VALUE
|
|
656
810
|
inline_array_to_s(VALUE self)
|
657
811
|
{
|
658
812
|
InlineArray* array;
|
659
|
-
ArrayType* arrayType;
|
660
813
|
VALUE argv[2];
|
661
814
|
|
662
815
|
Data_Get_Struct(self, InlineArray, array);
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
return Qnil;
|
816
|
+
|
817
|
+
if (array->componentType->nativeType != NATIVE_INT8 && array->componentType->nativeType != NATIVE_UINT8) {
|
818
|
+
VALUE dummy = Qnil;
|
819
|
+
return rb_call_super(0, &dummy);
|
668
820
|
}
|
669
821
|
|
670
822
|
argv[0] = UINT2NUM(array->field->offset);
|
671
|
-
argv[1] = UINT2NUM(
|
823
|
+
argv[1] = UINT2NUM(array->length);
|
672
824
|
|
673
825
|
return rb_funcall2(array->rbMemory, rb_intern("get_string"), 2, argv);
|
674
826
|
}
|
@@ -678,19 +830,11 @@ static VALUE
|
|
678
830
|
inline_array_to_ptr(VALUE self)
|
679
831
|
{
|
680
832
|
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
833
|
|
690
|
-
|
691
|
-
ptr->size = MIN(ptr->size, array->field->type->ffiType->size);
|
834
|
+
Data_Get_Struct(self, InlineArray, array);
|
692
835
|
|
693
|
-
return
|
836
|
+
return rb_funcall(array->rbMemory, rb_intern("slice"), 2,
|
837
|
+
UINT2NUM(array->field->offset), UINT2NUM(array->arrayType->base.ffiType->size));
|
694
838
|
}
|
695
839
|
|
696
840
|
|
@@ -711,6 +855,9 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
711
855
|
rbffi_StructInlineArrayClass = rb_define_class_under(rbffi_StructClass, "InlineArray", rb_cObject);
|
712
856
|
rb_global_variable(&rbffi_StructInlineArrayClass);
|
713
857
|
|
858
|
+
rbffi_StructLayoutCharArrayClass = rb_define_class_under(rbffi_StructLayoutClass,
|
859
|
+
"CharArray", rbffi_StructInlineArrayClass);
|
860
|
+
rb_global_variable(&rbffi_StructLayoutCharArrayClass);
|
714
861
|
|
715
862
|
|
716
863
|
rb_define_alloc_func(StructClass, struct_allocate);
|
@@ -756,10 +903,11 @@ rbffi_Struct_Init(VALUE moduleFFI)
|
|
756
903
|
rb_define_method(rbffi_StructInlineArrayClass, "each", inline_array_each, 0);
|
757
904
|
rb_define_method(rbffi_StructInlineArrayClass, "size", inline_array_size, 0);
|
758
905
|
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
906
|
rb_define_method(rbffi_StructInlineArrayClass, "to_ptr", inline_array_to_ptr, 0);
|
762
907
|
|
908
|
+
rb_define_method(rbffi_StructLayoutCharArrayClass, "to_s", inline_array_to_s, 0);
|
909
|
+
rb_define_alias(rbffi_StructLayoutCharArrayClass, "to_str", "to_s");
|
910
|
+
|
763
911
|
id_pointer_ivar = rb_intern("@pointer");
|
764
912
|
id_layout_ivar = rb_intern("@layout");
|
765
913
|
id_layout = rb_intern("layout");
|