static void vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super) { if (ci->flag & VM_CALL_ARGS_BLOCKARG) { rb_proc_t *po; VALUE proc; proc = *(--reg_cfp->sp); if (NIL_P(proc)) { calling->blockptr = NULL; } else if (SYMBOL_P(proc) && rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) { calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp); calling->blockptr->iseq = (rb_iseq_t *)proc; calling->blockptr->proc = proc; } else if (RUBY_VM_IFUNC_P(proc)) { calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp); calling->blockptr->iseq = (rb_iseq_t *)proc; calling->blockptr->proc = proc; } else { if (!rb_obj_is_proc(proc)) { VALUE b; b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"); if (NIL_P(b) || !rb_obj_is_proc(b)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)", rb_obj_classname(proc)); } proc = b; } GetProcPtr(proc, po); calling->blockptr = &po->block; RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp)->proc = proc; } } else if (blockiseq != 0) { /* likely */ rb_block_t *blockptr = calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp); blockptr->iseq = blockiseq; blockptr->proc = 0; } else { if (is_super) { calling->blockptr = GET_BLOCK_PTR(); } else { calling->blockptr = NULL; } } }
/* call-seq: creds = Credentials.new auth_proc proc: (required) Proc that generates auth metadata Initializes CallCredential instances. */ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) { grpc_rb_call_credentials* wrapper = NULL; grpc_call_credentials* creds = NULL; grpc_metadata_credentials_plugin plugin; grpc_ruby_once_init(); TypedData_Get_Struct(self, grpc_rb_call_credentials, &grpc_rb_call_credentials_data_type, wrapper); plugin.get_metadata = grpc_rb_call_credentials_plugin_get_metadata; plugin.destroy = grpc_rb_call_credentials_plugin_destroy; if (!rb_obj_is_proc(proc)) { rb_raise(rb_eTypeError, "Argument to CallCredentials#new must be a proc"); return Qnil; } plugin.state = (void*)proc; plugin.type = ""; creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL); if (creds == NULL) { rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why"); return Qnil; } wrapper->mark = proc; wrapper->wrapped = creds; rb_ivar_set(self, id_callback, proc); return self; }
/* * call-seq: * Enumerator.new(size = nil) { |yielder| ... } * Enumerator.new(obj, method = :each, *args) * * Creates a new Enumerator object, which can be used as an * Enumerable. * * In the first form, iteration is defined by the given block, in * which a "yielder" object, given as block parameter, can be used to * yield a value by calling the +yield+ method (aliased as +<<+): * * fib = Enumerator.new do |y| * a = b = 1 * loop do * y << a * a, b = b, a + b * end * end * * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] * * The optional parameter can be used to specify how to calculate the size * in a lazy fashion (see Enumerator#size). It can either be a value or * a callable object. * * In the second, deprecated, form, a generated Enumerator iterates over the * given object using the given method with the given arguments passed. * * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum * instead. * * e = Enumerator.new(ObjectSpace, :each_object) * #-> ObjectSpace.enum_for(:each_object) * * e.select { |obj| obj.is_a?(Class) } #=> array of all classes * */ static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj) { VALUE recv, meth = sym_each; VALUE size = Qnil; if (rb_block_given_p()) { rb_check_arity(argc, 0, 1); recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc()); if (argc) { if (NIL_P(argv[0]) || rb_obj_is_proc(argv[0]) || (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == INFINITY)) { size = argv[0]; } else { size = rb_to_int(argv[0]); } argc = 0; } } else { rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum"); recv = *argv++; if (--argc) { meth = *argv++; --argc; } } return enumerator_init(obj, recv, meth, argc, argv, 0, size); }
/* :nodoc: */ static VALUE generator_initialize(int argc, VALUE *argv, VALUE obj) { VALUE proc; if (argc == 0) { rb_need_block(); proc = rb_block_proc(); } else { rb_scan_args(argc, argv, "1", &proc); if (!rb_obj_is_proc(proc)) rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)", rb_obj_classname(proc)); if (rb_block_given_p()) { rb_warn("given block not used"); } } return generator_init(obj, proc); }
// default behavior of async (doesn't accept Symbol) // call-seq: // async { } // async Proc.new static VALUE kern_async(int argc, VALUE *argv, VALUE self) { VALUE obj; rb_proc_t *proc; rb_iseq_t *niseq; rb_scan_args(argc, argv, "01", &obj); if (!NIL_P(obj)) { if (!rb_obj_is_proc(obj)) { VALUE thread = rb_thread_current(); rb_thread_t * th; TypedData_Get_Struct(thread, rb_thread_t, RTYPEDDATA_TYPE(thread), th); if (self == th->vm->top_self) { return mod_async(CLASS_OF(self), obj); } else { rb_raise(rb_eTypeError, "wrong argument type (expected Proc)"); } } } else if (rb_block_given_p()) { obj = rb_block_proc(); } else { rb_raise(rb_eArgError, "Proc or block is required"); } proc = (rb_proc_t *)DATA_PTR(obj); // うーーー niseq = transform(obj); proc->block.iseq = niseq; return obj; }
static void thread_add_trace_func(rb_thread_t *th, VALUE trace) { if (!rb_obj_is_proc(trace)) { rb_raise(rb_eTypeError, "trace_func needs to be Proc"); } rb_threadptr_add_event_hook(th, call_trace_func, RUBY_EVENT_ALL, trace, RUBY_EVENT_HOOK_FLAG_SAFE); }
static void respond_with_message(char *buf, size_t size) { VALUE respond_callback; if(zmq_response_socket) zmq_send(zmq_response_socket, buf, size, 0); respond_callback = rb_ivar_get(server_instance, rb_intern("@respond_callback")); if (rb_obj_is_proc(respond_callback) == Qtrue) { VALUE message = rb_str_new(buf, size); VALUE argv[] = { message }; rb_proc_call_with_block(respond_callback, 1, argv, Qnil); } }
static void publish_message(char *buf, size_t size) { VALUE publish_callback; if(zmq_publisher) zmq_send(zmq_publisher, buf, size, 0); publish_callback = rb_ivar_get(server_instance, rb_intern("@publish_callback")); if (rb_obj_is_proc(publish_callback) == Qtrue) { VALUE message = rb_str_new(buf, size); VALUE argv[] = { message }; rb_proc_call_with_block(publish_callback, 1, argv, Qnil); } }
static VALUE enumerator_size(VALUE obj) { struct enumerator *e = enumerator_ptr(obj); if (e->size_fn) { return (*e->size_fn)(e->obj, e->args, obj); } if (rb_obj_is_proc(e->size)) { if (e->args) return rb_proc_call(e->size, e->args); else return rb_proc_call_with_block(e->size, 0, 0, Qnil); } return e->size; }
static VALUE set_trace_func(VALUE obj, VALUE trace) { rb_remove_event_hook(call_trace_func); if (NIL_P(trace)) { return Qnil; } if (!rb_obj_is_proc(trace)) { rb_raise(rb_eTypeError, "trace_func needs to be Proc"); } rb_add_event_hook(call_trace_func, RUBY_EVENT_ALL, trace); return trace; }
static VALUE rb_mod_define_method(VALUE mod, SEL sel, int argc, VALUE *argv) { #if MACRUBY_STATIC not_implemented_in_static(sel); #else ID id; VALUE body; if (argc == 1) { id = rb_to_id(argv[0]); body = rb_block_lambda(); } else if (argc == 2) { id = rb_to_id(argv[0]); body = argv[1]; if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Method)", rb_obj_classname(body)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } if (rb_obj_is_method(body)) { rb_vm_method_t *data; Data_Get_Struct(body, rb_vm_method_t, data); if (data->node == NULL) { rb_raise(rb_eArgError, "cannot use Method object of pure Objective-C method"); } SEL msel = rb_vm_id_to_sel(id, data->arity); rb_vm_define_method2((Class)mod, msel, data->node, data->node->flags, false); } else { rb_vm_block_t *proc; GetProcPtr(body, proc); rb_vm_define_method3((Class)mod, id, proc); } return body; #endif }
static VALUE state_machine_add(int argc, VALUE argv[], VALUE self) { VALUE pool = rb_ivar_get(self, rb_intern("@pool")); volatile VALUE key_or_hash, value, parent, block; rb_scan_args(argc, argv, "12&", &key_or_hash, &value, &parent, &block); if (rb_block_given_p()) { rb_hash_aset(pool, key_or_hash, block); } else { if (RB_TYPE_P(key_or_hash, T_HASH)) { volatile VALUE ary = rb_funcall(key_or_hash, rb_intern("to_a"), 0); int i, len = RARRAY_LENINT(ary); for (i = 0; i < len; ++i) { volatile VALUE pair = RARRAY_PTR(ary)[i]; state_machine_add(2, (VALUE[]){ RARRAY_PTR(pair)[0], RARRAY_PTR(pair)[1] }, self); } } else { if (rb_obj_is_proc(value) == Qtrue) { rb_hash_aset(pool, key_or_hash, value); } else { rb_hash_aset(pool, key_or_hash, rb_obj_method(NIL_P(parent) ? rb_ivar_get(self, rb_intern("@parent")) : parent, value)); } } }
static VALUE rb_mod_define_method(int argc, VALUE *argv, VALUE mod) { ID id; VALUE body; NODE *node; int noex = NOEX_PUBLIC; if (argc == 1) { id = rb_to_id(argv[0]); body = rb_block_lambda(); } else if (argc == 2) { id = rb_to_id(argv[0]); body = argv[1]; if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Method)", rb_obj_classname(body)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } if (RDATA(body)->dmark == (RUBY_DATA_FUNC) bm_mark) { struct METHOD *method = (struct METHOD *)DATA_PTR(body); VALUE rklass = method->rklass; if (rklass != mod) { if (FL_TEST(rklass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't bind singleton method to a different class"); } if (!RTEST(rb_class_inherited_p(mod, rklass))) { rb_raise(rb_eTypeError, "bind argument must be a subclass of %s", rb_class2name(rklass)); } } node = method->body; } else if (rb_obj_is_proc(body)) { rb_proc_t *proc; body = proc_dup(body); GetProcPtr(body, proc); if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) { proc->block.iseq->defined_method_id = id; proc->block.iseq->klass = mod; proc->is_lambda = Qtrue; } node = NEW_BMETHOD(body); } else { /* type error */ rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)"); } /* TODO: visibility */ rb_add_method(mod, id, node, noex); return body; }
static inline int caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, VALUE flag, int argc, rb_iseq_t *blockiseq, rb_block_t **block) { rb_block_t *blockptr = 0; if (block) { if (flag & VM_CALL_ARGS_BLOCKARG_BIT) { rb_proc_t *po; VALUE proc; proc = *(--cfp->sp); if (proc != Qnil) { if (!rb_obj_is_proc(proc)) { VALUE b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"); if (NIL_P(b) || !rb_obj_is_proc(b)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)", rb_obj_classname(proc)); } proc = b; } GetProcPtr(proc, po); blockptr = &po->block; RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp)->proc = proc; *block = blockptr; } } else if (blockiseq) { blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp); blockptr->iseq = blockiseq; blockptr->proc = 0; *block = blockptr; } } /* expand top of stack? */ if (flag & VM_CALL_ARGS_SPLAT_BIT) { VALUE ary = *(cfp->sp - 1); VALUE *ptr; int i; VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"); if (NIL_P(tmp)) { /* do nothing */ } else { long len = RARRAY_LEN(tmp); ptr = RARRAY_PTR(tmp); cfp->sp -= 1; CHECK_STACK_OVERFLOW(cfp, len); for (i = 0; i < len; i++) { *cfp->sp++ = ptr[i]; } argc += i-1; } } return argc; }