Ruby
3.1.0dev(2021-09-10revisionb76ad15ed0da636161de0243c547ee1e6fc95681)
|
Go to the documentation of this file.
7 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
8 # define RB_OBJ_STRING(obj) (obj)
10 # define PRIsVALUE "s"
11 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
12 # define RB_OBJ_STRING(obj) StringValueCStr(obj)
17 #define MAX_ARGS (SIZE_MAX / (sizeof(void *) + sizeof(fiddle_generic)) - 1)
19 #define Check_Max_Args(name, len) \
20 Check_Max_Args_(name, len, "")
21 #define Check_Max_Args_Long(name, len) \
22 Check_Max_Args_(name, len, "l")
23 #define Check_Max_Args_(name, len, fmt) \
25 if ((size_t)(len) >= MAX_ARGS) { \
26 rb_raise(rb_eTypeError, \
28 "that it can cause integer overflow (%"fmt"d)", \
42 function_memsize(
const void *p)
44 ffi_cif *
ptr = (ffi_cif *)p;
48 #if !defined(FFI_NO_RAW_API) || !FFI_NO_RAW_API
57 {0, deallocate, function_memsize,},
81 normalize_argument_types(
const char *
name,
85 VALUE normalized_arg_types;
91 n_arg_types = RARRAY_LENINT(arg_types);
95 for (i = 0; i < n_arg_types; i++) {
101 if (i != n_arg_types - 1) {
103 "Fiddle::TYPE_VARIADIC must be the last argument type: "
118 return normalized_arg_types;
125 VALUE ptr, arg_types, ret_type, abi, kwargs;
129 bool is_variadic =
false;
136 if (!
NIL_P(kwargs)) {
142 static ID kw[kw_max_];
145 kw[kw_name] = rb_intern_const(
"name");
146 kw[kw_need_gvl] = rb_intern_const(
"need_gvl");
153 need_gvl =
args[kw_need_gvl];
162 c_ffi_abi =
NIL_P(abi) ? FFI_DEFAULT_ABI :
NUM2INT(abi);
165 c_ret_type =
NUM2INT(ret_type);
167 ret_type =
INT2FIX(c_ret_type);
169 arg_types = normalize_argument_types(
"argument types",
172 #ifndef HAVE_FFI_PREP_CIF_VAR
175 "ffi_prep_cif_var() is required in libffi "
176 "for variadic arguments");
181 rb_iv_set(
self,
"@argument_types", arg_types);
182 rb_iv_set(
self,
"@return_type", ret_type);
200 nogvl_ffi_call(
void *
ptr)
221 int n_fixed_args = 0;
226 VALUE alloc_buffer = 0;
230 arg_types =
rb_iv_get(
self,
"@argument_types");
232 is_variadic =
rb_iv_get(
self,
"@is_variadic");
235 n_arg_types = RARRAY_LENINT(arg_types);
236 n_fixed_args = n_arg_types;
237 if (
RTEST(is_variadic)) {
238 if (
argc < n_arg_types) {
241 if (((
argc - n_arg_types) % 2) != 0) {
243 "variadic arguments must be type and value pairs: "
247 n_call_args = n_arg_types + ((
argc - n_arg_types) / 2);
250 if (
argc != n_arg_types) {
253 n_call_args = n_arg_types;
259 if (is_variadic && args.
cif->arg_types) {
264 if (!args.
cif->arg_types) {
265 VALUE fixed_arg_types = arg_types;
268 ffi_type *ffi_return_type;
269 ffi_type **ffi_arg_types;
273 for (i = n_fixed_args; i <
argc; i += 2) {
277 c_arg_type =
NUM2INT(arg_type);
282 return_type =
rb_iv_get(
self,
"@return_type");
283 c_return_type =
FIX2INT(return_type);
286 ffi_arg_types =
xcalloc(n_call_args + 1,
sizeof(ffi_type *));
287 for (i_call = 0; i_call < n_call_args; i_call++) {
291 c_arg_type =
FIX2INT(arg_type);
294 ffi_arg_types[i_call] =
NULL;
297 #ifdef HAVE_FFI_PREP_CIF_VAR
298 result = ffi_prep_cif_var(args.
cif,
307 result = FFI_BAD_TYPEDEF;
311 result = ffi_prep_cif(args.
cif,
317 if (result != FFI_OK) {
318 xfree(ffi_arg_types);
324 generic_args =
ALLOCV(alloc_buffer,
326 sizeof(
void *) * (n_call_args + 1));
327 args.
values = (
void **)((
char *)generic_args +
330 for (i = 0, i_call = 0;
331 i <
argc && i_call < n_call_args;
338 c_arg_type =
FIX2INT(arg_type);
339 if (i >= n_fixed_args) {
348 else if (cPointer !=
CLASS_OF(src)) {
350 if (
NIL_P(converted_args)) {
360 if (src != original_src) {
361 if (
NIL_P(converted_args)) {
366 args.
values[i_call] = (
void *)&generic_args[i_call];
371 if (
RTEST(need_gvl)) {
379 int errno_keep = errno;
381 DWORD error = WSAGetLastError();
382 int socket_error = WSAGetLastError();
443 #ifdef HAVE_CONST_FFI_STDCALL
VALUE rb_const_get(VALUE, ID)
VALUE rb_ary_new_capa(long capa)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
#define GENERIC2VALUE(_type, _retval)
#define VALUE2GENERIC(_type, _src, _dst)
ID rb_intern(const char *)
VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type)
#define UNLIMITED_ARGUMENTS
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_iv_get(VALUE, const char *)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_iv_set(VALUE, const char *, VALUE)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_cObject
Object class.
VALUE rb_ary_push(VALUE ary, VALUE item)
#define INT2FFI_TYPE(_type)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void Init_fiddle_function(void)
void rb_define_const(VALUE, const char *, VALUE)
#define TypedData_Get_Struct(obj, type, data_type, sval)
#define RARRAY_AREF(a, i)
#define Check_Max_Args(name, len)
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
VALUE rb_ary_dup(VALUE ary)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_fiddle_type_ensure(VALUE type)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
void rb_error_arity(int argc, int min, int max)
const rb_data_type_t function_data_type