static VALUE rb_dl_get_last_error(VALUE self) { return rb_thread_local_aref(rb_thread_current(), id_last_error); }
VALUE rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self) { VALUE addr, name, type, calltype; struct cfunc_data *data; void *saddr; const char *sname; rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype); saddr = (void*)(NUM2PTR(rb_Integer(addr))); sname = NIL_P(name) ? NULL : StringValuePtr(name); Data_Get_Struct(self, struct cfunc_data, data); if( data->name ) xfree(data->name); data->ptr = saddr; data->name = sname ? strdup(sname) : 0; data->type = (type == Qnil) ? DLTYPE_VOID : NUM2INT(type); data->calltype = (calltype == Qnil) ? CFUNC_CDECL : SYM2ID(calltype); return Qnil; }
VALUE rb_dlcfunc_call(VALUE self, VALUE ary) { struct cfunc_data *cfunc; int i; DLSTACK_TYPE stack[DLSTACK_SIZE]; VALUE result = Qnil; rb_secure_update(self); memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE); Check_Type(ary, T_ARRAY); Data_Get_Struct(self, struct cfunc_data, cfunc); if( cfunc->ptr == 0 ){ rb_raise(rb_eDLError, "can't call null-function"); return Qnil; } for( i = 0; i < RARRAY_LEN(ary); i++ ){ if( i >= DLSTACK_SIZE ){ rb_raise(rb_eDLError, "too many arguments (stack overflow)"); } rb_check_safe_obj(RARRAY_PTR(ary)[i]); stack[i] = NUM2LONG(RARRAY_PTR(ary)[i]); } /* calltype == CFUNC_CDECL */ if( cfunc->calltype == CFUNC_CDECL #ifndef FUNC_STDCALL || cfunc->calltype == CFUNC_STDCALL #endif ){ switch( cfunc->type ){ case DLTYPE_VOID: #define CASE(n) case n: { \ DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \ f(DLSTACK_ARGS##n(stack)); \ result = Qnil; \ }
VALUE rb_dlcfunc_call(VALUE self, VALUE ary) { struct cfunc_data *cfunc; int i; DLSTACK_TYPE stack[DLSTACK_SIZE]; VALUE result = Qnil; rb_secure_update(self); memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE); Check_Type(ary, T_ARRAY); Data_Get_Struct(self, struct cfunc_data, cfunc); if( cfunc->ptr == 0 ){ rb_raise(rb_eDLError, "can't call null-function"); return Qnil; } for( i = 0; i < RARRAY_LEN(ary); i++ ){ if( i >= DLSTACK_SIZE ){ rb_raise(rb_eDLError, "too many arguments (stack overflow)"); } rb_check_safe_obj(RARRAY_PTR(ary)[i]); stack[i] = NUM2LONG(RARRAY_PTR(ary)[i]); } /* calltype == CFUNC_CDECL */ if( cfunc->calltype == CFUNC_CDECL #ifndef FUNC_STDCALL || cfunc->calltype == CFUNC_STDCALL #endif ){ switch( cfunc->type ){ case DLTYPE_VOID: #define CASE(n) case n: { \ DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \ f(DLSTACK_ARGS##n(stack)); \ result = Qnil; \ }
VALUE rb_dlcfunc_calltype(VALUE self) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); return ID2SYM(cfunc->calltype); }
VALUE rb_dlcfunc_set_calltype(VALUE self, VALUE sym) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); cfunc->calltype = SYM2ID(sym); return sym; }
VALUE rb_dlcfunc_ctype(VALUE self) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); return INT2NUM(cfunc->type); }
VALUE rb_dlcfunc_set_ctype(VALUE self, VALUE ctype) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); cfunc->type = NUM2INT(ctype); return ctype; }
VALUE rb_dlcfunc_inspect(VALUE self) { VALUE val; char *str; int str_size; struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); str_size = (cfunc->name ? strlen(cfunc->name) : 0) + 100; str = ruby_xmalloc(str_size); snprintf(str, str_size - 1, "#<DL::CFunc:%p ptr=%p type=%d name='%s'>", cfunc, cfunc->ptr, cfunc->type, cfunc->name ? cfunc->name : ""); val = rb_tainted_str_new2(str); ruby_xfree(str); return val; }
VALUE rb_dlcfunc_name(VALUE self) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); return cfunc->name ? rb_tainted_str_new2(cfunc->name) : Qnil; }
VALUE rb_dlcfunc_ptr(VALUE self) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); return PTR2NUM(cfunc->ptr); }
VALUE rb_dlcfunc_set_ptr(VALUE self, VALUE addr) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); cfunc->ptr = NUM2PTR(addr); return Qnil; }
VALUE rb_dlcfunc_to_i(VALUE self) { struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); return PTR2NUM(cfunc->ptr); }
VALUE rb_dlcfunc_inspect(VALUE self) { VALUE val; char *str; int str_size; struct cfunc_data *cfunc; Data_Get_Struct(self, struct cfunc_data, cfunc); str_size = (cfunc->name ? strlen(cfunc->name) : 0) + 100; str = ruby_xmalloc(str_size); snprintf(str, str_size - 1, "#<DL::CFunc:%p ptr=%p type=%d name='%s'>", cfunc, cfunc->ptr, cfunc->type, cfunc->name ? cfunc->name : ""); val = rb_tainted_str_new2(str); ruby_xfree(str); return val; }