summaryrefslogtreecommitdiff
path: root/ext/fiddle
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fiddle')
-rw-r--r--ext/fiddle/closure.c33
-rw-r--r--ext/fiddle/conversions.c55
-rw-r--r--ext/fiddle/conversions.h2
-rw-r--r--ext/fiddle/depend24
-rw-r--r--ext/fiddle/extconf.rb7
-rw-r--r--ext/fiddle/fiddle.c77
-rw-r--r--ext/fiddle/fiddle.gemspec1
-rw-r--r--ext/fiddle/fiddle.h18
-rw-r--r--ext/fiddle/function.c9
-rw-r--r--ext/fiddle/handle.c9
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb28
-rw-r--r--ext/fiddle/lib/fiddle/import.rb2
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb12
-rw-r--r--ext/fiddle/lib/fiddle/value.rb28
-rw-r--r--ext/fiddle/lib/fiddle/version.rb2
-rw-r--r--ext/fiddle/pointer.c50
-rwxr-xr-xext/fiddle/win32/libffi-config.rb10
17 files changed, 289 insertions, 78 deletions
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 892f522a62..2b4cdb6608 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -1,4 +1,5 @@
#include <fiddle.h>
+#include <stdbool.h>
#include <ruby/thread.h>
int ruby_thread_has_gvl_p(void); /* from internal.h */
@@ -54,10 +55,13 @@ closure_memsize(const void * ptr)
}
const rb_data_type_t closure_data_type = {
- "fiddle/closure",
- {0, dealloc, closure_memsize,},
- 0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY,
+ .wrap_struct_name = "fiddle/closure",
+ .function = {
+ .dmark = 0,
+ .dfree = dealloc,
+ .dsize = closure_memsize
+ },
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};
struct callback_args {
@@ -136,6 +140,20 @@ with_gvl_callback(void *ptr)
rb_ary_push(params,
rb_str_new_cstr(*((const char **)(x->args[i]))));
break;
+ case TYPE_BOOL:
+ if (sizeof(bool) == sizeof(char)) {
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned char *)x->args[i]));
+ } else if (sizeof(bool) == sizeof(short)) {
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned short *)x->args[i]));
+ } else if (sizeof(bool) == sizeof(int)) {
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned int *)x->args[i]));
+ } else if (sizeof(bool) == sizeof(long)) {
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned long *)x->args[i]));
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
+ }
+ break;
default:
rb_raise(rb_eRuntimeError, "closure args: %d", type);
}
@@ -185,6 +203,13 @@ with_gvl_callback(void *ptr)
/* Dangerous. Callback must keep reference of the String. */
*((const char **)(x->resp)) = StringValueCStr(ret);
break;
+ case TYPE_BOOL:
+ if (sizeof(bool) == sizeof(long)) {
+ *(unsigned long *)x->resp = RB_TEST(ret);
+ } else {
+ *(ffi_arg *)x->resp = RB_TEST(ret);
+ }
+ break;
default:
rb_raise(rb_eRuntimeError, "closure retval: %d", type);
}
diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c
index 3b70f7de4c..796bf929c3 100644
--- a/ext/fiddle/conversions.c
+++ b/ext/fiddle/conversions.c
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
#include <fiddle.h>
VALUE
@@ -44,6 +46,7 @@ rb_fiddle_type_ensure(VALUE type)
ID ptrdiff_t_id;
ID intptr_t_id;
ID uintptr_t_id;
+ ID bool_id;
RUBY_CONST_ID(void_id, "void");
RUBY_CONST_ID(voidp_id, "voidp");
RUBY_CONST_ID(char_id, "char");
@@ -74,6 +77,7 @@ rb_fiddle_type_ensure(VALUE type)
RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
RUBY_CONST_ID(intptr_t_id, "intptr_t");
RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
+ RUBY_CONST_ID(bool_id, "bool");
if (type_id == void_id) {
return INT2NUM(TYPE_VOID);
}
@@ -144,6 +148,9 @@ rb_fiddle_type_ensure(VALUE type)
else if (type_id == uintptr_t_id) {
return INT2NUM(TYPE_UINTPTR_T);
}
+ else if (type_id == bool_id) {
+ return INT2NUM(TYPE_BOOL);
+ }
else {
type = original_type;
}
@@ -187,6 +194,20 @@ rb_fiddle_int_to_ffi_type(int type)
return &ffi_type_double;
case TYPE_CONST_STRING:
return &ffi_type_pointer;
+ case TYPE_BOOL:
+ signed_p = 0;
+ if (sizeof(bool) == sizeof(char)) {
+ return rb_ffi_type_of(char);
+ } else if (sizeof(bool) == sizeof(short)) {
+ return rb_ffi_type_of(short);
+ } else if (sizeof(bool) == sizeof(int)) {
+ return rb_ffi_type_of(int);
+ } else if (sizeof(bool) == sizeof(long)) {
+ return rb_ffi_type_of(long);
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
+ }
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
@@ -209,7 +230,11 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
dst->pointer = NUM2PTR(rb_Integer(*src));
break;
case TYPE_CHAR:
- dst->schar = (signed char)NUM2INT(*src);
+ if (RB_TYPE_P(*src, RUBY_T_STRING) && RSTRING_LEN(*src) == 1) {
+ dst->schar = RSTRING_PTR(*src)[0];
+ } else {
+ dst->schar = (signed char)NUM2INT(*src);
+ }
break;
case TYPE_UCHAR:
dst->uchar = (unsigned char)NUM2UINT(*src);
@@ -254,8 +279,23 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
dst->pointer = rb_string_value_cstr(src);
}
break;
+ case TYPE_BOOL:
+ if (sizeof(bool) == sizeof(char)) {
+ dst->uchar = RB_TEST(*src);
+ } else if (sizeof(bool) == sizeof(short)) {
+ dst->ushort = RB_TEST(*src);
+ } else if (sizeof(bool) == sizeof(int)) {
+ dst->uint = RB_TEST(*src);
+ } else if (sizeof(bool) == sizeof(long)) {
+ dst->ulong = RB_TEST(*src);
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
+ }
+ break;
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
+ break;
}
}
@@ -314,6 +354,19 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
else {
return Qnil;
}
+ case TYPE_BOOL:
+ if (sizeof(bool) == sizeof(char)) {
+ return CBOOL2RBBOOL((unsigned char)retval.fffi_arg);
+ } else if (sizeof(bool) == sizeof(short)) {
+ return CBOOL2RBBOOL((unsigned short)retval.fffi_arg);
+ } else if (sizeof(bool) == sizeof(int)) {
+ return CBOOL2RBBOOL((unsigned int)retval.fffi_arg);
+ } else if (sizeof(bool) == sizeof(long)) {
+ return CBOOL2RBBOOL(retval.ulong);
+ } else {
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
+ (unsigned int)sizeof(bool));
+ }
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h
index c7c12a9234..7a1e928d56 100644
--- a/ext/fiddle/conversions.h
+++ b/ext/fiddle/conversions.h
@@ -50,4 +50,6 @@ VALUE generic_to_value(VALUE rettype, fiddle_generic retval);
# define NUM2PTR(x) ((void*)(NUM2ULL(x)))
#endif
+#define CBOOL2RBBOOL(cbool) ((cbool) ? RUBY_Qtrue : RUBY_Qfalse)
+
#endif
diff --git a/ext/fiddle/depend b/ext/fiddle/depend
index d6a053f05b..561785275e 100644
--- a/ext/fiddle/depend
+++ b/ext/fiddle/depend
@@ -105,6 +105,7 @@ closure.o: $(hdrdir)/ruby/internal/attr/noexcept.h
closure.o: $(hdrdir)/ruby/internal/attr/noinline.h
closure.o: $(hdrdir)/ruby/internal/attr/nonnull.h
closure.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+closure.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
closure.o: $(hdrdir)/ruby/internal/attr/pure.h
closure.o: $(hdrdir)/ruby/internal/attr/restrict.h
closure.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -164,7 +165,6 @@ closure.o: $(hdrdir)/ruby/internal/intern/enumerator.h
closure.o: $(hdrdir)/ruby/internal/intern/error.h
closure.o: $(hdrdir)/ruby/internal/intern/eval.h
closure.o: $(hdrdir)/ruby/internal/intern/file.h
-closure.o: $(hdrdir)/ruby/internal/intern/gc.h
closure.o: $(hdrdir)/ruby/internal/intern/hash.h
closure.o: $(hdrdir)/ruby/internal/intern/io.h
closure.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -195,7 +195,6 @@ closure.o: $(hdrdir)/ruby/internal/memory.h
closure.o: $(hdrdir)/ruby/internal/method.h
closure.o: $(hdrdir)/ruby/internal/module.h
closure.o: $(hdrdir)/ruby/internal/newobj.h
-closure.o: $(hdrdir)/ruby/internal/rgengc.h
closure.o: $(hdrdir)/ruby/internal/scan_args.h
closure.o: $(hdrdir)/ruby/internal/special_consts.h
closure.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -270,6 +269,7 @@ conversions.o: $(hdrdir)/ruby/internal/attr/noexcept.h
conversions.o: $(hdrdir)/ruby/internal/attr/noinline.h
conversions.o: $(hdrdir)/ruby/internal/attr/nonnull.h
conversions.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+conversions.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
conversions.o: $(hdrdir)/ruby/internal/attr/pure.h
conversions.o: $(hdrdir)/ruby/internal/attr/restrict.h
conversions.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -329,7 +329,6 @@ conversions.o: $(hdrdir)/ruby/internal/intern/enumerator.h
conversions.o: $(hdrdir)/ruby/internal/intern/error.h
conversions.o: $(hdrdir)/ruby/internal/intern/eval.h
conversions.o: $(hdrdir)/ruby/internal/intern/file.h
-conversions.o: $(hdrdir)/ruby/internal/intern/gc.h
conversions.o: $(hdrdir)/ruby/internal/intern/hash.h
conversions.o: $(hdrdir)/ruby/internal/intern/io.h
conversions.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -360,7 +359,6 @@ conversions.o: $(hdrdir)/ruby/internal/memory.h
conversions.o: $(hdrdir)/ruby/internal/method.h
conversions.o: $(hdrdir)/ruby/internal/module.h
conversions.o: $(hdrdir)/ruby/internal/newobj.h
-conversions.o: $(hdrdir)/ruby/internal/rgengc.h
conversions.o: $(hdrdir)/ruby/internal/scan_args.h
conversions.o: $(hdrdir)/ruby/internal/special_consts.h
conversions.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -434,6 +432,7 @@ fiddle.o: $(hdrdir)/ruby/internal/attr/noexcept.h
fiddle.o: $(hdrdir)/ruby/internal/attr/noinline.h
fiddle.o: $(hdrdir)/ruby/internal/attr/nonnull.h
fiddle.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
fiddle.o: $(hdrdir)/ruby/internal/attr/pure.h
fiddle.o: $(hdrdir)/ruby/internal/attr/restrict.h
fiddle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -493,7 +492,6 @@ fiddle.o: $(hdrdir)/ruby/internal/intern/enumerator.h
fiddle.o: $(hdrdir)/ruby/internal/intern/error.h
fiddle.o: $(hdrdir)/ruby/internal/intern/eval.h
fiddle.o: $(hdrdir)/ruby/internal/intern/file.h
-fiddle.o: $(hdrdir)/ruby/internal/intern/gc.h
fiddle.o: $(hdrdir)/ruby/internal/intern/hash.h
fiddle.o: $(hdrdir)/ruby/internal/intern/io.h
fiddle.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -524,7 +522,6 @@ fiddle.o: $(hdrdir)/ruby/internal/memory.h
fiddle.o: $(hdrdir)/ruby/internal/method.h
fiddle.o: $(hdrdir)/ruby/internal/module.h
fiddle.o: $(hdrdir)/ruby/internal/newobj.h
-fiddle.o: $(hdrdir)/ruby/internal/rgengc.h
fiddle.o: $(hdrdir)/ruby/internal/scan_args.h
fiddle.o: $(hdrdir)/ruby/internal/special_consts.h
fiddle.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -598,6 +595,7 @@ function.o: $(hdrdir)/ruby/internal/attr/noexcept.h
function.o: $(hdrdir)/ruby/internal/attr/noinline.h
function.o: $(hdrdir)/ruby/internal/attr/nonnull.h
function.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+function.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
function.o: $(hdrdir)/ruby/internal/attr/pure.h
function.o: $(hdrdir)/ruby/internal/attr/restrict.h
function.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -657,7 +655,6 @@ function.o: $(hdrdir)/ruby/internal/intern/enumerator.h
function.o: $(hdrdir)/ruby/internal/intern/error.h
function.o: $(hdrdir)/ruby/internal/intern/eval.h
function.o: $(hdrdir)/ruby/internal/intern/file.h
-function.o: $(hdrdir)/ruby/internal/intern/gc.h
function.o: $(hdrdir)/ruby/internal/intern/hash.h
function.o: $(hdrdir)/ruby/internal/intern/io.h
function.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -688,7 +685,6 @@ function.o: $(hdrdir)/ruby/internal/memory.h
function.o: $(hdrdir)/ruby/internal/method.h
function.o: $(hdrdir)/ruby/internal/module.h
function.o: $(hdrdir)/ruby/internal/newobj.h
-function.o: $(hdrdir)/ruby/internal/rgengc.h
function.o: $(hdrdir)/ruby/internal/scan_args.h
function.o: $(hdrdir)/ruby/internal/special_consts.h
function.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -763,6 +759,7 @@ handle.o: $(hdrdir)/ruby/internal/attr/noexcept.h
handle.o: $(hdrdir)/ruby/internal/attr/noinline.h
handle.o: $(hdrdir)/ruby/internal/attr/nonnull.h
handle.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+handle.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
handle.o: $(hdrdir)/ruby/internal/attr/pure.h
handle.o: $(hdrdir)/ruby/internal/attr/restrict.h
handle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -822,7 +819,6 @@ handle.o: $(hdrdir)/ruby/internal/intern/enumerator.h
handle.o: $(hdrdir)/ruby/internal/intern/error.h
handle.o: $(hdrdir)/ruby/internal/intern/eval.h
handle.o: $(hdrdir)/ruby/internal/intern/file.h
-handle.o: $(hdrdir)/ruby/internal/intern/gc.h
handle.o: $(hdrdir)/ruby/internal/intern/hash.h
handle.o: $(hdrdir)/ruby/internal/intern/io.h
handle.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -853,7 +849,6 @@ handle.o: $(hdrdir)/ruby/internal/memory.h
handle.o: $(hdrdir)/ruby/internal/method.h
handle.o: $(hdrdir)/ruby/internal/module.h
handle.o: $(hdrdir)/ruby/internal/newobj.h
-handle.o: $(hdrdir)/ruby/internal/rgengc.h
handle.o: $(hdrdir)/ruby/internal/scan_args.h
handle.o: $(hdrdir)/ruby/internal/special_consts.h
handle.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -928,6 +923,7 @@ memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h
memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h
memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h
memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -996,7 +992,6 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h
memory_view.o: $(hdrdir)/ruby/internal/intern/error.h
memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h
memory_view.o: $(hdrdir)/ruby/internal/intern/file.h
-memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h
memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h
memory_view.o: $(hdrdir)/ruby/internal/intern/io.h
memory_view.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1027,7 +1022,6 @@ memory_view.o: $(hdrdir)/ruby/internal/memory.h
memory_view.o: $(hdrdir)/ruby/internal/method.h
memory_view.o: $(hdrdir)/ruby/internal/module.h
memory_view.o: $(hdrdir)/ruby/internal/newobj.h
-memory_view.o: $(hdrdir)/ruby/internal/rgengc.h
memory_view.o: $(hdrdir)/ruby/internal/scan_args.h
memory_view.o: $(hdrdir)/ruby/internal/special_consts.h
memory_view.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1104,6 +1098,7 @@ pinned.o: $(hdrdir)/ruby/internal/attr/noexcept.h
pinned.o: $(hdrdir)/ruby/internal/attr/noinline.h
pinned.o: $(hdrdir)/ruby/internal/attr/nonnull.h
pinned.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+pinned.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
pinned.o: $(hdrdir)/ruby/internal/attr/pure.h
pinned.o: $(hdrdir)/ruby/internal/attr/restrict.h
pinned.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1163,7 +1158,6 @@ pinned.o: $(hdrdir)/ruby/internal/intern/enumerator.h
pinned.o: $(hdrdir)/ruby/internal/intern/error.h
pinned.o: $(hdrdir)/ruby/internal/intern/eval.h
pinned.o: $(hdrdir)/ruby/internal/intern/file.h
-pinned.o: $(hdrdir)/ruby/internal/intern/gc.h
pinned.o: $(hdrdir)/ruby/internal/intern/hash.h
pinned.o: $(hdrdir)/ruby/internal/intern/io.h
pinned.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1194,7 +1188,6 @@ pinned.o: $(hdrdir)/ruby/internal/memory.h
pinned.o: $(hdrdir)/ruby/internal/method.h
pinned.o: $(hdrdir)/ruby/internal/module.h
pinned.o: $(hdrdir)/ruby/internal/newobj.h
-pinned.o: $(hdrdir)/ruby/internal/rgengc.h
pinned.o: $(hdrdir)/ruby/internal/scan_args.h
pinned.o: $(hdrdir)/ruby/internal/special_consts.h
pinned.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1269,6 +1262,7 @@ pointer.o: $(hdrdir)/ruby/internal/attr/noexcept.h
pointer.o: $(hdrdir)/ruby/internal/attr/noinline.h
pointer.o: $(hdrdir)/ruby/internal/attr/nonnull.h
pointer.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+pointer.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
pointer.o: $(hdrdir)/ruby/internal/attr/pure.h
pointer.o: $(hdrdir)/ruby/internal/attr/restrict.h
pointer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1337,7 +1331,6 @@ pointer.o: $(hdrdir)/ruby/internal/intern/enumerator.h
pointer.o: $(hdrdir)/ruby/internal/intern/error.h
pointer.o: $(hdrdir)/ruby/internal/intern/eval.h
pointer.o: $(hdrdir)/ruby/internal/intern/file.h
-pointer.o: $(hdrdir)/ruby/internal/intern/gc.h
pointer.o: $(hdrdir)/ruby/internal/intern/hash.h
pointer.o: $(hdrdir)/ruby/internal/intern/io.h
pointer.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1368,7 +1361,6 @@ pointer.o: $(hdrdir)/ruby/internal/memory.h
pointer.o: $(hdrdir)/ruby/internal/method.h
pointer.o: $(hdrdir)/ruby/internal/module.h
pointer.o: $(hdrdir)/ruby/internal/newobj.h
-pointer.o: $(hdrdir)/ruby/internal/rgengc.h
pointer.o: $(hdrdir)/ruby/internal/scan_args.h
pointer.o: $(hdrdir)/ruby/internal/special_consts.h
pointer.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb
index d550d23f79..2d85b3eea5 100644
--- a/ext/fiddle/extconf.rb
+++ b/ext/fiddle/extconf.rb
@@ -63,6 +63,11 @@ unless bundle
end
if have_ffi_header && (have_library('ffi') || have_library('libffi'))
have_libffi = true
+ checking_for("undefined FFI_GO_CLOSURES is used") do
+ if egrep_cpp(/warning: 'FFI_GO_CLOSURES' is not defined/, cpp_include(ffi_header), "2>&1")
+ $defs.push('-DFFI_GO_CLOSURES=0')
+ end
+ end
end
end
@@ -151,7 +156,7 @@ if libffi_version
libffi_version = libffi_version.gsub(/-rc\d+/, '')
libffi_version = (libffi_version.split('.').map(&:to_i) + [0,0])[0,3]
$defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % libffi_version }})
- puts "libffi_version: #{libffi_version.join('.')}"
+ warn "libffi_version: #{libffi_version.join('.')}"
end
case
diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c
index acc1cd0837..f420d9fa3b 100644
--- a/ext/fiddle/fiddle.c
+++ b/ext/fiddle/fiddle.c
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
#include <fiddle.h>
VALUE mFiddle;
@@ -58,18 +60,16 @@ rb_fiddle_free(VALUE self, VALUE addr)
/*
* call-seq: Fiddle.dlunwrap(addr)
*
- * Returns the hexadecimal representation of a memory pointer address +addr+
+ * Returns the Ruby object stored at the memory address +addr+
*
* Example:
*
- * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
- * => #<Fiddle::Handle:0x00000001342460>
- *
- * lib['strcpy'].to_s(16)
- * => "7f59de6dd240"
- *
- * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
- * => "7f59de6dd240"
+ * x = Object.new
+ * # => #<Object:0x0000000107c7d870>
+ * Fiddle.dlwrap(x)
+ * # => 4425504880
+ * Fiddle.dlunwrap(_)
+ * # => #<Object:0x0000000107c7d870>
*/
VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
@@ -80,15 +80,22 @@ rb_fiddle_ptr2value(VALUE self, VALUE addr)
/*
* call-seq: Fiddle.dlwrap(val)
*
- * Returns a memory pointer of a function's hexadecimal address location +val+
+ * Returns the memory address of the Ruby object stored at +val+
*
* Example:
*
- * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
- * => #<Fiddle::Handle:0x00000001342460>
+ * x = Object.new
+ * # => #<Object:0x0000000107c7d870>
+ * Fiddle.dlwrap(x)
+ * # => 4425504880
+ *
+ * In the case +val+ is not a heap allocated object, this method will return
+ * the tagged pointer value.
*
- * Fiddle.dlwrap(lib['strcpy'].to_s(16))
- * => 25522520
+ * Example:
+ *
+ * Fiddle.dlwrap(123)
+ * # => 247
*/
static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
@@ -352,6 +359,12 @@ Init_fiddle(void)
*/
rb_define_const(mFiddleTypes, "UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
+ /* Document-const: Fiddle::Types::BOOL
+ *
+ * C type - bool
+ */
+ rb_define_const(mFiddleTypes, "BOOL" , INT2NUM(TYPE_BOOL));
+
/* Document-const: ALIGN_VOIDP
*
* The alignment size of a void*
@@ -456,6 +469,12 @@ Init_fiddle(void)
*/
rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
+ /* Document-const: ALIGN_BOOL
+ *
+ * The alignment size of a bool
+ */
+ rb_define_const(mFiddle, "ALIGN_BOOL", INT2NUM(ALIGN_OF(bool)));
+
/* Document-const: WINDOWS
*
* Returns a boolean regarding whether the host is WIN32
@@ -630,6 +649,12 @@ Init_fiddle(void)
*/
rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
+ /* Document-const: SIZEOF_BOOL
+ *
+ * size of a bool
+ */
+ rb_define_const(mFiddle, "SIZEOF_BOOL", INT2NUM(sizeof(bool)));
+
/* Document-const: RUBY_FREE
*
* Address of the ruby_xfree() function
@@ -650,6 +675,30 @@ Init_fiddle(void)
rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1);
+ /* Document-const: Qtrue
+ *
+ * The value of Qtrue
+ */
+ rb_define_const(mFiddle, "Qtrue", INT2NUM(Qtrue));
+
+ /* Document-const: Qfalse
+ *
+ * The value of Qfalse
+ */
+ rb_define_const(mFiddle, "Qfalse", INT2NUM(Qfalse));
+
+ /* Document-const: Qnil
+ *
+ * The value of Qnil
+ */
+ rb_define_const(mFiddle, "Qnil", INT2NUM(Qnil));
+
+ /* Document-const: Qundef
+ *
+ * The value of Qundef
+ */
+ rb_define_const(mFiddle, "Qundef", INT2NUM(Qundef));
+
Init_fiddle_function();
Init_fiddle_closure();
Init_fiddle_handle();
diff --git a/ext/fiddle/fiddle.gemspec b/ext/fiddle/fiddle.gemspec
index 878109395b..3a1072dd49 100644
--- a/ext/fiddle/fiddle.gemspec
+++ b/ext/fiddle/fiddle.gemspec
@@ -56,4 +56,5 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 2.5.0"
spec.metadata["msys2_mingw_dependencies"] = "libffi"
+ spec.metadata["changelog_uri"] = "https://github.com/ruby/fiddle/releases"
end
diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h
index 10eb9ceedb..348baa9ab9 100644
--- a/ext/fiddle/fiddle.h
+++ b/ext/fiddle/fiddle.h
@@ -118,7 +118,7 @@
#define TYPE_UINT -TYPE_INT
#define TYPE_LONG 5
#define TYPE_ULONG -TYPE_LONG
-#if HAVE_LONG_LONG
+#ifdef HAVE_LONG_LONG
#define TYPE_LONG_LONG 6
#define TYPE_ULONG_LONG -TYPE_LONG_LONG
#endif
@@ -126,6 +126,7 @@
#define TYPE_DOUBLE 8
#define TYPE_VARIADIC 9
#define TYPE_CONST_STRING 10
+#define TYPE_BOOL 11
#define TYPE_INT8_T TYPE_CHAR
#define TYPE_UINT8_T -TYPE_INT8_T
@@ -196,7 +197,20 @@
#endif
#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
-#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
+/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
+ clang versions < 8.0.0 have the same bug. */
+#if defined(HAVE__ALIGNOF)
+# /* Autoconf detected availability of a sane `_Alignof()`. */
+# define ALIGN_OF(type) RB_GNUC_EXTENSION(_Alignof(type))
+#elif (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112 \
+ || (defined(__GNUC__) && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
+ && !defined(__clang__)) \
+ || (defined(__clang__) && __clang_major__ < 8))
+# define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
+#else
+# define ALIGN_OF(type) _Alignof(type)
+#endif
#define ALIGN_VOIDP ALIGN_OF(void*)
#define ALIGN_CHAR ALIGN_OF(char)
diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c
index 274d181d17..5469e09e37 100644
--- a/ext/fiddle/function.c
+++ b/ext/fiddle/function.c
@@ -53,8 +53,13 @@ function_memsize(const void *p)
}
const rb_data_type_t function_data_type = {
- "fiddle/function",
- {0, deallocate, function_memsize,},
+ .wrap_struct_name = "fiddle/function",
+ .function = {
+ .dmark = 0,
+ .dfree = deallocate,
+ .dsize = function_memsize
+ },
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};
static VALUE
diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c
index ae8cc3a581..8ba416952a 100644
--- a/ext/fiddle/handle.c
+++ b/ext/fiddle/handle.c
@@ -50,8 +50,13 @@ fiddle_handle_memsize(const void *ptr)
}
static const rb_data_type_t fiddle_handle_data_type = {
- "fiddle/handle",
- {0, fiddle_handle_free, fiddle_handle_memsize,},
+ .wrap_struct_name = "fiddle/handle",
+ .function = {
+ .dmark = 0,
+ .dfree = fiddle_handle_free,
+ .dsize = fiddle_handle_memsize
+ },
+ .flags = RUBY_TYPED_WB_PROTECTED,
};
/*
diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb
index 9a70402953..264ca166dd 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -165,18 +165,30 @@ module Fiddle
raise(RuntimeError, "unsupported type: #{ty}")
end
return TYPE_ULONG_LONG
- when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/
- return TYPE_LONG
- when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/
+ when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\Aunsigned\s+int\s+long(?:\s+\w+)?\z/,
+ /\Along(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
+ /\Aint\s+unsigned\s+long(?:\s+\w+)?\z/,
+ /\A(?:int\s+)?long\s+unsigned(?:\s+\w+)?\z/
return TYPE_ULONG
+ when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\A(?:signed\s+)?int\s+long(?:\s+\w+)?\z/,
+ /\Along(?:\s+int)?\s+signed(?:\s+\w+)?\z/
+ return TYPE_LONG
+ when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\Aunsigned\s+int\s+short(?:\s+\w+)?\z/,
+ /\Ashort(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
+ /\Aint\s+unsigned\s+short(?:\s+\w+)?\z/,
+ /\A(?:int\s+)?short\s+unsigned(?:\s+\w+)?\z/
+ return TYPE_USHORT
+ when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/,
+ /\A(?:signed\s+)?int\s+short(?:\s+\w+)?\z/,
+ /\Aint\s+(?:signed\s+)?short(?:\s+\w+)?\z/
+ return TYPE_SHORT
when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
return TYPE_INT
when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
return TYPE_UINT
- when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
- return TYPE_SHORT
- when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
- return TYPE_USHORT
when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
return TYPE_CHAR
when /\Aunsigned\s+char(?:\s+\w+)?\z/
@@ -235,6 +247,8 @@ module Fiddle
return TYPE_INTPTR_T
when /\Auintptr_t(?:\s+\w+)?\z/
return TYPE_UINTPTR_T
+ when "bool"
+ return TYPE_BOOL
when /\*/, /\[[\s\d]*\]/
return TYPE_VOIDP
when "..."
diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb
index 09ffcef544..050708fb96 100644
--- a/ext/fiddle/lib/fiddle/import.rb
+++ b/ext/fiddle/lib/fiddle/import.rb
@@ -119,6 +119,8 @@ module Fiddle
return SIZEOF_VOIDP
when TYPE_CONST_STRING
return SIZEOF_CONST_STRING
+ when TYPE_BOOL
+ return SIZEOF_BOOL
else
if defined?(TYPE_LONG_LONG) and
ty == TYPE_LONG_LONG
diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb
index 545b985d50..81088f402b 100644
--- a/ext/fiddle/lib/fiddle/pack.rb
+++ b/ext/fiddle/lib/fiddle/pack.rb
@@ -15,6 +15,7 @@ module Fiddle
TYPE_USHORT => ALIGN_SHORT,
TYPE_UINT => ALIGN_INT,
TYPE_ULONG => ALIGN_LONG,
+ TYPE_BOOL => ALIGN_BOOL,
}
PACK_MAP = {
@@ -30,6 +31,16 @@ module Fiddle
TYPE_UINT => "I!",
TYPE_ULONG => "L!",
}
+ case SIZEOF_BOOL
+ when SIZEOF_CHAR
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UCHAR]
+ when SIZEOF_SHORT
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_USHORT]
+ when SIZEOF_INT
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UINT]
+ when SIZEOF_LONG
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_ULONG]
+ end
SIZE_MAP = {
TYPE_VOIDP => SIZEOF_VOIDP,
@@ -43,6 +54,7 @@ module Fiddle
TYPE_USHORT => SIZEOF_SHORT,
TYPE_UINT => SIZEOF_INT,
TYPE_ULONG => SIZEOF_LONG,
+ TYPE_BOOL => SIZEOF_BOOL,
}
if defined?(TYPE_LONG_LONG)
ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG
diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb
index 01fec1c206..5f0b2e951e 100644
--- a/ext/fiddle/lib/fiddle/value.rb
+++ b/ext/fiddle/lib/fiddle/value.rb
@@ -6,17 +6,17 @@ module Fiddle
def unsigned_value(val, ty)
case ty.abs
when TYPE_CHAR
- [val].pack("c").unpack("C")[0]
+ [val].pack("c").unpack1("C")
when TYPE_SHORT
- [val].pack("s!").unpack("S!")[0]
+ [val].pack("s!").unpack1("S!")
when TYPE_INT
- [val].pack("i!").unpack("I!")[0]
+ [val].pack("i!").unpack1("I!")
when TYPE_LONG
- [val].pack("l!").unpack("L!")[0]
+ [val].pack("l!").unpack1("L!")
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
- [val].pack("q").unpack("Q")[0]
+ [val].pack("q").unpack1("Q")
else
val
end
@@ -26,17 +26,17 @@ module Fiddle
def signed_value(val, ty)
case ty.abs
when TYPE_CHAR
- [val].pack("C").unpack("c")[0]
+ [val].pack("C").unpack1("c")
when TYPE_SHORT
- [val].pack("S!").unpack("s!")[0]
+ [val].pack("S!").unpack1("s!")
when TYPE_INT
- [val].pack("I!").unpack("i!")[0]
+ [val].pack("I!").unpack1("i!")
when TYPE_LONG
- [val].pack("L!").unpack("l!")[0]
+ [val].pack("L!").unpack1("l!")
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
- [val].pack("Q").unpack("q")[0]
+ [val].pack("Q").unpack1("q")
else
val
end
@@ -80,11 +80,11 @@ module Fiddle
else
case SIZEOF_VOIDP
when SIZEOF_LONG
- return [arg].pack("p").unpack("l!")[0]
+ return [arg].pack("p").unpack1("l!")
else
if defined?(SIZEOF_LONG_LONG) and
SIZEOF_VOIDP == SIZEOF_LONG_LONG
- return [arg].pack("p").unpack("q")[0]
+ return [arg].pack("p").unpack1("q")
else
raise(RuntimeError, "sizeof(void*)?")
end
@@ -102,10 +102,8 @@ module Fiddle
return val.unpack('C*')
end
end
- return arg
- else
- return arg
end
+ return arg
else
if( arg.respond_to?(:to_ptr) )
return arg.to_ptr.to_i
diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb
index 719dc62e37..6c5109dca8 100644
--- a/ext/fiddle/lib/fiddle/version.rb
+++ b/ext/fiddle/lib/fiddle/version.rb
@@ -1,3 +1,3 @@
module Fiddle
- VERSION = "1.1.1"
+ VERSION = "1.1.3"
end
diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c
index 15107e3862..1b7d7a69f6 100644
--- a/ext/fiddle/pointer.c
+++ b/ext/fiddle/pointer.c
@@ -88,8 +88,13 @@ fiddle_ptr_memsize(const void *ptr)
}
static const rb_data_type_t fiddle_ptr_data_type = {
- "fiddle/pointer",
- {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
+ .wrap_struct_name = "fiddle/pointer",
+ .function = {
+ .dmark = fiddle_ptr_mark,
+ .dfree = fiddle_ptr_free,
+ .dsize = fiddle_ptr_memsize,
+ },
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
};
#ifdef HAVE_RUBY_MEMORY_VIEW_H
@@ -135,8 +140,8 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wra
data->free = func;
data->freed = false;
data->size = size;
- data->wrap[0] = wrap0;
- data->wrap[1] = wrap1;
+ RB_OBJ_WRITE(val, &data->wrap[0], wrap0);
+ RB_OBJ_WRITE(val, &data->wrap[1], wrap1);
return val;
}
@@ -235,8 +240,8 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
(*(data->free))(data->ptr);
}
- data->wrap[0] = wrap;
- data->wrap[1] = funcwrap;
+ RB_OBJ_WRITE(self, &data->wrap[0], wrap);
+ RB_OBJ_WRITE(self, &data->wrap[1], funcwrap);
data->ptr = p;
data->size = s;
data->free = f;
@@ -314,7 +319,7 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
}
obj = rb_fiddle_ptr_malloc(klass, s,f);
- if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
+ if (wrap) RB_OBJ_WRITE(obj, &RPTR_DATA(obj)->wrap[1], wrap);
if (rb_block_given_p()) {
if (!f) {
@@ -795,10 +800,37 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
if (num == val) wrap = 0;
ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
}
- if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
+ if (wrap) RB_OBJ_WRITE(ptr, &RPTR_DATA(ptr)->wrap[0], wrap);
return ptr;
}
+/*
+ * call-seq:
+ * Fiddle::Pointer.read(address, len) => string
+ *
+ * Or read the memory at address +address+ with length +len+ and return a
+ * string with that memory
+ */
+
+static VALUE
+rb_fiddle_ptr_read_mem(VALUE klass, VALUE address, VALUE len)
+{
+ return rb_str_new((char *)NUM2PTR(address), NUM2ULONG(len));
+}
+
+/*
+ * call-seq:
+ * Fiddle::Pointer.write(address, str)
+ *
+ * Write bytes in +str+ to the location pointed to by +address+.
+ */
+static VALUE
+rb_fiddle_ptr_write_mem(VALUE klass, VALUE addr, VALUE str)
+{
+ memcpy(NUM2PTR(addr), StringValuePtr(str), RSTRING_LEN(str));
+ return str;
+}
+
void
Init_fiddle_pointer(void)
{
@@ -815,6 +847,8 @@ Init_fiddle_pointer(void)
rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1);
rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1);
rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1);
+ rb_define_singleton_method(rb_cPointer, "read", rb_fiddle_ptr_read_mem, 2);
+ rb_define_singleton_method(rb_cPointer, "write", rb_fiddle_ptr_write_mem, 2);
rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
diff --git a/ext/fiddle/win32/libffi-config.rb b/ext/fiddle/win32/libffi-config.rb
index 985fc29d36..8e8069a943 100755
--- a/ext/fiddle/win32/libffi-config.rb
+++ b/ext/fiddle/win32/libffi-config.rb
@@ -23,7 +23,7 @@ until ARGV.empty?
end
end
-IO.foreach("#{srcdir}/configure.ac") do |line|
+File.foreach("#{srcdir}/configure.ac") do |line|
if /^AC_INIT\((.*)\)/ =~ line
version = $1.split(/,\s*/)[1]
version.gsub!(/\A\[|\]\z/, '')
@@ -38,11 +38,11 @@ conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])
FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true)
-hdr = IO.binread("#{srcdir}/include/ffi.h.in")
+hdr = File.binread("#{srcdir}/include/ffi.h.in")
hdr.gsub!(/@(\w+)@/) {conf[$1] || $&}
hdr.gsub!(/^(#if\s+)@\w+@/, '\10')
-IO.binwrite("#{builddir}/include/ffi.h", hdr)
+File.binwrite("#{builddir}/include/ffi.h", hdr)
-mk = IO.binread("#{basedir}/libffi.mk.tmpl")
+mk = File.binread("#{basedir}/libffi.mk.tmpl")
mk.gsub!(/@(\w+)@/) {conf[$1] || $&}
-IO.binwrite("Makefile", mk)
+File.binwrite("Makefile", mk)