Beispiel #1
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;
}
Beispiel #2
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;
}