示例#1
0
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;
	}
    }
}
示例#2
0
/*
  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;
}
示例#3
0
/*
 * 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);
}
示例#4
0
/* :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);
}
示例#5
0
// 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;
}
示例#6
0
文件: vm_trace.c 项目: Chatto/VGdesk
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);
}
示例#7
0
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);
  }
}
示例#8
0
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);
  }
}
示例#9
0
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;
}
示例#10
0
文件: vm_trace.c 项目: ksperling/ruby
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;
}
示例#11
0
文件: proc.c 项目: MSch/MacRuby
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
}
示例#12
0
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));
            }
        }
    }
示例#13
0
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;
}
示例#14
0
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;
}