mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Use rb_execution_context_t instead of rb_thread_t
to represent execution context [Feature #14038] * vm_core.h (rb_thread_t): rb_thread_t::ec is now a pointer. There are many code using `th` to represent execution context (such as cfp, VM stack and so on). To access `ec`, they need to use `th->ec->...` (adding one indirection) so that we need to replace them by passing `ec` instead of `th`. * vm_core.h (GET_EC()): introduced to access current ec. Also remove `ruby_current_thread` global variable. * cont.c (rb_context_t): introduce rb_context_t::thread_ptr instead of rb_context_t::thread_value. * cont.c (ec_set_vm_stack): added to update vm_stack explicitly. * cont.c (ec_switch): added to switch ec explicitly. * cont.c (rb_fiber_close): added to terminate fibers explicitly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
07f04f468d
commit
837fd5e494
32 changed files with 743 additions and 576 deletions
4
.gdbinit
4
.gdbinit
|
@ -1119,8 +1119,8 @@ define rb_ps_thread
|
|||
set $ps_thread_th = (rb_thread_t*)$ps_thread->data
|
||||
printf "* #<Thread:%p rb_thread_t:%p native_thread:%p>\n", \
|
||||
$ps_thread, $ps_thread_th, $ps_thread_th->thread_id
|
||||
set $cfp = $ps_thread_th->ec.cfp
|
||||
set $cfpend = (rb_control_frame_t *)($ps_thread_th->ec.vm_stack + $ps_thread_th->ec.vm_stack_size)-1
|
||||
set $cfp = $ps_thread_th->ec->cfp
|
||||
set $cfpend = (rb_control_frame_t *)($ps_thread_th->ec->vm_stack + $ps_thread_th->ec.vm_stack_size)-1
|
||||
while $cfp < $cfpend
|
||||
if $cfp->iseq
|
||||
if !((VALUE)$cfp->iseq & RUBY_IMMEDIATE_MASK) && (((imemo_ifunc << RUBY_FL_USHIFT) | RUBY_T_IMEMO)==$cfp->iseq->flags & ((RUBY_IMEMO_MASK << RUBY_FL_USHIFT) | RUBY_T_MASK))
|
||||
|
|
|
@ -7604,7 +7604,7 @@ caller_location(VALUE *path, VALUE *realpath)
|
|||
{
|
||||
const rb_thread_t *const th = GET_THREAD();
|
||||
const rb_control_frame_t *const cfp =
|
||||
rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp) {
|
||||
int line = rb_vm_get_sourceline(cfp);
|
||||
|
|
375
cont.c
375
cont.c
|
@ -83,8 +83,8 @@ enum context_type {
|
|||
struct cont_saved_vm_stack {
|
||||
VALUE *ptr;
|
||||
#ifdef CAPTURE_JUST_VALID_VM_STACK
|
||||
size_t slen; /* length of stack (head of th->ec.vm_stack) */
|
||||
size_t clen; /* length of control frames (tail of th->ec.vm_stack) */
|
||||
size_t slen; /* length of stack (head of th->ec->vm_stack) */
|
||||
size_t clen; /* length of control frames (tail of th->ec->vm_stack) */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -110,7 +110,7 @@ typedef struct rb_context_struct {
|
|||
rb_jmpbuf_t jmpbuf;
|
||||
rb_ensure_entry_t *ensure_array;
|
||||
rb_ensure_list_t *ensure_list;
|
||||
VALUE thread_value;
|
||||
rb_thread_t *thread_ptr;
|
||||
} rb_context_t;
|
||||
|
||||
|
||||
|
@ -189,15 +189,62 @@ fiber_status_name(enum fiber_status s)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
fiber_verify(const rb_fiber_t *fib)
|
||||
{
|
||||
#if VM_CHECK_MODE > 0
|
||||
VM_ASSERT(fib->cont.saved_ec.fiber == fib);
|
||||
|
||||
switch (fib->status) {
|
||||
case FIBER_RESUMED:
|
||||
VM_ASSERT(fib->cont.saved_ec.vm_stack != NULL);
|
||||
break;
|
||||
case FIBER_SUSPENDED:
|
||||
VM_ASSERT(fib->cont.saved_ec.vm_stack != NULL);
|
||||
break;
|
||||
case FIBER_CREATED:
|
||||
case FIBER_TERMINATED:
|
||||
/* TODO */
|
||||
break;
|
||||
default:
|
||||
VM_UNREACHABLE(fiber_verify);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if VM_CHECK_MODE > 0
|
||||
void
|
||||
rb_ec_verify(const rb_execution_context_t *ec)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
fiber_status_set(const rb_fiber_t *fib, enum fiber_status s)
|
||||
{
|
||||
if (0) fprintf(stderr, "fib: %p, status: %s -> %s\n", fib, fiber_status_name(fib->status), fiber_status_name(s));
|
||||
VM_ASSERT(!FIBER_TERMINATED_P(fib));
|
||||
VM_ASSERT(fib->status != s);
|
||||
fiber_verify(fib);
|
||||
*((enum fiber_status *)&fib->status) = s;
|
||||
}
|
||||
|
||||
void
|
||||
ec_set_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t size)
|
||||
{
|
||||
*(VALUE **)(&ec->vm_stack) = stack;
|
||||
*(size_t *)(&ec->vm_stack_size) = size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ec_switch(rb_thread_t *th, rb_fiber_t *fib)
|
||||
{
|
||||
rb_execution_context_t *ec = &fib->cont.saved_ec;
|
||||
ruby_current_execution_context_ptr = th->ec = ec;
|
||||
VM_ASSERT(ec->fiber->cont.self == 0 || ec->vm_stack != NULL);
|
||||
}
|
||||
|
||||
static const rb_data_type_t cont_data_type, fiber_data_type;
|
||||
static VALUE rb_cContinuation;
|
||||
static VALUE rb_cFiber;
|
||||
|
@ -214,13 +261,13 @@ static VALUE rb_eFiberError;
|
|||
NOINLINE(static VALUE cont_capture(volatile int *volatile stat));
|
||||
|
||||
#define THREAD_MUST_BE_RUNNING(th) do { \
|
||||
if (!(th)->ec.tag) rb_raise(rb_eThreadError, "not running thread"); \
|
||||
if (!(th)->ec->tag) rb_raise(rb_eThreadError, "not running thread"); \
|
||||
} while (0)
|
||||
|
||||
static VALUE
|
||||
cont_thread_value(const rb_context_t *cont)
|
||||
{
|
||||
return cont->thread_value;
|
||||
return cont->thread_ptr->self;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -252,10 +299,9 @@ cont_mark(void *ptr)
|
|||
}
|
||||
else {
|
||||
/* fiber */
|
||||
const rb_thread_t *th = rb_thread_ptr(cont_thread_value(cont));
|
||||
const rb_fiber_t *fib = (rb_fiber_t*)cont;
|
||||
|
||||
if ((th->ec.fiber != fib) && !FIBER_TERMINATED_P(fib)) {
|
||||
if (!FIBER_TERMINATED_P(fib)) {
|
||||
rb_gc_mark_locations(cont->machine.stack,
|
||||
cont->machine.stack + cont->machine.stack_size);
|
||||
}
|
||||
|
@ -277,7 +323,8 @@ cont_free(void *ptr)
|
|||
rb_context_t *cont = ptr;
|
||||
|
||||
RUBY_FREE_ENTER("cont");
|
||||
RUBY_FREE_UNLESS_NULL(cont->saved_ec.vm_stack);
|
||||
ruby_xfree(cont->saved_ec.vm_stack);
|
||||
|
||||
#if FIBER_USE_NATIVE
|
||||
if (cont->type == CONTINUATION_CONTEXT) {
|
||||
/* cont */
|
||||
|
@ -287,22 +334,19 @@ cont_free(void *ptr)
|
|||
else {
|
||||
/* fiber */
|
||||
const rb_fiber_t *fib = (rb_fiber_t*)cont;
|
||||
const rb_thread_t *const th = GET_THREAD();
|
||||
#ifdef _WIN32
|
||||
if (th && th->ec.fiber != fib && cont->type != ROOT_FIBER_CONTEXT) {
|
||||
if (cont->type != ROOT_FIBER_CONTEXT) {
|
||||
/* don't delete root fiber handle */
|
||||
if (fib->fib_handle) {
|
||||
DeleteFiber(fib->fib_handle);
|
||||
}
|
||||
}
|
||||
#else /* not WIN32 */
|
||||
if (th && th->ec.fiber != fib) {
|
||||
if (fib->ss_sp) {
|
||||
if (cont->type == ROOT_FIBER_CONTEXT) {
|
||||
rb_bug("Illegal root fiber parameter");
|
||||
}
|
||||
munmap((void*)fib->ss_sp, fib->ss_size);
|
||||
if (fib->ss_sp != NULL) {
|
||||
if (cont->type == ROOT_FIBER_CONTEXT) {
|
||||
rb_bug("Illegal root fiber parameter");
|
||||
}
|
||||
munmap((void*)fib->ss_sp, fib->ss_size);
|
||||
}
|
||||
else {
|
||||
/* It may reached here when finalize */
|
||||
|
@ -352,32 +396,21 @@ cont_memsize(const void *ptr)
|
|||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
fiber_verify(const rb_fiber_t *fib)
|
||||
rb_thread_t *
|
||||
rb_fiberptr_thread_ptr(const rb_fiber_t *fib)
|
||||
{
|
||||
#if VM_CHECK_MODE > 0
|
||||
switch (fib->status) {
|
||||
case FIBER_RESUMED:
|
||||
VM_ASSERT(fib->cont.saved_ec.vm_stack == NULL);
|
||||
break;
|
||||
case FIBER_SUSPENDED:
|
||||
VM_ASSERT(fib->cont.saved_ec.vm_stack != NULL);
|
||||
break;
|
||||
case FIBER_CREATED:
|
||||
case FIBER_TERMINATED:
|
||||
/* TODO */
|
||||
break;
|
||||
default:
|
||||
VM_UNREACHABLE(fiber_verify);
|
||||
}
|
||||
#endif
|
||||
return fib->cont.thread_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
rb_fiber_mark_self(const rb_fiber_t *fib)
|
||||
{
|
||||
if (fib)
|
||||
if (fib->cont.self) {
|
||||
rb_gc_mark(fib->cont.self);
|
||||
}
|
||||
else {
|
||||
rb_execution_context_mark(&fib->cont.saved_ec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -387,7 +420,17 @@ fiber_mark(void *ptr)
|
|||
RUBY_MARK_ENTER("cont");
|
||||
fiber_verify(fib);
|
||||
rb_gc_mark(fib->first_proc);
|
||||
rb_fiber_mark_self(fib->prev);
|
||||
if (fib->prev) rb_fiber_mark_self(fib->prev);
|
||||
|
||||
#if !FIBER_USE_NATIVE
|
||||
if (fib->status == FIBER_TERMINATED) {
|
||||
/* FIBER_TERMINATED fiber should not mark machine stack */
|
||||
if (fib->cont.saved_ec.machine.stack_end != NULL) {
|
||||
fib->cont.saved_ec.machine.stack_end = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cont_mark(&fib->cont);
|
||||
RUBY_MARK_LEAVE("cont");
|
||||
}
|
||||
|
@ -397,8 +440,7 @@ fiber_free(void *ptr)
|
|||
{
|
||||
rb_fiber_t *fib = ptr;
|
||||
RUBY_FREE_ENTER("fiber");
|
||||
if (fib->cont.type != ROOT_FIBER_CONTEXT &&
|
||||
fib->cont.saved_ec.local_storage) {
|
||||
if (fib->cont.saved_ec.local_storage) {
|
||||
st_free_table(fib->cont.saved_ec.local_storage);
|
||||
}
|
||||
|
||||
|
@ -437,18 +479,18 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
|
|||
{
|
||||
size_t size;
|
||||
|
||||
SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
|
||||
SET_MACHINE_STACK_END(&th->ec->machine.stack_end);
|
||||
#ifdef __ia64
|
||||
th->machine.register_stack_end = rb_ia64_bsp();
|
||||
#endif
|
||||
|
||||
if (th->ec.machine.stack_start > th->ec.machine.stack_end) {
|
||||
size = cont->machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end;
|
||||
cont->machine.stack_src = th->ec.machine.stack_end;
|
||||
if (th->ec->machine.stack_start > th->ec->machine.stack_end) {
|
||||
size = cont->machine.stack_size = th->ec->machine.stack_start - th->ec->machine.stack_end;
|
||||
cont->machine.stack_src = th->ec->machine.stack_end;
|
||||
}
|
||||
else {
|
||||
size = cont->machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start;
|
||||
cont->machine.stack_src = th->ec.machine.stack_start;
|
||||
size = cont->machine.stack_size = th->ec->machine.stack_end - th->ec->machine.stack_start;
|
||||
cont->machine.stack_src = th->ec->machine.stack_start;
|
||||
}
|
||||
|
||||
if (cont->machine.stack) {
|
||||
|
@ -490,7 +532,7 @@ cont_save_thread(rb_context_t *cont, rb_thread_t *th)
|
|||
VM_ASSERT(th->status == THREAD_RUNNABLE);
|
||||
|
||||
/* save thread context */
|
||||
*sec = th->ec;
|
||||
*sec = *th->ec;
|
||||
|
||||
/* saved_thread->machine.stack_end should be NULL */
|
||||
/* because it may happen GC afterward */
|
||||
|
@ -507,7 +549,7 @@ cont_init(rb_context_t *cont, rb_thread_t *th)
|
|||
{
|
||||
/* save thread context */
|
||||
cont_save_thread(cont, th);
|
||||
cont->thread_value = th->self;
|
||||
cont->thread_ptr = th;
|
||||
cont->saved_ec.local_storage = NULL;
|
||||
cont->saved_ec.local_storage_recursive_hash = Qnil;
|
||||
cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil;
|
||||
|
@ -527,13 +569,40 @@ cont_new(VALUE klass)
|
|||
return cont;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
show_vm_stack(const rb_execution_context_t *ec)
|
||||
{
|
||||
VALUE *p = ec->vm_stack;
|
||||
while (p < ec->cfp->sp) {
|
||||
fprintf(stderr, "%3d ", (int)(p - ec->vm_stack));
|
||||
rb_obj_info_dump(*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
show_vm_pcs(const rb_control_frame_t *cfp,
|
||||
const rb_control_frame_t *end_of_cfp)
|
||||
{
|
||||
int i=0;
|
||||
while (cfp != end_of_cfp) {
|
||||
int pc = 0;
|
||||
if (cfp->iseq) {
|
||||
pc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||
}
|
||||
fprintf(stderr, "%2d pc: %d\n", i++, pc);
|
||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static VALUE
|
||||
cont_capture(volatile int *volatile stat)
|
||||
{
|
||||
rb_context_t *volatile cont;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
volatile VALUE contval;
|
||||
rb_execution_context_t *ec = &th->ec;
|
||||
const rb_execution_context_t *ec = th->ec;
|
||||
|
||||
THREAD_MUST_BE_RUNNING(th);
|
||||
rb_vm_stack_to_heap(th);
|
||||
|
@ -544,15 +613,18 @@ cont_capture(volatile int *volatile stat)
|
|||
cont->saved_vm_stack.slen = ec->cfp->sp - ec->vm_stack;
|
||||
cont->saved_vm_stack.clen = ec->vm_stack + ec->vm_stack_size - (VALUE*)ec->cfp;
|
||||
cont->saved_vm_stack.ptr = ALLOC_N(VALUE, cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
|
||||
MEMCPY(cont->saved_vm_stack.ptr, ec->vm_stack, VALUE, cont->saved_vm_stack.slen);
|
||||
MEMCPY(cont->saved_vm_stack.ptr,
|
||||
ec->vm_stack,
|
||||
VALUE, cont->saved_vm_stack.slen);
|
||||
MEMCPY(cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen,
|
||||
(VALUE*)ec->cfp, VALUE, cont->saved_vm_stack.clen);
|
||||
(VALUE*)ec->cfp,
|
||||
VALUE,
|
||||
cont->saved_vm_stack.clen);
|
||||
#else
|
||||
cont->saved_vm_stack.ptr = ALLOC_N(VALUE, ec->vm_stack_size);
|
||||
MEMCPY(cont->saved_vm_stack.ptr, ec->vm_stack, VALUE, ec->vm_stack_size);
|
||||
#endif
|
||||
cont->saved_ec.vm_stack = NULL;
|
||||
|
||||
ec_set_vm_stack(&cont->saved_ec, NULL, 0);
|
||||
cont_save_machine_stack(th, cont);
|
||||
|
||||
/* backup ensure_list to array for search in another context */
|
||||
|
@ -560,10 +632,10 @@ cont_capture(volatile int *volatile stat)
|
|||
rb_ensure_list_t *p;
|
||||
int size = 0;
|
||||
rb_ensure_entry_t *entry;
|
||||
for (p=th->ec.ensure_list; p; p=p->next)
|
||||
for (p=th->ec->ensure_list; p; p=p->next)
|
||||
size++;
|
||||
entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1);
|
||||
for (p=th->ec.ensure_list; p; p=p->next) {
|
||||
for (p=th->ec->ensure_list; p; p=p->next) {
|
||||
if (!p->entry.marker)
|
||||
p->entry.marker = rb_ary_tmp_new(0); /* dummy object */
|
||||
*entry++ = p->entry;
|
||||
|
@ -590,10 +662,8 @@ cont_capture(volatile int *volatile stat)
|
|||
static inline void
|
||||
fiber_restore_thread(rb_thread_t *th, rb_fiber_t *fib)
|
||||
{
|
||||
th->ec = fib->cont.saved_ec;
|
||||
fib->cont.saved_ec.vm_stack = NULL;
|
||||
|
||||
VM_ASSERT(th->ec.vm_stack != NULL);
|
||||
ec_switch(th, fib);
|
||||
VM_ASSERT(th->ec->fiber == fib);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -605,36 +675,44 @@ cont_restore_thread(rb_context_t *cont)
|
|||
if (cont->type == CONTINUATION_CONTEXT) {
|
||||
/* continuation */
|
||||
rb_execution_context_t *sec = &cont->saved_ec;
|
||||
const rb_fiber_t *fib;
|
||||
rb_fiber_t *fib = NULL;
|
||||
|
||||
fib = th->ec.fiber = sec->fiber;
|
||||
if (fib == NULL) fib = th->root_fiber;
|
||||
|
||||
if (fib && fib->cont.saved_ec.vm_stack) {
|
||||
th->ec.vm_stack_size = fib->cont.saved_ec.vm_stack_size;
|
||||
th->ec.vm_stack = fib->cont.saved_ec.vm_stack;
|
||||
if (sec->fiber != NULL) {
|
||||
fib = sec->fiber;
|
||||
}
|
||||
else if (th->root_fiber) {
|
||||
fib = th->root_fiber;
|
||||
}
|
||||
|
||||
if (fib && th->ec != &fib->cont.saved_ec) {
|
||||
ec_switch(th, fib);
|
||||
}
|
||||
|
||||
/* copy vm stack */
|
||||
#ifdef CAPTURE_JUST_VALID_VM_STACK
|
||||
MEMCPY(th->ec.vm_stack, cont->saved_vm_stack.ptr, VALUE, cont->saved_vm_stack.slen);
|
||||
MEMCPY(th->ec.vm_stack + sec->vm_stack_size - cont->saved_vm_stack.clen,
|
||||
cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen, VALUE, cont->saved_vm_stack.clen);
|
||||
MEMCPY(th->ec->vm_stack,
|
||||
cont->saved_vm_stack.ptr,
|
||||
VALUE, cont->saved_vm_stack.slen);
|
||||
MEMCPY(th->ec->vm_stack + th->ec->vm_stack_size - cont->saved_vm_stack.clen,
|
||||
cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen,
|
||||
VALUE, cont->saved_vm_stack.clen);
|
||||
#else
|
||||
MEMCPY(th->ec.vm_stack, cont->saved_vm_stack.ptr, VALUE, sec->vm_stack_size);
|
||||
MEMCPY(th->ec->vm_stack, cont->saved_vm_stack.ptr, VALUE, sec->vm_stack_size);
|
||||
#endif
|
||||
|
||||
/* other members of ec */
|
||||
th->ec.cfp = sec->cfp;
|
||||
th->ec.safe_level = sec->safe_level;
|
||||
th->ec.raised_flag = sec->raised_flag;
|
||||
th->ec.tag = sec->tag;
|
||||
th->ec.protect_tag = sec->protect_tag;
|
||||
th->ec.root_lep = sec->root_lep;
|
||||
th->ec.root_svar = sec->root_svar;
|
||||
th->ec.ensure_list = sec->ensure_list;
|
||||
th->ec.errinfo = sec->errinfo;
|
||||
th->ec.trace_arg = sec->trace_arg;
|
||||
|
||||
VM_ASSERT(th->ec.vm_stack != NULL);
|
||||
th->ec->cfp = sec->cfp;
|
||||
th->ec->safe_level = sec->safe_level;
|
||||
th->ec->raised_flag = sec->raised_flag;
|
||||
th->ec->tag = sec->tag;
|
||||
th->ec->protect_tag = sec->protect_tag;
|
||||
th->ec->root_lep = sec->root_lep;
|
||||
th->ec->root_svar = sec->root_svar;
|
||||
th->ec->ensure_list = sec->ensure_list;
|
||||
th->ec->errinfo = sec->errinfo;
|
||||
th->ec->trace_arg = sec->trace_arg;
|
||||
|
||||
VM_ASSERT(th->ec->vm_stack != NULL);
|
||||
}
|
||||
else {
|
||||
/* fiber */
|
||||
|
@ -651,7 +729,7 @@ fiber_set_stack_location(void)
|
|||
VALUE *ptr;
|
||||
|
||||
SET_MACHINE_STACK_END(&ptr);
|
||||
th->ec.machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE));
|
||||
th->ec->machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE));
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
|
@ -762,19 +840,19 @@ fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib)
|
|||
/* save oldfib's machine stack / TODO: is it needed? */
|
||||
if (!FIBER_TERMINATED_P(oldfib)) {
|
||||
STACK_GROW_DIR_DETECTION;
|
||||
SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
|
||||
SET_MACHINE_STACK_END(&th->ec->machine.stack_end);
|
||||
if (STACK_DIR_UPPER(0, 1)) {
|
||||
oldfib->cont.machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end;
|
||||
oldfib->cont.machine.stack = th->ec.machine.stack_end;
|
||||
oldfib->cont.machine.stack_size = th->ec->machine.stack_start - th->ec->machine.stack_end;
|
||||
oldfib->cont.machine.stack = th->ec->machine.stack_end;
|
||||
}
|
||||
else {
|
||||
oldfib->cont.machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start;
|
||||
oldfib->cont.machine.stack = th->ec.machine.stack_start;
|
||||
oldfib->cont.machine.stack_size = th->ec->machine.stack_end - th->ec->machine.stack_start;
|
||||
oldfib->cont.machine.stack = th->ec->machine.stack_start;
|
||||
}
|
||||
}
|
||||
|
||||
/* exchange machine_stack_start between oldfib and newfib */
|
||||
oldfib->cont.saved_ec.machine.stack_start = th->ec.machine.stack_start;
|
||||
oldfib->cont.saved_ec.machine.stack_start = th->ec->machine.stack_start;
|
||||
|
||||
/* oldfib->machine.stack_end should be NULL */
|
||||
oldfib->cont.saved_ec.machine.stack_end = NULL;
|
||||
|
@ -1128,15 +1206,15 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
|
|||
if (cont_thread_value(cont) != th->self) {
|
||||
rb_raise(rb_eRuntimeError, "continuation called across threads");
|
||||
}
|
||||
if (cont->saved_ec.protect_tag != th->ec.protect_tag) {
|
||||
if (cont->saved_ec.protect_tag != th->ec->protect_tag) {
|
||||
rb_raise(rb_eRuntimeError, "continuation called across stack rewinding barrier");
|
||||
}
|
||||
if (cont->saved_ec.fiber) {
|
||||
if (th->ec.fiber != cont->saved_ec.fiber) {
|
||||
if (th->ec->fiber != cont->saved_ec.fiber) {
|
||||
rb_raise(rb_eRuntimeError, "continuation called across fiber");
|
||||
}
|
||||
}
|
||||
rollback_ensure_stack(contval, th->ec.ensure_list, cont->ensure_array);
|
||||
rollback_ensure_stack(contval, th->ec->ensure_list, cont->ensure_array);
|
||||
|
||||
cont->argc = argc;
|
||||
cont->value = make_passing_arg(argc, argv);
|
||||
|
@ -1270,15 +1348,13 @@ fiber_init(VALUE fibval, VALUE proc)
|
|||
rb_context_t *cont = &fib->cont;
|
||||
rb_execution_context_t *sec = &cont->saved_ec;
|
||||
rb_thread_t *cth = GET_THREAD();
|
||||
size_t fib_stack_size = cth->vm->default_params.fiber_vm_stack_size / sizeof(VALUE);
|
||||
|
||||
/* initialize cont */
|
||||
cont->saved_vm_stack.ptr = NULL;
|
||||
ec_set_vm_stack(sec, NULL, 0);
|
||||
|
||||
sec->vm_stack = NULL;
|
||||
sec->vm_stack_size = 0;
|
||||
|
||||
sec->vm_stack_size = cth->vm->default_params.fiber_vm_stack_size / sizeof(VALUE);
|
||||
sec->vm_stack = ALLOC_N(VALUE, sec->vm_stack_size);
|
||||
ec_set_vm_stack(sec, ALLOC_N(VALUE, fib_stack_size), fib_stack_size);
|
||||
sec->cfp = (void *)(sec->vm_stack + sec->vm_stack_size);
|
||||
|
||||
rb_vm_push_frame(sec,
|
||||
|
@ -1324,11 +1400,12 @@ static void rb_fiber_terminate(rb_fiber_t *fib);
|
|||
void
|
||||
rb_fiber_start(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_fiber_t *fib = th->ec.fiber;
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
rb_fiber_t *fib = th->ec->fiber;
|
||||
rb_proc_t *proc;
|
||||
enum ruby_tag_type state;
|
||||
|
||||
VM_ASSERT(th->ec == ruby_current_execution_context_ptr);
|
||||
VM_ASSERT(FIBER_RESUMED_P(fib));
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
|
@ -1339,9 +1416,9 @@ rb_fiber_start(void)
|
|||
GetProcPtr(fib->first_proc, proc);
|
||||
argv = (argc = cont->argc) > 1 ? RARRAY_CONST_PTR(args) : &args;
|
||||
cont->value = Qnil;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec.root_lep = rb_vm_proc_local_ep(fib->first_proc);
|
||||
th->ec.root_svar = Qfalse;
|
||||
th->ec->errinfo = Qnil;
|
||||
th->ec->root_lep = rb_vm_proc_local_ep(fib->first_proc);
|
||||
th->ec->root_svar = Qfalse;
|
||||
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
|
||||
cont->value = rb_vm_invoke_proc(th, proc, argc, argv, VM_BLOCK_HANDLER_NONE);
|
||||
|
@ -1352,10 +1429,10 @@ rb_fiber_start(void)
|
|||
VM_ASSERT(FIBER_RESUMED_P(fib));
|
||||
|
||||
if (state == TAG_RAISE || state == TAG_FATAL) {
|
||||
rb_threadptr_pending_interrupt_enque(th, th->ec.errinfo);
|
||||
rb_threadptr_pending_interrupt_enque(th, th->ec->errinfo);
|
||||
}
|
||||
else {
|
||||
VALUE err = rb_vm_make_jump_tag_but_local_jump(state, th->ec.errinfo);
|
||||
VALUE err = rb_vm_make_jump_tag_but_local_jump(state, th->ec->errinfo);
|
||||
if (!NIL_P(err))
|
||||
rb_threadptr_pending_interrupt_enque(th, err);
|
||||
}
|
||||
|
@ -1369,30 +1446,54 @@ rb_fiber_start(void)
|
|||
static rb_fiber_t *
|
||||
root_fiber_alloc(rb_thread_t *th)
|
||||
{
|
||||
rb_fiber_t *fib;
|
||||
/* no need to allocate vm stack */
|
||||
fib = fiber_t_alloc(fiber_alloc(rb_cFiber));
|
||||
fib->cont.type = ROOT_FIBER_CONTEXT;
|
||||
VALUE fibval = fiber_alloc(rb_cFiber);
|
||||
rb_fiber_t *fib = th->ec->fiber;
|
||||
|
||||
VM_ASSERT(DATA_PTR(fibval) == NULL);
|
||||
VM_ASSERT(fib->cont.type == ROOT_FIBER_CONTEXT);
|
||||
VM_ASSERT(fib->status == FIBER_RESUMED);
|
||||
|
||||
th->root_fiber = fib;
|
||||
DATA_PTR(fibval) = fib;
|
||||
fib->cont.self = fibval;
|
||||
#if FIBER_USE_NATIVE
|
||||
#ifdef _WIN32
|
||||
fib->fib_handle = ConvertThreadToFiber(0);
|
||||
if (fib->fib_handle == 0) {
|
||||
fib->fib_handle = ConvertThreadToFiber(0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
fiber_status_set(fib, FIBER_RESUMED); /* skip CREATED */
|
||||
th->root_fiber = th->ec.fiber = fib;
|
||||
return fib;
|
||||
}
|
||||
|
||||
void
|
||||
rb_threadptr_root_fiber_setup(rb_thread_t *th)
|
||||
{
|
||||
rb_fiber_t *fib = ruby_mimmalloc(sizeof(rb_fiber_t));
|
||||
MEMZERO(fib, rb_fiber_t, 1);
|
||||
fib->cont.type = ROOT_FIBER_CONTEXT;
|
||||
fib->cont.saved_ec.fiber = fib;
|
||||
fib->cont.thread_ptr = th;
|
||||
fiber_status_set(fib, FIBER_RESUMED); /* skip CREATED */
|
||||
th->ec = &fib->cont.saved_ec;
|
||||
th->root_fiber = th->ec->fiber = fib;
|
||||
#if FIBER_USE_NATIVE
|
||||
#ifdef _WIN32
|
||||
if (fib->fib_handle == 0) {
|
||||
fib->fib_handle = ConvertThreadToFiber(0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline rb_fiber_t*
|
||||
fiber_current(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
if (th->ec.fiber == NULL) {
|
||||
rb_fiber_t *fib = root_fiber_alloc(th);
|
||||
/* Running thread object has stack management responsibility */
|
||||
fib->cont.saved_ec.vm_stack = NULL;
|
||||
if (th->ec->fiber->cont.self == 0) {
|
||||
root_fiber_alloc(th);
|
||||
}
|
||||
return th->ec.fiber;
|
||||
return th->ec->fiber;
|
||||
}
|
||||
|
||||
static inline rb_fiber_t*
|
||||
|
@ -1426,9 +1527,8 @@ fiber_store(rb_fiber_t *next_fib, rb_thread_t *th)
|
|||
{
|
||||
rb_fiber_t *fib;
|
||||
|
||||
if (th->ec.fiber != NULL) {
|
||||
fib = th->ec.fiber;
|
||||
cont_save_thread(&fib->cont, th);
|
||||
if (th->ec->fiber != NULL) {
|
||||
fib = th->ec->fiber;
|
||||
}
|
||||
else {
|
||||
/* create root fiber */
|
||||
|
@ -1475,14 +1575,14 @@ fiber_store(rb_fiber_t *next_fib, rb_thread_t *th)
|
|||
terminated_machine_stack.size = 0;
|
||||
}
|
||||
#endif /* not _WIN32 */
|
||||
fib = th->ec.fiber;
|
||||
fib = th->ec->fiber;
|
||||
if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value);
|
||||
return fib->cont.value;
|
||||
|
||||
#else /* FIBER_USE_NATIVE */
|
||||
if (ruby_setjmp(fib->cont.jmpbuf)) {
|
||||
/* restored */
|
||||
fib = th->ec.fiber;
|
||||
fib = th->ec->fiber;
|
||||
if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value);
|
||||
if (next_fib->cont.value == Qundef) {
|
||||
cont_restore_0(&next_fib->cont, &next_fib->cont.value);
|
||||
|
@ -1505,7 +1605,7 @@ fiber_switch(rb_fiber_t *fib, int argc, const VALUE *argv, int is_resume)
|
|||
rb_context_t *cont = &fib->cont;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
|
||||
if (th->ec.fiber == fib) {
|
||||
if (th->ec->fiber == fib) {
|
||||
/* ignore fiber context switch
|
||||
* because destination fiber is same as current fiber
|
||||
*/
|
||||
|
@ -1515,13 +1615,13 @@ fiber_switch(rb_fiber_t *fib, int argc, const VALUE *argv, int is_resume)
|
|||
if (cont_thread_value(cont) != th->self) {
|
||||
rb_raise(rb_eFiberError, "fiber called across threads");
|
||||
}
|
||||
else if (cont->saved_ec.protect_tag != th->ec.protect_tag) {
|
||||
else if (cont->saved_ec.protect_tag != th->ec->protect_tag) {
|
||||
rb_raise(rb_eFiberError, "fiber called across stack rewinding barrier");
|
||||
}
|
||||
else if (FIBER_TERMINATED_P(fib)) {
|
||||
value = rb_exc_new2(rb_eFiberError, "dead fiber called");
|
||||
|
||||
if (!FIBER_TERMINATED_P(th->ec.fiber)) {
|
||||
if (!FIBER_TERMINATED_P(th->ec->fiber)) {
|
||||
rb_exc_raise(value);
|
||||
VM_UNREACHABLE(fiber_switch);
|
||||
}
|
||||
|
@ -1535,7 +1635,7 @@ fiber_switch(rb_fiber_t *fib, int argc, const VALUE *argv, int is_resume)
|
|||
cont->argc = -1;
|
||||
cont->value = value;
|
||||
#if FIBER_USE_NATIVE
|
||||
fiber_setcontext(th->root_fiber, th->ec.fiber);
|
||||
fiber_setcontext(th->root_fiber, th->ec->fiber);
|
||||
#else
|
||||
cont_restore_0(cont, &value);
|
||||
#endif
|
||||
|
@ -1567,13 +1667,33 @@ rb_fiber_transfer(VALUE fibval, int argc, const VALUE *argv)
|
|||
return fiber_switch(fib, argc, argv, 0);
|
||||
}
|
||||
|
||||
void
|
||||
rb_fiber_close(rb_fiber_t *fib)
|
||||
{
|
||||
VALUE *vm_stack = fib->cont.saved_ec.vm_stack;
|
||||
fiber_status_set(fib, FIBER_TERMINATED);
|
||||
if (fib->cont.type == ROOT_FIBER_CONTEXT) {
|
||||
rb_thread_recycle_stack_release(vm_stack);
|
||||
}
|
||||
else {
|
||||
ruby_xfree(vm_stack);
|
||||
}
|
||||
ec_set_vm_stack(&fib->cont.saved_ec, NULL, 0);
|
||||
|
||||
#if !FIBER_USE_NATIVE
|
||||
/* should not mark machine stack any more */
|
||||
fib->cont.saved_ec.machine.stack_end = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
rb_fiber_terminate(rb_fiber_t *fib)
|
||||
{
|
||||
VALUE value = fib->cont.value;
|
||||
VM_ASSERT(FIBER_RESUMED_P(fib));
|
||||
|
||||
fiber_status_set(fib, FIBER_TERMINATED);
|
||||
rb_fiber_close(fib);
|
||||
|
||||
#if FIBER_USE_NATIVE && !defined(_WIN32)
|
||||
/* Ruby must not switch to other thread until storing terminated_machine_stack */
|
||||
terminated_machine_stack.ptr = fib->ss_sp;
|
||||
|
@ -1583,6 +1703,7 @@ rb_fiber_terminate(rb_fiber_t *fib)
|
|||
fib->cont.machine.stack = NULL;
|
||||
fib->cont.machine.stack_size = 0;
|
||||
#endif
|
||||
|
||||
fiber_switch(return_fiber(), 1, &value, 0);
|
||||
}
|
||||
|
||||
|
@ -1613,8 +1734,8 @@ rb_fiber_reset_root_local_storage(VALUE thval)
|
|||
{
|
||||
rb_thread_t *th = rb_thread_ptr(thval);
|
||||
|
||||
if (th->root_fiber && th->root_fiber != th->ec.fiber) {
|
||||
th->ec.local_storage = th->root_fiber->cont.saved_ec.local_storage;
|
||||
if (th->root_fiber && th->root_fiber != th->ec->fiber) {
|
||||
th->ec->local_storage = th->root_fiber->cont.saved_ec.local_storage;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1794,7 +1915,7 @@ Init_Cont(void)
|
|||
#else /* not WIN32 */
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
|
||||
SET_MACHINE_STACK_END(&th->ec->machine.stack_end);
|
||||
#endif
|
||||
|
||||
rb_cFiber = rb_define_class("Fiber", rb_cObject);
|
||||
|
|
4
error.c
4
error.c
|
@ -525,7 +525,7 @@ die(void)
|
|||
|
||||
abort();
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
void
|
||||
rb_bug(const char *fmt, ...)
|
||||
{
|
||||
|
@ -1300,7 +1300,7 @@ name_err_initialize(int argc, VALUE *argv, VALUE self)
|
|||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp =
|
||||
rb_vm_get_ruby_level_next_cfp(th,
|
||||
RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp));
|
||||
RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec->cfp));
|
||||
if (cfp) iseqw = rb_iseqw_new(cfp->iseq);
|
||||
}
|
||||
rb_ivar_set(self, id_iseq, iseqw);
|
||||
|
|
96
eval.c
96
eval.c
|
@ -129,7 +129,7 @@ static void
|
|||
ruby_finalize_1(void)
|
||||
{
|
||||
ruby_sig_finalize();
|
||||
GET_THREAD()->ec.errinfo = Qnil;
|
||||
GET_THREAD()->ec->errinfo = Qnil;
|
||||
rb_gc_call_finalizer_at_exit();
|
||||
}
|
||||
|
||||
|
@ -174,8 +174,8 @@ ruby_cleanup(volatile int ex)
|
|||
SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(th); });
|
||||
|
||||
step_0: step++;
|
||||
errs[1] = th->ec.errinfo;
|
||||
th->ec.safe_level = 0;
|
||||
errs[1] = th->ec->errinfo;
|
||||
th->ec->safe_level = 0;
|
||||
ruby_init_stack(&errs[STACK_UPPER(errs, 0, 1)]);
|
||||
|
||||
SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
|
||||
|
@ -184,7 +184,7 @@ ruby_cleanup(volatile int ex)
|
|||
/* protect from Thread#raise */
|
||||
th->status = THREAD_KILLED;
|
||||
|
||||
errs[0] = th->ec.errinfo;
|
||||
errs[0] = th->ec->errinfo;
|
||||
SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
|
||||
}
|
||||
else {
|
||||
|
@ -194,7 +194,7 @@ ruby_cleanup(volatile int ex)
|
|||
}
|
||||
if (ex == 0) ex = state;
|
||||
}
|
||||
th->ec.errinfo = errs[1];
|
||||
th->ec->errinfo = errs[1];
|
||||
sysex = error_handle(ex);
|
||||
|
||||
state = 0;
|
||||
|
@ -203,7 +203,7 @@ ruby_cleanup(volatile int ex)
|
|||
|
||||
if (!RTEST(err)) continue;
|
||||
|
||||
/* th->ec.errinfo contains a NODE while break'ing */
|
||||
/* th->ec->errinfo contains a NODE while break'ing */
|
||||
if (THROW_DATA_P(err)) continue;
|
||||
|
||||
if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
|
||||
|
@ -237,7 +237,7 @@ ruby_exec_internal(void *n)
|
|||
{
|
||||
volatile int state;
|
||||
rb_iseq_t *iseq = (rb_iseq_t *)n;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
|
||||
if (!n) return 0;
|
||||
|
||||
|
@ -478,7 +478,7 @@ exc_setup_message(rb_thread_t *th, VALUE mesg, VALUE *cause)
|
|||
int nocause = 0;
|
||||
|
||||
if (NIL_P(mesg)) {
|
||||
mesg = th->ec.errinfo;
|
||||
mesg = th->ec->errinfo;
|
||||
if (INTERNAL_EXCEPTION_P(mesg)) TH_JUMP_TAG(th, TAG_FATAL);
|
||||
nocause = 1;
|
||||
}
|
||||
|
@ -531,19 +531,19 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
|
|||
}
|
||||
|
||||
if (!NIL_P(mesg)) {
|
||||
th->ec.errinfo = mesg;
|
||||
th->ec->errinfo = mesg;
|
||||
}
|
||||
|
||||
if (RTEST(ruby_debug) && !NIL_P(e = th->ec.errinfo) &&
|
||||
if (RTEST(ruby_debug) && !NIL_P(e = th->ec->errinfo) &&
|
||||
!rb_obj_is_kind_of(e, rb_eSystemExit)) {
|
||||
enum ruby_tag_type state;
|
||||
|
||||
mesg = e;
|
||||
TH_PUSH_TAG(th);
|
||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
e = rb_obj_as_string(mesg);
|
||||
th->ec.errinfo = mesg;
|
||||
th->ec->errinfo = mesg;
|
||||
if (file && line) {
|
||||
e = rb_sprintf("Exception `%"PRIsVALUE"' at %s:%d - %"PRIsVALUE"\n",
|
||||
rb_obj_class(mesg), file, line, e);
|
||||
|
@ -559,8 +559,8 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
|
|||
warn_print_str(e);
|
||||
}
|
||||
TH_POP_TAG();
|
||||
if (state == TAG_FATAL && th->ec.errinfo == exception_error) {
|
||||
th->ec.errinfo = mesg;
|
||||
if (state == TAG_FATAL && th->ec->errinfo == exception_error) {
|
||||
th->ec->errinfo = mesg;
|
||||
}
|
||||
else if (state) {
|
||||
rb_threadptr_reset_raised(th);
|
||||
|
@ -570,14 +570,14 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
|
|||
|
||||
if (rb_threadptr_set_raised(th)) {
|
||||
fatal:
|
||||
th->ec.errinfo = exception_error;
|
||||
th->ec->errinfo = exception_error;
|
||||
rb_threadptr_reset_raised(th);
|
||||
TH_JUMP_TAG(th, TAG_FATAL);
|
||||
}
|
||||
|
||||
if (tag != TAG_FATAL) {
|
||||
RUBY_DTRACE_HOOK(RAISE, rb_obj_classname(th->ec.errinfo));
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->ec.cfp->self, 0, 0, 0, mesg);
|
||||
RUBY_DTRACE_HOOK(RAISE, rb_obj_classname(th->ec->errinfo));
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->ec->cfp->self, 0, 0, 0, mesg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -797,7 +797,7 @@ void
|
|||
rb_raise_jump(VALUE mesg, VALUE cause)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
const rb_control_frame_t *cfp = th->ec.cfp;
|
||||
const rb_control_frame_t *cfp = th->ec->cfp;
|
||||
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
|
||||
VALUE klass = me->owner;
|
||||
VALUE self = cfp->self;
|
||||
|
@ -835,7 +835,7 @@ int
|
|||
rb_block_given_p(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
if (rb_vm_frame_block_handler(th->ec.cfp) == VM_BLOCK_HANDLER_NONE) {
|
||||
if (rb_vm_frame_block_handler(th->ec->cfp) == VM_BLOCK_HANDLER_NONE) {
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
|
@ -896,10 +896,10 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
|
|||
VALUE (* r_proc) (ANYARGS), VALUE data2, ...)
|
||||
{
|
||||
enum ruby_tag_type state;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *volatile cfp = th->ec.cfp;
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
rb_control_frame_t *volatile cfp = th->ec->cfp;
|
||||
volatile VALUE result = Qfalse;
|
||||
volatile VALUE e_info = th->ec.errinfo;
|
||||
volatile VALUE e_info = th->ec->errinfo;
|
||||
va_list args;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
|
@ -911,7 +911,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
|
|||
/* escape from r_proc */
|
||||
if (state == TAG_RETRY) {
|
||||
state = 0;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
result = Qfalse;
|
||||
goto retry_entry;
|
||||
}
|
||||
|
@ -925,7 +925,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
|
|||
|
||||
va_init_list(args, data2);
|
||||
while ((eclass = va_arg(args, VALUE)) != 0) {
|
||||
if (rb_obj_is_kind_of(th->ec.errinfo, eclass)) {
|
||||
if (rb_obj_is_kind_of(th->ec->errinfo, eclass)) {
|
||||
handle = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -936,9 +936,9 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
|
|||
result = Qnil;
|
||||
state = 0;
|
||||
if (r_proc) {
|
||||
result = (*r_proc) (data2, th->ec.errinfo);
|
||||
result = (*r_proc) (data2, th->ec->errinfo);
|
||||
}
|
||||
th->ec.errinfo = e_info;
|
||||
th->ec->errinfo = e_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -993,15 +993,15 @@ rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate)
|
|||
{
|
||||
volatile VALUE result = Qnil;
|
||||
volatile enum ruby_tag_type state;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *volatile cfp = th->ec.cfp;
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
rb_control_frame_t *volatile cfp = th->ec->cfp;
|
||||
struct rb_vm_protect_tag protect_tag;
|
||||
rb_jmpbuf_t org_jmpbuf;
|
||||
|
||||
protect_tag.prev = th->ec.protect_tag;
|
||||
protect_tag.prev = th->ec->protect_tag;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
th->ec.protect_tag = &protect_tag;
|
||||
th->ec->protect_tag = &protect_tag;
|
||||
MEMCPY(&org_jmpbuf, &(th)->root_jmpbuf, rb_jmpbuf_t, 1);
|
||||
if ((state = TH_EXEC_TAG()) == TAG_NONE) {
|
||||
SAVE_ROOT_JMPBUF(th, result = (*proc) (data));
|
||||
|
@ -1010,7 +1010,7 @@ rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate)
|
|||
rb_vm_rewind_cfp(th, cfp);
|
||||
}
|
||||
MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
|
||||
th->ec.protect_tag = protect_tag.prev;
|
||||
th->ec->protect_tag = protect_tag.prev;
|
||||
TH_POP_TAG();
|
||||
|
||||
if (pstate != NULL) *pstate = state;
|
||||
|
@ -1037,25 +1037,25 @@ rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE
|
|||
int state;
|
||||
volatile VALUE result = Qnil;
|
||||
VALUE errinfo;
|
||||
rb_thread_t *const th = GET_THREAD();
|
||||
rb_thread_t *const volatile th = GET_THREAD();
|
||||
rb_ensure_list_t ensure_list;
|
||||
ensure_list.entry.marker = 0;
|
||||
ensure_list.entry.e_proc = e_proc;
|
||||
ensure_list.entry.data2 = data2;
|
||||
ensure_list.next = th->ec.ensure_list;
|
||||
th->ec.ensure_list = &ensure_list;
|
||||
ensure_list.next = th->ec->ensure_list;
|
||||
th->ec->ensure_list = &ensure_list;
|
||||
TH_PUSH_TAG(th);
|
||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||
result = (*b_proc) (data1);
|
||||
}
|
||||
TH_POP_TAG();
|
||||
errinfo = th->ec.errinfo;
|
||||
errinfo = th->ec->errinfo;
|
||||
if (!NIL_P(errinfo) && !RB_TYPE_P(errinfo, T_OBJECT)) {
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
}
|
||||
th->ec.ensure_list=ensure_list.next;
|
||||
th->ec->ensure_list=ensure_list.next;
|
||||
(*ensure_list.entry.e_proc)(ensure_list.entry.data2);
|
||||
th->ec.errinfo = errinfo;
|
||||
th->ec->errinfo = errinfo;
|
||||
if (state)
|
||||
TH_JUMP_TAG(th, state);
|
||||
return result;
|
||||
|
@ -1102,7 +1102,7 @@ frame_called_id(rb_control_frame_t *cfp)
|
|||
ID
|
||||
rb_frame_this_func(void)
|
||||
{
|
||||
return frame_func_id(GET_THREAD()->ec.cfp);
|
||||
return frame_func_id(GET_THREAD()->ec->cfp);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1119,15 +1119,15 @@ rb_frame_this_func(void)
|
|||
ID
|
||||
rb_frame_callee(void)
|
||||
{
|
||||
return frame_called_id(GET_THREAD()->ec.cfp);
|
||||
return frame_called_id(GET_THREAD()->ec->cfp);
|
||||
}
|
||||
|
||||
static rb_control_frame_t *
|
||||
previous_frame(rb_thread_t *th)
|
||||
{
|
||||
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp);
|
||||
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec->cfp);
|
||||
/* check if prev_cfp can be accessible */
|
||||
if ((void *)(th->ec.vm_stack + th->ec.vm_stack_size) == (void *)(prev_cfp)) {
|
||||
if ((void *)(th->ec->vm_stack + th->ec->vm_stack_size) == (void *)(prev_cfp)) {
|
||||
return 0;
|
||||
}
|
||||
return prev_cfp;
|
||||
|
@ -1159,7 +1159,7 @@ ID
|
|||
rb_frame_last_func(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
ID mid;
|
||||
|
||||
while (!(mid = frame_func_id(cfp)) &&
|
||||
|
@ -1439,7 +1439,7 @@ rb_mod_refine(VALUE module, VALUE klass)
|
|||
id_refined_class, id_defined_at;
|
||||
VALUE refinements, activated_refinements;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
||||
|
||||
if (block_handler == VM_BLOCK_HANDLER_NONE) {
|
||||
rb_raise(rb_eArgError, "no block given");
|
||||
|
@ -1724,7 +1724,7 @@ top_using(VALUE self, VALUE module)
|
|||
static const VALUE *
|
||||
errinfo_place(rb_thread_t *th)
|
||||
{
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
|
||||
|
||||
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
|
||||
|
@ -1751,7 +1751,7 @@ get_thread_errinfo(rb_thread_t *th)
|
|||
return *ptr;
|
||||
}
|
||||
else {
|
||||
return th->ec.errinfo;
|
||||
return th->ec->errinfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1777,7 +1777,7 @@ VALUE
|
|||
rb_errinfo(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
return th->ec.errinfo;
|
||||
return th->ec->errinfo;
|
||||
}
|
||||
|
||||
/*! Sets the current exception (\c $!) to the given value
|
||||
|
@ -1794,7 +1794,7 @@ rb_set_errinfo(VALUE err)
|
|||
if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
|
||||
rb_raise(rb_eTypeError, "assigning non-exception to $!");
|
||||
}
|
||||
GET_THREAD()->ec.errinfo = err;
|
||||
GET_THREAD()->ec->errinfo = err;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
|
@ -69,7 +69,7 @@ set_backtrace(VALUE info, VALUE bt)
|
|||
static void
|
||||
error_print(rb_thread_t *th)
|
||||
{
|
||||
rb_threadptr_error_print(th, th->ec.errinfo);
|
||||
rb_threadptr_error_print(th, th->ec->errinfo);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -167,7 +167,7 @@ void
|
|||
rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo)
|
||||
{
|
||||
volatile VALUE errat = Qundef;
|
||||
volatile int raised_flag = th->ec.raised_flag;
|
||||
volatile int raised_flag = th->ec->raised_flag;
|
||||
volatile VALUE eclass = Qundef, emesg = Qundef;
|
||||
|
||||
if (NIL_P(errinfo))
|
||||
|
@ -202,7 +202,7 @@ rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo)
|
|||
}
|
||||
error:
|
||||
TH_POP_TAG();
|
||||
th->ec.errinfo = errinfo;
|
||||
th->ec->errinfo = errinfo;
|
||||
rb_thread_raised_set(th, raised_flag);
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,7 @@ error_handle(int ex)
|
|||
warn_print("unexpected throw\n");
|
||||
break;
|
||||
case TAG_RAISE: {
|
||||
VALUE errinfo = th->ec.errinfo;
|
||||
VALUE errinfo = th->ec->errinfo;
|
||||
if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
|
||||
status = sysexit_status(errinfo);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ vm_passed_block_handler_set(rb_thread_t *th, VALUE block_handler)
|
|||
static inline void
|
||||
pass_passed_block_handler(rb_thread_t *th)
|
||||
{
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
||||
vm_block_handler_verify(block_handler);
|
||||
vm_passed_block_handler_set(th, block_handler);
|
||||
VM_ENV_FLAGS_SET(th->ec.cfp->ep, VM_FRAME_FLAG_PASSED);
|
||||
VM_ENV_FLAGS_SET(th->ec->cfp->ep, VM_FRAME_FLAG_PASSED);
|
||||
}
|
||||
|
||||
#define PASS_PASSED_BLOCK_HANDLER_TH(th) pass_passed_block_handler(th)
|
||||
|
@ -133,16 +133,16 @@ LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
|
|||
struct rb_vm_tag _tag; \
|
||||
_tag.state = TAG_NONE; \
|
||||
_tag.tag = Qundef; \
|
||||
_tag.prev = _th->ec.tag;
|
||||
_tag.prev = _th->ec->tag;
|
||||
|
||||
#define TH_POP_TAG() \
|
||||
_th->ec.tag = _tag.prev; \
|
||||
_th->ec->tag = _tag.prev; \
|
||||
} while (0)
|
||||
|
||||
#define TH_TMPPOP_TAG() \
|
||||
_th->ec.tag = _tag.prev
|
||||
_th->ec->tag = _tag.prev
|
||||
|
||||
#define TH_REPUSH_TAG() (void)(_th->ec.tag = &_tag)
|
||||
#define TH_REPUSH_TAG() (void)(_th->ec->tag = &_tag)
|
||||
|
||||
#define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
|
||||
#define POP_TAG() TH_POP_TAG()
|
||||
|
@ -174,12 +174,12 @@ LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
|
|||
#undef RB_OBJ_WRITE
|
||||
#define RB_OBJ_WRITE(a, slot, b) UNALIGNED_MEMBER_ACCESS(rb_obj_write((VALUE)(a), (VALUE *)(slot), (VALUE)(b), __FILE__, __LINE__))
|
||||
|
||||
/* clear th->ec.tag->state, and return the value */
|
||||
/* clear th->ec->tag->state, and return the value */
|
||||
static inline int
|
||||
rb_threadptr_tag_state(rb_thread_t *th)
|
||||
{
|
||||
enum ruby_tag_type state = th->ec.tag->state;
|
||||
th->ec.tag->state = TAG_NONE;
|
||||
enum ruby_tag_type state = th->ec->tag->state;
|
||||
th->ec->tag->state = TAG_NONE;
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -187,8 +187,8 @@ NORETURN(static inline void rb_threadptr_tag_jump(rb_thread_t *, enum ruby_tag_t
|
|||
static inline void
|
||||
rb_threadptr_tag_jump(rb_thread_t *th, enum ruby_tag_type st)
|
||||
{
|
||||
th->ec.tag->state = st;
|
||||
ruby_longjmp(th->ec.tag->buf, 1);
|
||||
th->ec->tag->state = st;
|
||||
ruby_longjmp(th->ec->tag->buf, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -282,10 +282,10 @@ enum {
|
|||
};
|
||||
int rb_threadptr_set_raised(rb_thread_t *th);
|
||||
int rb_threadptr_reset_raised(rb_thread_t *th);
|
||||
#define rb_thread_raised_set(th, f) ((th)->ec.raised_flag |= (f))
|
||||
#define rb_thread_raised_reset(th, f) ((th)->ec.raised_flag &= ~(f))
|
||||
#define rb_thread_raised_p(th, f) (((th)->ec.raised_flag & (f)) != 0)
|
||||
#define rb_thread_raised_clear(th) ((th)->ec.raised_flag = 0)
|
||||
#define rb_thread_raised_set(th, f) ((th)->ec->raised_flag |= (f))
|
||||
#define rb_thread_raised_reset(th, f) ((th)->ec->raised_flag &= ~(f))
|
||||
#define rb_thread_raised_p(th, f) (((th)->ec->raised_flag & (f)) != 0)
|
||||
#define rb_thread_raised_clear(th) ((th)->ec->raised_flag = 0)
|
||||
int rb_threadptr_stack_check(rb_thread_t *th);
|
||||
|
||||
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
|
||||
|
|
10
eval_jump.c
10
eval_jump.c
|
@ -116,26 +116,26 @@ rb_exec_end_proc(void)
|
|||
enum ruby_tag_type state;
|
||||
volatile int safe = rb_safe_level();
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
volatile VALUE errinfo = th->ec.errinfo;
|
||||
volatile VALUE errinfo = th->ec->errinfo;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||
again:
|
||||
exec_end_procs_chain(&ephemeral_end_procs, &th->ec.errinfo);
|
||||
exec_end_procs_chain(&end_procs, &th->ec.errinfo);
|
||||
exec_end_procs_chain(&ephemeral_end_procs, &th->ec->errinfo);
|
||||
exec_end_procs_chain(&end_procs, &th->ec->errinfo);
|
||||
}
|
||||
else {
|
||||
VAR_INITIALIZED(th);
|
||||
TH_TMPPOP_TAG();
|
||||
error_handle(state);
|
||||
if (!NIL_P(th->ec.errinfo)) errinfo = th->ec.errinfo;
|
||||
if (!NIL_P(th->ec->errinfo)) errinfo = th->ec->errinfo;
|
||||
TH_REPUSH_TAG();
|
||||
goto again;
|
||||
}
|
||||
TH_POP_TAG();
|
||||
|
||||
rb_set_safe_level_force(safe);
|
||||
th->ec.errinfo = errinfo;
|
||||
th->ec->errinfo = errinfo;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
18
gc.c
18
gc.c
|
@ -1812,7 +1812,7 @@ rb_objspace_set_event_hook(const rb_event_flag_t event)
|
|||
static void
|
||||
gc_event_hook_body(rb_thread_t *th, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
|
||||
{
|
||||
EXEC_EVENT_HOOK(th, event, th->ec.cfp->self, 0, 0, 0, data);
|
||||
EXEC_EVENT_HOOK(th, event, th->ec->cfp->self, 0, 0, 0, data);
|
||||
}
|
||||
|
||||
#define gc_event_hook_available_p(objspace) ((objspace)->flags.has_hook)
|
||||
|
@ -2784,16 +2784,16 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
|||
long finished;
|
||||
int safe;
|
||||
} saved;
|
||||
rb_thread_t *const th = GET_THREAD();
|
||||
rb_thread_t *const volatile th = GET_THREAD();
|
||||
#define RESTORE_FINALIZER() (\
|
||||
th->ec.cfp = saved.cfp, \
|
||||
th->ec->cfp = saved.cfp, \
|
||||
rb_set_safe_level_force(saved.safe), \
|
||||
rb_set_errinfo(saved.errinfo))
|
||||
|
||||
saved.safe = rb_safe_level();
|
||||
saved.errinfo = rb_errinfo();
|
||||
saved.objid = nonspecial_obj_id(obj);
|
||||
saved.cfp = th->ec.cfp;
|
||||
saved.cfp = th->ec->cfp;
|
||||
saved.finished = 0;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
|
@ -4001,7 +4001,7 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
|
|||
size_t
|
||||
ruby_stack_length(VALUE **p)
|
||||
{
|
||||
rb_execution_context_t *ec = &GET_THREAD()->ec;
|
||||
rb_execution_context_t *ec = GET_THREAD()->ec;
|
||||
SET_STACK_END;
|
||||
if (p) *p = STACK_UPPER(STACK_END, STACK_START, STACK_END);
|
||||
return STACK_LENGTH;
|
||||
|
@ -4019,7 +4019,7 @@ ruby_stack_length(VALUE **p)
|
|||
static int
|
||||
stack_check(rb_thread_t *th, int water_mark)
|
||||
{
|
||||
rb_execution_context_t *ec = &th->ec;
|
||||
rb_execution_context_t *ec = th->ec;
|
||||
int ret;
|
||||
SET_STACK_END;
|
||||
ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
|
||||
|
@ -4784,7 +4784,7 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
|
|||
{
|
||||
struct gc_list *list;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_execution_context_t *ec = &th->ec;
|
||||
rb_execution_context_t *ec = th->ec;
|
||||
|
||||
#if PRINT_ROOT_TICKS
|
||||
tick_t start_tick = tick();
|
||||
|
@ -4831,7 +4831,7 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
|
|||
mark_tbl(objspace, finalizer_table);
|
||||
|
||||
MARK_CHECKPOINT("machine_context");
|
||||
mark_current_machine_context(objspace, &th->ec);
|
||||
mark_current_machine_context(objspace, th->ec);
|
||||
|
||||
MARK_CHECKPOINT("encodings");
|
||||
rb_gc_mark_encodings();
|
||||
|
@ -7712,7 +7712,7 @@ rb_memerror(void)
|
|||
rb_thread_raised_set(th, RAISED_NOMEMORY);
|
||||
exc = ruby_vm_special_exception_copy(exc);
|
||||
}
|
||||
th->ec.errinfo = exc;
|
||||
th->ec->errinfo = exc;
|
||||
TH_JUMP_TAG(th, TAG_RAISE);
|
||||
}
|
||||
|
||||
|
|
|
@ -1678,8 +1678,8 @@ opt_call_c_function
|
|||
reg_cfp = (funcptr)(th, reg_cfp);
|
||||
|
||||
if (reg_cfp == 0) {
|
||||
VALUE err = th->ec.errinfo;
|
||||
th->ec.errinfo = Qnil;
|
||||
VALUE err = th->ec->errinfo;
|
||||
th->ec->errinfo = Qnil;
|
||||
THROW_EXCEPTION(err);
|
||||
}
|
||||
|
||||
|
|
|
@ -1721,7 +1721,6 @@ VALUE rb_uninterruptible(VALUE (*b_proc)(ANYARGS), VALUE data);
|
|||
VALUE rb_mutex_owned_p(VALUE self);
|
||||
|
||||
/* thread_pthread.c, thread_win32.c */
|
||||
void Init_native_thread(void);
|
||||
int rb_divert_reserved_fd(int fd);
|
||||
|
||||
/* transcode.c */
|
||||
|
|
4
iseq.c
4
iseq.c
|
@ -663,7 +663,7 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, c
|
|||
}
|
||||
|
||||
if (!node) {
|
||||
rb_exc_raise(th->ec.errinfo);
|
||||
rb_exc_raise(th->ec->errinfo);
|
||||
}
|
||||
else {
|
||||
INITIALIZED VALUE label = parent ?
|
||||
|
@ -870,7 +870,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
|
|||
parser = rb_parser_new();
|
||||
rb_parser_set_context(parser, NULL, FALSE);
|
||||
node = rb_parser_compile_file_path(parser, file, f, NUM2INT(line));
|
||||
if (!node) exc = GET_THREAD()->ec.errinfo;
|
||||
if (!node) exc = GET_THREAD()->ec->errinfo;
|
||||
|
||||
rb_io_close(f);
|
||||
if (!node) rb_exc_raise(exc);
|
||||
|
|
12
load.c
12
load.c
|
@ -587,7 +587,7 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
|
|||
rb_thread_t *volatile th0 = th;
|
||||
#endif
|
||||
|
||||
th->ec.errinfo = Qnil; /* ensure */
|
||||
th->ec->errinfo = Qnil; /* ensure */
|
||||
|
||||
if (!wrap) {
|
||||
th->top_wrapper = 0;
|
||||
|
@ -631,11 +631,11 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
|
|||
* rb_iseq_load_iseq case */
|
||||
VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
|
||||
if (NIL_P(exc)) return state;
|
||||
th->ec.errinfo = exc;
|
||||
th->ec->errinfo = exc;
|
||||
return TAG_RAISE;
|
||||
}
|
||||
|
||||
if (!NIL_P(th->ec.errinfo)) {
|
||||
if (!NIL_P(th->ec->errinfo)) {
|
||||
/* exception during load */
|
||||
return TAG_RAISE;
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ rb_load_internal(VALUE fname, int wrap)
|
|||
rb_thread_t *curr_th = GET_THREAD();
|
||||
int state = rb_load_internal0(curr_th, fname, wrap);
|
||||
if (state) {
|
||||
if (state == TAG_RAISE) rb_exc_raise(curr_th->ec.errinfo);
|
||||
if (state == TAG_RAISE) rb_exc_raise(curr_th->ec->errinfo);
|
||||
TH_JUMP_TAG(curr_th, state);
|
||||
}
|
||||
}
|
||||
|
@ -963,7 +963,7 @@ rb_require_internal(VALUE fname, int safe)
|
|||
{
|
||||
volatile int result = -1;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
volatile VALUE errinfo = th->ec.errinfo;
|
||||
volatile VALUE errinfo = th->ec->errinfo;
|
||||
enum ruby_tag_type state;
|
||||
struct {
|
||||
int safe;
|
||||
|
@ -1024,7 +1024,7 @@ rb_require_internal(VALUE fname, int safe)
|
|||
return state;
|
||||
}
|
||||
|
||||
th->ec.errinfo = errinfo;
|
||||
th->ec->errinfo = errinfo;
|
||||
|
||||
RUBY_DTRACE_HOOK(REQUIRE_RETURN, RSTRING_PTR(fname));
|
||||
|
||||
|
|
10
proc.c
10
proc.c
|
@ -333,7 +333,7 @@ VALUE
|
|||
rb_binding_new(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
return rb_vm_make_binding(th, th->ec.cfp);
|
||||
return rb_vm_make_binding(th, th->ec->cfp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -698,7 +698,7 @@ proc_new(VALUE klass, int8_t is_lambda)
|
|||
{
|
||||
VALUE procval;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
VALUE block_handler;
|
||||
|
||||
if ((block_handler = rb_vm_frame_block_handler(cfp)) == VM_BLOCK_HANDLER_NONE) {
|
||||
|
@ -1049,7 +1049,7 @@ rb_block_arity(void)
|
|||
{
|
||||
int min, max;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
VALUE block_handler = rb_vm_frame_block_handler(cfp);
|
||||
struct rb_block block;
|
||||
|
||||
|
@ -1082,7 +1082,7 @@ int
|
|||
rb_block_min_max_arity(int *max)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
VALUE block_handler = rb_vm_frame_block_handler(cfp);
|
||||
struct rb_block block;
|
||||
|
||||
|
@ -1911,7 +1911,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
|
|||
body = rb_block_lambda();
|
||||
#else
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
||||
if (block_handler == VM_BLOCK_HANDLER_NONE) rb_raise(rb_eArgError, proc_without_block);
|
||||
|
||||
switch (vm_block_handler_type(block_handler)) {
|
||||
|
|
|
@ -3765,7 +3765,7 @@ rb_f_exit_bang(int argc, VALUE *argv, VALUE obj)
|
|||
void
|
||||
rb_exit(int status)
|
||||
{
|
||||
if (GET_THREAD()->ec.tag) {
|
||||
if (GET_THREAD()->ec->tag) {
|
||||
VALUE args[2];
|
||||
|
||||
args[0] = INT2NUM(status);
|
||||
|
@ -3851,7 +3851,7 @@ rb_f_abort(int argc, const VALUE *argv)
|
|||
rb_check_arity(argc, 0, 1);
|
||||
if (argc == 0) {
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE errinfo = th->ec.errinfo;
|
||||
VALUE errinfo = th->ec->errinfo;
|
||||
if (!NIL_P(errinfo)) {
|
||||
rb_threadptr_error_print(th, errinfo);
|
||||
}
|
||||
|
|
12
safe.c
12
safe.c
|
@ -34,13 +34,13 @@ ruby_safe_level_2_warning(void)
|
|||
int
|
||||
rb_safe_level(void)
|
||||
{
|
||||
return GET_THREAD()->ec.safe_level;
|
||||
return GET_THREAD()->ec->safe_level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_set_safe_level_force(int safe)
|
||||
{
|
||||
GET_THREAD()->ec.safe_level = safe;
|
||||
GET_THREAD()->ec->safe_level = safe;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -48,11 +48,11 @@ rb_set_safe_level(int level)
|
|||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
|
||||
if (level > th->ec.safe_level) {
|
||||
if (level > th->ec->safe_level) {
|
||||
if (level > SAFE_LEVEL_MAX) {
|
||||
rb_raise(rb_eArgError, "$SAFE=2 to 4 are obsolete");
|
||||
}
|
||||
th->ec.safe_level = level;
|
||||
th->ec->safe_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ static void
|
|||
safe_setter(VALUE val)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
int current_level = th->ec.safe_level;
|
||||
int current_level = th->ec->safe_level;
|
||||
int level = NUM2INT(val);
|
||||
|
||||
if (level == current_level) {
|
||||
|
@ -84,7 +84,7 @@ safe_setter(VALUE val)
|
|||
/* block parameters */
|
||||
rb_vm_stack_to_heap(th);
|
||||
|
||||
th->ec.safe_level = level;
|
||||
th->ec->safe_level = level;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
8
signal.c
8
signal.c
|
@ -838,13 +838,13 @@ check_stack_overflow(int sig, const uintptr_t addr, const ucontext_t *ctx)
|
|||
* the fault page can be the next. */
|
||||
if (sp_page == fault_page || sp_page == fault_page + 1 ||
|
||||
sp_page <= fault_page && fault_page <= bp_page) {
|
||||
rb_thread_t *th = ruby_current_thread;
|
||||
rb_thread_t *th = ruby_current_thread();
|
||||
int crit = FALSE;
|
||||
if ((uintptr_t)th->ec.tag->buf / pagesize <= fault_page + 1) {
|
||||
if ((uintptr_t)th->ec->tag->buf / pagesize <= fault_page + 1) {
|
||||
/* drop the last tag if it is close to the fault,
|
||||
* otherwise it can cause stack overflow again at the same
|
||||
* place. */
|
||||
th->ec.tag = th->ec.tag->prev;
|
||||
th->ec->tag = th->ec->tag->prev;
|
||||
crit = TRUE;
|
||||
}
|
||||
reset_sigmask(sig);
|
||||
|
@ -856,7 +856,7 @@ static void
|
|||
check_stack_overflow(int sig, const void *addr)
|
||||
{
|
||||
int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
|
||||
rb_thread_t *th = ruby_current_thread;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
if (ruby_stack_overflowed_p(th, addr)) {
|
||||
reset_sigmask(sig);
|
||||
rb_threadptr_stack_overflow(th, FALSE);
|
||||
|
|
79
thread.c
79
thread.c
|
@ -139,8 +139,8 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio
|
|||
do { \
|
||||
FLUSH_REGISTER_WINDOWS; \
|
||||
RB_GC_SAVE_MACHINE_REGISTER_STACK(th); \
|
||||
setjmp((th)->ec.machine.regs); \
|
||||
SET_MACHINE_STACK_END(&(th)->ec.machine.stack_end); \
|
||||
setjmp((th)->ec->machine.regs); \
|
||||
SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); \
|
||||
} while (0)
|
||||
|
||||
#define GVL_UNLOCK_BEGIN() do { \
|
||||
|
@ -526,9 +526,9 @@ thread_cleanup_func_before_exec(void *th_ptr)
|
|||
{
|
||||
rb_thread_t *th = th_ptr;
|
||||
th->status = THREAD_KILLED;
|
||||
th->ec.machine.stack_start = th->ec.machine.stack_end = NULL;
|
||||
th->ec->machine.stack_start = th->ec->machine.stack_end = NULL;
|
||||
#ifdef __ia64
|
||||
th->ec.machine.register_stack_start = th->ec.machine.register_stack_end = NULL;
|
||||
th->ec->machine.register_stack_start = th->ec->machine.register_stack_end = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -581,9 +581,9 @@ thread_do_start(rb_thread_t *th, VALUE args)
|
|||
if (!th->first_func) {
|
||||
rb_proc_t *proc;
|
||||
GetProcPtr(th->first_proc, proc);
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec.root_lep = rb_vm_proc_local_ep(th->first_proc);
|
||||
th->ec.root_svar = Qfalse;
|
||||
th->ec->errinfo = Qnil;
|
||||
th->ec->root_lep = rb_vm_proc_local_ep(th->first_proc);
|
||||
th->ec->root_svar = Qfalse;
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_THREAD_BEGIN, th->self, 0, 0, 0, Qundef);
|
||||
th->value = rb_vm_invoke_proc(th, proc,
|
||||
(int)RARRAY_LEN(args), RARRAY_CONST_PTR(args),
|
||||
|
@ -614,9 +614,9 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||
|
||||
ruby_thread_set_native(th);
|
||||
|
||||
th->ec.machine.stack_start = stack_start;
|
||||
th->ec->machine.stack_start = stack_start;
|
||||
#ifdef __ia64
|
||||
th->ec.machine.register_stack_start = register_stack_start;
|
||||
th->ec->machine.register_stack_start = register_stack_start;
|
||||
#endif
|
||||
thread_debug("thread start: %p\n", (void *)th);
|
||||
|
||||
|
@ -630,7 +630,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||
SAVE_ROOT_JMPBUF(th, thread_do_start(th, args));
|
||||
}
|
||||
else {
|
||||
errinfo = th->ec.errinfo;
|
||||
errinfo = th->ec->errinfo;
|
||||
if (state == TAG_FATAL) {
|
||||
/* fatal error within this thread, need to stop whole script */
|
||||
}
|
||||
|
@ -696,8 +696,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||
rb_threadptr_unlock_all_locking_mutexes(th);
|
||||
rb_check_deadlock(th->vm);
|
||||
|
||||
rb_thread_recycle_stack_release(th->ec.vm_stack);
|
||||
th->ec.vm_stack = NULL;
|
||||
rb_fiber_close(th->ec->fiber);
|
||||
}
|
||||
native_mutex_lock(&th->vm->thread_destruct_lock);
|
||||
/* make sure vm->running_thread never point me after this point.*/
|
||||
|
@ -923,8 +922,8 @@ thread_join(rb_thread_t *target_th, double delay)
|
|||
thread_debug("thread_join: success (thid: %"PRI_THREAD_ID")\n",
|
||||
thread_id_str(target_th));
|
||||
|
||||
if (target_th->ec.errinfo != Qnil) {
|
||||
VALUE err = target_th->ec.errinfo;
|
||||
if (target_th->ec->errinfo != Qnil) {
|
||||
VALUE err = target_th->ec->errinfo;
|
||||
|
||||
if (FIXNUM_P(err)) {
|
||||
switch (err) {
|
||||
|
@ -935,7 +934,7 @@ thread_join(rb_thread_t *target_th, double delay)
|
|||
rb_bug("thread_join: Fixnum (%d) should not reach here.", FIX2INT(err));
|
||||
}
|
||||
}
|
||||
else if (THROW_DATA_P(target_th->ec.errinfo)) {
|
||||
else if (THROW_DATA_P(target_th->ec->errinfo)) {
|
||||
rb_bug("thread_join: THROW_DATA should not reach here.");
|
||||
}
|
||||
else {
|
||||
|
@ -1437,7 +1436,7 @@ rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
|
|||
{
|
||||
volatile VALUE val = Qundef; /* shouldn't be used */
|
||||
rb_vm_t *vm = GET_VM();
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_thread_t *volatile th = GET_THREAD();
|
||||
volatile int saved_errno = 0;
|
||||
enum ruby_tag_type state;
|
||||
struct waiting_fd wfd;
|
||||
|
@ -1858,7 +1857,7 @@ static VALUE
|
|||
rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
|
||||
{
|
||||
VALUE mask;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
volatile VALUE r = Qnil;
|
||||
enum ruby_tag_type state;
|
||||
|
||||
|
@ -2008,7 +2007,7 @@ rb_threadptr_to_kill(rb_thread_t *th)
|
|||
rb_threadptr_pending_interrupt_clear(th);
|
||||
th->status = THREAD_RUNNABLE;
|
||||
th->to_kill = 1;
|
||||
th->ec.errinfo = INT2FIX(TAG_FATAL);
|
||||
th->ec->errinfo = INT2FIX(TAG_FATAL);
|
||||
TH_JUMP_TAG(th, TAG_FATAL);
|
||||
}
|
||||
|
||||
|
@ -2031,7 +2030,7 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
|
|||
rb_atomic_t interrupt;
|
||||
int postponed_job_interrupt = 0;
|
||||
|
||||
if (th->ec.raised_flag) return;
|
||||
if (th->ec->raised_flag) return;
|
||||
|
||||
while ((interrupt = threadptr_get_interrupts(th)) != 0) {
|
||||
int sig;
|
||||
|
@ -2095,7 +2094,7 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
|
|||
if (th->status == THREAD_RUNNABLE)
|
||||
th->running_time_us += TIME_QUANTUM_USEC;
|
||||
|
||||
EXEC_EVENT_HOOK(th, RUBY_INTERNAL_EVENT_SWITCH, th->ec.cfp->self,
|
||||
EXEC_EVENT_HOOK(th, RUBY_INTERNAL_EVENT_SWITCH, th->ec->cfp->self,
|
||||
0, 0, 0, Qundef);
|
||||
|
||||
rb_thread_schedule_limits(limits_us);
|
||||
|
@ -2172,20 +2171,20 @@ rb_threadptr_signal_exit(rb_thread_t *th)
|
|||
int
|
||||
rb_threadptr_set_raised(rb_thread_t *th)
|
||||
{
|
||||
if (th->ec.raised_flag & RAISED_EXCEPTION) {
|
||||
if (th->ec->raised_flag & RAISED_EXCEPTION) {
|
||||
return 1;
|
||||
}
|
||||
th->ec.raised_flag |= RAISED_EXCEPTION;
|
||||
th->ec->raised_flag |= RAISED_EXCEPTION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rb_threadptr_reset_raised(rb_thread_t *th)
|
||||
{
|
||||
if (!(th->ec.raised_flag & RAISED_EXCEPTION)) {
|
||||
if (!(th->ec->raised_flag & RAISED_EXCEPTION)) {
|
||||
return 0;
|
||||
}
|
||||
th->ec.raised_flag &= ~RAISED_EXCEPTION;
|
||||
th->ec->raised_flag &= ~RAISED_EXCEPTION;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2822,8 +2821,8 @@ rb_thread_status(VALUE thread)
|
|||
rb_thread_t *target_th = rb_thread_ptr(thread);
|
||||
|
||||
if (rb_threadptr_dead(target_th)) {
|
||||
if (!NIL_P(target_th->ec.errinfo) &&
|
||||
!FIXNUM_P(target_th->ec.errinfo)) {
|
||||
if (!NIL_P(target_th->ec->errinfo) &&
|
||||
!FIXNUM_P(target_th->ec->errinfo)) {
|
||||
return Qnil;
|
||||
}
|
||||
else {
|
||||
|
@ -2907,7 +2906,7 @@ rb_thread_stop_p(VALUE thread)
|
|||
static VALUE
|
||||
rb_thread_safe_level(VALUE thread)
|
||||
{
|
||||
return INT2NUM(rb_thread_ptr(thread)->ec.safe_level);
|
||||
return INT2NUM(rb_thread_ptr(thread)->ec->safe_level);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2994,11 +2993,11 @@ static VALUE
|
|||
threadptr_local_aref(rb_thread_t *th, ID id)
|
||||
{
|
||||
if (id == recursive_key) {
|
||||
return th->ec.local_storage_recursive_hash;
|
||||
return th->ec->local_storage_recursive_hash;
|
||||
}
|
||||
else {
|
||||
st_data_t val;
|
||||
st_table *local_storage = th->ec.local_storage;
|
||||
st_table *local_storage = th->ec->local_storage;
|
||||
|
||||
if (local_storage != NULL && st_lookup(local_storage, id, &val)) {
|
||||
return (VALUE)val;
|
||||
|
@ -3102,10 +3101,10 @@ rb_thread_fetch(int argc, VALUE *argv, VALUE self)
|
|||
id = rb_check_id(&key);
|
||||
|
||||
if (id == recursive_key) {
|
||||
return target_th->ec.local_storage_recursive_hash;
|
||||
return target_th->ec->local_storage_recursive_hash;
|
||||
}
|
||||
else if (id && target_th->ec.local_storage &&
|
||||
st_lookup(target_th->ec.local_storage, id, &val)) {
|
||||
else if (id && target_th->ec->local_storage &&
|
||||
st_lookup(target_th->ec->local_storage, id, &val)) {
|
||||
return val;
|
||||
}
|
||||
else if (block_given) {
|
||||
|
@ -3123,11 +3122,11 @@ static VALUE
|
|||
threadptr_local_aset(rb_thread_t *th, ID id, VALUE val)
|
||||
{
|
||||
if (id == recursive_key) {
|
||||
th->ec.local_storage_recursive_hash = val;
|
||||
th->ec->local_storage_recursive_hash = val;
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
st_table *local_storage = th->ec.local_storage;
|
||||
st_table *local_storage = th->ec->local_storage;
|
||||
|
||||
if (NIL_P(val)) {
|
||||
if (!local_storage) return Qnil;
|
||||
|
@ -3136,7 +3135,7 @@ threadptr_local_aset(rb_thread_t *th, ID id, VALUE val)
|
|||
}
|
||||
else {
|
||||
if (local_storage == NULL) {
|
||||
th->ec.local_storage = local_storage = st_init_numtable();
|
||||
th->ec->local_storage = local_storage = st_init_numtable();
|
||||
}
|
||||
st_insert(local_storage, id, val);
|
||||
return val;
|
||||
|
@ -3249,7 +3248,7 @@ static VALUE
|
|||
rb_thread_key_p(VALUE self, VALUE key)
|
||||
{
|
||||
ID id = rb_check_id(&key);
|
||||
st_table *local_storage = rb_thread_ptr(self)->ec.local_storage;
|
||||
st_table *local_storage = rb_thread_ptr(self)->ec->local_storage;
|
||||
|
||||
if (!id || local_storage == NULL) {
|
||||
return Qfalse;
|
||||
|
@ -3292,7 +3291,7 @@ rb_thread_alone(void)
|
|||
static VALUE
|
||||
rb_thread_keys(VALUE self)
|
||||
{
|
||||
st_table *local_storage = rb_thread_ptr(self)->ec.local_storage;
|
||||
st_table *local_storage = rb_thread_ptr(self)->ec->local_storage;
|
||||
VALUE ary = rb_ary_new();
|
||||
|
||||
if (local_storage) {
|
||||
|
@ -4481,13 +4480,13 @@ rb_thread_shield_destroy(VALUE self)
|
|||
static VALUE
|
||||
threadptr_recursive_hash(rb_thread_t *th)
|
||||
{
|
||||
return th->ec.local_storage_recursive_hash;
|
||||
return th->ec->local_storage_recursive_hash;
|
||||
}
|
||||
|
||||
static void
|
||||
threadptr_recursive_hash_set(rb_thread_t *th, VALUE hash)
|
||||
{
|
||||
th->ec.local_storage_recursive_hash = hash;
|
||||
th->ec->local_storage_recursive_hash = hash;
|
||||
}
|
||||
|
||||
ID rb_frame_last_func(void);
|
||||
|
@ -4982,7 +4981,7 @@ rb_check_deadlock(rb_vm_t *vm)
|
|||
static void
|
||||
update_coverage(VALUE data, const rb_trace_arg_t *trace_arg)
|
||||
{
|
||||
VALUE coverage = rb_iseq_coverage(GET_THREAD()->ec.cfp->iseq);
|
||||
VALUE coverage = rb_iseq_coverage(GET_THREAD()->ec->cfp->iseq);
|
||||
if (RB_TYPE_P(coverage, T_ARRAY) && !RBASIC_CLASS(coverage)) {
|
||||
long arg = FIX2INT(trace_arg->data);
|
||||
switch (arg % 16) {
|
||||
|
|
|
@ -446,10 +446,8 @@ ruby_thread_set_native(rb_thread_t *th)
|
|||
static void native_thread_init(rb_thread_t *th);
|
||||
|
||||
void
|
||||
Init_native_thread(void)
|
||||
Init_native_thread(rb_thread_t *th)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
|
||||
pthread_key_create(&ruby_native_thread_key, NULL);
|
||||
th->thread_id = pthread_self();
|
||||
fill_thread_id_str(th);
|
||||
|
@ -827,8 +825,8 @@ native_thread_init_stack(rb_thread_t *th)
|
|||
rb_nativethread_id_t curr = pthread_self();
|
||||
|
||||
if (pthread_equal(curr, native_main_thread.id)) {
|
||||
th->ec.machine.stack_start = native_main_thread.stack_start;
|
||||
th->ec.machine.stack_maxsize = native_main_thread.stack_maxsize;
|
||||
th->ec->machine.stack_start = native_main_thread.stack_start;
|
||||
th->ec->machine.stack_maxsize = native_main_thread.stack_maxsize;
|
||||
}
|
||||
else {
|
||||
#ifdef STACKADDR_AVAILABLE
|
||||
|
@ -837,11 +835,11 @@ native_thread_init_stack(rb_thread_t *th)
|
|||
|
||||
if (get_stack(&start, &size) == 0) {
|
||||
uintptr_t diff = (uintptr_t)start - (uintptr_t)&curr;
|
||||
th->ec.machine.stack_start = (VALUE *)&curr;
|
||||
th->ec.machine.stack_maxsize = size - diff;
|
||||
th->ec->machine.stack_start = (VALUE *)&curr;
|
||||
th->ec->machine.stack_maxsize = size - diff;
|
||||
}
|
||||
#elif defined get_stack_of
|
||||
if (!th->ec.machine.stack_maxsize) {
|
||||
if (!th->ec->machine.stack_maxsize) {
|
||||
native_mutex_lock(&th->interrupt_lock);
|
||||
native_mutex_unlock(&th->interrupt_lock);
|
||||
}
|
||||
|
@ -850,9 +848,9 @@ native_thread_init_stack(rb_thread_t *th)
|
|||
#endif
|
||||
}
|
||||
#ifdef __ia64
|
||||
th->ec.machine.register_stack_start = native_main_thread.register_stack_start;
|
||||
th->ec.machine.stack_maxsize /= 2;
|
||||
th->ec.machine.register_stack_maxsize = th->ec.machine.stack_maxsize;
|
||||
th->ec->machine.register_stack_start = native_main_thread.register_stack_start;
|
||||
th->ec->machine.stack_maxsize /= 2;
|
||||
th->ec->machine.register_stack_maxsize = th->ec->machine.stack_maxsize;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -880,7 +878,7 @@ thread_start_func_1(void *th_ptr)
|
|||
native_thread_init(th);
|
||||
/* run */
|
||||
#if defined USE_NATIVE_THREAD_INIT
|
||||
thread_start_func_2(th, th->ec.machine.stack_start, rb_ia64_bsp());
|
||||
thread_start_func_2(th, th->ec->machine.stack_start, rb_ia64_bsp());
|
||||
#else
|
||||
thread_start_func_2(th, &stack_start, rb_ia64_bsp());
|
||||
#endif
|
||||
|
@ -1002,10 +1000,10 @@ native_thread_create(rb_thread_t *th)
|
|||
const size_t stack_size = th->vm->default_params.thread_machine_stack_size;
|
||||
const size_t space = space_size(stack_size);
|
||||
|
||||
th->ec.machine.stack_maxsize = stack_size - space;
|
||||
th->ec->machine.stack_maxsize = stack_size - space;
|
||||
#ifdef __ia64
|
||||
th->ec.machine.stack_maxsize /= 2;
|
||||
th->ec.machine.register_stack_maxsize = th->ec.machine.stack_maxsize;
|
||||
th->ec->machine.stack_maxsize /= 2;
|
||||
th->ec->machine.register_stack_maxsize = th->ec->machine.stack_maxsize;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREAD_ATTR_INIT
|
||||
|
@ -1028,8 +1026,8 @@ native_thread_create(rb_thread_t *th)
|
|||
#ifdef get_stack_of
|
||||
if (!err) {
|
||||
get_stack_of(th->thread_id,
|
||||
&th->ec.machine.stack_start,
|
||||
&th->ec.machine.stack_maxsize);
|
||||
&th->ec->machine.stack_start,
|
||||
&th->ec->machine.stack_maxsize);
|
||||
}
|
||||
native_mutex_unlock(&th->interrupt_lock);
|
||||
#endif
|
||||
|
@ -1745,8 +1743,8 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr)
|
|||
else
|
||||
#endif
|
||||
if (th) {
|
||||
size = th->ec.machine.stack_maxsize;
|
||||
base = (char *)th->ec.machine.stack_start - STACK_DIR_UPPER(0, size);
|
||||
size = th->ec->machine.stack_maxsize;
|
||||
base = (char *)th->ec->machine.stack_start - STACK_DIR_UPPER(0, size);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
|
|
|
@ -140,10 +140,8 @@ ruby_thread_set_native(rb_thread_t *th)
|
|||
}
|
||||
|
||||
void
|
||||
Init_native_thread(void)
|
||||
Init_native_thread(rb_thread_t *th)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
|
||||
ruby_native_thread_key = TlsAlloc();
|
||||
ruby_thread_set_native(th);
|
||||
DuplicateHandle(GetCurrentProcess(),
|
||||
|
@ -546,8 +544,8 @@ native_thread_init_stack(rb_thread_t *th)
|
|||
size = end - base;
|
||||
space = size / 5;
|
||||
if (space > 1024*1024) space = 1024*1024;
|
||||
th->ec.machine.stack_start = (VALUE *)end - 1;
|
||||
th->ec.machine.stack_maxsize = size - space;
|
||||
th->ec->machine.stack_start = (VALUE *)end - 1;
|
||||
th->ec->machine.stack_maxsize = size - space;
|
||||
}
|
||||
|
||||
#ifndef InterlockedExchangePointer
|
||||
|
@ -575,7 +573,7 @@ thread_start_func_1(void *th_ptr)
|
|||
thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
|
||||
th->thread_id, th->native_thread_data.interrupt_event);
|
||||
|
||||
thread_start_func_2(th, th->ec.machine.stack_start, rb_ia64_bsp());
|
||||
thread_start_func_2(th, th->ec->machine.stack_start, rb_ia64_bsp());
|
||||
|
||||
w32_close_handle(thread_id);
|
||||
thread_debug("thread deleted (th: %p)\n", th);
|
||||
|
|
256
vm.c
256
vm.c
|
@ -88,8 +88,8 @@ rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
|
|||
static int
|
||||
VM_CFP_IN_HEAP_P(const rb_thread_t *th, const rb_control_frame_t *cfp)
|
||||
{
|
||||
const VALUE *start = th->ec.vm_stack;
|
||||
const VALUE *end = (VALUE *)th->ec.vm_stack + th->ec.vm_stack_size;
|
||||
const VALUE *start = th->ec->vm_stack;
|
||||
const VALUE *end = (VALUE *)th->ec->vm_stack + th->ec->vm_stack_size;
|
||||
VM_ASSERT(start != NULL);
|
||||
|
||||
if (start <= (VALUE *)cfp && (VALUE *)cfp < end) {
|
||||
|
@ -138,7 +138,9 @@ vm_ep_in_heap_p_(const rb_execution_context_t *ec, const VALUE *ep)
|
|||
int
|
||||
rb_vm_ep_in_heap_p(const VALUE *ep)
|
||||
{
|
||||
return vm_ep_in_heap_p_(&GET_THREAD()->ec, ep);
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
if (th->ec->vm_stack == NULL) return TRUE;
|
||||
return vm_ep_in_heap_p_(th->ec, ep);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -317,8 +319,8 @@ VALUE rb_mRubyVMFrozenCore;
|
|||
|
||||
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
|
||||
VALUE ruby_vm_const_missing_count = 0;
|
||||
rb_thread_t *ruby_current_thread = 0;
|
||||
rb_vm_t *ruby_current_vm = 0;
|
||||
rb_vm_t *ruby_current_vm_ptr = NULL;
|
||||
rb_execution_context_t *ruby_current_execution_context_ptr = NULL;
|
||||
rb_event_flag_t ruby_vm_event_flags;
|
||||
rb_serial_t ruby_vm_global_method_state = 1;
|
||||
rb_serial_t ruby_vm_global_constant_state = 1;
|
||||
|
@ -450,7 +452,7 @@ vm_set_top_stack(rb_thread_t *th, const rb_iseq_t *iseq)
|
|||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH, th->top_self,
|
||||
VM_BLOCK_HANDLER_NONE,
|
||||
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
||||
iseq->body->iseq_encoded, th->ec.cfp->sp,
|
||||
iseq->body->iseq_encoded, th->ec->cfp->sp,
|
||||
iseq->body->local_table_size, iseq->body->stack_max);
|
||||
}
|
||||
|
||||
|
@ -461,7 +463,7 @@ vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref
|
|||
vm_block_self(base_block), VM_GUARDED_PREV_EP(vm_block_ep(base_block)),
|
||||
(VALUE)cref, /* cref or me */
|
||||
iseq->body->iseq_encoded,
|
||||
th->ec.cfp->sp, iseq->body->local_table_size,
|
||||
th->ec->cfp->sp, iseq->body->local_table_size,
|
||||
iseq->body->stack_max);
|
||||
}
|
||||
|
||||
|
@ -478,7 +480,7 @@ vm_set_main_stack(rb_thread_t *th, const rb_iseq_t *iseq)
|
|||
|
||||
/* save binding */
|
||||
if (iseq->body->local_table_size > 0) {
|
||||
vm_bind_update_env(toplevel_binding, bind, vm_make_env_object(th, th->ec.cfp));
|
||||
vm_bind_update_env(toplevel_binding, bind, vm_make_env_object(th, th->ec->cfp));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,7 +534,7 @@ void
|
|||
rb_vm_pop_cfunc_frame(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
|
||||
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, cfp->self, me->def->original_id, me->called_id, me->owner, Qnil);
|
||||
|
@ -544,11 +546,11 @@ void
|
|||
rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||
{
|
||||
/* check skipped frame */
|
||||
while (th->ec.cfp != cfp) {
|
||||
while (th->ec->cfp != cfp) {
|
||||
#if VMDEBUG
|
||||
printf("skipped frame: %s\n", vm_frametype_name(th->ec.cfp));
|
||||
printf("skipped frame: %s\n", vm_frametype_name(th->ec->cfp));
|
||||
#endif
|
||||
if (VM_FRAME_TYPE(th->ec.cfp) != VM_FRAME_MAGIC_CFUNC) {
|
||||
if (VM_FRAME_TYPE(th->ec->cfp) != VM_FRAME_MAGIC_CFUNC) {
|
||||
rb_vm_pop_frame(th);
|
||||
}
|
||||
else { /* unlikely path */
|
||||
|
@ -730,7 +732,7 @@ vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
void
|
||||
rb_vm_stack_to_heap(rb_thread_t *th)
|
||||
{
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
while ((cfp = rb_vm_get_binding_creatable_next_cfp(th, cfp)) != 0) {
|
||||
vm_make_env_object(th, cfp);
|
||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
|
@ -812,7 +814,7 @@ rb_proc_create_from_captured(VALUE klass,
|
|||
VALUE procval = rb_proc_alloc(klass);
|
||||
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
||||
|
||||
VM_ASSERT(VM_EP_IN_HEAP_P(&GET_THREAD()->ec, captured->ep));
|
||||
VM_ASSERT(VM_EP_IN_HEAP_P(GET_THREAD()->ec, captured->ep));
|
||||
|
||||
/* copy block */
|
||||
RB_OBJ_WRITE(procval, &proc->block.as.captured.self, captured->self);
|
||||
|
@ -854,7 +856,7 @@ rb_proc_create(VALUE klass, const struct rb_block *block,
|
|||
VALUE procval = rb_proc_alloc(klass);
|
||||
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
||||
|
||||
VM_ASSERT(VM_EP_IN_HEAP_P(&GET_THREAD()->ec, vm_block_ep(block)));
|
||||
VM_ASSERT(VM_EP_IN_HEAP_P(GET_THREAD()->ec, vm_block_ep(block)));
|
||||
rb_vm_block_copy(procval, &proc->block, block);
|
||||
vm_block_type_set(&proc->block, block->type);
|
||||
proc->safe_level = safe_level;
|
||||
|
@ -879,13 +881,13 @@ rb_vm_make_proc_lambda(rb_thread_t *th, const struct rb_captured_block *captured
|
|||
rb_control_frame_t *cfp = VM_CAPTURED_BLOCK_TO_CFP(captured);
|
||||
vm_make_env_object(th, cfp);
|
||||
}
|
||||
VM_ASSERT(VM_EP_IN_HEAP_P(&th->ec, captured->ep));
|
||||
VM_ASSERT(VM_EP_IN_HEAP_P(th->ec, captured->ep));
|
||||
VM_ASSERT(imemo_type_p(captured->code.val, imemo_iseq) ||
|
||||
imemo_type_p(captured->code.val, imemo_ifunc));
|
||||
|
||||
procval = rb_proc_create_from_captured(klass, captured,
|
||||
imemo_type(captured->code.val) == imemo_iseq ? block_type_iseq : block_type_ifunc,
|
||||
(int8_t)th->ec.safe_level, FALSE, is_lambda);
|
||||
(int8_t)th->ec->safe_level, FALSE, is_lambda);
|
||||
return procval;
|
||||
}
|
||||
|
||||
|
@ -959,7 +961,7 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
|
|||
ALLOCV_END(idtmp);
|
||||
|
||||
vm_set_eval_stack(th, iseq, 0, base_block);
|
||||
vm_bind_update_env(bindval, bind, envval = vm_make_env_object(th, th->ec.cfp));
|
||||
vm_bind_update_env(bindval, bind, envval = vm_make_env_object(th, th->ec->cfp));
|
||||
rb_vm_pop_frame(th);
|
||||
|
||||
env = (const rb_env_t *)envval;
|
||||
|
@ -977,7 +979,7 @@ invoke_block(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const struct rb
|
|||
VM_GUARDED_PREV_EP(captured->ep),
|
||||
(VALUE)cref, /* cref or method */
|
||||
iseq->body->iseq_encoded + opt_pc,
|
||||
th->ec.cfp->sp + arg_size,
|
||||
th->ec->cfp->sp + arg_size,
|
||||
iseq->body->local_table_size - arg_size,
|
||||
iseq->body->stack_max);
|
||||
return vm_exec(th);
|
||||
|
@ -994,13 +996,13 @@ invoke_bmethod(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const struct
|
|||
VM_GUARDED_PREV_EP(captured->ep),
|
||||
(VALUE)me,
|
||||
iseq->body->iseq_encoded + opt_pc,
|
||||
th->ec.cfp->sp + arg_size,
|
||||
th->ec->cfp->sp + arg_size,
|
||||
iseq->body->local_table_size - arg_size,
|
||||
iseq->body->stack_max);
|
||||
|
||||
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->def->original_id);
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->def->original_id, me->called_id, me->owner, Qnil);
|
||||
VM_ENV_FLAGS_SET(th->ec.cfp->ep, VM_FRAME_FLAG_FINISH);
|
||||
VM_ENV_FLAGS_SET(th->ec->cfp->ep, VM_FRAME_FLAG_FINISH);
|
||||
ret = vm_exec(th);
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, self, me->def->original_id, me->called_id, me->owner, ret);
|
||||
RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->owner, me->def->original_id);
|
||||
|
@ -1015,7 +1017,7 @@ invoke_iseq_block_from_c(rb_thread_t *th, const struct rb_captured_block *captur
|
|||
const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);
|
||||
int i, opt_pc;
|
||||
VALUE type = VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0);
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
VALUE *sp = cfp->sp;
|
||||
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
|
||||
th->passed_bmethod_me = NULL;
|
||||
|
@ -1075,7 +1077,7 @@ invoke_block_from_c_bh(rb_thread_t *th, VALUE block_handler,
|
|||
static inline VALUE
|
||||
check_block_handler(rb_thread_t *th)
|
||||
{
|
||||
VALUE block_handler = VM_CF_BLOCK_HANDLER(th->ec.cfp);
|
||||
VALUE block_handler = VM_CF_BLOCK_HANDLER(th->ec->cfp);
|
||||
vm_block_handler_verify(block_handler);
|
||||
if (UNLIKELY(block_handler == VM_BLOCK_HANDLER_NONE)) {
|
||||
rb_vm_localjump_error("no block given", Qnil, 0);
|
||||
|
@ -1145,16 +1147,16 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
|
|||
{
|
||||
VALUE val = Qundef;
|
||||
enum ruby_tag_type state;
|
||||
volatile int stored_safe = th->ec.safe_level;
|
||||
volatile int stored_safe = th->ec->safe_level;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||
th->ec.safe_level = proc->safe_level;
|
||||
th->ec->safe_level = proc->safe_level;
|
||||
val = invoke_block_from_c_proc(th, proc, self, argc, argv, passed_block_handler, proc->is_lambda);
|
||||
}
|
||||
TH_POP_TAG();
|
||||
|
||||
th->ec.safe_level = stored_safe;
|
||||
th->ec->safe_level = stored_safe;
|
||||
|
||||
if (state) {
|
||||
TH_JUMP_TAG(th, state);
|
||||
|
@ -1216,14 +1218,14 @@ static VALUE
|
|||
vm_svar_get(VALUE key)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
return vm_cfp_svar_get(th, th->ec.cfp, key);
|
||||
return vm_cfp_svar_get(th, th->ec->cfp, key);
|
||||
}
|
||||
|
||||
static void
|
||||
vm_svar_set(VALUE key, VALUE val)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
vm_cfp_svar_set(th, th->ec.cfp, key, val);
|
||||
vm_cfp_svar_set(th, th->ec->cfp, key, val);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -1256,7 +1258,7 @@ VALUE
|
|||
rb_sourcefilename(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp) {
|
||||
return rb_iseq_path(cfp->iseq);
|
||||
|
@ -1270,7 +1272,7 @@ const char *
|
|||
rb_sourcefile(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp) {
|
||||
return RSTRING_PTR(rb_iseq_path(cfp->iseq));
|
||||
|
@ -1284,7 +1286,7 @@ int
|
|||
rb_sourceline(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp) {
|
||||
return rb_vm_get_sourceline(cfp);
|
||||
|
@ -1298,7 +1300,7 @@ VALUE
|
|||
rb_source_location(int *pline)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp) {
|
||||
if (pline) *pline = rb_vm_get_sourceline(cfp);
|
||||
|
@ -1322,7 +1324,7 @@ rb_cref_t *
|
|||
rb_vm_cref(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp == NULL) {
|
||||
return NULL;
|
||||
|
@ -1335,7 +1337,7 @@ rb_cref_t *
|
|||
rb_vm_cref_replace_with_duplicated_cref(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
rb_cref_t *cref = vm_cref_replace_with_duplicated_cref(cfp->ep);
|
||||
return cref;
|
||||
}
|
||||
|
@ -1344,7 +1346,7 @@ const rb_cref_t *
|
|||
rb_vm_cref_in_context(VALUE self, VALUE cbase)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
const rb_cref_t *cref;
|
||||
if (cfp->self != self) return NULL;
|
||||
if (!vm_env_cref_by_cref(cfp->ep)) return NULL;
|
||||
|
@ -1369,7 +1371,7 @@ VALUE
|
|||
rb_vm_cbase(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp == 0) {
|
||||
rb_raise(rb_eRuntimeError, "Can't call on top of Fiber or Thread");
|
||||
|
@ -1445,7 +1447,7 @@ rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
|
|||
return Qnil;
|
||||
}
|
||||
if (val == Qundef) {
|
||||
val = GET_THREAD()->ec.tag->retval;
|
||||
val = GET_THREAD()->ec->tag->retval;
|
||||
}
|
||||
return make_localjump_error(mesg, val, state);
|
||||
}
|
||||
|
@ -1474,7 +1476,7 @@ next_not_local_frame(rb_control_frame_t *cfp)
|
|||
static void
|
||||
vm_iter_break(rb_thread_t *th, VALUE val)
|
||||
{
|
||||
rb_control_frame_t *cfp = next_not_local_frame(th->ec.cfp);
|
||||
rb_control_frame_t *cfp = next_not_local_frame(th->ec->cfp);
|
||||
const VALUE *ep = VM_CF_PREV_EP(cfp);
|
||||
const rb_control_frame_t *target_cfp = rb_vm_search_cf_from_ep(th, cfp, ep);
|
||||
|
||||
|
@ -1484,7 +1486,7 @@ vm_iter_break(rb_thread_t *th, VALUE val)
|
|||
}
|
||||
#endif
|
||||
|
||||
th->ec.errinfo = (VALUE)THROW_DATA_NEW(val, target_cfp, TAG_BREAK);
|
||||
th->ec->errinfo = (VALUE)THROW_DATA_NEW(val, target_cfp, TAG_BREAK);
|
||||
TH_JUMP_TAG(th, TAG_BREAK);
|
||||
}
|
||||
|
||||
|
@ -1670,33 +1672,33 @@ hook_before_rewind(rb_thread_t *th, const rb_control_frame_t *cfp, int will_fini
|
|||
if (state == TAG_RAISE && RBASIC_CLASS(err) == rb_eSysStackError) {
|
||||
return;
|
||||
}
|
||||
switch (VM_FRAME_TYPE(th->ec.cfp)) {
|
||||
switch (VM_FRAME_TYPE(th->ec->cfp)) {
|
||||
case VM_FRAME_MAGIC_METHOD:
|
||||
RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->ec.cfp->self, 0, 0, 0, frame_return_value(err));
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->ec->cfp->self, 0, 0, 0, frame_return_value(err));
|
||||
THROW_DATA_CONSUMED_SET(err);
|
||||
break;
|
||||
case VM_FRAME_MAGIC_BLOCK:
|
||||
if (VM_FRAME_BMETHOD_P(th->ec.cfp)) {
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->ec.cfp->self, 0, 0, 0, frame_return_value(err));
|
||||
if (VM_FRAME_BMETHOD_P(th->ec->cfp)) {
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->ec->cfp->self, 0, 0, 0, frame_return_value(err));
|
||||
|
||||
if (!will_finish_vm_exec) {
|
||||
/* kick RUBY_EVENT_RETURN at invoke_block_from_c() for bmethod */
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->ec.cfp->self,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->def->original_id,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->called_id,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->owner,
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->ec->cfp->self,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->def->original_id,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->called_id,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->owner,
|
||||
frame_return_value(err));
|
||||
}
|
||||
THROW_DATA_CONSUMED_SET(err);
|
||||
}
|
||||
else {
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->ec.cfp->self, 0, 0, 0, frame_return_value(err));
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->ec->cfp->self, 0, 0, 0, frame_return_value(err));
|
||||
THROW_DATA_CONSUMED_SET(err);
|
||||
}
|
||||
break;
|
||||
case VM_FRAME_MAGIC_CLASS:
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->ec.cfp->self, 0, 0, 0, Qnil);
|
||||
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->ec->cfp->self, 0, 0, 0, Qnil);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1794,7 +1796,7 @@ vm_exec(rb_thread_t *th)
|
|||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||
vm_loop_start:
|
||||
result = vm_exec_core(th, initial);
|
||||
VM_ASSERT(th->ec.tag == &_tag);
|
||||
VM_ASSERT(th->ec->tag == &_tag);
|
||||
if ((state = _tag.state) != TAG_NONE) {
|
||||
err = (struct vm_throw_data *)result;
|
||||
_tag.state = TAG_NONE;
|
||||
|
@ -1811,27 +1813,27 @@ vm_exec(rb_thread_t *th)
|
|||
VALUE type;
|
||||
const rb_control_frame_t *escape_cfp;
|
||||
|
||||
err = (struct vm_throw_data *)th->ec.errinfo;
|
||||
err = (struct vm_throw_data *)th->ec->errinfo;
|
||||
rb_thread_raised_reset(th, RAISED_STACKOVERFLOW);
|
||||
|
||||
exception_handler:
|
||||
cont_pc = cont_sp = 0;
|
||||
catch_iseq = NULL;
|
||||
|
||||
while (th->ec.cfp->pc == 0 || th->ec.cfp->iseq == 0) {
|
||||
if (UNLIKELY(VM_FRAME_TYPE(th->ec.cfp) == VM_FRAME_MAGIC_CFUNC)) {
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->ec.cfp->self,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->def->original_id,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->called_id,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->owner, Qnil);
|
||||
while (th->ec->cfp->pc == 0 || th->ec->cfp->iseq == 0) {
|
||||
if (UNLIKELY(VM_FRAME_TYPE(th->ec->cfp) == VM_FRAME_MAGIC_CFUNC)) {
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->ec->cfp->self,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->def->original_id,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->called_id,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->owner, Qnil);
|
||||
RUBY_DTRACE_CMETHOD_RETURN_HOOK(th,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->owner,
|
||||
rb_vm_frame_method_entry(th->ec.cfp)->def->original_id);
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->owner,
|
||||
rb_vm_frame_method_entry(th->ec->cfp)->def->original_id);
|
||||
}
|
||||
rb_vm_pop_frame(th);
|
||||
}
|
||||
|
||||
cfp = th->ec.cfp;
|
||||
cfp = th->ec->cfp;
|
||||
epc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||
|
||||
escape_cfp = NULL;
|
||||
|
@ -1858,10 +1860,10 @@ vm_exec(rb_thread_t *th)
|
|||
}
|
||||
}
|
||||
if (catch_iseq == NULL) {
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
result = THROW_DATA_VAL(err);
|
||||
THROW_DATA_CATCH_FRAME_SET(err, cfp + 1);
|
||||
hook_before_rewind(th, th->ec.cfp, TRUE, state, err);
|
||||
hook_before_rewind(th, th->ec->cfp, TRUE, state, err);
|
||||
rb_vm_pop_frame(th);
|
||||
goto finish_vme;
|
||||
}
|
||||
|
@ -1873,9 +1875,9 @@ vm_exec(rb_thread_t *th)
|
|||
#if OPT_STACK_CACHING
|
||||
initial = THROW_DATA_VAL(err);
|
||||
#else
|
||||
*th->ec.cfp->sp++ = THROW_DATA_VAL(err);
|
||||
*th->ec->cfp->sp++ = THROW_DATA_VAL(err);
|
||||
#endif
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
goto vm_loop_start;
|
||||
}
|
||||
}
|
||||
|
@ -1914,7 +1916,7 @@ vm_exec(rb_thread_t *th)
|
|||
escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||
if (cfp == escape_cfp) {
|
||||
cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
goto vm_loop_start;
|
||||
}
|
||||
}
|
||||
|
@ -1944,11 +1946,11 @@ vm_exec(rb_thread_t *th)
|
|||
#if OPT_STACK_CACHING
|
||||
initial = THROW_DATA_VAL(err);
|
||||
#else
|
||||
*th->ec.cfp->sp++ = THROW_DATA_VAL(err);
|
||||
*th->ec->cfp->sp++ = THROW_DATA_VAL(err);
|
||||
#endif
|
||||
}
|
||||
th->ec.errinfo = Qnil;
|
||||
VM_ASSERT(th->ec.tag->state == TAG_NONE);
|
||||
th->ec->errinfo = Qnil;
|
||||
VM_ASSERT(th->ec->tag->state == TAG_NONE);
|
||||
goto vm_loop_start;
|
||||
}
|
||||
}
|
||||
|
@ -1998,16 +2000,16 @@ vm_exec(rb_thread_t *th)
|
|||
catch_iseq->body->stack_max);
|
||||
|
||||
state = 0;
|
||||
th->ec.tag->state = TAG_NONE;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->tag->state = TAG_NONE;
|
||||
th->ec->errinfo = Qnil;
|
||||
goto vm_loop_start;
|
||||
}
|
||||
else {
|
||||
hook_before_rewind(th, th->ec.cfp, FALSE, state, err);
|
||||
hook_before_rewind(th, th->ec->cfp, FALSE, state, err);
|
||||
|
||||
if (VM_FRAME_FINISHED_P(th->ec.cfp)) {
|
||||
if (VM_FRAME_FINISHED_P(th->ec->cfp)) {
|
||||
rb_vm_pop_frame(th);
|
||||
th->ec.errinfo = (VALUE)err;
|
||||
th->ec->errinfo = (VALUE)err;
|
||||
TH_TMPPOP_TAG();
|
||||
TH_JUMP_TAG(th, state);
|
||||
}
|
||||
|
@ -2064,7 +2066,7 @@ rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *idp, ID *cal
|
|||
int
|
||||
rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, ID *called_idp, VALUE *klassp)
|
||||
{
|
||||
return rb_vm_control_frame_id_and_class(th->ec.cfp, idp, called_idp, klassp);
|
||||
return rb_vm_control_frame_id_and_class(th->ec->cfp, idp, called_idp, klassp);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -2076,7 +2078,7 @@ rb_frame_method_id_and_class(ID *idp, VALUE *klassp)
|
|||
VALUE
|
||||
rb_thread_current_status(const rb_thread_t *th)
|
||||
{
|
||||
const rb_control_frame_t *cfp = th->ec.cfp;
|
||||
const rb_control_frame_t *cfp = th->ec->cfp;
|
||||
const rb_callable_method_entry_t *me;
|
||||
VALUE str = Qnil;
|
||||
|
||||
|
@ -2102,7 +2104,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
|
|||
VALUE block_handler, VALUE filename)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
const rb_control_frame_t *reg_cfp = th->ec.cfp;
|
||||
const rb_control_frame_t *reg_cfp = th->ec->cfp;
|
||||
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
VALUE val;
|
||||
|
||||
|
@ -2216,7 +2218,7 @@ ruby_vm_destruct(rb_vm_t *vm)
|
|||
}
|
||||
/* after freeing objspace, you *can't* use ruby_xfree() */
|
||||
ruby_mimfree(vm);
|
||||
ruby_current_vm = 0;
|
||||
ruby_current_vm_ptr = NULL;
|
||||
}
|
||||
RUBY_FREE_LEAVE("vm");
|
||||
return 0;
|
||||
|
@ -2366,11 +2368,14 @@ rb_thread_recycle_stack_release(VALUE *stack)
|
|||
ruby_xfree(stack);
|
||||
}
|
||||
|
||||
void rb_fiber_mark_self(rb_fiber_t *fib);
|
||||
|
||||
void
|
||||
rb_execution_context_mark(const rb_execution_context_t *ec)
|
||||
{
|
||||
#if VM_CHECK_MODE > 0
|
||||
void rb_ec_verify(const rb_execution_context_t *ec); /* cont.c */
|
||||
rb_ec_verify(ec);
|
||||
#endif
|
||||
|
||||
/* mark VM stack */
|
||||
if (ec->vm_stack) {
|
||||
VALUE *p = ec->vm_stack;
|
||||
|
@ -2394,8 +2399,7 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
|
|||
}
|
||||
|
||||
/* mark machine stack */
|
||||
if (&GET_THREAD()->ec != ec &&
|
||||
ec->machine.stack_start && ec->machine.stack_end) {
|
||||
if (ec->machine.stack_start && ec->machine.stack_end) {
|
||||
rb_gc_mark_machine_stack(ec);
|
||||
rb_gc_mark_locations((VALUE *)&ec->machine.regs,
|
||||
(VALUE *)(&ec->machine.regs) +
|
||||
|
@ -2407,16 +2411,16 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
|
|||
rb_mark_tbl(ec->local_storage);
|
||||
RUBY_MARK_UNLESS_NULL(ec->local_storage_recursive_hash);
|
||||
RUBY_MARK_UNLESS_NULL(ec->local_storage_recursive_hash_for_trace);
|
||||
rb_fiber_mark_self(ec->fiber);
|
||||
}
|
||||
|
||||
void rb_fiber_mark_self(rb_fiber_t *fib);
|
||||
|
||||
void
|
||||
rb_thread_mark(void *ptr)
|
||||
{
|
||||
rb_thread_t *th = ptr;
|
||||
RUBY_MARK_ENTER("thread");
|
||||
|
||||
rb_execution_context_mark(&th->ec);
|
||||
rb_fiber_mark_self(th->ec->fiber);
|
||||
|
||||
/* mark ruby objects */
|
||||
RUBY_MARK_UNLESS_NULL(th->first_proc);
|
||||
|
@ -2444,11 +2448,6 @@ thread_free(void *ptr)
|
|||
rb_thread_t *th = ptr;
|
||||
RUBY_FREE_ENTER("thread");
|
||||
|
||||
if (th->ec.vm_stack != NULL) {
|
||||
rb_thread_recycle_stack_release(th->ec.vm_stack);
|
||||
th->ec.vm_stack = NULL;
|
||||
}
|
||||
|
||||
if (th->locking_mutex != Qfalse) {
|
||||
rb_bug("thread_free: locking_mutex must be NULL (%p:%p)", (void *)th, (void *)th->locking_mutex);
|
||||
}
|
||||
|
@ -2456,10 +2455,13 @@ thread_free(void *ptr)
|
|||
rb_bug("thread_free: keeping_mutexes must be NULL (%p:%p)", (void *)th, (void *)th->keeping_mutexes);
|
||||
}
|
||||
|
||||
if (th->ec.local_storage) {
|
||||
st_free_table(th->ec.local_storage);
|
||||
if (th->ec->local_storage) {
|
||||
st_free_table(th->ec->local_storage);
|
||||
}
|
||||
|
||||
if (th->ec == ruby_current_execution_context_ptr)
|
||||
ruby_current_execution_context_ptr = NULL;
|
||||
|
||||
if (th->vm && th->vm->main_thread == th) {
|
||||
RUBY_GC_INFO("main thread\n");
|
||||
}
|
||||
|
@ -2471,8 +2473,6 @@ thread_free(void *ptr)
|
|||
#endif
|
||||
ruby_xfree(ptr);
|
||||
}
|
||||
if (ruby_current_thread == th)
|
||||
ruby_current_thread = NULL;
|
||||
|
||||
RUBY_FREE_LEAVE("thread");
|
||||
}
|
||||
|
@ -2484,10 +2484,10 @@ thread_memsize(const void *ptr)
|
|||
size_t size = sizeof(rb_thread_t);
|
||||
|
||||
if (!th->root_fiber) {
|
||||
size += th->ec.vm_stack_size * sizeof(VALUE);
|
||||
size += th->ec->vm_stack_size * sizeof(VALUE);
|
||||
}
|
||||
if (th->ec.local_storage) {
|
||||
size += st_memsize(th->ec.local_storage);
|
||||
if (th->ec->local_storage) {
|
||||
size += st_memsize(th->ec->local_storage);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
@ -2524,35 +2524,39 @@ thread_alloc(VALUE klass)
|
|||
return obj;
|
||||
}
|
||||
|
||||
void rb_threadptr_root_fiber_setup(rb_thread_t *th);
|
||||
|
||||
static void
|
||||
th_init(rb_thread_t *th, VALUE self)
|
||||
{
|
||||
th->self = self;
|
||||
rb_threadptr_root_fiber_setup(th);
|
||||
|
||||
/* allocate thread stack */
|
||||
#ifdef USE_SIGALTSTACK
|
||||
/* altstack of main thread is reallocated in another place */
|
||||
th->altstack = malloc(rb_sigaltstack_size());
|
||||
#endif
|
||||
/* th->ec.vm_stack_size is word number.
|
||||
* th->vm->default_params.thread_vm_stack_size is byte size.
|
||||
*/
|
||||
th->ec.vm_stack_size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
|
||||
th->ec.vm_stack = thread_recycle_stack(th->ec.vm_stack_size);
|
||||
{
|
||||
/* vm_stack_size is word number.
|
||||
* th->vm->default_params.thread_vm_stack_size is byte size. */
|
||||
size_t size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
|
||||
ec_set_vm_stack(th->ec, thread_recycle_stack(size), size);
|
||||
}
|
||||
|
||||
th->ec.cfp = (void *)(th->ec.vm_stack + th->ec.vm_stack_size);
|
||||
th->ec->cfp = (void *)(th->ec->vm_stack + th->ec->vm_stack_size);
|
||||
|
||||
vm_push_frame(th, 0 /* dummy iseq */, VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_CFRAME /* dummy frame */,
|
||||
Qnil /* dummy self */, VM_BLOCK_HANDLER_NONE /* dummy block ptr */,
|
||||
0 /* dummy cref/me */,
|
||||
0 /* dummy pc */, th->ec.vm_stack, 0, 0);
|
||||
0 /* dummy pc */, th->ec->vm_stack, 0, 0);
|
||||
|
||||
th->status = THREAD_RUNNABLE;
|
||||
th->last_status = Qnil;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec.root_svar = Qfalse;
|
||||
th->ec.local_storage_recursive_hash = Qnil;
|
||||
th->ec.local_storage_recursive_hash_for_trace = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
th->ec->root_svar = Qfalse;
|
||||
th->ec->local_storage_recursive_hash = Qnil;
|
||||
th->ec->local_storage_recursive_hash_for_trace = Qnil;
|
||||
#ifdef NON_SCALAR_THREAD_ID
|
||||
th->thread_id_string[0] = '\0';
|
||||
#endif
|
||||
|
@ -2575,7 +2579,7 @@ ruby_thread_init(VALUE self)
|
|||
|
||||
th->top_wrapper = 0;
|
||||
th->top_self = rb_vm_top_self();
|
||||
th->ec.root_svar = Qfalse;
|
||||
th->ec->root_svar = Qfalse;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -2617,11 +2621,11 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, int is_single
|
|||
|
||||
#define REWIND_CFP(expr) do { \
|
||||
rb_thread_t *th__ = GET_THREAD(); \
|
||||
VALUE *const curr_sp = (th__->ec.cfp++)->sp; \
|
||||
VALUE *const saved_sp = th__->ec.cfp->sp; \
|
||||
th__->ec.cfp->sp = curr_sp; \
|
||||
VALUE *const curr_sp = (th__->ec->cfp++)->sp; \
|
||||
VALUE *const saved_sp = th__->ec->cfp->sp; \
|
||||
th__->ec->cfp->sp = curr_sp; \
|
||||
expr; \
|
||||
(th__->ec.cfp--)->sp = saved_sp; \
|
||||
(th__->ec->cfp--)->sp = saved_sp; \
|
||||
} while (0)
|
||||
|
||||
static VALUE
|
||||
|
@ -3065,7 +3069,7 @@ Init_VM(void)
|
|||
|
||||
/* VM bootstrap: phase 2 */
|
||||
{
|
||||
rb_vm_t *vm = ruby_current_vm;
|
||||
rb_vm_t *vm = ruby_current_vm_ptr;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE filename = rb_fstring_cstr("<main>");
|
||||
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
|
@ -3087,12 +3091,12 @@ Init_VM(void)
|
|||
rb_vm_living_threads_insert(vm, th);
|
||||
|
||||
rb_gc_register_mark_object((VALUE)iseq);
|
||||
th->ec.cfp->iseq = iseq;
|
||||
th->ec.cfp->pc = iseq->body->iseq_encoded;
|
||||
th->ec.cfp->self = th->top_self;
|
||||
th->ec->cfp->iseq = iseq;
|
||||
th->ec->cfp->pc = iseq->body->iseq_encoded;
|
||||
th->ec->cfp->self = th->top_self;
|
||||
|
||||
VM_ENV_FLAGS_UNSET(th->ec.cfp->ep, VM_FRAME_FLAG_CFRAME);
|
||||
VM_STACK_ENV_WRITE(th->ec.cfp->ep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, FALSE, NULL, FALSE));
|
||||
VM_ENV_FLAGS_UNSET(th->ec->cfp->ep, VM_FRAME_FLAG_CFRAME);
|
||||
VM_STACK_ENV_WRITE(th->ec->cfp->ep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, FALSE, NULL, FALSE));
|
||||
|
||||
/*
|
||||
* The Binding of the top level scope
|
||||
|
@ -3110,7 +3114,7 @@ void
|
|||
rb_vm_set_progname(VALUE filename)
|
||||
{
|
||||
rb_thread_t *th = GET_VM()->main_thread;
|
||||
rb_control_frame_t *cfp = (void *)(th->ec.vm_stack + th->ec.vm_stack_size);
|
||||
rb_control_frame_t *cfp = (void *)(th->ec->vm_stack + th->ec->vm_stack_size);
|
||||
--cfp;
|
||||
|
||||
rb_iseq_pathobj_set(cfp->iseq, rb_str_dup(filename), rb_iseq_realpath(cfp->iseq));
|
||||
|
@ -3129,15 +3133,15 @@ Init_BareVM(void)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
MEMZERO(th, rb_thread_t, 1);
|
||||
rb_thread_set_current_raw(th);
|
||||
|
||||
vm_init2(vm);
|
||||
vm->objspace = rb_objspace_alloc();
|
||||
ruby_current_vm = vm;
|
||||
|
||||
Init_native_thread();
|
||||
vm->objspace = rb_objspace_alloc();
|
||||
ruby_current_vm_ptr = vm;
|
||||
|
||||
Init_native_thread(th);
|
||||
th->vm = vm;
|
||||
th_init(th, 0);
|
||||
rb_thread_set_current_raw(th);
|
||||
ruby_thread_init_stack(th);
|
||||
}
|
||||
|
||||
|
@ -3293,7 +3297,7 @@ vm_analysis_operand(int insn, int n, VALUE op)
|
|||
HASH_ASET(ihash, INT2FIX(n), ophash);
|
||||
}
|
||||
/* intern */
|
||||
valstr = rb_insn_operand_intern(GET_THREAD()->ec.cfp->iseq, insn, n, op, 0, 0, 0, 0);
|
||||
valstr = rb_insn_operand_intern(GET_THREAD()->ec->cfp->iseq, insn, n, op, 0, 0, 0, 0);
|
||||
|
||||
/* set count */
|
||||
if ((cv = rb_hash_aref(ophash, valstr)) == Qnil) {
|
||||
|
@ -3406,7 +3410,7 @@ vm_collect_usage_operand(int insn, int n, VALUE op)
|
|||
if (RUBY_DTRACE_INSN_OPERAND_ENABLED()) {
|
||||
VALUE valstr;
|
||||
|
||||
valstr = rb_insn_operand_intern(GET_THREAD()->ec.cfp->iseq, insn, n, op, 0, 0, 0, 0);
|
||||
valstr = rb_insn_operand_intern(GET_THREAD()->ec->cfp->iseq, insn, n, op, 0, 0, 0, 0);
|
||||
|
||||
RUBY_DTRACE_INSN_OPERAND(RSTRING_PTR(valstr), rb_insns_name(insn));
|
||||
RB_GC_GUARD(valstr);
|
||||
|
|
10
vm_args.c
10
vm_args.c
|
@ -508,7 +508,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq,
|
|||
int given_argc;
|
||||
struct args_info args_body, *args;
|
||||
VALUE keyword_hash = Qnil;
|
||||
VALUE * const orig_sp = th->ec.cfp->sp;
|
||||
VALUE * const orig_sp = th->ec->cfp->sp;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
|
@ -528,7 +528,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq,
|
|||
for (i=calling->argc; i<iseq->body->param.size; i++) {
|
||||
locals[i] = Qnil;
|
||||
}
|
||||
th->ec.cfp->sp = &locals[i];
|
||||
th->ec->cfp->sp = &locals[i];
|
||||
|
||||
/* setup args */
|
||||
args = &args_body;
|
||||
|
@ -587,7 +587,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq,
|
|||
}
|
||||
else {
|
||||
if (arg_setup_type == arg_setup_block) {
|
||||
CHECK_VM_STACK_OVERFLOW(th->ec.cfp, min_argc);
|
||||
CHECK_VM_STACK_OVERFLOW(th->ec->cfp, min_argc);
|
||||
given_argc = min_argc;
|
||||
args_extend(args, min_argc);
|
||||
}
|
||||
|
@ -683,7 +683,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq,
|
|||
}
|
||||
#endif
|
||||
|
||||
th->ec.cfp->sp = orig_sp;
|
||||
th->ec->cfp->sp = orig_sp;
|
||||
return opt_pc;
|
||||
}
|
||||
|
||||
|
@ -696,7 +696,7 @@ raise_argument_error(rb_thread_t *th, const rb_iseq_t *iseq, const VALUE exc)
|
|||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL, Qnil /* self */,
|
||||
VM_BLOCK_HANDLER_NONE /* specval*/, Qfalse /* me or cref */,
|
||||
iseq->body->iseq_encoded,
|
||||
th->ec.cfp->sp, 0, 0 /* stack_max */);
|
||||
th->ec->cfp->sp, 0, 0 /* stack_max */);
|
||||
at = rb_threadptr_backtrace_object(th);
|
||||
rb_vm_pop_frame(th);
|
||||
}
|
||||
|
|
|
@ -427,7 +427,7 @@ backtrace_each(rb_thread_t *th,
|
|||
void (*iter_cfunc)(void *arg, const rb_control_frame_t *cfp, ID mid),
|
||||
void *arg)
|
||||
{
|
||||
rb_control_frame_t *last_cfp = th->ec.cfp;
|
||||
rb_control_frame_t *last_cfp = th->ec->cfp;
|
||||
rb_control_frame_t *start_cfp = RUBY_VM_END_CONTROL_FRAME(th);
|
||||
rb_control_frame_t *cfp;
|
||||
ptrdiff_t size, i;
|
||||
|
@ -439,7 +439,7 @@ backtrace_each(rb_thread_t *th,
|
|||
* top frame
|
||||
* ...
|
||||
* 2nd frame <- lev:0
|
||||
* current frame <- th->ec.cfp
|
||||
* current frame <- th->ec->cfp
|
||||
*/
|
||||
|
||||
start_cfp =
|
||||
|
@ -1172,12 +1172,12 @@ VALUE
|
|||
rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data)
|
||||
{
|
||||
rb_debug_inspector_t dbg_context;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
enum ruby_tag_type state;
|
||||
volatile VALUE MAYBE_UNUSED(result);
|
||||
|
||||
dbg_context.th = th;
|
||||
dbg_context.cfp = dbg_context.th->ec.cfp;
|
||||
dbg_context.cfp = dbg_context.th->ec->cfp;
|
||||
dbg_context.backtrace = rb_threadptr_backtrace_location_ary(th, 0, 0);
|
||||
dbg_context.backtrace_size = RARRAY_LEN(dbg_context.backtrace);
|
||||
dbg_context.contexts = collect_caller_bindings(th);
|
||||
|
@ -1247,7 +1247,7 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
|
|||
{
|
||||
int i;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
|
||||
rb_control_frame_t *cfp = th->ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
|
||||
const rb_callable_method_entry_t *cme;
|
||||
|
||||
for (i=0; i<limit && cfp != end_cfp;) {
|
||||
|
|
68
vm_core.h
68
vm_core.h
|
@ -778,12 +778,14 @@ typedef struct rb_execution_context_struct {
|
|||
} machine;
|
||||
} rb_execution_context_t;
|
||||
|
||||
void ec_set_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t size);
|
||||
|
||||
typedef struct rb_thread_struct {
|
||||
struct list_node vmlt_node;
|
||||
VALUE self;
|
||||
rb_vm_t *vm;
|
||||
|
||||
rb_execution_context_t ec;
|
||||
rb_execution_context_t *ec;
|
||||
|
||||
VALUE last_status; /* $? */
|
||||
|
||||
|
@ -1237,7 +1239,7 @@ VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp);
|
|||
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) ((cfp)+1)
|
||||
#define RUBY_VM_NEXT_CONTROL_FRAME(cfp) ((cfp)-1)
|
||||
#define RUBY_VM_END_CONTROL_FRAME(th) \
|
||||
((rb_control_frame_t *)((th)->ec.vm_stack + (th)->ec.vm_stack_size))
|
||||
((rb_control_frame_t *)((th)->ec->vm_stack + (th)->ec->vm_stack_size))
|
||||
#define RUBY_VM_VALID_CONTROL_FRAME_P(cfp, ecfp) \
|
||||
((void *)(ecfp) > (void *)(cfp))
|
||||
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
|
||||
|
@ -1469,7 +1471,7 @@ extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
|
|||
extern void rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp, const VALUE *_pc);
|
||||
extern void rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp);
|
||||
|
||||
#define SDR() rb_vmdebug_stack_dump_raw(GET_THREAD(), GET_THREAD()->ec.cfp)
|
||||
#define SDR() rb_vmdebug_stack_dump_raw(GET_THREAD(), GET_THREAD()->ec->cfp)
|
||||
#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_THREAD(), (cfp))
|
||||
void rb_vm_bugreport(const void *);
|
||||
NORETURN(void rb_bug_context(const void *, const char *fmt, ...));
|
||||
|
@ -1569,19 +1571,62 @@ VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_
|
|||
/* for thread */
|
||||
|
||||
#if RUBY_VM_THREAD_MODEL == 2
|
||||
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
|
||||
extern rb_thread_t *ruby_current_thread;
|
||||
extern rb_vm_t *ruby_current_vm;
|
||||
extern rb_vm_t *ruby_current_vm_ptr;
|
||||
extern rb_execution_context_t *ruby_current_execution_context_ptr;
|
||||
extern rb_event_flag_t ruby_vm_event_flags;
|
||||
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
|
||||
#define GET_VM() ruby_current_vm
|
||||
#define GET_THREAD() ruby_current_thread
|
||||
#define GET_VM() ruby_current_vm()
|
||||
#define GET_THREAD() ruby_current_thread()
|
||||
#define GET_EC() ruby_current_execution_context()
|
||||
|
||||
#define rb_thread_set_current_raw(th) (void)(ruby_current_thread = (th))
|
||||
rb_thread_t *rb_fiberptr_thread_ptr(const rb_fiber_t *fib);
|
||||
|
||||
static inline rb_thread_t *
|
||||
rb_ec_thread_ptr(const rb_execution_context_t *ec)
|
||||
{
|
||||
return rb_fiberptr_thread_ptr(ec->fiber);
|
||||
}
|
||||
|
||||
static inline rb_vm_t *
|
||||
rb_ec_vm_ptr(const rb_execution_context_t *ec)
|
||||
{
|
||||
const rb_thread_t *th = rb_fiberptr_thread_ptr(ec->fiber);
|
||||
if (th) {
|
||||
return rb_fiberptr_thread_ptr(ec->fiber)->vm;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline rb_execution_context_t *
|
||||
ruby_current_execution_context(void)
|
||||
{
|
||||
return ruby_current_execution_context_ptr;
|
||||
}
|
||||
|
||||
static inline rb_thread_t *
|
||||
ruby_current_thread(void)
|
||||
{
|
||||
const rb_execution_context_t *ec = GET_EC();
|
||||
return rb_ec_thread_ptr(ec);
|
||||
}
|
||||
|
||||
static inline rb_vm_t *
|
||||
ruby_current_vm(void)
|
||||
{
|
||||
VM_ASSERT(ruby_current_vm_ptr == NULL ||
|
||||
ruby_current_execution_context_ptr == NULL ||
|
||||
rb_ec_thread_ptr(GET_EC()) == NULL ||
|
||||
rb_ec_vm_ptr(GET_EC()) == ruby_current_vm_ptr);
|
||||
return ruby_current_vm_ptr;
|
||||
}
|
||||
|
||||
#define rb_thread_set_current_raw(th) (void)(ruby_current_execution_context_ptr = (th)->ec)
|
||||
#define rb_thread_set_current(th) do { \
|
||||
if ((th)->vm->running_thread != (th)) { \
|
||||
(th)->running_time_us = 0; \
|
||||
|
@ -1622,11 +1667,14 @@ void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v);
|
|||
int rb_threadptr_pending_interrupt_active_p(rb_thread_t *th);
|
||||
void rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo);
|
||||
void rb_execution_context_mark(const rb_execution_context_t *ec);
|
||||
void rb_fiber_close(rb_fiber_t *fib);
|
||||
void Init_native_thread(rb_thread_t *th);
|
||||
|
||||
#define RUBY_VM_CHECK_INTS(th) ruby_vm_check_ints(th)
|
||||
static inline void
|
||||
ruby_vm_check_ints(rb_thread_t *th)
|
||||
{
|
||||
VM_ASSERT(th->ec == ruby_current_execution_context_ptr);
|
||||
if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) {
|
||||
rb_threadptr_execute_interrupts(th, 0);
|
||||
}
|
||||
|
@ -1669,7 +1717,7 @@ ruby_exec_event_hook_orig(rb_thread_t *const th, const rb_event_flag_t flag,
|
|||
struct rb_trace_arg_struct trace_arg;
|
||||
trace_arg.event = flag;
|
||||
trace_arg.th = th;
|
||||
trace_arg.cfp = th->ec.cfp;
|
||||
trace_arg.cfp = th->ec->cfp;
|
||||
trace_arg.self = self;
|
||||
trace_arg.id = id;
|
||||
trace_arg.called_id = called_id;
|
||||
|
|
44
vm_dump.c
44
vm_dump.c
|
@ -22,14 +22,14 @@
|
|||
#define MAX_POSBUF 128
|
||||
|
||||
#define VM_CFP_CNT(th, cfp) \
|
||||
((rb_control_frame_t *)((th)->ec.vm_stack + (th)->ec.vm_stack_size) - \
|
||||
((rb_control_frame_t *)((th)->ec->vm_stack + (th)->ec->vm_stack_size) - \
|
||||
(rb_control_frame_t *)(cfp))
|
||||
|
||||
static void
|
||||
control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||
{
|
||||
ptrdiff_t pc = -1;
|
||||
ptrdiff_t ep = cfp->ep - th->ec.vm_stack;
|
||||
ptrdiff_t ep = cfp->ep - th->ec->vm_stack;
|
||||
char ep_in_heap = ' ';
|
||||
char posbuf[MAX_POSBUF+1];
|
||||
int line = 0;
|
||||
|
@ -39,7 +39,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
|
||||
const rb_callable_method_entry_t *me;
|
||||
|
||||
if (ep < 0 || (size_t)ep > th->ec.vm_stack_size) {
|
||||
if (ep < 0 || (size_t)ep > th->ec->vm_stack_size) {
|
||||
ep = (ptrdiff_t)cfp->ep;
|
||||
ep_in_heap = 'p';
|
||||
}
|
||||
|
@ -112,14 +112,14 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
}
|
||||
|
||||
fprintf(stderr, "c:%04"PRIdPTRDIFF" ",
|
||||
((rb_control_frame_t *)(th->ec.vm_stack + th->ec.vm_stack_size) - cfp));
|
||||
((rb_control_frame_t *)(th->ec->vm_stack + th->ec->vm_stack_size) - cfp));
|
||||
if (pc == -1) {
|
||||
fprintf(stderr, "p:---- ");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc);
|
||||
}
|
||||
fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - th->ec.vm_stack);
|
||||
fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - th->ec->vm_stack);
|
||||
fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000);
|
||||
fprintf(stderr, "%-6s", magic);
|
||||
if (line) {
|
||||
|
@ -145,12 +145,12 @@ rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
VALUE *p, *st, *t;
|
||||
|
||||
fprintf(stderr, "-- stack frame ------------\n");
|
||||
for (p = st = th->ec.vm_stack; p < sp; p++) {
|
||||
for (p = st = th->ec->vm_stack; p < sp; p++) {
|
||||
fprintf(stderr, "%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p);
|
||||
|
||||
t = (VALUE *)*p;
|
||||
if (th->ec.vm_stack <= t && t < sp) {
|
||||
fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF(t) - th->ec.vm_stack));
|
||||
if (th->ec->vm_stack <= t && t < sp) {
|
||||
fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF(t) - th->ec->vm_stack));
|
||||
}
|
||||
|
||||
if (p == ep)
|
||||
|
@ -162,7 +162,7 @@ rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
|
||||
fprintf(stderr, "-- Control frame information "
|
||||
"-----------------------------------------------\n");
|
||||
while ((void *)cfp < (void *)(th->ec.vm_stack + th->ec.vm_stack_size)) {
|
||||
while ((void *)cfp < (void *)(th->ec->vm_stack + th->ec->vm_stack_size)) {
|
||||
control_frame_dump(th, cfp);
|
||||
cfp++;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ void
|
|||
rb_vmdebug_stack_dump_raw_current(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_vmdebug_stack_dump_raw(th, th->ec.cfp);
|
||||
rb_vmdebug_stack_dump_raw(th, th->ec->cfp);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -213,7 +213,7 @@ void
|
|||
rb_vmdebug_stack_dump_th(VALUE thval)
|
||||
{
|
||||
rb_thread_t *target_th = rb_thread_ptr(thval);
|
||||
rb_vmdebug_stack_dump_raw(target_th, target_th->ec.cfp);
|
||||
rb_vmdebug_stack_dump_raw(target_th, target_th->ec->cfp);
|
||||
}
|
||||
|
||||
#if VMDEBUG > 2
|
||||
|
@ -285,11 +285,11 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
break;
|
||||
}
|
||||
fprintf(stderr, " stack %2d: %8s (%"PRIdPTRDIFF")\n", i, StringValueCStr(rstr),
|
||||
(ptr - th->ec.vm_stack));
|
||||
(ptr - th->ec->vm_stack));
|
||||
}
|
||||
}
|
||||
else if (VM_FRAME_FINISHED_P(cfp)) {
|
||||
if ((th)->ec.vm_stack + (th)->ec.vm_stack_size > (VALUE *)(cfp + 1)) {
|
||||
if ((th)->ec->vm_stack + (th)->ec->vm_stack_size > (VALUE *)(cfp + 1)) {
|
||||
vm_stack_dump_each(th, cfp + 1);
|
||||
}
|
||||
else {
|
||||
|
@ -305,22 +305,22 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
void
|
||||
rb_vmdebug_debug_print_register(rb_thread_t *th)
|
||||
{
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
ptrdiff_t pc = -1;
|
||||
ptrdiff_t ep = cfp->ep - th->ec.vm_stack;
|
||||
ptrdiff_t ep = cfp->ep - th->ec->vm_stack;
|
||||
ptrdiff_t cfpi;
|
||||
|
||||
if (VM_FRAME_RUBYFRAME_P(cfp)) {
|
||||
pc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||
}
|
||||
|
||||
if (ep < 0 || (size_t)ep > th->ec.vm_stack_size) {
|
||||
if (ep < 0 || (size_t)ep > th->ec->vm_stack_size) {
|
||||
ep = -1;
|
||||
}
|
||||
|
||||
cfpi = ((rb_control_frame_t *)(th->ec.vm_stack + th->ec.vm_stack_size)) - cfp;
|
||||
cfpi = ((rb_control_frame_t *)(th->ec->vm_stack + th->ec->vm_stack_size)) - cfp;
|
||||
fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n",
|
||||
pc, (cfp->sp - th->ec.vm_stack), ep, cfpi);
|
||||
pc, (cfp->sp - th->ec->vm_stack), ep, cfpi);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -342,7 +342,7 @@ rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp, const VALUE
|
|||
printf(" ");
|
||||
}
|
||||
printf("| ");
|
||||
if(0)printf("[%03ld] ", (long)(cfp->sp - th->ec.vm_stack));
|
||||
if(0)printf("[%03ld] ", (long)(cfp->sp - th->ec->vm_stack));
|
||||
|
||||
/* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp)); */
|
||||
if (pc >= 0) {
|
||||
|
@ -377,7 +377,7 @@ rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp
|
|||
|
||||
#if VMDEBUG > 2
|
||||
/* stack_dump_thobj(th); */
|
||||
vm_stack_dump_each(th, th->ec.cfp);
|
||||
vm_stack_dump_each(th, th->ec->cfp);
|
||||
|
||||
#if OPT_STACK_CACHING
|
||||
{
|
||||
|
@ -397,7 +397,7 @@ VALUE
|
|||
rb_vmdebug_thread_dump_state(VALUE self)
|
||||
{
|
||||
rb_thread_t *th = rb_thread_ptr(self);
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
|
||||
fprintf(stderr, "Thread state dump:\n");
|
||||
fprintf(stderr, "pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp);
|
||||
|
@ -1085,6 +1085,6 @@ rb_vmdebug_stack_dump_all_threads(void)
|
|||
#else
|
||||
fprintf(stderr, "th: %p, native_id: %p\n", th, (void *)th->thread_id);
|
||||
#endif
|
||||
rb_vmdebug_stack_dump_raw(th, th->ec.cfp);
|
||||
rb_vmdebug_stack_dump_raw(th, th->ec->cfp);
|
||||
}
|
||||
}
|
||||
|
|
62
vm_eval.c
62
vm_eval.c
|
@ -74,7 +74,7 @@ vm_call0_cfunc_with_frame(rb_thread_t* th, struct rb_calling_info *calling, cons
|
|||
RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, me->owner, me->def->original_id);
|
||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->def->original_id, mid, me->owner, Qnil);
|
||||
{
|
||||
rb_control_frame_t *reg_cfp = th->ec.cfp;
|
||||
rb_control_frame_t *reg_cfp = th->ec->cfp;
|
||||
|
||||
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
|
||||
block_handler, (VALUE)me,
|
||||
|
@ -113,7 +113,7 @@ vm_call0_body(rb_thread_t* th, struct rb_calling_info *calling, const struct rb_
|
|||
switch (cc->me->def->type) {
|
||||
case VM_METHOD_TYPE_ISEQ:
|
||||
{
|
||||
rb_control_frame_t *reg_cfp = th->ec.cfp;
|
||||
rb_control_frame_t *reg_cfp = th->ec->cfp;
|
||||
int i;
|
||||
|
||||
CHECK_VM_STACK_OVERFLOW(reg_cfp, calling->argc + 1);
|
||||
|
@ -124,7 +124,7 @@ vm_call0_body(rb_thread_t* th, struct rb_calling_info *calling, const struct rb_
|
|||
}
|
||||
|
||||
vm_call_iseq_setup(th, reg_cfp, calling, ci, cc);
|
||||
VM_ENV_FLAGS_SET(th->ec.cfp->ep, VM_FRAME_FLAG_FINISH);
|
||||
VM_ENV_FLAGS_SET(th->ec->cfp->ep, VM_FRAME_FLAG_FINISH);
|
||||
return vm_exec(th); /* CHECK_INTS in this function */
|
||||
}
|
||||
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
||||
|
@ -211,10 +211,10 @@ rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv, c
|
|||
static inline VALUE
|
||||
vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
|
||||
{
|
||||
VALUE recv = th->ec.cfp->self;
|
||||
VALUE recv = th->ec->cfp->self;
|
||||
VALUE klass;
|
||||
ID id;
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
|
||||
|
||||
if (VM_FRAME_RUBYFRAME_P(cfp)) {
|
||||
|
@ -247,7 +247,7 @@ rb_current_receiver(void)
|
|||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp;
|
||||
if (!th || !(cfp = th->ec.cfp))
|
||||
if (!th || !(cfp = th->ec->cfp))
|
||||
rb_raise(rb_eRuntimeError, "no self, no life");
|
||||
return cfp->self;
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
|
|||
static int
|
||||
check_funcall_callable(rb_thread_t *th, const rb_callable_method_entry_t *me)
|
||||
{
|
||||
return rb_method_call_status(th, me, CALL_FCALL, th->ec.cfp->self) == MISSING_NONE;
|
||||
return rb_method_call_status(th, me, CALL_FCALL, th->ec->cfp->self) == MISSING_NONE;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -585,7 +585,7 @@ static inline VALUE
|
|||
rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
return rb_call0(recv, mid, argc, argv, scope, th->ec.cfp->self);
|
||||
return rb_call0(recv, mid, argc, argv, scope, th->ec->cfp->self);
|
||||
}
|
||||
|
||||
NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
|
||||
|
@ -850,7 +850,7 @@ rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pas
|
|||
static VALUE *
|
||||
current_vm_stack_arg(rb_thread_t *th, const VALUE *argv)
|
||||
{
|
||||
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp);
|
||||
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec->cfp);
|
||||
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, prev_cfp)) return NULL;
|
||||
if (prev_cfp->sp + 1 != argv) return NULL;
|
||||
return prev_cfp->sp + 1;
|
||||
|
@ -869,7 +869,7 @@ send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
|
|||
self = Qundef;
|
||||
}
|
||||
else {
|
||||
self = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp)->self;
|
||||
self = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec->cfp)->self;
|
||||
}
|
||||
|
||||
if (argc == 0) {
|
||||
|
@ -1112,7 +1112,7 @@ rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
|
|||
{
|
||||
enum ruby_tag_type state;
|
||||
volatile VALUE retval = Qnil;
|
||||
rb_control_frame_t *const cfp = th->ec.cfp;
|
||||
rb_control_frame_t *const cfp = th->ec->cfp;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
state = TH_EXEC_TAG();
|
||||
|
@ -1134,15 +1134,15 @@ rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
|
|||
retval = (*it_proc) (data1);
|
||||
}
|
||||
else if (state == TAG_BREAK || state == TAG_RETRY) {
|
||||
const struct vm_throw_data *const err = (struct vm_throw_data *)th->ec.errinfo;
|
||||
const struct vm_throw_data *const err = (struct vm_throw_data *)th->ec->errinfo;
|
||||
const rb_control_frame_t *const escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||
|
||||
if (cfp == escape_cfp) {
|
||||
rb_vm_rewind_cfp(th, cfp);
|
||||
|
||||
state = 0;
|
||||
th->ec.tag->state = TAG_NONE;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->tag->state = TAG_NONE;
|
||||
th->ec->errinfo = Qnil;
|
||||
|
||||
if (state == TAG_RETRY) goto iter_retry;
|
||||
retval = THROW_DATA_VAL(err);
|
||||
|
@ -1296,7 +1296,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||
base_block = &bind->block;
|
||||
}
|
||||
else {
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp != 0) {
|
||||
block.as.captured = *VM_CFP_TO_CAPTURED_BLOCK(cfp);
|
||||
|
@ -1318,7 +1318,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||
iseq = rb_iseq_compile_with_option(src, fname, realpath, INT2FIX(line), base_block, Qnil);
|
||||
|
||||
if (!iseq) {
|
||||
rb_exc_raise(adjust_backtrace_in_eval(th, th->ec.errinfo));
|
||||
rb_exc_raise(adjust_backtrace_in_eval(th, th->ec->errinfo));
|
||||
}
|
||||
|
||||
/* TODO: what the code checking? */
|
||||
|
@ -1340,7 +1340,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||
|
||||
/* save new env */
|
||||
if (bind && iseq->body->local_table_size > 0) {
|
||||
vm_bind_update_env(scope, bind, vm_make_env_object(th, th->ec.cfp));
|
||||
vm_bind_update_env(scope, bind, vm_make_env_object(th, th->ec->cfp));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1357,7 +1357,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||
|
||||
if (state) {
|
||||
if (state == TAG_RAISE) {
|
||||
adjust_backtrace_in_eval(th, th->ec.errinfo);
|
||||
adjust_backtrace_in_eval(th, th->ec->errinfo);
|
||||
}
|
||||
TH_JUMP_TAG(th, state);
|
||||
}
|
||||
|
@ -1546,7 +1546,7 @@ static VALUE
|
|||
yield_under(VALUE under, VALUE self, int argc, const VALUE *argv)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
VALUE block_handler = VM_CF_BLOCK_HANDLER(cfp);
|
||||
VALUE new_block_handler = 0;
|
||||
const struct rb_captured_block *captured = NULL;
|
||||
|
@ -1580,7 +1580,7 @@ yield_under(VALUE under, VALUE self, int argc, const VALUE *argv)
|
|||
new_captured.self = self;
|
||||
ep = captured->ep;
|
||||
|
||||
VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(th->ec.cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
|
||||
VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(th->ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
|
||||
}
|
||||
|
||||
cref = vm_cref_push(th, under, ep, TRUE);
|
||||
|
@ -1591,7 +1591,7 @@ VALUE
|
|||
rb_yield_refine_block(VALUE refinement, VALUE refinements)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE block_handler = VM_CF_BLOCK_HANDLER(th->ec.cfp);
|
||||
VALUE block_handler = VM_CF_BLOCK_HANDLER(th->ec->cfp);
|
||||
|
||||
if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
|
||||
rb_bug("rb_yield_refine_block: an iseq block is required");
|
||||
|
@ -1603,7 +1603,7 @@ rb_yield_refine_block(VALUE refinement, VALUE refinements)
|
|||
const VALUE *ep = captured->ep;
|
||||
rb_cref_t *cref = vm_cref_push(th, refinement, ep, TRUE);
|
||||
CREF_REFINEMENTS_SET(cref, refinements);
|
||||
VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(th->ec.cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
|
||||
VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(th->ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
|
||||
new_captured.self = refinement;
|
||||
return vm_yield_with_cref(th, 0, NULL, cref, FALSE);
|
||||
}
|
||||
|
@ -1875,7 +1875,7 @@ void
|
|||
rb_throw_obj(VALUE tag, VALUE value)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
struct rb_vm_tag *tt = th->ec.tag;
|
||||
struct rb_vm_tag *tt = th->ec->tag;
|
||||
|
||||
while (tt) {
|
||||
if (tt->tag == tag) {
|
||||
|
@ -1892,7 +1892,7 @@ rb_throw_obj(VALUE tag, VALUE value)
|
|||
rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
|
||||
}
|
||||
|
||||
th->ec.errinfo = (VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
|
||||
th->ec->errinfo = (VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
|
||||
TH_JUMP_TAG(th, TAG_THROW);
|
||||
}
|
||||
|
||||
|
@ -1986,7 +1986,7 @@ vm_catch_protect(VALUE tag, rb_block_call_func *func, VALUE data,
|
|||
{
|
||||
enum ruby_tag_type state;
|
||||
VALUE val = Qnil; /* OK */
|
||||
rb_control_frame_t *volatile saved_cfp = th->ec.cfp;
|
||||
rb_control_frame_t *volatile saved_cfp = th->ec->cfp;
|
||||
|
||||
TH_PUSH_TAG(th);
|
||||
|
||||
|
@ -1996,10 +1996,10 @@ vm_catch_protect(VALUE tag, rb_block_call_func *func, VALUE data,
|
|||
/* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
|
||||
val = (*func)(tag, data, 1, (const VALUE *)&tag, Qnil);
|
||||
}
|
||||
else if (state == TAG_THROW && THROW_DATA_VAL((struct vm_throw_data *)th->ec.errinfo) == tag) {
|
||||
else if (state == TAG_THROW && THROW_DATA_VAL((struct vm_throw_data *)th->ec->errinfo) == tag) {
|
||||
rb_vm_rewind_cfp(th, saved_cfp);
|
||||
val = th->ec.tag->retval;
|
||||
th->ec.errinfo = Qnil;
|
||||
val = th->ec->tag->retval;
|
||||
th->ec->errinfo = Qnil;
|
||||
state = 0;
|
||||
}
|
||||
TH_POP_TAG();
|
||||
|
@ -2081,7 +2081,7 @@ rb_f_local_variables(void)
|
|||
struct local_var_list vars;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp =
|
||||
vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp));
|
||||
vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec->cfp));
|
||||
unsigned int i;
|
||||
|
||||
local_var_list_init(&vars);
|
||||
|
@ -2137,7 +2137,7 @@ VALUE
|
|||
rb_f_block_given_p(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
|
||||
|
||||
if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
|
||||
|
@ -2152,7 +2152,7 @@ VALUE
|
|||
rb_current_realfilepath(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
|
||||
if (cfp != 0) return rb_iseq_realpath(cfp->iseq);
|
||||
return Qnil;
|
||||
|
|
10
vm_exec.c
10
vm_exec.c
|
@ -84,7 +84,7 @@ vm_exec_core(rb_thread_t *th, VALUE initial)
|
|||
#undef RESTORE_REGS
|
||||
#define RESTORE_REGS() \
|
||||
{ \
|
||||
VM_REG_CFP = th->ec.cfp; \
|
||||
VM_REG_CFP = th->ec->cfp; \
|
||||
reg_pc = reg_cfp->pc; \
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ vm_exec_core(rb_thread_t *th, VALUE initial)
|
|||
return (VALUE)insns_address_table;
|
||||
}
|
||||
#endif
|
||||
reg_cfp = th->ec.cfp;
|
||||
reg_cfp = th->ec->cfp;
|
||||
reg_pc = reg_cfp->pc;
|
||||
|
||||
#if OPT_STACK_CACHING
|
||||
|
@ -142,7 +142,7 @@ rb_vm_get_insns_address_table(void)
|
|||
static VALUE
|
||||
vm_exec_core(rb_thread_t *th, VALUE initial)
|
||||
{
|
||||
register rb_control_frame_t *reg_cfp = th->ec.cfp;
|
||||
register rb_control_frame_t *reg_cfp = th->ec->cfp;
|
||||
|
||||
while (1) {
|
||||
reg_cfp = ((rb_insn_func_t) (*GET_PC()))(th, reg_cfp);
|
||||
|
@ -158,8 +158,8 @@ vm_exec_core(rb_thread_t *th, VALUE initial)
|
|||
return ret;
|
||||
}
|
||||
else {
|
||||
VALUE err = th->ec.errinfo;
|
||||
th->ec.errinfo = Qnil;
|
||||
VALUE err = th->ec->errinfo;
|
||||
th->ec->errinfo = Qnil;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,11 +157,11 @@ default: \
|
|||
|
||||
#endif
|
||||
|
||||
#define VM_SP_CNT(th, sp) ((sp) - (th)->ec.vm_stack)
|
||||
#define VM_SP_CNT(th, sp) ((sp) - (th)->ec->vm_stack)
|
||||
|
||||
#if OPT_CALL_THREADED_CODE
|
||||
#define THROW_EXCEPTION(exc) do { \
|
||||
th->ec.errinfo = (VALUE)(exc); \
|
||||
th->ec->errinfo = (VALUE)(exc); \
|
||||
return 0; \
|
||||
} while (0)
|
||||
#else
|
||||
|
|
|
@ -35,14 +35,14 @@ static void
|
|||
threadptr_stack_overflow(rb_thread_t *th, int setup)
|
||||
{
|
||||
VALUE mesg = th->vm->special_exceptions[ruby_error_sysstack];
|
||||
th->ec.raised_flag = RAISED_STACKOVERFLOW;
|
||||
th->ec->raised_flag = RAISED_STACKOVERFLOW;
|
||||
if (setup) {
|
||||
VALUE at = rb_threadptr_backtrace_object(th);
|
||||
mesg = ruby_vm_special_exception_copy(mesg);
|
||||
rb_ivar_set(mesg, idBt, at);
|
||||
rb_ivar_set(mesg, idBt_locations, at);
|
||||
}
|
||||
th->ec.errinfo = mesg;
|
||||
th->ec->errinfo = mesg;
|
||||
TH_JUMP_TAG(th, TAG_RAISE);
|
||||
}
|
||||
|
||||
|
@ -57,8 +57,8 @@ void
|
|||
rb_threadptr_stack_overflow(rb_thread_t *th, int crit)
|
||||
{
|
||||
if (crit || rb_during_gc()) {
|
||||
th->ec.raised_flag = RAISED_STACKOVERFLOW;
|
||||
th->ec.errinfo = th->vm->special_exceptions[ruby_error_stackfatal];
|
||||
th->ec->raised_flag = RAISED_STACKOVERFLOW;
|
||||
th->ec->errinfo = th->vm->special_exceptions[ruby_error_stackfatal];
|
||||
TH_JUMP_TAG(th, TAG_RAISE);
|
||||
}
|
||||
#ifdef USE_SIGALTSTACK
|
||||
|
@ -266,7 +266,7 @@ vm_push_frame(rb_thread_t *th,
|
|||
int local_size,
|
||||
int stack_max)
|
||||
{
|
||||
return vm_push_frame_(&th->ec, iseq, type, self, specval, cref_or_me, pc, sp, local_size, stack_max);
|
||||
return vm_push_frame_(th->ec, iseq, type, self, specval, cref_or_me, pc, sp, local_size, stack_max);
|
||||
}
|
||||
|
||||
rb_control_frame_t *
|
||||
|
@ -293,7 +293,7 @@ vm_pop_frame(rb_thread_t *th, rb_control_frame_t *cfp, const VALUE *ep)
|
|||
if (VM_CHECK_MODE >= 4) rb_gc_verify_internal_consistency();
|
||||
if (VMDEBUG == 2) SDR();
|
||||
|
||||
th->ec.cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
th->ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
|
||||
return flags & VM_FRAME_FLAG_FINISH;
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ vm_pop_frame(rb_thread_t *th, rb_control_frame_t *cfp, const VALUE *ep)
|
|||
void
|
||||
rb_vm_pop_frame(rb_thread_t *th)
|
||||
{
|
||||
vm_pop_frame(th, th->ec.cfp, th->ec.cfp->ep);
|
||||
vm_pop_frame(th, th->ec->cfp, th->ec->cfp->ep);
|
||||
}
|
||||
|
||||
/* method dispatch */
|
||||
|
@ -406,11 +406,11 @@ lep_svar(rb_thread_t *th, const VALUE *lep)
|
|||
{
|
||||
VALUE svar;
|
||||
|
||||
if (lep && (th == NULL || th->ec.root_lep != lep)) {
|
||||
if (lep && (th == NULL || th->ec->root_lep != lep)) {
|
||||
svar = lep[VM_ENV_DATA_INDEX_ME_CREF];
|
||||
}
|
||||
else {
|
||||
svar = th->ec.root_svar;
|
||||
svar = th->ec->root_svar;
|
||||
}
|
||||
|
||||
VM_ASSERT(svar == Qfalse || vm_svar_valid_p(svar));
|
||||
|
@ -423,11 +423,11 @@ lep_svar_write(rb_thread_t *th, const VALUE *lep, const struct vm_svar *svar)
|
|||
{
|
||||
VM_ASSERT(vm_svar_valid_p((VALUE)svar));
|
||||
|
||||
if (lep && (th == NULL || th->ec.root_lep != lep)) {
|
||||
if (lep && (th == NULL || th->ec->root_lep != lep)) {
|
||||
vm_env_write(lep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)svar);
|
||||
}
|
||||
else {
|
||||
RB_OBJ_WRITE(th->self, &th->ec.root_svar, svar);
|
||||
RB_OBJ_WRITE(th->self, &th->ec->root_svar, svar);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -757,7 +757,7 @@ vm_cref_push(rb_thread_t *th, VALUE klass, const VALUE *ep, int pushed_by_eval)
|
|||
prev_cref = vm_env_cref(ep);
|
||||
}
|
||||
else {
|
||||
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp) {
|
||||
prev_cref = vm_env_cref(cfp->ep);
|
||||
|
@ -830,7 +830,7 @@ vm_get_ev_const(rb_thread_t *th, VALUE orig_klass, ID id, int is_defined)
|
|||
|
||||
if (orig_klass == Qnil) {
|
||||
/* in current lexical scope */
|
||||
const rb_cref_t *root_cref = rb_vm_get_cref(th->ec.cfp->ep);
|
||||
const rb_cref_t *root_cref = rb_vm_get_cref(th->ec->cfp->ep);
|
||||
const rb_cref_t *cref;
|
||||
VALUE klass = Qnil;
|
||||
|
||||
|
@ -876,10 +876,10 @@ vm_get_ev_const(rb_thread_t *th, VALUE orig_klass, ID id, int is_defined)
|
|||
|
||||
/* search self */
|
||||
if (root_cref && !NIL_P(CREF_CLASS(root_cref))) {
|
||||
klass = vm_get_iclass(th->ec.cfp, CREF_CLASS(root_cref));
|
||||
klass = vm_get_iclass(th->ec->cfp, CREF_CLASS(root_cref));
|
||||
}
|
||||
else {
|
||||
klass = CLASS_OF(th->ec.cfp->self);
|
||||
klass = CLASS_OF(th->ec->cfp->self);
|
||||
}
|
||||
|
||||
if (is_defined) {
|
||||
|
@ -1066,16 +1066,16 @@ vm_throw_continue(rb_thread_t *th, VALUE err)
|
|||
/* continue throw */
|
||||
|
||||
if (FIXNUM_P(err)) {
|
||||
th->ec.tag->state = FIX2INT(err);
|
||||
th->ec->tag->state = FIX2INT(err);
|
||||
}
|
||||
else if (SYMBOL_P(err)) {
|
||||
th->ec.tag->state = TAG_THROW;
|
||||
th->ec->tag->state = TAG_THROW;
|
||||
}
|
||||
else if (THROW_DATA_P(err)) {
|
||||
th->ec.tag->state = THROW_DATA_STATE((struct vm_throw_data *)err);
|
||||
th->ec->tag->state = THROW_DATA_STATE((struct vm_throw_data *)err);
|
||||
}
|
||||
else {
|
||||
th->ec.tag->state = TAG_RAISE;
|
||||
th->ec->tag->state = TAG_RAISE;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -1230,7 +1230,7 @@ vm_throw_start(rb_thread_t *const th, rb_control_frame_t *const reg_cfp, enum ru
|
|||
rb_bug("isns(throw): unsupport throw type");
|
||||
}
|
||||
|
||||
th->ec.tag->state = state;
|
||||
th->ec->tag->state = state;
|
||||
return (VALUE)THROW_DATA_NEW(throwobj, escape_cfp, state);
|
||||
}
|
||||
|
||||
|
@ -1554,8 +1554,8 @@ vm_base_ptr(const rb_control_frame_t *cfp)
|
|||
#if VM_DEBUG_BP_CHECK
|
||||
if (bp != cfp->bp_check) {
|
||||
fprintf(stderr, "bp_check: %ld, bp: %ld\n",
|
||||
(long)(cfp->bp_check - GET_THREAD()->ec.vm_stack),
|
||||
(long)(bp - GET_THREAD()->ec.vm_stack));
|
||||
(long)(cfp->bp_check - GET_THREAD()->ec->vm_stack),
|
||||
(long)(bp - GET_THREAD()->ec->vm_stack));
|
||||
rb_bug("vm_base_ptr: unreachable");
|
||||
}
|
||||
#endif
|
||||
|
@ -1624,7 +1624,7 @@ vm_callee_setup_arg(rb_thread_t *th, struct rb_calling_info *calling, const stru
|
|||
const rb_iseq_t *iseq, VALUE *argv, int param_size, int local_size)
|
||||
{
|
||||
if (LIKELY(simple_iseq_p(iseq) && !(ci->flag & VM_CALL_KW_SPLAT))) {
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
|
||||
CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */
|
||||
|
||||
|
@ -1707,7 +1707,7 @@ vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_
|
|||
}
|
||||
|
||||
vm_pop_frame(th, cfp, cfp->ep);
|
||||
cfp = th->ec.cfp;
|
||||
cfp = th->ec->cfp;
|
||||
|
||||
sp_orig = sp = cfp->sp;
|
||||
|
||||
|
@ -1873,7 +1873,7 @@ static inline int
|
|||
vm_cfp_consistent_p(rb_thread_t *th, const rb_control_frame_t *reg_cfp)
|
||||
{
|
||||
const int ov_flags = RAISED_STACKOVERFLOW;
|
||||
if (LIKELY(reg_cfp == th->ec.cfp + 1)) return TRUE;
|
||||
if (LIKELY(reg_cfp == th->ec->cfp + 1)) return TRUE;
|
||||
if (rb_thread_raised_p(th, ov_flags)) {
|
||||
rb_thread_raised_reset(th, ov_flags);
|
||||
return TRUE;
|
||||
|
@ -1883,7 +1883,7 @@ vm_cfp_consistent_p(rb_thread_t *th, const rb_control_frame_t *reg_cfp)
|
|||
|
||||
#define CHECK_CFP_CONSISTENCY(func) \
|
||||
(LIKELY(vm_cfp_consistent_p(th, reg_cfp)) ? (void)0 : \
|
||||
rb_bug(func ": cfp consistency error (%p, %p)", reg_cfp, th->ec.cfp+1))
|
||||
rb_bug(func ": cfp consistency error (%p, %p)", reg_cfp, th->ec->cfp+1))
|
||||
|
||||
static inline
|
||||
const rb_method_cfunc_t *
|
||||
|
@ -1930,7 +1930,7 @@ vm_call_cfunc_with_frame(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb
|
|||
|
||||
vm_push_frame(th, NULL, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
|
||||
block_handler, (VALUE)me,
|
||||
0, th->ec.cfp->sp, 0, 0);
|
||||
0, th->ec->cfp->sp, 0, 0);
|
||||
|
||||
if (len >= 0) rb_check_arity(argc, len, len);
|
||||
|
||||
|
@ -2564,7 +2564,7 @@ vm_yield_with_cfunc(rb_thread_t *th,
|
|||
self,
|
||||
VM_GUARDED_PREV_EP(captured->ep),
|
||||
(VALUE)me,
|
||||
0, th->ec.cfp->sp, 0, 0);
|
||||
0, th->ec->cfp->sp, 0, 0);
|
||||
val = (*ifunc->func)(arg, ifunc->data, argc, argv, blockarg);
|
||||
rb_vm_pop_frame(th);
|
||||
|
||||
|
@ -2609,7 +2609,7 @@ static int
|
|||
vm_callee_setup_block_arg(rb_thread_t *th, struct rb_calling_info *calling, const struct rb_call_info *ci, const rb_iseq_t *iseq, VALUE *argv, const enum arg_setup_type arg_setup_type)
|
||||
{
|
||||
if (simple_iseq_p(iseq)) {
|
||||
rb_control_frame_t *cfp = th->ec.cfp;
|
||||
rb_control_frame_t *cfp = th->ec->cfp;
|
||||
VALUE arg0;
|
||||
|
||||
CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */
|
||||
|
@ -2694,7 +2694,7 @@ vm_invoke_symbol_block(rb_thread_t *th, rb_control_frame_t *reg_cfp,
|
|||
{
|
||||
VALUE val;
|
||||
int argc;
|
||||
CALLER_SETUP_ARG(th->ec.cfp, calling, ci);
|
||||
CALLER_SETUP_ARG(th->ec->cfp, calling, ci);
|
||||
argc = calling->argc;
|
||||
val = vm_yield_with_symbol(th, symbol, argc, STACK_ADDR_FROM_TOP(argc), VM_BLOCK_HANDLER_NONE);
|
||||
POPN(argc);
|
||||
|
@ -2708,7 +2708,7 @@ vm_invoke_ifunc_block(rb_thread_t *th, rb_control_frame_t *reg_cfp,
|
|||
{
|
||||
VALUE val;
|
||||
int argc;
|
||||
CALLER_SETUP_ARG(th->ec.cfp, calling, ci);
|
||||
CALLER_SETUP_ARG(th->ec->cfp, calling, ci);
|
||||
argc = calling->argc;
|
||||
val = vm_yield_with_cfunc(th, captured, captured->self, argc, STACK_ADDR_FROM_TOP(argc), VM_BLOCK_HANDLER_NONE);
|
||||
POPN(argc); /* TODO: should put before C/yield? */
|
||||
|
@ -2773,7 +2773,7 @@ static VALUE
|
|||
vm_make_proc_with_iseq(const rb_iseq_t *blockiseq)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
struct rb_captured_block *captured;
|
||||
|
||||
if (cfp == 0) {
|
||||
|
@ -3313,7 +3313,7 @@ vm_once_dispatch(ISEQ iseq, IC ic, rb_thread_t *th)
|
|||
val = is->once.value = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is);
|
||||
/* is->once.running_thread is cleared by vm_once_clear() */
|
||||
is->once.running_thread = RUNNING_THREAD_ONCE_DONE; /* success */
|
||||
rb_iseq_add_mark_object(th->ec.cfp->iseq, val);
|
||||
rb_iseq_add_mark_object(th->ec->cfp->iseq, val);
|
||||
return val;
|
||||
}
|
||||
else if (is->once.running_thread == th) {
|
||||
|
|
|
@ -54,7 +54,7 @@ RUBY_SYMBOL_EXPORT_END
|
|||
#define VM_REG_EP (VM_REG_CFP->ep)
|
||||
|
||||
#define RESTORE_REGS() do { \
|
||||
VM_REG_CFP = th->ec.cfp; \
|
||||
VM_REG_CFP = th->ec->cfp; \
|
||||
} while (0)
|
||||
|
||||
#define REG_A reg_a
|
||||
|
@ -102,7 +102,7 @@ enum vm_regan_acttype {
|
|||
#define SET_SV(x) (*GET_SP() = (x))
|
||||
/* set current stack value as x */
|
||||
|
||||
#define GET_SP_COUNT() (VM_REG_SP - th->ec.vm_stack)
|
||||
#define GET_SP_COUNT() (VM_REG_SP - th->ec->vm_stack)
|
||||
|
||||
/* instruction sequence C struct */
|
||||
#define GET_ISEQ() (GET_CFP()->iseq)
|
||||
|
|
|
@ -264,7 +264,7 @@ method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def,
|
|||
|
||||
def->body.attr.id = (ID)(VALUE)opts;
|
||||
|
||||
cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (cfp && (line = rb_vm_get_sourceline(cfp))) {
|
||||
VALUE location = rb_ary_new3(2, rb_iseq_path(cfp->iseq), INT2FIX(line));
|
||||
|
@ -1089,7 +1089,7 @@ static rb_method_visibility_t
|
|||
rb_scope_visibility_get(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (!vm_env_cref_by_cref(cfp->ep)) {
|
||||
return METHOD_VISI_PUBLIC;
|
||||
|
@ -1103,7 +1103,7 @@ static int
|
|||
rb_scope_module_func_check(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
|
||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec->cfp);
|
||||
|
||||
if (!vm_env_cref_by_cref(cfp->ep)) {
|
||||
return FALSE;
|
||||
|
|
52
vm_trace.c
52
vm_trace.c
|
@ -304,31 +304,31 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
|
|||
rb_thread_t *th = trace_arg->th;
|
||||
|
||||
if (trace_arg->event & RUBY_INTERNAL_EVENT_MASK) {
|
||||
if (th->ec.trace_arg && (th->ec.trace_arg->event & RUBY_INTERNAL_EVENT_MASK)) {
|
||||
if (th->ec->trace_arg && (th->ec->trace_arg->event & RUBY_INTERNAL_EVENT_MASK)) {
|
||||
/* skip hooks because this thread doing INTERNAL_EVENT */
|
||||
}
|
||||
else {
|
||||
rb_trace_arg_t *prev_trace_arg = th->ec.trace_arg;
|
||||
rb_trace_arg_t *prev_trace_arg = th->ec->trace_arg;
|
||||
th->vm->trace_running++;
|
||||
th->ec.trace_arg = trace_arg;
|
||||
th->ec->trace_arg = trace_arg;
|
||||
exec_hooks_unprotected(th, &th->event_hooks, trace_arg);
|
||||
exec_hooks_unprotected(th, &th->vm->event_hooks, trace_arg);
|
||||
th->ec.trace_arg = prev_trace_arg;
|
||||
th->ec->trace_arg = prev_trace_arg;
|
||||
th->vm->trace_running--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (th->ec.trace_arg == NULL && /* check reentrant */
|
||||
if (th->ec->trace_arg == NULL && /* check reentrant */
|
||||
trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
|
||||
const VALUE errinfo = th->ec.errinfo;
|
||||
const VALUE old_recursive = th->ec.local_storage_recursive_hash;
|
||||
const VALUE errinfo = th->ec->errinfo;
|
||||
const VALUE old_recursive = th->ec->local_storage_recursive_hash;
|
||||
int state = 0;
|
||||
|
||||
th->ec.local_storage_recursive_hash = th->ec.local_storage_recursive_hash_for_trace;
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->local_storage_recursive_hash = th->ec->local_storage_recursive_hash_for_trace;
|
||||
th->ec->errinfo = Qnil;
|
||||
|
||||
th->vm->trace_running++;
|
||||
th->ec.trace_arg = trace_arg;
|
||||
th->ec->trace_arg = trace_arg;
|
||||
{
|
||||
/* thread local traces */
|
||||
state = exec_hooks_protected(th, &th->event_hooks, trace_arg);
|
||||
|
@ -338,19 +338,19 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
|
|||
state = exec_hooks_protected(th, &th->vm->event_hooks, trace_arg);
|
||||
if (state) goto terminate;
|
||||
|
||||
th->ec.errinfo = errinfo;
|
||||
th->ec->errinfo = errinfo;
|
||||
}
|
||||
terminate:
|
||||
th->ec.trace_arg = NULL;
|
||||
th->ec->trace_arg = NULL;
|
||||
th->vm->trace_running--;
|
||||
|
||||
th->ec.local_storage_recursive_hash_for_trace = th->ec.local_storage_recursive_hash;
|
||||
th->ec.local_storage_recursive_hash = old_recursive;
|
||||
th->ec->local_storage_recursive_hash_for_trace = th->ec->local_storage_recursive_hash;
|
||||
th->ec->local_storage_recursive_hash = old_recursive;
|
||||
|
||||
if (state) {
|
||||
if (pop_p) {
|
||||
if (VM_FRAME_FINISHED_P(th->ec.cfp)) {
|
||||
th->ec.tag = th->ec.tag->prev;
|
||||
if (VM_FRAME_FINISHED_P(th->ec->cfp)) {
|
||||
th->ec->tag = th->ec->tag->prev;
|
||||
}
|
||||
rb_vm_pop_frame(th);
|
||||
}
|
||||
|
@ -379,12 +379,12 @@ rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg)
|
|||
VALUE result = Qnil;
|
||||
rb_thread_t *volatile th = GET_THREAD();
|
||||
enum ruby_tag_type state;
|
||||
const int tracing = th->ec.trace_arg ? 1 : 0;
|
||||
const int volatile tracing = th->ec->trace_arg ? 1 : 0;
|
||||
rb_trace_arg_t dummy_trace_arg;
|
||||
dummy_trace_arg.event = 0;
|
||||
|
||||
if (!tracing) th->vm->trace_running++;
|
||||
if (!th->ec.trace_arg) th->ec.trace_arg = &dummy_trace_arg;
|
||||
if (!th->ec->trace_arg) th->ec->trace_arg = &dummy_trace_arg;
|
||||
|
||||
raised = rb_threadptr_reset_raised(th);
|
||||
|
||||
|
@ -398,7 +398,7 @@ rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg)
|
|||
rb_threadptr_set_raised(th);
|
||||
}
|
||||
|
||||
if (th->ec.trace_arg == &dummy_trace_arg) th->ec.trace_arg = 0;
|
||||
if (th->ec->trace_arg == &dummy_trace_arg) th->ec->trace_arg = 0;
|
||||
if (!tracing) th->vm->trace_running--;
|
||||
|
||||
if (state) {
|
||||
|
@ -706,7 +706,7 @@ tpptr(VALUE tpval)
|
|||
static rb_trace_arg_t *
|
||||
get_trace_arg(void)
|
||||
{
|
||||
rb_trace_arg_t *trace_arg = GET_THREAD()->ec.trace_arg;
|
||||
rb_trace_arg_t *trace_arg = GET_THREAD()->ec->trace_arg;
|
||||
if (trace_arg == 0) {
|
||||
rb_raise(rb_eRuntimeError, "access from outside");
|
||||
}
|
||||
|
@ -1310,7 +1310,7 @@ static VALUE
|
|||
tracepoint_inspect(VALUE self)
|
||||
{
|
||||
rb_tp_t *tp = tpptr(self);
|
||||
rb_trace_arg_t *trace_arg = GET_THREAD()->ec.trace_arg;
|
||||
rb_trace_arg_t *trace_arg = GET_THREAD()->ec->trace_arg;
|
||||
|
||||
if (trace_arg) {
|
||||
switch (trace_arg->event) {
|
||||
|
@ -1591,12 +1591,12 @@ rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func,
|
|||
void
|
||||
rb_postponed_job_flush(rb_vm_t *vm)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_thread_t * volatile th = GET_THREAD();
|
||||
const unsigned long block_mask = POSTPONED_JOB_INTERRUPT_MASK|TRAP_INTERRUPT_MASK;
|
||||
unsigned long saved_mask = th->interrupt_mask & block_mask;
|
||||
VALUE saved_errno = th->ec.errinfo;
|
||||
volatile unsigned long saved_mask = th->interrupt_mask & block_mask;
|
||||
VALUE volatile saved_errno = th->ec->errinfo;
|
||||
|
||||
th->ec.errinfo = Qnil;
|
||||
th->ec->errinfo = Qnil;
|
||||
/* mask POSTPONED_JOB dispatch */
|
||||
th->interrupt_mask |= block_mask;
|
||||
{
|
||||
|
@ -1614,5 +1614,5 @@ rb_postponed_job_flush(rb_vm_t *vm)
|
|||
}
|
||||
/* restore POSTPONED_JOB mask */
|
||||
th->interrupt_mask &= ~(saved_mask ^ block_mask);
|
||||
th->ec.errinfo = saved_errno;
|
||||
th->ec->errinfo = saved_errno;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue