Exemple #1
0
static VALUE
proc_call(VALUE procval, SEL sel, int argc, const VALUE *argv)
{
#if 0
    rb_proc_t *proc;
    rb_block_t *blockptr = 0;
    GetProcPtr(procval, proc);

    if (BUILTIN_TYPE(proc->block.iseq) != T_NODE &&
	proc->block.iseq->arg_block != -1) {

	if (rb_block_given_p()) {
	    rb_proc_t *proc;
	    VALUE procval;
	    procval = rb_block_proc();
	    GetProcPtr(procval, proc);
	    blockptr = &proc->block;
	}
    }

    return vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			  argc, argv, blockptr);
#endif
    rb_vm_block_t *proc;
    GetProcPtr(procval, proc);
    return rb_vm_block_eval(proc, argc, argv);
}
Exemple #2
0
static VALUE
proc_eq(VALUE self, SEL sel, VALUE other)
{
    if (self == other) {
	return Qtrue;
    }
    else if (rb_obj_is_kind_of(other, rb_cProc)) {
	rb_vm_block_t *self_b, *other_b;
	GetProcPtr(self, self_b);
	GetProcPtr(other, other_b);
	return self_b == other_b ? Qtrue : Qfalse;
    }
    return Qfalse;
}
Exemple #3
0
static VALUE
proc_dup(VALUE self)
{
    VALUE procval = proc_alloc(rb_cProc);
    rb_proc_t *src, *dst;
    GetProcPtr(self, src);
    GetProcPtr(procval, dst);

    dst->block = src->block;
    dst->envval = src->envval;
    dst->safe_level = dst->safe_level;
    dst->special_cref_stack = src->special_cref_stack;
    
    return procval;
}
Exemple #4
0
VALUE
rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
{
    VALUE procval, envval, blockprocval = 0;
    rb_proc_t *proc;
    rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);

    if (block->proc) {
	rb_bug("rb_vm_make_proc: Proc value is already created.");
    }

    if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
	    rb_proc_t *p;

	    blockprocval = vm_make_proc_from_block(
		th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp));

	    GetProcPtr(blockprocval, p);
	    *cfp->lfp = GC_GUARDED_PTR(&p->block);
	}

    envval = rb_vm_make_env_object(th, cfp);

    if (PROCDEBUG) {
	check_env_value(envval);
    }
    procval = rb_proc_alloc(klass);
    GetProcPtr(procval, proc);
    proc->blockprocval = blockprocval;
    proc->block.self = block->self;
    proc->block.lfp = block->lfp;
    proc->block.dfp = block->dfp;
    proc->block.iseq = block->iseq;
    proc->block.proc = procval;
    proc->envval = envval;
    proc->safe_level = th->safe_level;

    if (VMDEBUG) {
	if (th->stack < block->dfp && block->dfp < th->stack + th->stack_size) {
	    rb_bug("invalid ptr: block->dfp");
	}
	if (th->stack < block->lfp && block->lfp < th->stack + th->stack_size) {
	    rb_bug("invalid ptr: block->lfp");
	}
    }

    return procval;
}
Exemple #5
0
static VALUE
proc_hash(VALUE self, SEL sel)
{
    rb_vm_block_t *b;
    GetProcPtr(self, b);
    return LONG2FIX(b);
}
Exemple #6
0
int
rb_proc_arity(VALUE proc)
{
    rb_vm_block_t *b;
    GetProcPtr(proc, b);
    return rb_vm_arity_n(b->arity);
}
Exemple #7
0
static VALUE
proc_dup(VALUE self, SEL sel)
{
    rb_vm_block_t *src;
    GetProcPtr(self, src);
    return Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, src);
}
Exemple #8
0
VALUE
rb_proc_call_with_block(VALUE self, int argc, VALUE *argv, VALUE pass_procval)
{
    rb_proc_t *proc;
    rb_block_t *block = 0;
    GetProcPtr(self, proc);

    if (!NIL_P(pass_procval)) {
	rb_proc_t *pass_proc;
	GetProcPtr(pass_procval, pass_proc);
	block = &pass_proc->block;
    }

    return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			     argc, argv, block);
}
Exemple #9
0
static VALUE
proc_yield(int argc, VALUE *argv, VALUE procval)
{
    rb_proc_t *proc;
    GetProcPtr(procval, proc);
    return th_invoke_proc(GET_THREAD(), proc, proc->block.self, argc, argv);
}
Exemple #10
0
/*
 * call-seq:
 *   proc.dump(limit) => String
 *
 * Dump a Proc to a String.
 */
static VALUE proc_dump(VALUE self, VALUE limit)
{
  if(rb_safe_level() >= 4)
  {
    /* no access to potentially sensitive data from the sandbox */
    rb_raise(rb_eSecurityError, "Insecure: can't dump proc");
  }

  {
#ifdef RUBY_VM
    rb_proc_t * p;
    VALUE iseq, str;
    rb_iseq_t * iseqdat;
    GetProcPtr(self, p);
    iseq = p->block.iseq->self;
    iseqdat = iseq_check(iseq);
    iseqdat->type = ISEQ_TYPE_TOP; /* TODO: is this right? */
    str = marshal_dump(iseq, limit);
    return str;
#else
    struct BLOCK * b;
    VALUE body, var, arr;

    Data_Get_Struct(self, struct BLOCK, b);
    body = wrap_node(b->body);
    var = wrap_node(b->var);
    arr = rb_assoc_new(body, var);
    return marshal_dump(arr, limit);
#endif
  }
}
Exemple #11
0
static VALUE
proc_to_s(VALUE self)
{
    VALUE str = 0;
    rb_proc_t *proc;
    const char *cname = rb_obj_classname(self);
    rb_iseq_t *iseq;
    const char *is_lambda;
    
    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    is_lambda = proc->is_lambda ? " (lambda)" : "";

    if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
	int line_no = 0;
	
	if (iseq->insn_info_table) {
	    line_no = rb_iseq_first_lineno(iseq);
	}
	str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self,
			 RSTRING_PTR(iseq->filename),
			 line_no, is_lambda);
    }
    else {
	str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
			 is_lambda);
    }

    if (OBJ_TAINTED(self)) {
	OBJ_TAINT(str);
    }
    return str;
}
Exemple #12
0
static VALUE
proc_arity(VALUE self)
{
    rb_proc_t *proc;
    rb_iseq_t *iseq;
    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    if (iseq) {
	if (BUILTIN_TYPE(iseq) != T_NODE) {
	    if (iseq->arg_rest < 0) {
		return INT2FIX(iseq->argc);
	    }
	    else {
		return INT2FIX(-(iseq->argc + 1 + iseq->arg_post_len));
	    }
	}
	else {
	    NODE *node = (NODE *)iseq;
	    if (nd_type(node) == NODE_IFUNC && node->nd_cfnc == bmcall) {
		/* method(:foo).to_proc.arity */
		return INT2FIX(method_arity(node->nd_tval));
	    }
	}
    }
    return INT2FIX(-1);
}
Exemple #13
0
static VALUE
proc_to_s(VALUE self)
{
    VALUE str = 0;
    rb_proc_t *proc;
    char *cname = rb_obj_classname(self);
    rb_iseq_t *iseq;
    
    GetProcPtr(self, proc);
    iseq = proc->block.iseq;

    if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
	int line_no = 0;
	
	if (iseq->insn_info_tbl) {
	    line_no = iseq->insn_info_tbl[0].line_no;
	}
	str = rb_sprintf("#<%s:%lx@%s:%d>", cname, self,
			 RSTRING_PTR(iseq->filename),
			 line_no);
    }
    else {
	str = rb_sprintf("#<%s:%p>", cname, proc->block.iseq);
    }

    if (OBJ_TAINTED(self)) {
	OBJ_TAINT(str);
    }
    return str;
}
Exemple #14
0
static VALUE
proc_dup(VALUE self)
{
    VALUE procval = rb_proc_alloc(rb_cProc);
    rb_proc_t *src, *dst;
    GetProcPtr(self, src);
    GetProcPtr(procval, dst);

    dst->block = src->block;
    dst->block.proc = procval;
    dst->envval = src->envval;
    dst->safe_level = src->safe_level;
    dst->is_lambda = src->is_lambda;

    return procval;
}
Exemple #15
0
static sighandler_t
trap_handler(VALUE *cmd, int sig)
{
    sighandler_t func = sighandler;
    VALUE command;

    if (NIL_P(*cmd)) {
	func = SIG_IGN;
    }
    else {
	command = rb_check_string_type(*cmd);
	if (!NIL_P(command)) {
	    SafeStringValue(command);	/* taint check */
	    *cmd = command;
	    switch (RSTRING_LEN(command)) {
	      case 0:
                goto sig_ign;
		break;
              case 14:
		if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
                    func = SIG_DFL;
                    *cmd = 0;
		}
                break;
	      case 7:
		if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
sig_ign:
                    func = SIG_IGN;
                    *cmd = 0;
		}
		else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
sig_dfl:
                    func = default_handler(sig);
                    *cmd = 0;
		}
		else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
                    goto sig_dfl;
		}
		break;
	      case 6:
		if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
                    goto sig_ign;
		}
		break;
	      case 4:
		if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
		    *cmd = Qundef;
		}
		break;
	    }
	}
	else {
	    rb_proc_t *proc;
	    GetProcPtr(*cmd, proc);
	}
    }

    return func;
}
Exemple #16
0
static void
signal_exec(VALUE cmd, int sig)
{
    rb_proc_t *proc;
    VALUE signum = INT2FIX(sig);
    GetProcPtr(cmd, proc);
    vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 1, &signum, 0);
}
Exemple #17
0
VALUE
rb_proc_call(VALUE self, VALUE args)
{
    rb_proc_t *proc;
    GetProcPtr(self, proc);
    return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			     RARRAY_LEN(args), RARRAY_PTR(args), 0);
}
Exemple #18
0
static VALUE
proc_lambda_p(VALUE procval)
{
    rb_proc_t *proc;
    GetProcPtr(procval, proc);

    return proc->is_lambda ? Qtrue : Qfalse;
}
Exemple #19
0
static VALUE
proc_lambda_p(VALUE procval, SEL sel)
{
    rb_vm_block_t *proc;
    GetProcPtr(procval, proc);

    return (proc->flags & VM_BLOCK_LAMBDA) == VM_BLOCK_LAMBDA
	? Qtrue : Qfalse;
}
Exemple #20
0
static VALUE proc_references(VALUE rbproc)
{
    rb_proc_t* proc;
    GetProcPtr(rbproc, proc);

    if (!NIL_P(proc->envval))
        return env_references(proc->envval);
    return rb_ary_new();
}
Exemple #21
0
VALUE
proc_invoke(VALUE self, VALUE args, VALUE alt_self, VALUE alt_klass)
{
    rb_proc_t *proc;
    GetProcPtr(self, proc);

    /* ignore self and klass */
    return th_invoke_proc(GET_THREAD(), proc, proc->block.self,
			  RARRAY_LEN(args), RARRAY_PTR(args));
}
Exemple #22
0
static VALUE
proc_new(VALUE klass, int is_lambda)
{
    VALUE procval = Qnil;
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th->cfp;
    rb_block_t *block;

    if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0 &&
	!RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {

	block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
    }
    else {
	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);

	if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0 &&
	    !RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {

	    block = GC_GUARDED_PTR_REF(cfp->lfp[0]);

	    if (block->proc) {
		return block->proc;
	    }

	    /* TODO: check more (cfp limit, called via cfunc, etc) */
	    while (cfp->dfp != block->dfp) {
		cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
	    }

	    if (is_lambda) {
		rb_warn("tried to create Proc object without a block");
	    }
	}
	else {
	    rb_raise(rb_eArgError,
		     "tried to create Proc object without a block");
	}
    }

    procval = block->proc;
    if (procval && RBASIC(procval)->klass == klass) {
	return procval;
    }

    procval = vm_make_proc(th, cfp, block, klass);

    if (is_lambda) {
	rb_proc_t *proc;
	GetProcPtr(procval, proc);
	proc->is_lambda = Qtrue;
    }
    return procval;
}
Exemple #23
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;
	}
    }
}
Exemple #24
0
static VALUE
proc_hash(VALUE self)
{
    int hash;
    rb_proc_t *proc;
    GetProcPtr(self, proc);
    hash = (long)proc->block.iseq;
    hash ^= (long)proc->envval;
    hash ^= (long)proc->block.lfp >> 16;
    return INT2FIX(hash);
}
Exemple #25
0
VALUE
rb_proc_call(VALUE self, VALUE args)
{
#if 0
    rb_proc_t *proc;
    GetProcPtr(self, proc);
    return vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			  RARRAY_LEN(args), RARRAY_PTR(args), 0);
#endif
    return proc_call(self, 0, RARRAY_LEN(args), RARRAY_PTR(args));
}
Exemple #26
0
static VALUE
proc_eq(VALUE self, VALUE other)
{
    if (self == other) {
	return Qtrue;
    }
    else {
	if (TYPE(other)          == T_DATA &&
	    RBASIC(other)->klass == rb_cProc &&
	    CLASS_OF(self)       == CLASS_OF(other)) {
	    rb_proc_t *p1, *p2;
	    GetProcPtr(self, p1);
	    GetProcPtr(other, p2);
	    if (p1->block.iseq == p2->block.iseq && p1->envval == p2->envval) {
		return Qtrue;
	    }
	}
    }
    return Qfalse;
}
Exemple #27
0
VALUE
rb_proc_new(
    VALUE (*func)(ANYARGS), /* VALUE yieldarg[, VALUE procarg] */
    VALUE val)
{
    rb_proc_t *proc;
    VALUE procval = rb_iterate((VALUE(*)(VALUE))mproc, 0, func, val);
    GetProcPtr(procval, proc);
    ((NODE*)proc->block.iseq)->u3.state = 1;
    return procval;
}
Exemple #28
0
static VALUE
proc_new(VALUE klass, int is_lambda)
{
    VALUE procval = Qnil;
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th->cfp;
    rb_block_t *block;

    if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0 &&
	!RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {

	block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
    }
    else {
	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);

	if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0 &&
	    !RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {

	    block = GC_GUARDED_PTR_REF(cfp->lfp[0]);

	    if (is_lambda) {
		rb_warn("tried to create Proc object without a block");
	    }
	}
	else {
	    rb_raise(rb_eArgError,
		     "tried to create Proc object without a block");
	}
    }

    procval = block->proc;

    if (procval) {
	if (RBASIC(procval)->klass == klass) {
	    return procval;
	}
	else {
	    VALUE newprocval = proc_dup(procval);
	    RBASIC(newprocval)->klass = klass;
	    return newprocval;
	}
    }

    procval = rb_vm_make_proc(th, block, klass);

    if (is_lambda) {
	rb_proc_t *proc;
	GetProcPtr(procval, proc);
	proc->is_lambda = Qtrue;
    }
    return procval;
}
Exemple #29
0
static rb_iseq_t *
get_proc_iseq(VALUE self)
{
    rb_proc_t *proc;
    rb_iseq_t *iseq;

    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    if (!RUBY_VM_NORMAL_ISEQ_P(iseq))
	return 0;
    return iseq;
}
static inline int
block_proc_is_lambda(const VALUE procval)
{
    rb_proc_t *proc;

    if (procval) {
	GetProcPtr(procval, proc);
	return proc->is_lambda;
    }
    else {
	return 0;
    }
}