// // From Guy Decoux [ruby-talk:144098] // static VALUE ts_each(VALUE *tmp) { return rb_funcall2(tmp[0], (ID)tmp[1], (int)tmp[2], (VALUE *)tmp[3]); }
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); } }
static VALUE evalHelper(evalArg *arg) { VALUE argv[] = { arg->string, Qnil, arg->filename }; return rb_funcall2(Qnil, rb_intern("eval"), ARRAY_SIZE(argv), argv); }
/* * call-seq: * Complex(x[, y]) -> numeric * * Returns x+i*y; */ static VALUE nucomp_f_complex(int argc, VALUE *argv, VALUE klass) { return rb_funcall2(rb_cComplex, id_convert, argc, argv); }
static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data) { Closure* closure = (Closure *) user_data; Function* fn = (Function *) closure->info; FunctionType *cbInfo = fn->info; VALUE* rbParams; VALUE rbReturnValue; int i; rbParams = ALLOCA_N(VALUE, cbInfo->parameterCount); for (i = 0; i < cbInfo->parameterCount; ++i) { VALUE param; switch (cbInfo->parameterTypes[i]->nativeType) { case NATIVE_INT8: param = INT2NUM(*(int8_t *) parameters[i]); break; case NATIVE_UINT8: param = UINT2NUM(*(uint8_t *) parameters[i]); break; case NATIVE_INT16: param = INT2NUM(*(int16_t *) parameters[i]); break; case NATIVE_UINT16: param = UINT2NUM(*(uint16_t *) parameters[i]); break; case NATIVE_INT32: param = INT2NUM(*(int32_t *) parameters[i]); break; case NATIVE_UINT32: param = UINT2NUM(*(uint32_t *) parameters[i]); break; case NATIVE_INT64: param = LL2NUM(*(int64_t *) parameters[i]); break; case NATIVE_UINT64: param = ULL2NUM(*(uint64_t *) parameters[i]); break; case NATIVE_LONG: param = LONG2NUM(*(long *) parameters[i]); break; case NATIVE_ULONG: param = ULONG2NUM(*(unsigned long *) parameters[i]); break; case NATIVE_FLOAT32: param = rb_float_new(*(float *) parameters[i]); break; case NATIVE_FLOAT64: param = rb_float_new(*(double *) parameters[i]); break; case NATIVE_STRING: param = (*(void **) parameters[i] != NULL) ? rb_tainted_str_new2(*(char **) parameters[i]) : Qnil; break; case NATIVE_POINTER: param = rbffi_Pointer_NewInstance(*(void **) parameters[i]); break; case NATIVE_BOOL: param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse; break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: param = rbffi_NativeValue_ToRuby(cbInfo->parameterTypes[i], rb_ary_entry(cbInfo->rbParameterTypes, i), parameters[i], Qnil); break; default: param = Qnil; break; } rbParams[i] = param; } rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams); if (rbReturnValue == Qnil || TYPE(rbReturnValue) == T_NIL) { memset(retval, 0, cbInfo->ffiReturnType->size); } else switch (cbInfo->returnType->nativeType) { case NATIVE_INT8: case NATIVE_INT16: case NATIVE_INT32: *((ffi_sarg *) retval) = NUM2INT(rbReturnValue); break; case NATIVE_UINT8: case NATIVE_UINT16: case NATIVE_UINT32: *((ffi_arg *) retval) = NUM2UINT(rbReturnValue); break; case NATIVE_INT64: *((int64_t *) retval) = NUM2LL(rbReturnValue); break; case NATIVE_UINT64: *((uint64_t *) retval) = NUM2ULL(rbReturnValue); break; case NATIVE_LONG: *((ffi_sarg *) retval) = NUM2LONG(rbReturnValue); break; case NATIVE_ULONG: *((ffi_arg *) retval) = NUM2ULONG(rbReturnValue); break; case NATIVE_FLOAT32: *((float *) retval) = (float) NUM2DBL(rbReturnValue); break; case NATIVE_FLOAT64: *((double *) retval) = NUM2DBL(rbReturnValue); break; case NATIVE_POINTER: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; } else { // Default to returning NULL if not a value pointer object. handles nil case as well *((void **) retval) = NULL; } break; case NATIVE_BOOL: *((ffi_arg *) retval) = rbReturnValue == Qtrue; break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) { VALUE function; function = rbffi_Function_ForProc(cbInfo->rbReturnType, rbReturnValue); *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address; } else { *((void **) retval) = NULL; } break; default: *((ffi_arg *) retval) = 0; break; } }
static VALUE variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE rbReturnType, VALUE options) { VariadicInvoker* invoker = NULL; VALUE retval = Qnil; VALUE convention = Qnil; VALUE fixed = Qnil; #if defined(X86_WIN32) VALUE rbConventionStr; #endif int i; Check_Type(options, T_HASH); convention = rb_hash_aref(options, ID2SYM(rb_intern("convention"))); Data_Get_Struct(self, VariadicInvoker, invoker); invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums"))); invoker->rbAddress = rbFunction; invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address; #if defined(X86_WIN32) rbConventionStr = rb_funcall2(convention, rb_intern("to_s"), 0, NULL); invoker->abi = (RTEST(convention) && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0) ? FFI_STDCALL : FFI_DEFAULT_ABI; #else invoker->abi = FFI_DEFAULT_ABI; #endif invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType); if (!RTEST(invoker->rbReturnType)) { VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName)); } Data_Get_Struct(rbReturnType, Type, invoker->returnType); invoker->paramCount = -1; fixed = rb_ary_new2(RARRAY_LEN(rbParameterTypes) - 1); for (i = 0; i < RARRAY_LEN(rbParameterTypes); ++i) { VALUE entry = rb_ary_entry(rbParameterTypes, i); VALUE rbType = rbffi_Type_Lookup(entry); Type* type; if (!RTEST(rbType)) { VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName)); } Data_Get_Struct(rbType, Type, type); if (type->nativeType != NATIVE_VARARGS) { rb_ary_push(fixed, entry); } } /* * @fixed and @type_map are used by the parameter mangling ruby code */ rb_iv_set(self, "@fixed", fixed); rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map")))); return retval; }
static VALUE eval_expression(VALUE args) { return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args)); }
/* * call-seq: * Digest::Class.bubblebabble(string, ...) -> hash_string * * Returns the BubbleBabble encoded hash value of a given _string_. */ static VALUE rb_digest_class_s_bubblebabble(int argc, VALUE *argv, VALUE klass) { return bubblebabble_str_new(rb_funcall2(klass, id_digest, argc, argv)); }
VALUE rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr) { switch (type->nativeType) { case NATIVE_VOID: return Qnil; case NATIVE_INT8: return INT2NUM((signed char) *(ffi_sarg *) ptr); case NATIVE_INT16: return INT2NUM((signed short) *(ffi_sarg *) ptr); case NATIVE_INT32: return INT2NUM((signed int) *(ffi_sarg *) ptr); case NATIVE_LONG: return LONG2NUM((signed long) *(ffi_sarg *) ptr); case NATIVE_INT64: return LL2NUM(*(signed long long *) ptr); case NATIVE_UINT8: return UINT2NUM((unsigned char) *(ffi_arg *) ptr); case NATIVE_UINT16: return UINT2NUM((unsigned short) *(ffi_arg *) ptr); case NATIVE_UINT32: return UINT2NUM((unsigned int) *(ffi_arg *) ptr); case NATIVE_ULONG: return ULONG2NUM((unsigned long) *(ffi_arg *) ptr); case NATIVE_UINT64: return ULL2NUM(*(unsigned long long *) ptr); case NATIVE_FLOAT32: return rb_float_new(*(float *) ptr); case NATIVE_FLOAT64: return rb_float_new(*(double *) ptr); case NATIVE_LONGDOUBLE: return rbffi_longdouble_new(*(long double *) ptr); case NATIVE_STRING: return (*(void **) ptr != NULL) ? rb_tainted_str_new2(*(char **) ptr) : Qnil; case NATIVE_POINTER: return rbffi_Pointer_NewInstance(*(void **) ptr); case NATIVE_BOOL: return ((unsigned char) *(ffi_arg *) ptr) ? Qtrue : Qfalse; case NATIVE_FUNCTION: case NATIVE_CALLBACK: { return *(void **) ptr != NULL ? rbffi_Function_NewInstance(rbType, rbffi_Pointer_NewInstance(*(void **) ptr)) : Qnil; } case NATIVE_STRUCT: { StructByValue* sbv = (StructByValue *)type; AbstractMemory* mem; VALUE rbMemory = rbffi_MemoryPointer_NewInstance(1, sbv->base.ffiType->size, false); Data_Get_Struct(rbMemory, AbstractMemory, mem); memcpy(mem->address, ptr, sbv->base.ffiType->size); RB_GC_GUARD(rbMemory); RB_GC_GUARD(rbType); return rb_class_new_instance(1, &rbMemory, sbv->rbStructClass); } case NATIVE_MAPPED: { /* * For mapped types, first convert to the real native type, then upcall to * ruby to convert to the expected return type */ MappedType* m = (MappedType *) type; VALUE values[2], rbReturnValue; values[0] = rbffi_NativeValue_ToRuby(m->type, m->rbType, ptr); values[1] = Qnil; rbReturnValue = rb_funcall2(m->rbConverter, id_from_native, 2, values); RB_GC_GUARD(values[0]); RB_GC_GUARD(rbType); return rbReturnValue; } default: rb_raise(rb_eRuntimeError, "Unknown type: %d", type->nativeType); return Qnil; } }
/** * this function will safely be executed (gvl acquired) * this should not create a blocking/bottleneck situation since the access to rb_mKernel is * mutex-protected by proxenet before * * */ static void* _safe_call_func(void* arg) { struct proxenet_ruby_args* args = (struct proxenet_ruby_args*) arg; VALUE rRet = rb_funcall2(args->rVM, args->rFunc, 3, args->rArgs); return (void*)rRet; }
/* * call-seq: * Digest::Class.hexdigest(string[, ...]) -> hash_string * * Returns the hex-encoded hash value of a given _string_. This is * almost equivalent to * Digest.hexencode(Digest::Class.new(*parameters).digest(string)). */ static VALUE rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass) { return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv)); }
static VALUE fntype_initialize(int argc, VALUE* argv, VALUE self) { FunctionType *fnInfo; ffi_status status; VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbOptions = Qnil; VALUE rbEnums = Qnil, rbConvention = Qnil, rbBlocking = Qnil; #if defined(_WIN32) || defined(__WIN32__) VALUE rbConventionStr; #endif int i, nargs; nargs = rb_scan_args(argc, argv, "21", &rbReturnType, &rbParamTypes, &rbOptions); if (nargs >= 3 && rbOptions != Qnil) { rbConvention = rb_hash_aref(rbOptions, ID2SYM(rb_intern("convention"))); rbEnums = rb_hash_aref(rbOptions, ID2SYM(rb_intern("enums"))); rbBlocking = rb_hash_aref(rbOptions, ID2SYM(rb_intern("blocking"))); } Check_Type(rbParamTypes, T_ARRAY); Data_Get_Struct(self, FunctionType, fnInfo); fnInfo->parameterCount = (int) RARRAY_LEN(rbParamTypes); fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes)); fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *)); fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes)); fnInfo->rbParameterTypes = rb_ary_new2(fnInfo->parameterCount); fnInfo->rbEnums = rbEnums; fnInfo->blocking = RTEST(rbBlocking); fnInfo->hasStruct = false; for (i = 0; i < fnInfo->parameterCount; ++i) { VALUE entry = rb_ary_entry(rbParamTypes, i); VALUE type = rbffi_Type_Lookup(entry); if (!RTEST(type)) { VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName)); } if (rb_obj_is_kind_of(type, rbffi_FunctionTypeClass)) { REALLOC_N(fnInfo->callbackParameters, VALUE, fnInfo->callbackCount + 1); fnInfo->callbackParameters[fnInfo->callbackCount++] = type; } if (rb_obj_is_kind_of(type, rbffi_StructByValueClass)) { fnInfo->hasStruct = true; } rb_ary_push(fnInfo->rbParameterTypes, type); Data_Get_Struct(type, Type, fnInfo->parameterTypes[i]); fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType; fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType; } fnInfo->rbReturnType = rbffi_Type_Lookup(rbReturnType); if (!RTEST(fnInfo->rbReturnType)) { VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName)); } if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) { fnInfo->hasStruct = true; } Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType); fnInfo->ffiReturnType = fnInfo->returnType->ffiType; #if defined(_WIN32) || defined(__WIN32__) rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil; fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0) ? FFI_STDCALL : FFI_DEFAULT_ABI; #else fnInfo->abi = FFI_DEFAULT_ABI; #endif status = ffi_prep_cif(&fnInfo->ffi_cif, fnInfo->abi, fnInfo->parameterCount, fnInfo->ffiReturnType, fnInfo->ffiParameterTypes); switch (status) { case FFI_BAD_ABI: rb_raise(rb_eArgError, "Invalid ABI specified"); case FFI_BAD_TYPEDEF: rb_raise(rb_eArgError, "Invalid argument type specified"); case FFI_OK: break; default: rb_raise(rb_eArgError, "Unknown FFI error"); } fnInfo->invoke = rbffi_GetInvoker(fnInfo); return self; }
VALUE rbclt_callback_func_invoke (RBCLTCallbackFunc *func, int arg_count, const VALUE *argv) { return rb_funcall2 (func->proc, id_call, arg_count, argv); }
/** * Call a ruby function with parameters * * @arg the callback structure * @return the value returned the called ruby function */ VALUE FunCallWrap(VALUE rdata) { struct my_callback* data = (struct my_callback*) rdata; return rb_funcall2(data->obj,data->method_id,data->nargs,data->args); }
static VALUE pkcs11_library_new(int argc, VALUE *argv, VALUE self) { return rb_funcall2(cPKCS11, sNEW, argc, argv); }
void rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes, FFIStorage* paramStorage, void** ffiValues, VALUE* callbackParameters, int callbackCount, VALUE enums) { VALUE callbackProc = Qnil; FFIStorage* param = ¶mStorage[0]; int i, argidx, cbidx, argCount; if (unlikely(paramCount != -1 && paramCount != argc)) { if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) { callbackProc = rb_block_proc(); } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount); } } argCount = paramCount != -1 ? paramCount : argc; for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) { Type* paramType = paramTypes[i]; int type; if (unlikely(paramType->nativeType == NATIVE_MAPPED)) { VALUE values[] = { argv[argidx], Qnil }; argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values); paramType = ((MappedType *) paramType)->type; } type = argidx < argc ? TYPE(argv[argidx]) : T_NONE; ffiValues[i] = param; switch (paramType->nativeType) { case NATIVE_INT8: param->s8 = NUM2INT(argv[argidx]); ++argidx; ADJ(param, INT8); break; case NATIVE_INT16: param->s16 = NUM2INT(argv[argidx]); ++argidx; ADJ(param, INT16); break; case NATIVE_INT32: if (unlikely(type == T_SYMBOL && enums != Qnil)) { VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]); param->s32 = NUM2INT(value); } else { param->s32 = NUM2INT(argv[argidx]); } ++argidx; ADJ(param, INT32); break; case NATIVE_BOOL: if (type != T_TRUE && type != T_FALSE) { rb_raise(rb_eTypeError, "wrong argument type (expected a boolean parameter)"); } param->s8 = argv[argidx++] == Qtrue; ADJ(param, INT8); break; case NATIVE_UINT8: param->u8 = NUM2UINT(argv[argidx]); ADJ(param, INT8); ++argidx; break; case NATIVE_UINT16: param->u16 = NUM2UINT(argv[argidx]); ADJ(param, INT16); ++argidx; break; case NATIVE_UINT32: param->u32 = NUM2UINT(argv[argidx]); ADJ(param, INT32); ++argidx; break; case NATIVE_INT64: param->i64 = NUM2LL(argv[argidx]); ADJ(param, INT64); ++argidx; break; case NATIVE_UINT64: param->u64 = NUM2ULL(argv[argidx]); ADJ(param, INT64); ++argidx; break; case NATIVE_LONG: *(ffi_sarg *) param = NUM2LONG(argv[argidx]); ADJ(param, LONG); ++argidx; break; case NATIVE_ULONG: *(ffi_arg *) param = NUM2ULONG(argv[argidx]); ADJ(param, LONG); ++argidx; break; case NATIVE_FLOAT32: param->f32 = (float) NUM2DBL(argv[argidx]); ADJ(param, FLOAT32); ++argidx; break; case NATIVE_FLOAT64: param->f64 = NUM2DBL(argv[argidx]); ADJ(param, FLOAT64); ++argidx; break; case NATIVE_LONGDOUBLE: param->ld = rbffi_num2longdouble(argv[argidx]); ADJ(param, LONGDOUBLE); ++argidx; break; case NATIVE_STRING: if (type == T_NIL) { param->ptr = NULL; } else { if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) { rb_raise(rb_eSecurityError, "Unsafe string parameter"); } param->ptr = StringValueCStr(argv[argidx]); } ADJ(param, ADDRESS); ++argidx; break; case NATIVE_POINTER: case NATIVE_BUFFER_IN: case NATIVE_BUFFER_OUT: case NATIVE_BUFFER_INOUT: param->ptr = getPointer(argv[argidx++], type); ADJ(param, ADDRESS); break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: if (callbackProc != Qnil) { param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]); } else { param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]); ++argidx; } ADJ(param, ADDRESS); break; case NATIVE_STRUCT: ffiValues[i] = getPointer(argv[argidx++], type); break; default: rb_raise(rb_eArgError, "Invalid parameter type: %d", paramType->nativeType); } } }
static inline VALUE vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, int num, const rb_block_t *blockptr, VALUE flag, ID id, const rb_method_entry_t *me, VALUE recv) { VALUE val; start_method_dispatch: if (me != 0) { if ((me->flag == 0)) { normal_method_dispatch: switch (me->def->type) { case VM_METHOD_TYPE_ISEQ:{ vm_setup_method(th, cfp, recv, num, blockptr, flag, me); return Qundef; } case VM_METHOD_TYPE_NOTIMPLEMENTED: case VM_METHOD_TYPE_CFUNC:{ val = vm_call_cfunc(th, cfp, num, recv, blockptr, me); break; } case VM_METHOD_TYPE_ATTRSET:{ if (num != 1) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num); } val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1)); cfp->sp -= 2; break; } case VM_METHOD_TYPE_IVAR:{ if (num != 0) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num); } val = rb_attr_get(recv, me->def->body.attr.id); cfp->sp -= 1; break; } case VM_METHOD_TYPE_MISSING:{ VALUE *argv = ALLOCA_N(VALUE, num+1); argv[0] = ID2SYM(me->def->original_id); MEMCPY(argv+1, cfp->sp - num, VALUE, num); cfp->sp += - num - 1; th->passed_block = blockptr; val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv); break; } case VM_METHOD_TYPE_BMETHOD:{ VALUE *argv = ALLOCA_N(VALUE, num); MEMCPY(argv, cfp->sp - num, VALUE, num); cfp->sp += - num - 1; val = vm_call_bmethod(th, recv, num, argv, blockptr, me); break; } case VM_METHOD_TYPE_ZSUPER:{ VALUE klass = RCLASS_SUPER(me->klass); me = rb_method_entry(klass, id); if (me != 0) { goto normal_method_dispatch; } else { goto start_method_dispatch; } } case VM_METHOD_TYPE_OPTIMIZED:{ switch (me->def->body.optimize_type) { case OPTIMIZED_METHOD_TYPE_SEND: { rb_control_frame_t *reg_cfp = cfp; rb_num_t i = num - 1; VALUE sym; if (num == 0) { rb_raise(rb_eArgError, "no method name given"); } sym = TOPN(i); id = SYMBOL_P(sym) ? SYM2ID(sym) : rb_to_id(sym); /* shift arguments */ if (i > 0) { MEMMOVE(&TOPN(i), &TOPN(i-1), VALUE, i); } me = rb_method_entry(CLASS_OF(recv), id); num -= 1; DEC_SP(1); flag |= VM_CALL_FCALL_BIT | VM_CALL_OPT_SEND_BIT; goto start_method_dispatch; } case OPTIMIZED_METHOD_TYPE_CALL: { rb_proc_t *proc; int argc = num; VALUE *argv = ALLOCA_N(VALUE, num); GetProcPtr(recv, proc); MEMCPY(argv, cfp->sp - num, VALUE, num); cfp->sp -= num + 1; val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr); break; } default: rb_bug("eval_invoke_method: unsupported optimized method type (%d)", me->def->body.optimize_type); } break; } default:{ rb_bug("eval_invoke_method: unsupported method type (%d)", me->def->type); break; } } } else { int noex_safe; if (!(flag & VM_CALL_FCALL_BIT) && (me->flag & NOEX_MASK) & NOEX_PRIVATE) { int stat = NOEX_PRIVATE; if (flag & VM_CALL_VCALL_BIT) { stat |= NOEX_VCALL; } val = vm_method_missing(th, id, recv, num, blockptr, stat); } else if (!(flag & VM_CALL_OPT_SEND_BIT) && (me->flag & NOEX_MASK) & NOEX_PROTECTED) { VALUE defined_class = me->klass; if (RB_TYPE_P(defined_class, T_ICLASS)) { defined_class = RBASIC(defined_class)->klass; } if (!rb_obj_is_kind_of(cfp->self, defined_class)) { val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED); } else { goto normal_method_dispatch; } } else if ((noex_safe = NOEX_SAFE(me->flag)) > th->safe_level && (noex_safe > 2)) { rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id)); } else { goto normal_method_dispatch; } } } else { /* method missing */ int stat = 0; if (flag & VM_CALL_VCALL_BIT) { stat |= NOEX_VCALL; } if (flag & VM_CALL_SUPER_BIT) { stat |= NOEX_SUPER; } if (id == idMethodMissing) { VALUE *argv = ALLOCA_N(VALUE, num); vm_method_missing_args(th, argv, num - 1, 0, stat); rb_raise_method_missing(th, num, argv, recv, stat); } else { val = vm_method_missing(th, id, recv, num, blockptr, stat); } } RUBY_VM_CHECK_INTS(); return val; }
static VALUE lp_respond_to_missing(int argc, VALUE* argv, VALUE self) { VALUE obj = lp_get_resolv(self); return rb_funcall2(obj, id_respond_to, argc, argv); }
static VALUE lazy_flat_map_i(VALUE i, VALUE yielder, int argc, VALUE *argv) { return rb_funcall2(yielder, id_yield, argc, argv); }
static VALUE bdb_deleg_each(VALUE *tmp) { return rb_funcall2(tmp[0], id_send, (int)tmp[1], (VALUE *)tmp[2]); }
static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs) { VALUE xpath_handler = Qnil; VALUE result; VALUE *argv; VALUE doc; VALUE node_set = Qnil; xmlNodeSetPtr xml_node_set = NULL; xmlXPathObjectPtr obj; int i; nokogiriNodeSetTuple *node_set_tuple; assert(ctx); assert(ctx->context); assert(ctx->context->userData); assert(ctx->context->doc); assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc)); xpath_handler = (VALUE)(ctx->context->userData); argv = (VALUE *)calloc((size_t)nargs, sizeof(VALUE)); for (i = 0 ; i < nargs ; ++i) { rb_gc_register_address(&argv[i]); } doc = DOC_RUBY_OBJECT(ctx->context->doc); if (nargs > 0) { i = nargs - 1; do { obj = valuePop(ctx); switch(obj->type) { case XPATH_STRING: argv[i] = NOKOGIRI_STR_NEW2(obj->stringval); break; case XPATH_BOOLEAN: argv[i] = obj->boolval == 1 ? Qtrue : Qfalse; break; case XPATH_NUMBER: argv[i] = rb_float_new(obj->floatval); break; case XPATH_NODESET: argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval, doc); break; default: argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj)); } xmlXPathFreeNodeSetList(obj); } while(i-- > 0); } result = rb_funcall2( xpath_handler, rb_intern((const char *)ctx->context->function), nargs, argv ); for (i = 0 ; i < nargs ; ++i) { rb_gc_unregister_address(&argv[i]); } free(argv); switch(TYPE(result)) { case T_FLOAT: case T_BIGNUM: case T_FIXNUM: xmlXPathReturnNumber(ctx, NUM2DBL(result)); break; case T_STRING: xmlXPathReturnString( ctx, (xmlChar *)xmlXPathWrapCString(StringValuePtr(result)) ); break; case T_TRUE: xmlXPathReturnTrue(ctx); break; case T_FALSE: xmlXPathReturnFalse(ctx); break; case T_NIL: break; case T_ARRAY: { VALUE args[2]; args[0] = doc; args[1] = result; node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet); Data_Get_Struct(node_set, nokogiriNodeSetTuple, node_set_tuple); xml_node_set = node_set_tuple->node_set; xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set)); } break; case T_DATA: if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) { Data_Get_Struct(result, nokogiriNodeSetTuple, node_set_tuple); xml_node_set = node_set_tuple->node_set; /* Copy the node set, otherwise it will get GC'd. */ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set)); break; } default: rb_raise(rb_eRuntimeError, "Invalid return type"); } }
/* * call-seq: * io.getch(min: nil, time: nil) -> char * * See IO#getch. */ static VALUE io_getch(int argc, VALUE *argv, VALUE io) { return rb_funcall2(io, rb_intern("getc"), argc, argv); }
DWORD CallbackFunction(CALLPARAM param, VALUE callback) { VALUE v_proto, v_return, v_proc, v_retval; VALUE argv[20]; int i, argc; char *a_proto; char *a_return; if(callback && !NIL_P(callback)){ v_proto = rb_iv_get(callback, "@prototype"); a_proto = RSTRING_PTR(v_proto); v_return = rb_iv_get(callback, "@return_type"); a_return = RSTRING_PTR(v_return); v_proc = rb_iv_get(callback, "@function"); argc = RSTRING_LEN(v_proto); for(i=0; i < RSTRING_LEN(v_proto); i++){ argv[i] = Qnil; switch(a_proto[i]){ case 'L': argv[i] = ULONG2NUM(param.params[i]); break; case 'P': if(param.params[i]) argv[i] = rb_str_new2((char *)param.params[i]); break; case 'I': argv[i] = INT2NUM(param.params[i]); break; default: rb_raise(cAPIProtoError, "Illegal prototype '%s'", a_proto[i]); } } v_retval = rb_funcall2(v_proc, rb_intern("call"), argc, argv); /* Handle true and false explicitly, as some CALLBACK functions * require TRUE or FALSE to break out of loops, etc. */ if(v_retval == Qtrue) return TRUE; else if(v_retval == Qfalse) return FALSE; switch (*a_return) { case 'I': return NUM2INT(v_retval); break; case 'L': return NUM2ULONG(v_retval); break; case 'S': return (unsigned long)RSTRING_PTR(v_retval); break; case 'P': if(NIL_P(v_retval)){ return 0; } else if(FIXNUM_P(v_retval)){ return NUM2ULONG(v_retval); } else{ StringValue(v_retval); rb_str_modify(v_retval); return (unsigned long)StringValuePtr(v_retval); } break; } } return 0; }
static VALUE do_sleep(VALUE args) { struct sleep_call *p = (struct sleep_call *)args; return rb_funcall2(p->mutex, id_sleep, 1, &p->timeout); }
/* * call-seq: * unixsocket.recv_io([klass [, mode]]) => io * * UNIXServer.open("/tmp/sock") {|serv| * UNIXSocket.open("/tmp/sock") {|c| * s = serv.accept * * c.send_io STDOUT * stdout = s.recv_io * * p STDOUT.fileno #=> 1 * p stdout.fileno #=> 7 * * stdout.puts "hello" # outputs "hello\n" to standard output. * } * } * */ static VALUE unix_recv_io(int argc, VALUE *argv, VALUE sock) { VALUE klass, mode; rb_io_t *fptr; struct iomsg_arg arg; struct iovec vec[2]; char buf[1]; int fd; #if FD_PASSING_BY_MSG_CONTROL struct { struct cmsghdr hdr; char pad[8+sizeof(int)+8]; } cmsg; #endif rb_scan_args(argc, argv, "02", &klass, &mode); if (argc == 0) klass = rb_cIO; if (argc <= 1) mode = Qnil; GetOpenFile(sock, fptr); arg.msg.msg_name = NULL; arg.msg.msg_namelen = 0; vec[0].iov_base = buf; vec[0].iov_len = sizeof(buf); arg.msg.msg_iov = vec; arg.msg.msg_iovlen = 1; #if FD_PASSING_BY_MSG_CONTROL arg.msg.msg_control = (caddr_t)&cmsg; arg.msg.msg_controllen = CMSG_SPACE(sizeof(int)); arg.msg.msg_flags = 0; cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_RIGHTS; fd = -1; memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int)); #else arg.msg.msg_accrights = (caddr_t)&fd; arg.msg.msg_accrightslen = sizeof(fd); fd = -1; #endif arg.fd = fptr->fd; rb_thread_wait_fd(arg.fd); if ((int)BLOCKING_REGION(recvmsg_blocking, &arg) == -1) rb_sys_fail("recvmsg(2)"); #if FD_PASSING_BY_MSG_CONTROL if (arg.msg.msg_controllen < sizeof(struct cmsghdr)) { rb_raise(rb_eSocket, "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)", (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr)); } if (cmsg.hdr.cmsg_level != SOL_SOCKET) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_level=%d, %d expected)", cmsg.hdr.cmsg_level, SOL_SOCKET); } if (cmsg.hdr.cmsg_type != SCM_RIGHTS) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_type=%d, %d expected)", cmsg.hdr.cmsg_type, SCM_RIGHTS); } if (arg.msg.msg_controllen < CMSG_LEN(sizeof(int))) { rb_raise(rb_eSocket, "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)", (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int))); } if (CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) { rb_raise(rb_eSocket, "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)", (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int))); } if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) { rsock_discard_cmsg_resource(&arg.msg); rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_len=%d, %d expected)", (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); } #else if (arg.msg.msg_accrightslen != sizeof(fd)) { rb_raise(rb_eSocket, "file descriptor was not passed (accrightslen) : %d != %d", arg.msg.msg_accrightslen, (int)sizeof(fd)); } #endif #if FD_PASSING_BY_MSG_CONTROL memcpy(&fd, CMSG_DATA(&cmsg.hdr), sizeof(int)); #endif if (klass == Qnil) return INT2FIX(fd); else { ID for_fd; int ff_argc; VALUE ff_argv[2]; CONST_ID(for_fd, "for_fd"); ff_argc = mode == Qnil ? 1 : 2; ff_argv[0] = INT2FIX(fd); ff_argv[1] = mode; return rb_funcall2(klass, for_fd, ff_argc, ff_argv); } }
static VALUE do_func_call(VALUE ptr) { struct proc_params_st *p = (struct proc_params_st *)ptr; return rb_funcall2(p->recv, p->mid, p->argc, p->argv); }
static VALUE rgssMainCb(VALUE block) { rb_funcall2(block, rb_intern("call"), 0, 0); return Qnil; }
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); }
static VALUE getc_call(VALUE io) { return rb_funcall2(io, id_getc, 0, 0); }
/** * this function will safely be executed (gvl acquired) * this should not create a blocking/bottleneck situation since the access to rb_mKernel is * mutex-protected by proxenet before * * @return the result of rb_funcall2() */ static VALUE proxenet_safe_func_call(VALUE arg) { struct proxenet_ruby_args* args = (struct proxenet_ruby_args*) arg; return rb_funcall2(args->rVM, args->rFunc, 3, args->rArgs); }