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; } }
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; } }