static VALUE id2ref(VALUE obj, SEL sel, VALUE objid) { #if SIZEOF_LONG == SIZEOF_VOIDP #define NUM2PTR(x) NUM2ULONG(x) #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP #define NUM2PTR(x) NUM2ULL(x) #endif VALUE ptr; void *p0; rb_secure(4); ptr = NUM2PTR(objid); p0 = (void *)ptr; if (ptr == Qtrue) return Qtrue; if (ptr == Qfalse) return Qfalse; if (ptr == Qnil) return Qnil; if (FIXNUM_P(ptr) || SYMBOL_P(ptr)) return ptr; if (auto_zone_is_valid_pointer(__auto_zone, p0)) { auto_memory_type_t type = auto_zone_get_layout_type(__auto_zone, p0); if ((type == AUTO_OBJECT_SCANNED || type == AUTO_OBJECT_UNSCANNED) && (NATIVE((VALUE)p0) || (BUILTIN_TYPE(p0) < T_FIXNUM && BUILTIN_TYPE(p0) != T_ICLASS))) return (VALUE)p0; } rb_raise(rb_eRangeError, "%p is not id value", p0); }
/* * call-seq: Fiddle.free(addr) * * Free the memory at address +addr+ */ VALUE rb_fiddle_free(VALUE self, VALUE addr) { void *ptr = NUM2PTR(addr); ruby_xfree(ptr); return Qnil; }
/* * call-seq: Fiddle.realloc(addr, size) * * Change the size of the memory allocated at the memory location +addr+ to * +size+ bytes. Returns the memory address of the reallocated memory, which * may be different than the address passed in. */ static VALUE rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size) { void *ptr = NUM2PTR(addr); ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size)); return PTR2NUM(ptr); }
/* * call-seq: DL.realloc(addr, size) * * Change the size of the memory allocated at the memory location +addr+ to * +size+ bytes. Returns the memory address of the reallocated memory, which * may be different than the address passed in. */ VALUE rb_dl_realloc(VALUE self, VALUE addr, VALUE size) { void *ptr = NUM2PTR(addr); rb_secure(4); ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size)); return PTR2NUM(ptr); }
static VALUE initialize(int argc, VALUE argv[], VALUE self) { ffi_cif * cif; ffi_type **arg_types, *rtype; ffi_status result; VALUE ptr, args, ret_type, abi, kwds, ary; int i, len; int nabi; void *cfunc; rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds); ptr = rb_Integer(ptr); cfunc = NUM2PTR(ptr); PTR2NUM(cfunc); nabi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi); abi = INT2FIX(nabi); i = NUM2INT(ret_type); rtype = INT2FFI_TYPE(i); ret_type = INT2FIX(i); Check_Type(args, T_ARRAY); len = RARRAY_LENINT(args); Check_Max_Args("args", len); ary = rb_ary_subseq(args, 0, len); for (i = 0; i < RARRAY_LEN(args); i++) { VALUE a = RARRAY_PTR(args)[i]; int type = NUM2INT(a); (void)INT2FFI_TYPE(type); /* raise */ if (INT2FIX(type) != a) rb_ary_store(ary, i, INT2FIX(type)); } OBJ_FREEZE(ary); rb_iv_set(self, "@ptr", ptr); rb_iv_set(self, "@args", args); rb_iv_set(self, "@return_type", ret_type); rb_iv_set(self, "@abi", abi); if (!NIL_P(kwds)) rb_hash_foreach(kwds, parse_keyword_arg_i, self); TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif); arg_types = xcalloc(len + 1, sizeof(ffi_type *)); for (i = 0; i < RARRAY_LEN(args); i++) { int type = NUM2INT(RARRAY_AREF(args, i)); arg_types[i] = INT2FFI_TYPE(type); } arg_types[len] = NULL; result = ffi_prep_cif(cif, nabi, len, rtype, arg_types); if (result) rb_raise(rb_eRuntimeError, "error creating CIF %d", result); return self; }
/* * call-seq: DL.free(addr) * * Free the memory at address +addr+ */ VALUE rb_dl_free(VALUE self, VALUE addr) { void *ptr = NUM2PTR(addr); rb_secure(4); ruby_xfree(ptr); return Qnil; }
static inline freefunc_t get_freefunc(VALUE func) { if (NIL_P(func)) { return NULL; } if (rb_dlcfunc_kind_p(func)) { return (freefunc_t)(VALUE)RCFUNC_DATA(func)->ptr; } return (freefunc_t)(VALUE)NUM2PTR(rb_Integer(func)); }
static VALUE function_call(int argc, VALUE argv[], VALUE self) { ffi_cif * cif; fiddle_generic retval; fiddle_generic *generic_args; void **values; VALUE cfunc, types, cPointer; int i; cfunc = rb_iv_get(self, "@ptr"); types = rb_iv_get(self, "@args"); cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); if(argc != RARRAY_LENINT(types)) { rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, RARRAY_LENINT(types)); } TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif); values = xcalloc((size_t)argc + 1, (size_t)sizeof(void *)); generic_args = xcalloc((size_t)argc, (size_t)sizeof(fiddle_generic)); for (i = 0; i < argc; i++) { VALUE type = RARRAY_PTR(types)[i]; VALUE src = argv[i]; if(NUM2INT(type) == TYPE_VOIDP) { if(NIL_P(src)) { src = INT2NUM(0); } else if(cPointer != CLASS_OF(src)) { src = rb_funcall(cPointer, rb_intern("[]"), 1, src); } src = rb_Integer(src); } VALUE2GENERIC(NUM2INT(type), src, &generic_args[i]); values[i] = (void *)&generic_args[i]; } values[argc] = NULL; ffi_call(cif, NUM2PTR(rb_Integer(cfunc)), &retval, values); rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno)); #if defined(HAVE_WINDOWS_H) rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno)); #endif xfree(values); xfree(generic_args); return GENERIC2VALUE(rb_iv_get(self, "@return_type"), retval); }
static VALUE cr_win32_printing_surface_initialize (VALUE self, VALUE hdc) { cairo_surface_t *surface = NULL; surface = cairo_win32_printing_surface_create (NUM2PTR (hdc)); cr_surface_check_status (surface); DATA_PTR (self) = surface; if (rb_block_given_p ()) yield_and_finish (self); return Qnil; }
static inline freefunc_t get_freefunc(VALUE func, volatile VALUE *wrap) { VALUE addrnum; if (NIL_P(func)) { *wrap = 0; return NULL; } addrnum = rb_Integer(func); *wrap = (addrnum != func) ? func : 0; return (freefunc_t)(VALUE)NUM2PTR(addrnum); }
void value_to_generic(int type, VALUE src, fiddle_generic * dst) { switch (type) { case TYPE_VOID: break; case TYPE_VOIDP: dst->pointer = NUM2PTR(rb_Integer(src)); break; case TYPE_CHAR: dst->schar = (signed char)NUM2INT(src); break; case -TYPE_CHAR: dst->uchar = (unsigned char)NUM2UINT(src); break; case TYPE_SHORT: dst->sshort = (unsigned short)NUM2INT(src); break; case -TYPE_SHORT: dst->sshort = (signed short)NUM2UINT(src); break; case TYPE_INT: dst->sint = NUM2INT(src); break; case -TYPE_INT: dst->uint = NUM2UINT(src); break; case TYPE_LONG: dst->slong = NUM2LONG(src); break; case -TYPE_LONG: dst->ulong = NUM2ULONG(src); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: dst->slong_long = NUM2LL(src); break; case -TYPE_LONG_LONG: dst->ulong_long = NUM2ULL(src); break; #endif case TYPE_FLOAT: dst->ffloat = (float)NUM2DBL(src); break; case TYPE_DOUBLE: dst->ddouble = NUM2DBL(src); break; default: rb_raise(rb_eRuntimeError, "unknown type %d", type); } }
static inline freefunc_t get_freefunc(VALUE func, volatile VALUE *wrap) { VALUE addrnum; if (NIL_P(func)) { *wrap = 0; return NULL; } if (rb_dlcfunc_kind_p(func)) { *wrap = func; return (freefunc_t)(VALUE)RCFUNC_DATA(func)->ptr; } addrnum = rb_Integer(func); *wrap = (addrnum != func) ? func : 0; return (freefunc_t)(VALUE)NUM2PTR(addrnum); }
static VALUE rb_struct_read(VALUE self, VALUE protocol) { DEBUG_FUNCTION_ENTRY(); protocol_method_table *pmt; //We haven't been supplied with a method table, try retrieving it... int has_gmt = rb_respond_to(protocol, rb_intern("get_protocol_method_table")); if (has_gmt) pmt = NUM2PTR(rb_funcall(protocol, get_protocol_method_table_ID, 0)); else pmt = &default_table; VALUE ret = struct_read(self, protocol, pmt); DEBUG_FUNCTION_EXIT(); return ret; }
void value_to_generic(int type, VALUE src, fiddle_generic * dst) { int signed_p = 1; if (type < 0) { type = -1 * type; signed_p = 0; } switch (type) { case TYPE_VOID: break; case TYPE_VOIDP: dst->pointer = NUM2PTR(rb_Integer(src)); break; case TYPE_CHAR: dst->schar = NUM2INT(src); break; case TYPE_SHORT: dst->sshort = NUM2INT(src); break; case TYPE_INT: dst->sint = NUM2INT(src); break; case TYPE_LONG: if (signed_p) dst->slong = NUM2LONG(src); else dst->ulong = NUM2LONG(src); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: dst->long_long = rb_big2ull(src); break; #endif case TYPE_FLOAT: dst->ffloat = (float)NUM2DBL(src); break; case TYPE_DOUBLE: dst->ddouble = NUM2DBL(src); break; default: rb_raise(rb_eRuntimeError, "unknown type %d", type); } }
static VALUE cr_s_wrap (VALUE self, VALUE pointer) { VALUE result; VALUE rb_cr; cairo_t *cr; if (NIL_P (rb_cairo__cFFIPointer)) { rb_raise (rb_eNotImpError, "%s: FFI::Pointer is required", rb_id2name (rb_frame_this_func ())); } if (!RTEST (rb_obj_is_kind_of (pointer, rb_cairo__cFFIPointer))) { rb_raise (rb_eArgError, "must be FFI::Pointer: %s", rb_cairo__inspect (pointer)); } { VALUE rb_cr_address; rb_cr_address = rb_funcall (pointer, rb_intern ("address"), 0); cr = NUM2PTR (rb_cr_address); cr_check_status (cr); } rb_cr = rb_obj_alloc (self); cairo_reference (cr); DATA_PTR (rb_cr) = cr; rb_ivar_set (rb_cr, cr_id_surface, Qnil); if (rb_block_given_p ()) { result = rb_ensure (rb_yield, rb_cr, cr_destroy_with_destroy_check, rb_cr); } else { result = rb_cr; } return result; }
void PLCB__viewhandle_stop(SV *pp) { AV *req = (AV *)SvRV(pp); PLCB_t *parent = parent_from_req(req); SV **tmp, *vhsv; tmp = av_fetch(req, PLCB_VHIDX_VHANDLE, 0); if (!tmp) { return; } vhsv = *tmp; if (SvIOK(vhsv)) { lcb_VIEWHANDLE vh = NUM2PTR(lcb_VIEWHANDLE, SvUV(vhsv)); lcb_view_cancel(parent->instance, vh); av_store(req, PLCB_VHIDX_VHANDLE, SvREFCNT_inc(&PL_sv_undef)); av_store(req, PLCB_VHIDX_ISDONE, SvREFCNT_inc(&PL_sv_yes)); SvREFCNT_dec((SV *)req); } }
void callback(ffi_cif *cif, void *resp, void **args, void *ctx) { VALUE self = (VALUE)ctx; VALUE rbargs = rb_iv_get(self, "@args"); VALUE ctype = rb_iv_get(self, "@ctype"); int argc = RARRAY_LENINT(rbargs); VALUE params = rb_ary_tmp_new(argc); VALUE ret; VALUE cPointer; int i, type; cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); for (i = 0; i < argc; i++) { type = NUM2INT(RARRAY_PTR(rbargs)[i]); switch (type) { case TYPE_VOID: argc = 0; break; case TYPE_INT: rb_ary_push(params, INT2NUM(*(int *)args[i])); break; case -TYPE_INT: rb_ary_push(params, UINT2NUM(*(unsigned int *)args[i])); break; case TYPE_VOIDP: rb_ary_push(params, rb_funcall(cPointer, rb_intern("[]"), 1, PTR2NUM(*(void **)args[i]))); break; case TYPE_LONG: rb_ary_push(params, LONG2NUM(*(long *)args[i])); break; case -TYPE_LONG: rb_ary_push(params, ULONG2NUM(*(unsigned long *)args[i])); break; case TYPE_CHAR: rb_ary_push(params, INT2NUM(*(signed char *)args[i])); break; case -TYPE_CHAR: rb_ary_push(params, UINT2NUM(*(unsigned char *)args[i])); break; case TYPE_SHORT: rb_ary_push(params, INT2NUM(*(signed short *)args[i])); break; case -TYPE_SHORT: rb_ary_push(params, UINT2NUM(*(unsigned short *)args[i])); break; case TYPE_DOUBLE: rb_ary_push(params, rb_float_new(*(double *)args[i])); break; case TYPE_FLOAT: rb_ary_push(params, rb_float_new(*(float *)args[i])); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: rb_ary_push(params, LL2NUM(*(LONG_LONG *)args[i])); break; case -TYPE_LONG_LONG: rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)args[i])); break; #endif default: rb_raise(rb_eRuntimeError, "closure args: %d", type); } } ret = rb_funcall2(self, rb_intern("call"), argc, RARRAY_PTR(params)); RB_GC_GUARD(params); type = NUM2INT(ctype); switch (type) { case TYPE_VOID: break; case TYPE_LONG: *(long *)resp = NUM2LONG(ret); break; case -TYPE_LONG: *(unsigned long *)resp = NUM2ULONG(ret); break; case TYPE_CHAR: case TYPE_SHORT: case TYPE_INT: *(ffi_sarg *)resp = NUM2INT(ret); break; case -TYPE_CHAR: case -TYPE_SHORT: case -TYPE_INT: *(ffi_arg *)resp = NUM2UINT(ret); break; case TYPE_VOIDP: *(void **)resp = NUM2PTR(ret); break; case TYPE_DOUBLE: *(double *)resp = NUM2DBL(ret); break; case TYPE_FLOAT: *(float *)resp = (float)NUM2DBL(ret); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: *(LONG_LONG *)resp = NUM2LL(ret); break; case -TYPE_LONG_LONG: *(unsigned LONG_LONG *)resp = NUM2ULL(ret); break; #endif default: rb_raise(rb_eRuntimeError, "closure retval: %d", type); } }
void callback(ffi_cif *cif, void *resp, void **args, void *ctx) { VALUE self = (VALUE)ctx; VALUE rbargs = rb_iv_get(self, "@args"); VALUE ctype = rb_iv_get(self, "@ctype"); int argc = RARRAY_LENINT(rbargs); VALUE *params = xcalloc(argc, sizeof(VALUE *)); VALUE ret; VALUE cPointer; int i, type; cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); for (i = 0; i < argc; i++) { type = NUM2INT(RARRAY_PTR(rbargs)[i]); switch (type) { case TYPE_VOID: argc = 0; break; case TYPE_INT: params[i] = INT2NUM(*(int *)args[i]); break; case TYPE_VOIDP: params[i] = rb_funcall(cPointer, rb_intern("[]"), 1, PTR2NUM(*(void **)args[i])); break; case TYPE_LONG: params[i] = LONG2NUM(*(long *)args[i]); break; case TYPE_CHAR: params[i] = INT2NUM(*(char *)args[i]); break; case TYPE_DOUBLE: params[i] = rb_float_new(*(double *)args[i]); break; case TYPE_FLOAT: params[i] = rb_float_new(*(float *)args[i]); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: params[i] = rb_ull2inum(*(unsigned LONG_LONG *)args[i]); break; #endif default: rb_raise(rb_eRuntimeError, "closure args: %d", type); } } ret = rb_funcall2(self, rb_intern("call"), argc, params); type = NUM2INT(ctype); switch (type) { case TYPE_VOID: break; case TYPE_LONG: *(long *)resp = NUM2LONG(ret); break; case TYPE_CHAR: *(char *)resp = NUM2INT(ret); break; case TYPE_VOIDP: *(void **)resp = NUM2PTR(ret); break; case TYPE_INT: *(int *)resp = NUM2INT(ret); break; case TYPE_DOUBLE: *(double *)resp = NUM2DBL(ret); break; case TYPE_FLOAT: *(float *)resp = (float)NUM2DBL(ret); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: *(unsigned LONG_LONG *)resp = rb_big2ull(ret); break; #endif default: rb_raise(rb_eRuntimeError, "closure retval: %d", type); } xfree(params); }
VALUE rb_dl_ptr2value(VALUE self, VALUE addr) { rb_secure(4); return (VALUE)NUM2PTR(addr); }
/* * call-seq: Fiddle.dlunwrap(addr) * * Returns the hexadecimal representation of a memory pointer 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" */ VALUE rb_fiddle_ptr2value(VALUE self, VALUE addr) { return (VALUE)NUM2PTR(addr); }
static VALUE cr_win32_surface_initialize (int argc, VALUE *argv, VALUE self) { cairo_surface_t *surface = NULL; VALUE arg1, arg2, arg3, arg4; VALUE hdc, format, width, height; rb_scan_args (argc, argv, "13", &arg1, &arg2, &arg3, &arg4); switch (argc) { case 1: hdc = arg1; surface = cairo_win32_surface_create (NUM2PTR (hdc)); break; case 2: width = arg1; height = arg2; surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, NUM2INT (width), NUM2INT (height)); break; case 3: if (NIL_P (arg1) || (rb_cairo__is_kind_of (arg1, rb_cNumeric) && NUM2INT (arg1) != CAIRO_FORMAT_RGB24)) { # if CAIRO_CHECK_VERSION(1, 4, 0) HDC win32_hdc; hdc = arg1; width = arg2; height = arg3; win32_hdc = NIL_P (hdc) ? NULL : NUM2PTR (hdc); surface = cairo_win32_surface_create_with_ddb (win32_hdc, CAIRO_FORMAT_RGB24, NUM2INT (width), NUM2INT (height)); # else rb_raise (rb_eArgError, "Cairo::Win32Surface.new(hdc, width, height) " "is available since cairo >= 1.4.0"); # endif } else { format = arg1; width = arg2; height = arg3; surface = cairo_win32_surface_create_with_dib (RVAL2CRFORMAT (format), NUM2INT (width), NUM2INT (height)); } break; case 4: { # if CAIRO_CHECK_VERSION(1, 4, 0) HDC win32_hdc; hdc = arg1; format = arg2; width = arg3; height = arg4; win32_hdc = NIL_P (hdc) ? NULL : (HDC) NUM2UINT (hdc); surface = cairo_win32_surface_create_with_ddb (win32_hdc, RVAL2CRFORMAT (format), NUM2INT (width), NUM2INT (height)); # else rb_raise (rb_eArgError, "Cairo::Win32Surface.new(hdc, format, width, height) " "is available since cairo >= 1.4.0"); # endif } break; } if (!surface) rb_cairo_check_status (CAIRO_STATUS_INVALID_FORMAT); cr_surface_check_status (surface); DATA_PTR (self) = surface; if (rb_block_given_p ()) yield_and_finish (self); return Qnil; }
static VALUE function_call(int argc, VALUE argv[], VALUE self) { struct nogvl_ffi_call_args args = { 0 }; fiddle_generic *generic_args; VALUE cfunc, types, cPointer; int i; VALUE alloc_buffer = 0; cfunc = rb_iv_get(self, "@ptr"); types = rb_iv_get(self, "@args"); cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); Check_Max_Args("number of arguments", argc); if (argc != (i = RARRAY_LENINT(types))) { rb_error_arity(argc, i, i); } TypedData_Get_Struct(self, ffi_cif, &function_data_type, args.cif); if (rb_safe_level() >= 1) { for (i = 0; i < argc; i++) { VALUE src = argv[i]; if (OBJ_TAINTED(src)) { rb_raise(rb_eSecurityError, "tainted parameter not allowed"); } } } generic_args = ALLOCV(alloc_buffer, (size_t)(argc + 1) * sizeof(void *) + (size_t)argc * sizeof(fiddle_generic)); args.values = (void **)((char *)generic_args + (size_t)argc * sizeof(fiddle_generic)); for (i = 0; i < argc; i++) { VALUE type = RARRAY_AREF(types, i); VALUE src = argv[i]; int argtype = FIX2INT(type); if (argtype == TYPE_VOIDP) { if(NIL_P(src)) { src = INT2FIX(0); } else if(cPointer != CLASS_OF(src)) { src = rb_funcall(cPointer, rb_intern("[]"), 1, src); } src = rb_Integer(src); } VALUE2GENERIC(argtype, src, &generic_args[i]); args.values[i] = (void *)&generic_args[i]; } args.values[argc] = NULL; args.fn = NUM2PTR(cfunc); (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0); rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno)); #if defined(_WIN32) rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno)); #endif ALLOCV_END(alloc_buffer); return GENERIC2VALUE(rb_iv_get(self, "@return_type"), args.retval); }