示例#1
0
文件: cont.c 项目: 0x00evil/ruby
static VALUE
cont_capture(volatile int *stat)
{
    rb_context_t *cont;
    rb_thread_t *th = GET_THREAD();
    volatile VALUE contval;

    THREAD_MUST_BE_RUNNING(th);
    rb_vm_stack_to_heap(th);
    cont = cont_new(rb_cContinuation);
    contval = cont->self;

#ifdef CAPTURE_JUST_VALID_VM_STACK
    cont->vm_stack_slen = th->cfp->sp + th->mark_stack_len - th->stack;
    cont->vm_stack_clen = th->stack + th->stack_size - (VALUE*)th->cfp;
    cont->vm_stack = ALLOC_N(VALUE, cont->vm_stack_slen + cont->vm_stack_clen);
    MEMCPY(cont->vm_stack, th->stack, VALUE, cont->vm_stack_slen);
    MEMCPY(cont->vm_stack + cont->vm_stack_slen, (VALUE*)th->cfp, VALUE, cont->vm_stack_clen);
#else
    cont->vm_stack = ALLOC_N(VALUE, th->stack_size);
    MEMCPY(cont->vm_stack, th->stack, VALUE, th->stack_size);
#endif
    cont->saved_thread.stack = 0;

    cont_save_machine_stack(th, cont);

    /* backup ensure_list to array for search in another context */
    {
	rb_ensure_list_t *p;
	int size = 0;
	rb_ensure_entry_t *entry;
	for (p=th->ensure_list; p; p=p->next)
	    size++;
	entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1);
	for (p=th->ensure_list; p; p=p->next) {
	    if (!p->entry.marker)
		p->entry.marker = rb_ary_tmp_new(0); /* dummy object */
	    *entry++ = p->entry;
	}
	entry->marker = 0;
    }

    if (ruby_setjmp(cont->jmpbuf)) {
	volatile VALUE value;

	VAR_INITIALIZED(cont);
	value = cont->value;
	if (cont->argc == -1) rb_exc_raise(value);
	cont->value = Qnil;
	*stat = 1;
	return value;
    }
    else {
	*stat = 0;
	return contval;
    }
}
示例#2
0
文件: cont.c 项目: pascalt/captalog
static VALUE
cont_capture(volatile int *stat)
{
    rb_context_t *cont;
    rb_thread_t *th = GET_THREAD(), *sth;
    volatile VALUE contval;

    THREAD_MUST_BE_RUNNING(th);
    rb_vm_stack_to_heap(th);
    cont = cont_new(rb_cContinuation);
    contval = cont->self;
    sth = &cont->saved_thread;

#ifdef CAPTURE_JUST_VALID_VM_STACK
    cont->vm_stack_slen = th->cfp->sp + th->mark_stack_len - th->stack;
    cont->vm_stack_clen = th->stack + th->stack_size - (VALUE*)th->cfp;
    cont->vm_stack = ALLOC_N(VALUE, cont->vm_stack_slen + cont->vm_stack_clen);
    MEMCPY(cont->vm_stack, th->stack, VALUE, cont->vm_stack_slen);
    MEMCPY(cont->vm_stack + cont->vm_stack_slen, (VALUE*)th->cfp, VALUE, cont->vm_stack_clen);
#else
    cont->vm_stack = ALLOC_N(VALUE, th->stack_size);
    MEMCPY(cont->vm_stack, th->stack, VALUE, th->stack_size);
#endif
    sth->stack = 0;

    cont_save_machine_stack(th, cont);

    if (ruby_setjmp(cont->jmpbuf)) {
	VALUE value;

	value = cont->value;
	if (cont->argc == -1) rb_exc_raise(value);
	cont->value = Qnil;
	*stat = 1;
	return value;
    }
    else {
	*stat = 0;
	return cont->self;
    }
}