summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2021-11-11 18:06:33 +0900
committernagachika <nagachika@ruby-lang.org>2021-11-22 10:51:35 +0900
commit4716a8e157044b3a3a490c96957eb6c9204d70f1 (patch)
treea3c29a11af91d07f9f98102e4591e450051395bc /ext
parentb789399c099b51cd60a07fe686145c451d0a5d4e (diff)
Bump fiddle version to 1.0.8
Diffstat (limited to 'ext')
-rw-r--r--ext/fiddle/closure.c26
-rw-r--r--ext/fiddle/conversions.h1
-rw-r--r--ext/fiddle/extconf.rb43
-rw-r--r--ext/fiddle/function.c11
-rw-r--r--ext/fiddle/lib/fiddle.rb12
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb6
-rw-r--r--ext/fiddle/lib/fiddle/version.rb2
7 files changed, 89 insertions, 12 deletions
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 40cee55e9a..3679e5c9ad 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -130,6 +130,10 @@ with_gvl_callback(void *ptr)
rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i]));
break;
#endif
+ case TYPE_CONST_STRING:
+ rb_ary_push(params,
+ rb_str_new_cstr(*((const char **)(x->args[i]))));
+ break;
default:
rb_raise(rb_eRuntimeError, "closure args: %d", type);
}
@@ -175,6 +179,10 @@ with_gvl_callback(void *ptr)
*(unsigned LONG_LONG *)x->resp = NUM2ULL(ret);
break;
#endif
+ case TYPE_CONST_STRING:
+ /* Dangerous. Callback must keep reference of the String. */
+ *((const char **)(x->resp)) = StringValueCStr(ret);
+ break;
default:
rb_raise(rb_eRuntimeError, "closure retval: %d", type);
}
@@ -221,6 +229,7 @@ initialize(int rbargc, VALUE argv[], VALUE self)
{
VALUE ret;
VALUE args;
+ VALUE normalized_args;
VALUE abi;
fiddle_closure * cl;
ffi_cif * cif;
@@ -239,21 +248,26 @@ initialize(int rbargc, VALUE argv[], VALUE self)
cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
+ normalized_args = rb_ary_new_capa(argc);
for (i = 0; i < argc; i++) {
- int type = NUM2INT(RARRAY_AREF(args, i));
- cl->argv[i] = INT2FFI_TYPE(type);
+ VALUE arg = rb_fiddle_type_ensure(RARRAY_AREF(args, i));
+ rb_ary_push(normalized_args, arg);
+ cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg));
}
cl->argv[argc] = NULL;
+ ret = rb_fiddle_type_ensure(ret);
rb_iv_set(self, "@ctype", ret);
- rb_iv_set(self, "@args", args);
+ rb_iv_set(self, "@args", normalized_args);
cif = &cl->cif;
pcl = cl->pcl;
- result = ffi_prep_cif(cif, NUM2INT(abi), argc,
- INT2FFI_TYPE(NUM2INT(ret)),
- cl->argv);
+ result = ffi_prep_cif(cif,
+ NUM2INT(abi),
+ argc,
+ rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
+ cl->argv);
if (FFI_OK != result)
rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h
index 1de956e90c..c7c12a9234 100644
--- a/ext/fiddle/conversions.h
+++ b/ext/fiddle/conversions.h
@@ -24,7 +24,6 @@ typedef union
void * pointer; /* ffi_type_pointer */
} fiddle_generic;
-/* Deprecated. Use rb_fiddle_*() version. */
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);
diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb
index 6d1d5104a1..6ca685317e 100644
--- a/ext/fiddle/extconf.rb
+++ b/ext/fiddle/extconf.rb
@@ -3,6 +3,47 @@ require 'mkmf'
# :stopdoc:
+def gcc?
+ RbConfig::CONFIG["GCC"] == "yes"
+end
+
+def disable_optimization_build_flag(flags)
+ if gcc?
+ expanded_flags = RbConfig.expand(flags.dup)
+ optimization_option_pattern = /(^|\s)?-O\d(\s|$)?/
+ if optimization_option_pattern.match?(expanded_flags)
+ expanded_flags.gsub(optimization_option_pattern, '\\1-Og\\2')
+ else
+ flags + " -Og"
+ end
+ else
+ flags
+ end
+end
+
+def enable_debug_build_flag(flags)
+ if gcc?
+ expanded_flags = RbConfig.expand(flags.dup)
+ debug_option_pattern = /(^|\s)-g(?:gdb)?\d?(\s|$)/
+ if debug_option_pattern.match?(expanded_flags)
+ expanded_flags.gsub(debug_option_pattern, '\\1-ggdb3\\2')
+ else
+ flags + " -ggdb3"
+ end
+ else
+ flags
+ end
+end
+
+checking_for(checking_message("--enable-debug-build option")) do
+ enable_debug_build = enable_config("debug-build", false)
+ if enable_debug_build
+ $CFLAGS = disable_optimization_build_flag($CFLAGS)
+ $CFLAGS = enable_debug_build_flag($CFLAGS)
+ end
+ enable_debug_build
+end
+
libffi_version = nil
have_libffi = false
bundle = enable_config('bundled-libffi')
@@ -159,6 +200,8 @@ elsif have_header "windows.h"
%w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
abort "missing function #{func}" unless have_func(func)
end
+
+ have_library "ws2_32"
end
have_const('FFI_STDCALL', ffi_header)
diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c
index 1d82bc8a3e..d15a54bfa6 100644
--- a/ext/fiddle/function.c
+++ b/ext/fiddle/function.c
@@ -375,10 +375,17 @@ function_call(int argc, VALUE argv[], VALUE self)
(void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
}
- rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno));
+ {
+ int errno_keep = errno;
#if defined(_WIN32)
- rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno));
+ int socket_error = WSAGetLastError();
+ rb_funcall(mFiddle, rb_intern("win32_last_error="), 1,
+ INT2NUM(errno_keep));
+ rb_funcall(mFiddle, rb_intern("win32_last_socket_error="), 1,
+ INT2NUM(socket_error));
#endif
+ rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno_keep));
+ }
ALLOCV_END(alloc_buffer);
diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb
index 3fdf525b4c..4512989310 100644
--- a/ext/fiddle/lib/fiddle.rb
+++ b/ext/fiddle/lib/fiddle.rb
@@ -17,6 +17,18 @@ module Fiddle
def self.win32_last_error= error
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
end
+
+ # Returns the last win32 socket +Error+ of the current executing
+ # +Thread+ or nil if none
+ def self.win32_last_socket_error
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
+ end
+
+ # Sets the last win32 socket +Error+ of the current executing
+ # +Thread+ to +error+
+ def self.win32_last_socket_error= error
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
+ end
end
# Returns the last +Error+ of the current executing +Thread+ or nil if none
diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb
index 8a269393c6..93a05513c9 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -148,9 +148,11 @@ module Fiddle
#
def parse_ctype(ty, tymap=nil)
tymap ||= {}
- case ty
- when Array
+ if ty.is_a?(Array)
return [parse_ctype(ty[0], tymap), ty[1]]
+ end
+ ty = ty.gsub(/\Aconst\s+/, "")
+ case ty
when 'void'
return TYPE_VOID
when /\A(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?\z/
diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb
index d80cb7078f..a699371ee4 100644
--- a/ext/fiddle/lib/fiddle/version.rb
+++ b/ext/fiddle/lib/fiddle/version.rb
@@ -1,3 +1,3 @@
module Fiddle
- VERSION = "1.0.6"
+ VERSION = "1.0.8"
end