summaryrefslogtreecommitdiff
path: root/ext/fiddle
diff options
context:
space:
mode:
authorSutou Kouhei <kou@clear-code.com>2023-10-28 06:11:30 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2023-11-08 09:25:44 +0900
commit2a6d6d3d65de43635a5f6ad38dbca170f1e40119 (patch)
tree097aff88d59c4e7329138d98408ff706846f28fe /ext/fiddle
parentd30ea5831e0aedada3362a2d268e7bc836b93f27 (diff)
[ruby/fiddle] Use Ruby's true/false for C bool
GitHub: fix https://github.com/ruby/fiddle/pull/130 Reported by Benoit Daloze. Thanks!!! https://github.com/ruby/fiddle/commit/2640e0148e
Diffstat (limited to 'ext/fiddle')
-rw-r--r--ext/fiddle/closure.c21
-rw-r--r--ext/fiddle/conversions.c64
-rw-r--r--ext/fiddle/conversions.h3
-rw-r--r--ext/fiddle/fiddle.c8
-rw-r--r--ext/fiddle/fiddle.h1
-rw-r--r--ext/fiddle/lib/fiddle/import.rb2
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb12
7 files changed, 89 insertions, 22 deletions
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 3772dfda35..f39ff35f09 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -139,6 +139,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);
}
@@ -188,6 +202,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 66058d5d12..8c223ea959 100644
--- a/ext/fiddle/conversions.c
+++ b/ext/fiddle/conversions.c
@@ -3,25 +3,6 @@
#include <fiddle.h>
VALUE
-rb_fiddle_type_bool(void)
-{
- if (sizeof(bool) == sizeof(char)) {
- return INT2NUM(TYPE_UCHAR);
- } else if (sizeof(bool) == sizeof(short)) {
- return INT2NUM(TYPE_USHORT);
- } else if (sizeof(bool) == sizeof(int)) {
- return INT2NUM(TYPE_UINT);
- } else if (sizeof(bool) == sizeof(long)) {
- return INT2NUM(TYPE_ULONG);
- } else {
- rb_raise(rb_eNotImpError,
- "bool isn't supported: %u",
- (unsigned int)sizeof(bool));
- return RUBY_Qnil;
- }
-}
-
-VALUE
rb_fiddle_type_ensure(VALUE type)
{
VALUE original_type = type;
@@ -168,7 +149,7 @@ rb_fiddle_type_ensure(VALUE type)
return INT2NUM(TYPE_UINTPTR_T);
}
else if (type_id == bool_id) {
- return rb_fiddle_type_bool();
+ return INT2NUM(TYPE_BOOL);
}
else {
type = original_type;
@@ -213,6 +194,21 @@ 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);
+ return INT2NUM(TYPE_USHORT);
+ } 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);
}
@@ -284,8 +280,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;
}
}
@@ -344,6 +355,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 5ea569e3ff..7a1e928d56 100644
--- a/ext/fiddle/conversions.h
+++ b/ext/fiddle/conversions.h
@@ -24,7 +24,6 @@ typedef union
void * pointer; /* ffi_type_pointer */
} fiddle_generic;
-VALUE rb_fiddle_type_bool(void);
VALUE rb_fiddle_type_ensure(VALUE type);
ffi_type * rb_fiddle_int_to_ffi_type(int type);
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
@@ -51,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/fiddle.c b/ext/fiddle/fiddle.c
index 49120704ab..f420d9fa3b 100644
--- a/ext/fiddle/fiddle.c
+++ b/ext/fiddle/fiddle.c
@@ -363,7 +363,7 @@ Init_fiddle(void)
*
* C type - bool
*/
- rb_define_const(mFiddleTypes, "BOOL" , rb_fiddle_type_bool());
+ rb_define_const(mFiddleTypes, "BOOL" , INT2NUM(TYPE_BOOL));
/* Document-const: ALIGN_VOIDP
*
@@ -469,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
diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h
index 53db058807..348baa9ab9 100644
--- a/ext/fiddle/fiddle.h
+++ b/ext/fiddle/fiddle.h
@@ -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
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