summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog57
-rw-r--r--cont.c9
-rw-r--r--eval.c10
-rw-r--r--eval_intern.h2
-rw-r--r--insns.def48
-rw-r--r--proc.c14
-rw-r--r--thread.c4
-rw-r--r--vm.c211
-rw-r--r--vm_core.h43
-rw-r--r--vm_dump.c78
-rw-r--r--vm_eval.c30
-rw-r--r--vm_exec.h4
-rw-r--r--vm_insnhelper.c192
-rw-r--r--vm_insnhelper.h45
14 files changed, 413 insertions, 334 deletions
diff --git a/ChangeLog b/ChangeLog
index 66f0197216..0c4f839bbb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+Mon Jun 11 12:14:37 2012 Koichi Sasada <ko1@atdot.net>
+
+ * vm_core.h: remove lfp (local frame pointer) and rename
+ dfp (dynamic frame pointer) to ep (environment pointer).
+ This change make VM `normal' (similar to other interpreters).
+ Before this commit:
+ Each frame has two env pointers lfp and dfp. lfp points
+ local environment which is method/class/toplevel frame.
+ lfp[0] is block pointer.
+ dfp is block local frame. dfp[0] points previous (parent)
+ environment pointer.
+ lfp == dfp when frame is method/class/toplevel.
+ You can get lfp from dfp by traversing previous environment
+ pointers.
+ After this commit:
+ Each frame has only `ep' to point respective enviornoment.
+ If there is parent environment, then ep[0] points parent
+ envioenment (as dfp). If there are no more environment,
+ then ep[0] points block pointer (as lfp). We call such ep
+ as `LEP' (local EP). We add some macros to get LEP and to
+ detect LEP or not.
+ In short, we replace dfp and lfp with ep and LEP.
+ rb_block_t and rb_binding_t member `lfp' and `dfp' are removed
+ and member `ep' is added.
+ rename rb_thread_t's member `local_lfp' and `local_svar' to
+ `root_lep' and `root_svar'.
+ (VM_EP_PREV_EP(ep)): get previous environment pointer. This macro
+ assume that ep is not LEP.
+ (VM_EP_BLOCK_PTR(ep)): get block pointer. This macro assume
+ that ep is LEP.
+ (VM_EP_LEP_P(ep)): detect ep is LEP or not.
+ (VM_ENVVAL_BLOCK_PTR(ptr)): make block pointer.
+ (VM_ENVVAL_BLOCK_PTR_P(v)): detect v is block pointer.
+ (VM_ENVVAL_PREV_EP_PTR(ptr)): make prev environment pointer.
+ (VM_ENVVAL_PREV_EP_PTR_P(v)): detect v is prev env pointer.
+
+ * vm.c: apply above changes.
+ (VM_EP_LEP(ep)): get LEP.
+ (VM_CF_LEP(cfp)): get LEP of cfp->ep.
+ (VM_CF_PREV_EP(cfp)): utility function VM_EP_PREV_EP(cfp->ep).
+ (VM_CF_BLOCK_PTR(cfp)): utility function VM_EP_BLOCK_PTR(cfp->ep).
+
+ * vm.c, vm_eval.c, vm_insnhelper.c, vm_insnhelper.h, insns.def:
+ apply above changes.
+
+ * cont.c: ditto.
+
+ * eval.c, eval_intern.h: ditto.
+
+ * proc.c: ditto.
+
+ * thread.c: ditto.
+
+ * vm_dump.c: ditto.
+
+ * vm_exec.h: fix function name (on vm debug mode).
+
Mon Jun 11 11:52:18 2012 URABE Shyouhei <shyouhei@ruby-lang.org>
* compile.c (iseq_set_sequence): nonstatic initializer of an
diff --git a/cont.c b/cont.c
index 4ca1279d02..83769abb59 100644
--- a/cont.c
+++ b/cont.c
@@ -1059,9 +1059,8 @@ fiber_init(VALUE fibval, VALUE proc)
th->cfp->pc = 0;
th->cfp->sp = th->stack + 1;
th->cfp->bp = 0;
- th->cfp->lfp = th->stack;
- *th->cfp->lfp = 0;
- th->cfp->dfp = th->stack;
+ th->cfp->ep = th->stack;
+ *th->cfp->ep = VM_ENVVAL_BLOCK_PTR(0);
th->cfp->self = Qnil;
th->cfp->flag = 0;
th->cfp->iseq = 0;
@@ -1155,8 +1154,8 @@ rb_fiber_start(void)
argv = (argc = cont->argc) > 1 ? RARRAY_PTR(args) : &args;
cont->value = Qnil;
th->errinfo = Qnil;
- th->local_lfp = proc->block.lfp;
- th->local_svar = Qnil;
+ th->root_lep = rb_vm_ep_local_ep(proc->block.ep);
+ th->root_svar = Qnil;
fib->status = RUNNING;
cont->value = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, 0);
diff --git a/eval.c b/eval.c
index 54884850e9..3ec0e1a282 100644
--- a/eval.c
+++ b/eval.c
@@ -604,7 +604,7 @@ rb_block_given_p(void)
{
rb_thread_t *th = GET_THREAD();
- if (RUBY_VM_GET_BLOCK_PTR(th->cfp)) {
+ if (rb_vm_control_frame_block_ptr(th->cfp)) {
return TRUE;
}
else {
@@ -1054,12 +1054,12 @@ errinfo_place(rb_thread_t *th)
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
- return &cfp->dfp[-2];
+ return &cfp->ep[-2];
}
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
- !RB_TYPE_P(cfp->dfp[-2], T_NODE) &&
- !FIXNUM_P(cfp->dfp[-2])) {
- return &cfp->dfp[-2];
+ !RB_TYPE_P(cfp->ep[-2], T_NODE) &&
+ !FIXNUM_P(cfp->ep[-2])) {
+ return &cfp->ep[-2];
}
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
diff --git a/eval_intern.h b/eval_intern.h
index dd1092020b..fb852cbca5 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -5,7 +5,7 @@
#include "vm_core.h"
#define PASS_PASSED_BLOCK_TH(th) do { \
- (th)->passed_block = GC_GUARDED_PTR_REF((rb_block_t *)(th)->cfp->lfp[0]); \
+ (th)->passed_block = rb_vm_control_frame_block_ptr(th->cfp); \
(th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \
} while (0)
diff --git a/insns.def b/insns.def
index a4f792897b..379dbfba03 100644
--- a/insns.def
+++ b/insns.def
@@ -55,7 +55,7 @@ getlocal
()
(VALUE val)
{
- val = *(GET_LFP() - idx);
+ val = *(GET_LEP() - idx);
}
/**
@@ -69,7 +69,7 @@ setlocal
(VALUE val)
()
{
- (*(GET_LFP() - idx)) = val;
+ *(GET_LEP() - idx) = val;
}
/**
@@ -83,7 +83,7 @@ getspecial
()
(VALUE val)
{
- val = vm_getspecial(th, GET_LFP(), key, type);
+ val = vm_getspecial(th, GET_LEP(), key, type);
}
/**
@@ -97,7 +97,7 @@ setspecial
(VALUE obj)
()
{
- lfp_svar_set(th, GET_LFP(), key, obj);
+ lep_svar_set(th, GET_LEP(), key, obj);
}
/**
@@ -114,11 +114,11 @@ getdynamic
(VALUE val)
{
rb_num_t i;
- VALUE *dfp2 = GET_DFP();
+ VALUE *ep = GET_EP();
for (i = 0; i < level; i++) {
- dfp2 = GET_PREV_DFP(dfp2);
+ ep = GET_PREV_EP(ep);
}
- val = *(dfp2 - idx);
+ val = *(ep - idx);
}
/**
@@ -135,11 +135,11 @@ setdynamic
()
{
rb_num_t i;
- VALUE *dfp2 = GET_DFP();
+ VALUE *ep = GET_EP();
for (i = 0; i < level; i++) {
- dfp2 = GET_PREV_DFP(dfp2);
+ ep = GET_PREV_EP(ep);
}
- *(dfp2 - idx) = val;
+ *(ep - idx) = val;
}
/**
@@ -183,7 +183,7 @@ getclassvariable
()
(VALUE val)
{
- NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_EP());
val = rb_cvar_get(vm_get_cvar_base(cref), id);
}
@@ -198,7 +198,7 @@ setclassvariable
(VALUE val)
()
{
- NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_EP());
rb_cvar_set(vm_get_cvar_base(cref), id, val);
}
@@ -343,10 +343,10 @@ putspecialobject
val = rb_mRubyVMFrozenCore;
break;
case VM_SPECIAL_OBJECT_CBASE:
- val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
+ val = vm_get_cbase(GET_ISEQ(), GET_EP());
break;
case VM_SPECIAL_OBJECT_CONST_BASE:
- val = vm_get_const_base(GET_ISEQ(), GET_LFP(), GET_DFP());
+ val = vm_get_const_base(GET_ISEQ(), GET_EP());
break;
default:
rb_bug("putspecialobject insn: unknown value_type");
@@ -768,7 +768,7 @@ defined
}
break;
case DEFINED_IVAR2:
- klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
+ klass = vm_get_cbase(GET_ISEQ(), GET_EP());
break;
case DEFINED_GVAR:
if (rb_gvar_defined(rb_global_entry(SYM2ID(obj)))) {
@@ -777,7 +777,7 @@ defined
break;
case DEFINED_CVAR:
{
- NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_EP());
klass = vm_get_cvar_base(cref);
if (rb_cvar_defined(klass, SYM2ID(obj))) {
expr_type = "class variable";
@@ -842,7 +842,7 @@ defined
break;
}
case DEFINED_REF:{
- val = vm_getspecial(th, GET_LFP(), Qfalse, FIX2INT(obj));
+ val = vm_getspecial(th, GET_LEP(), Qfalse, FIX2INT(obj));
if (val != Qnil) {
expr_type = "global-variable";
}
@@ -971,9 +971,9 @@ defineclass
COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL));
/* enter scope */
- vm_push_frame(th, class_iseq,
- VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_BLOCK_PTR(),
- class_iseq->iseq_encoded, GET_SP(), 0,
+ vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS,
+ klass, VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
+ class_iseq->iseq_encoded, GET_SP(),
class_iseq->local_size);
RESTORE_REGS();
@@ -1315,11 +1315,11 @@ opt_checkenv
()
()
{
- if (GET_CFP()->bp != GET_DFP() + 1) {
- VALUE *new_dfp = GET_CFP()->bp - 1;
+ if (GET_CFP()->bp != GET_EP() + 1) {
+ VALUE *ep = GET_CFP()->bp - 1;
/* TODO: copy env and clean stack at creating env? */
- *new_dfp = *GET_DFP();
- SET_DFP(new_dfp);
+ *ep = *GET_EP();
+ SET_EP(ep);
}
}
diff --git a/proc.c b/proc.c
index b0437db9cd..1298c21c93 100644
--- a/proc.c
+++ b/proc.c
@@ -383,17 +383,13 @@ proc_new(VALUE klass, int is_lambda)
rb_control_frame_t *cfp = th->cfp;
rb_block_t *block;
- if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) {
-
- block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
+ if ((block = rb_vm_control_frame_block_ptr(cfp)) != 0) {
+ /* block found */
}
else {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) {
-
- block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
-
+ if ((block = rb_vm_control_frame_block_ptr(cfp)) != 0) {
if (is_lambda) {
rb_warn("tried to create Proc object without a block");
}
@@ -418,7 +414,7 @@ proc_new(VALUE klass, int is_lambda)
}
procval = rb_vm_make_proc(th, block, klass);
- rb_vm_rewrite_dfp_in_errinfo(th, cfp);
+ rb_vm_rewrite_ep_in_errinfo(th, cfp);
if (is_lambda) {
rb_proc_t *proc;
@@ -801,7 +797,7 @@ rb_hash_proc(st_index_t hash, VALUE prc)
GetProcPtr(prc, proc);
hash = rb_hash_uint(hash, (st_index_t)proc->block.iseq);
hash = rb_hash_uint(hash, (st_index_t)proc->envval);
- return rb_hash_uint(hash, (st_index_t)proc->block.lfp >> 16);
+ return rb_hash_uint(hash, (st_index_t)proc->block.ep >> 16);
}
/*
diff --git a/thread.c b/thread.c
index 609e726620..6ad4503470 100644
--- a/thread.c
+++ b/thread.c
@@ -454,8 +454,8 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
if (!th->first_func) {
GetProcPtr(th->first_proc, proc);
th->errinfo = Qnil;
- th->local_lfp = proc->block.lfp;
- th->local_svar = Qnil;
+ th->root_lep = rb_vm_ep_local_ep(proc->block.ep);
+ th->root_svar = Qnil;
th->value = rb_vm_invoke_proc(th, proc, proc->block.self,
(int)RARRAY_LEN(args), RARRAY_PTR(args), 0);
}
diff --git a/vm.c b/vm.c
index 0f7f0923d4..7a7de59f3a 100644
--- a/vm.c
+++ b/vm.c
@@ -19,6 +19,48 @@
#include "iseq.h"
#include "eval_intern.h"
+static inline VALUE *
+VM_EP_LEP(VALUE *ep)
+{
+ while (1) {
+ if (VM_EP_LEP_P(ep)) {
+ return ep;
+ }
+ ep = VM_EP_PREV_EP(ep);
+ }
+}
+
+VALUE *
+rb_vm_ep_local_ep(VALUE *ep)
+{
+ return VM_EP_LEP(ep);
+}
+
+static inline VALUE *
+VM_CF_LEP(rb_control_frame_t *cfp)
+{
+ return VM_EP_LEP(cfp->ep);
+}
+
+static inline VALUE *
+VM_CF_PREV_EP(rb_control_frame_t * cfp)
+{
+ return VM_EP_PREV_EP((cfp)->ep);
+}
+
+static inline rb_block_t *
+VM_CF_BLOCK_PTR(rb_control_frame_t *cfp)
+{
+ VALUE *ep = VM_CF_LEP(cfp);
+ return VM_EP_BLOCK_PTR(ep);
+}
+
+rb_block_t *
+rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp)
+{
+ return VM_CF_BLOCK_PTR(cfp);
+}
+
#include "vm_insnhelper.h"
#include "vm_insnhelper.c"
#include "vm_exec.h"
@@ -85,8 +127,8 @@ static inline VALUE
rb_vm_set_finish_env(rb_thread_t * th)
{
vm_push_frame(th, 0, VM_FRAME_MAGIC_FINISH,
- Qnil, th->cfp->lfp[0], 0,
- th->cfp->sp, 0, 1);
+ Qnil, VM_ENVVAL_BLOCK_PTR(VM_CF_BLOCK_PTR(th->cfp)), 0,
+ th->cfp->sp, 1);
th->cfp->pc = (VALUE *)&finish_insn_seq[0];
return Qtrue;
}
@@ -106,8 +148,8 @@ vm_set_top_stack(rb_thread_t * th, VALUE iseqval)
CHECK_STACK_OVERFLOW(th->cfp, iseq->local_size + iseq->stack_max);
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP,
- th->top_self, 0, iseq->iseq_encoded,
- th->cfp->sp, 0, iseq->local_size);
+ th->top_self, VM_ENVVAL_BLOCK_PTR(0), iseq->iseq_encoded,
+ th->cfp->sp, iseq->local_size);
}
static void
@@ -122,11 +164,11 @@ vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref)
CHECK_STACK_OVERFLOW(th->cfp, iseq->local_size + iseq->stack_max);
vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL, block->self,
- GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded,
- th->cfp->sp, block->lfp, iseq->local_size);
+ VM_ENVVAL_PREV_EP_PTR(block->ep), iseq->iseq_encoded,
+ th->cfp->sp, iseq->local_size);
if (cref) {
- th->cfp->dfp[-1] = (VALUE)cref;
+ th->cfp->ep[-1] = (VALUE)cref;
}
}
@@ -298,11 +340,10 @@ static int
check_env(rb_env_t * const env)
{
fprintf(stderr, "---\n");
- fprintf(stderr, "envptr: %p\n", (void *)&env->block.dfp[0]);
- fprintf(stderr, "envval: %10p ", (void *)env->block.dfp[1]);
- dp(env->block.dfp[1]);
- fprintf(stderr, "lfp: %10p\n", (void *)env->block.lfp);
- fprintf(stderr, "dfp: %10p\n", (void *)env->block.dfp);
+ fprintf(stderr, "envptr: %p\n", (void *)&env->block.ep[0]);
+ fprintf(stderr, "envval: %10p ", (void *)env->block.ep[1]);
+ dp(env->block.ep[1]);
+ fprintf(stderr, "ep: %10p\n", (void *)env->block.ep);
if (env->prev_envval) {
fprintf(stderr, ">>\n");
check_env_value(env->prev_envval);
@@ -345,16 +386,15 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp,
penvval = ENV_VAL(penvptr);
}
else {
- while (pcfp->dfp != penvptr) {
+ while (pcfp->ep != penvptr) {
pcfp++;
- if (pcfp->dfp == 0) {
+ if (pcfp->ep == 0) {
SDR();
- rb_bug("invalid dfp");
+ rb_bug("invalid ep");
}
}
penvval = vm_make_env_each(th, pcfp, penvptr, endptr);
- cfp->lfp = pcfp->lfp;
- *envptr = GC_GUARDED_PTR(pcfp->dfp);
+ *envptr = VM_ENVVAL_PREV_EP_PTR(pcfp->ep);
}
}
@@ -389,23 +429,19 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp,
nenvptr = &env->env[i - 1];
nenvptr[1] = envval; /* frame self */
- /* reset lfp/dfp in cfp */
- cfp->dfp = nenvptr;
- if (envptr == endptr) {
- cfp->lfp = nenvptr;
- }
+ /* reset ep in cfp */
+ cfp->ep = nenvptr;
/* as Binding */
env->block.self = cfp->self;
- env->block.lfp = cfp->lfp;
- env->block.dfp = cfp->dfp;
+ env->block.ep = cfp->ep;
env->block.iseq = cfp->iseq;
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
/* TODO */
env->block.iseq = 0;
} else {
- rb_vm_rewrite_dfp_in_errinfo(th, cfp);
+ rb_vm_rewrite_ep_in_errinfo(th, cfp);
}
return envval;
}
@@ -436,11 +472,11 @@ collect_local_variables_in_env(rb_env_t * env, const VALUE ary)
}
static int
-vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary)
+vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *ep, VALUE ary)
{
- if (ENV_IN_HEAP_P(th, dfp)) {
+ if (ENV_IN_HEAP_P(th, ep)) {
rb_env_t *env;
- GetEnvPtr(ENV_VAL(dfp), env);
+ GetEnvPtr(ENV_VAL(ep), env);
collect_local_variables_in_env(env, ary);
return 1;
}
@@ -459,7 +495,7 @@ rb_vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp)
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
- envval = vm_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
+ envval = vm_make_env_each(th, cfp, cfp->ep, VM_CF_LEP(cfp));
if (PROCDEBUG) {
check_env_value(envval);
@@ -469,21 +505,21 @@ rb_vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp)
}
void
-rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp)
+rb_vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp)
{
- /* rewrite dfp in errinfo to point to heap */
+ /* rewrite ep in errinfo to point to heap */
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
(cfp->iseq->type == ISEQ_TYPE_RESCUE ||
cfp->iseq->type == ISEQ_TYPE_ENSURE)) {
- VALUE errinfo = cfp->dfp[-2]; /* #$! */
+ VALUE errinfo = cfp->ep[-2]; /* #$! */
if (RB_TYPE_P(errinfo, T_NODE)) {
- VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
- if (! ENV_IN_HEAP_P(th, escape_dfp)) {
- VALUE dfpval = *escape_dfp;
- if (CLASS_OF(dfpval) == rb_cEnv) {
- rb_env_t *dfpenv;
- GetEnvPtr(dfpval, dfpenv);
- SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
+ VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(errinfo);
+ if (! ENV_IN_HEAP_P(th, escape_ep)) {
+ VALUE epval = *escape_ep;
+ if (CLASS_OF(epval) == rb_cEnv) {
+ rb_env_t *epenv;
+ GetEnvPtr(epval, epenv);
+ SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(epenv->env + epenv->local_size));
}
}
}
@@ -517,19 +553,19 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
VALUE procval, envval, blockprocval = 0;
rb_proc_t *proc;
rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);
+ rb_block_t *block2;
if (block->proc) {
rb_bug("rb_vm_make_proc: Proc value is already created.");
}
- if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
+ if ((block2 = VM_CF_BLOCK_PTR(cfp)) != 0) {
rb_proc_t *p;
- blockprocval = vm_make_proc_from_block(
- th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp));
+ blockprocval = vm_make_proc_from_block(th, block2);
GetProcPtr(blockprocval, p);
- *cfp->lfp = GC_GUARDED_PTR(&p->block);
+ *VM_CF_LEP(cfp) = VM_ENVVAL_BLOCK_PTR(&p->block);
}
envval = rb_vm_make_env_object(th, cfp);
@@ -541,19 +577,15 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
GetProcPtr(procval, proc);
proc->blockprocval = blockprocval;
proc->block.self = block->self;
- proc->block.lfp = block->lfp;
- proc->block.dfp = block->dfp;
+ proc->block.ep = block->ep;
proc->block.iseq = block->iseq;
proc->block.proc = procval;
proc->envval = envval;
proc->safe_level = th->safe_level;
if (VMDEBUG) {
- if (th->stack < block->dfp && block->dfp < th->stack + th->stack_size) {
- rb_bug("invalid ptr: block->dfp");
- }
- if (th->stack < block->lfp && block->lfp < th->stack + th->stack_size) {
- rb_bug("invalid ptr: block->lfp");
+ if (th->stack < block->ep && block->ep < th->stack + th->stack_size) {
+ rb_bug("invalid ptr: block->ep");
}
}
@@ -590,15 +622,14 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
type == VM_FRAME_MAGIC_LAMBDA);
ncfp = vm_push_frame(th, iseq, type,
- self, GC_GUARDED_PTR(block->dfp),
- iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
- iseq->local_size - arg_size);
+ self, VM_ENVVAL_PREV_EP_PTR(block->ep),
+ iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, iseq->local_size - arg_size);
ncfp->me = th->passed_me;
th->passed_me = 0;
th->passed_block = blockptr;
if (cref) {
- th->cfp->dfp[-1] = (VALUE)cref;
+ th->cfp->ep[-1] = (VALUE)cref;
}
return vm_exec(th);
@@ -611,7 +642,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
static inline const rb_block_t *
check_block(rb_thread_t *th)
{
- const rb_block_t *blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
+ const rb_block_t *blockptr = VM_CF_BLOCK_PTR(th->cfp);
if (blockptr == 0) {
rb_vm_localjump_error("no block given", Qnil, 0);
@@ -679,14 +710,14 @@ static VALUE
vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key)
{
cfp = vm_normal_frame(th, cfp);
- return lfp_svar_get(th, cfp ? cfp->lfp : 0, key);
+ return lep_svar_get(th, cfp ? VM_CF_LEP(cfp) : 0, key);
}
static void
vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, const VALUE val)
{
cfp = vm_normal_frame(th, cfp);
- lfp_svar_set(th, cfp ? cfp->lfp : 0, key, val);
+ lep_svar_set(th, cfp ? VM_CF_LEP(cfp) : 0, key, val);
}
static VALUE
@@ -780,7 +811,7 @@ rb_vm_cref(void)
if (cfp == 0) {
rb_raise(rb_eRuntimeError, "Can't call on top of Fiber or Thread");
}
- return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
+ return vm_get_cref(cfp->iseq, cfp->ep);
}
#if 0
@@ -804,7 +835,7 @@ rb_vm_cbase(void)
if (cfp == 0) {
rb_raise(rb_eRuntimeError, "Can't call on top of Fiber or Thread");
}
- return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp);
+ return vm_get_cbase(cfp->iseq, cfp->ep);
}
/* jump */
@@ -896,10 +927,10 @@ static void
vm_iter_break(rb_thread_t *th, VALUE val)
{
rb_control_frame_t *cfp = th->cfp;
- VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp);
+ VALUE *ep = VM_CF_PREV_EP(cfp);
th->state = TAG_BREAK;
- th->errinfo = (VALUE)NEW_THROW_OBJECT(val, (VALUE)dfp, TAG_BREAK);
+ th->errinfo = (VALUE)NEW_THROW_OBJECT(val, (VALUE)ep, TAG_BREAK);
TH_JUMP_TAG(th, TAG_BREAK);
}
@@ -1028,16 +1059,14 @@ vm_frametype_name(const rb_control_frame_t *cfp)
rb_iseq_t *iseq; // cfp[3], iseq
VALUE flag; // cfp[4], magic
VALUE self; // cfp[5], self
- VALUE *lfp; // cfp[6], local frame pointer
- VALUE *dfp; // cfp[7], dynamic frame pointer
- rb_iseq_t * block_iseq; // cfp[8], block iseq
- VALUE proc; // cfp[9], always 0
+ VALUE *ep; // cfp[6], env pointer
+ rb_iseq_t * block_iseq; // cfp[7], block iseq
+ VALUE proc; // cfp[8], always 0
};
struct BLOCK {
VALUE self;
- VALUE *lfp;
- VALUE *dfp;
+ VALUE *ep;
rb_iseq_t *block_iseq;
VALUE proc;
};
@@ -1054,8 +1083,8 @@ vm_frametype_name(const rb_control_frame_t *cfp)
...
VALUE paramN;
VALUE cref;
- VALUE special; // lfp [1]
- struct block_object *block_ptr | 0x01; // lfp [0]
+ VALUE special; // lep [1]
+ struct block_object *block_ptr | 0x01; // lep [0]
};
struct BLOCK_CONTROL_FRAME {
@@ -1070,7 +1099,7 @@ vm_frametype_name(const rb_control_frame_t *cfp)
...
VALUE paramN;
VALUE cref;
- VALUE *(prev_ptr | 0x01); // DFP[0]
+ VALUE *(prev_ptr | 0x01); // ep[0]
};
struct CLASS_CONTROL_FRAME {
@@ -1082,30 +1111,28 @@ vm_frametype_name(const rb_control_frame_t *cfp)
...
VALUE paramN;
VALUE cref;
- VALUE prev_dfp; // for frame jump
+ VALUE prev_ep; // for frame jump
};
struct C_METHOD_CONTROL_FRAME {
VALUE *pc; // 0
VALUE *sp; // stack pointer
VALUE *bp; // base pointer (used in exception)
- rb_iseq_t *iseq; // cmi
+ rb_iseq_t *iseq; // cmi
VALUE magic; // C_METHOD_FRAME
VALUE self; // ?
- VALUE *lfp; // lfp
- VALUE *dfp; // == lfp
- rb_iseq_t * block_iseq; //
+ VALUE *ep; // ep == lep
+ rb_iseq_t * block_iseq; //
VALUE proc; // always 0
};
struct C_BLOCK_CONTROL_FRAME {
VALUE *pc; // point only "finish" insn
VALUE *sp; // sp
- rb_iseq_t *iseq; // ?
+ rb_iseq_t *iseq; // ?
VALUE magic; // C_METHOD_FRAME
VALUE self; // needed?
- VALUE *lfp; // lfp
- VALUE *dfp; // lfp
+ VALUE *ep; // ep
rb_iseq_t * block_iseq; // 0
};
*/
@@ -1117,7 +1144,7 @@ vm_exec(rb_thread_t *th)
int state;
VALUE result, err;
VALUE initial = 0;
- VALUE *escape_dfp = NULL;
+ VALUE *escape_ep = NULL;
TH_PUSH_TAG(th);
_tag.retval = Qnil;
@@ -1155,12 +1182,12 @@ vm_exec(rb_thread_t *th)
epc = cfp->pc - cfp->iseq->iseq_encoded;
if (state == TAG_BREAK || state == TAG_RETURN) {
- escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
+ escape_ep = GET_THROWOBJ_CATCH_POINT(err);
- if (cfp->dfp == escape_dfp) {
+ if (cfp->ep == escape_ep) {
if (state == TAG_RETURN) {
if ((cfp + 1)->pc != &finish_insn_seq[0]) {
- SET_THROWOBJ_CATCH_POINT(err, (VALUE)(cfp + 1)->dfp);
+ SET_THROWOBJ_CATCH_POINT(err, (VALUE)(cfp + 1)->ep);
SET_THROWOBJ_STATE(err, state = TAG_BREAK);
}
else {
@@ -1224,9 +1251,9 @@ vm_exec(rb_thread_t *th)
break;
}
else if (entry->type == CATCH_TYPE_RETRY) {
- VALUE *escape_dfp;
- escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
- if (cfp->dfp == escape_dfp) {
+ VALUE *escape_ep;
+ escape_ep = GET_THROWOBJ_CATCH_POINT(err);
+ if (cfp->ep == escape_ep) {
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
th->errinfo = Qnil;
goto vm_loop_start;
@@ -1235,7 +1262,7 @@ vm_exec(rb_thread_t *th)
}
}
}
- else if (state == TAG_BREAK && ((VALUE)escape_dfp & ~0x03) == 0) {
+ else if (state == TAG_BREAK && ((VALUE)escape_ep & ~0x03) == 0) {
type = CATCH_TYPE_BREAK;
search_restart_point:
@@ -1302,8 +1329,8 @@ vm_exec(rb_thread_t *th)
/* push block frame */
cfp->sp[0] = err;
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK,
- cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
- cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1);
+ cfp->self, VM_ENVVAL_PREV_EP_PTR(cfp->ep), catch_iseq->iseq_encoded,
+ cfp->sp + 1 /* push value */, catch_iseq->local_size - 1);
state = 0;
th->state = 0;
@@ -1438,7 +1465,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
VALUE val;
vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP,
- recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
+ recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1);
val = (*func)(arg);
@@ -1645,7 +1672,7 @@ rb_thread_mark(void *ptr)
RUBY_MARK_UNLESS_NULL(th->value);
RUBY_MARK_UNLESS_NULL(th->errinfo);
RUBY_MARK_UNLESS_NULL(th->thrown_errinfo);
- RUBY_MARK_UNLESS_NULL(th->local_svar);
+ RUBY_MARK_UNLESS_NULL(th->root_svar);
RUBY_MARK_UNLESS_NULL(th->top_self);
RUBY_MARK_UNLESS_NULL(th->top_wrapper);
RUBY_MARK_UNLESS_NULL(th->fiber);
@@ -1781,8 +1808,8 @@ th_init(rb_thread_t *th, VALUE self)
th->cfp = (void *)(th->stack + th->stack_size);
- vm_push_frame(th, 0, VM_FRAME_MAGIC_TOP, Qnil, 0, 0,
- th->stack, 0, 1);
+ vm_push_frame(th, 0 /* dummy iseq */, VM_FRAME_MAGIC_TOP, Qnil /* dummy self */,
+ VM_ENVVAL_BLOCK_PTR(0), 0 /* dummy pc */, th->stack, 1);
th->status = THREAD_RUNNABLE;
th->errinfo = Qnil;
diff --git a/vm_core.h b/vm_core.h
index d71e34a899..e00f32ad09 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -349,17 +349,15 @@ typedef struct {
rb_iseq_t *iseq; /* cfp[3] */
VALUE flag; /* cfp[4] */
VALUE self; /* cfp[5] / block[0] */
- VALUE *lfp; /* cfp[6] / block[1] */
- VALUE *dfp; /* cfp[7] / block[2] */
- rb_iseq_t *block_iseq; /* cfp[8] / block[3] */
- VALUE proc; /* cfp[9] / block[4] */
- const rb_method_entry_t *me;/* cfp[10] */
+ VALUE *ep; /* cfp[6] / block[1] */
+ rb_iseq_t *block_iseq; /* cfp[7] / block[2] */
+ VALUE proc; /* cfp[8] / block[3] */
+ const rb_method_entry_t *me;/* cfp[9] */
} rb_control_frame_t;
typedef struct rb_block_struct {
VALUE self; /* share with method frame if it's only block */
- VALUE *lfp; /* share with method frame if it's only block */
- VALUE *dfp; /* share with method frame if it's only block */
+ VALUE *ep; /* share with method frame if it's only block */
rb_iseq_t *iseq;
VALUE proc;
} rb_block_t;
@@ -434,8 +432,8 @@ typedef struct rb_thread_struct {
/* eval env */
rb_block_t *base_block;
- VALUE *local_lfp;
- VALUE local_svar;
+ VALUE *root_lep;
+ VALUE root_svar;
/* thread control */
rb_thread_id_t thread_id;
@@ -622,7 +620,27 @@ typedef rb_control_frame_t *
#define GC_GUARDED_PTR_REF(p) ((void *)(((VALUE)(p)) & ~0x03))
#define GC_GUARDED_PTR_P(p) (((VALUE)(p)) & 0x01)
-#define RUBY_VM_GET_BLOCK_PTR(cfp) ((rb_block_t *)(GC_GUARDED_PTR_REF((cfp)->lfp[0])))
+/*
+ * block frame:
+ * ep[ 0]: prev frame
+ * ep[-1]: CREF (for *_eval)
+ *
+ * method frame:
+ * ep[ 0]: block pointer (ptr | VM_ENVVAL_BLOCK_PTR_FLAG)
+ */
+
+#define VM_ENVVAL_BLOCK_PTR_FLAG 0x02
+#define VM_ENVVAL_BLOCK_PTR(v) (GC_GUARDED_PTR(v) | VM_ENVVAL_BLOCK_PTR_FLAG)
+#define VM_ENVVAL_BLOCK_PTR_P(v) ((v) & VM_ENVVAL_BLOCK_PTR_FLAG)
+#define VM_ENVVAL_PREV_EP_PTR(v) ((VALUE)GC_GUARDED_PTR(v))
+#define VM_ENVVAL_PREV_EP_PTR_P(v) (!(VM_ENVVAL_BLOCK_PTR_P(v)))
+
+#define VM_EP_PREV_EP(ep) ((VALUE *)GC_GUARDED_PTR_REF((ep)[0]))
+#define VM_EP_BLOCK_PTR(ep) ((rb_block_t *)GC_GUARDED_PTR_REF((ep)[0]))
+#define VM_EP_LEP_P(ep) VM_ENVVAL_BLOCK_PTR_P((ep)[0])
+
+VALUE *rb_vm_ep_local_ep(VALUE *ep);
+rb_block_t *rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp);
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) ((cfp)+1)
#define RUBY_VM_NEXT_CONTROL_FRAME(cfp) ((cfp)-1)
@@ -647,6 +665,9 @@ VALUE rb_proc_alloc(VALUE klass);
/* for debug */
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);
+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()->cfp)
#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_THREAD(), (cfp))
void rb_vm_bugreport(void);
@@ -666,7 +687,7 @@ VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
int argc, const VALUE *argv, const rb_block_t *blockptr);
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
-void rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp);
+void rb_vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp);
void rb_vm_inc_const_missing_count(void);
void rb_vm_gvl_destroy(rb_vm_t *vm);
VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc,
diff --git a/vm_dump.c b/vm_dump.c
index 2766677cf3..d38f114b86 100644
--- a/vm_dump.c
+++ b/vm_dump.c
@@ -28,9 +28,8 @@ static void
control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
{
ptrdiff_t pc = -1, bp = -1;
- ptrdiff_t lfp = cfp->lfp - th->stack;
- ptrdiff_t dfp = cfp->dfp - th->stack;
- char lfp_in_heap = ' ', dfp_in_heap = ' ';
+ ptrdiff_t ep = cfp->ep - th->stack;
+ char ep_in_heap = ' ';
char posbuf[MAX_POSBUF+1];
int line = 0;
int nopos = 0;
@@ -42,13 +41,9 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */
}
- if (lfp < 0 || (size_t)lfp > th->stack_size) {
- lfp = (ptrdiff_t)cfp->lfp;
- lfp_in_heap = 'p';
- }
- if (dfp < 0 || (size_t)dfp > th->stack_size) {
- dfp = (ptrdiff_t)cfp->dfp;
- dfp_in_heap = 'p';
+ if (ep < 0 || (size_t)ep > th->stack_size) {
+ ep = (ptrdiff_t)cfp->ep;
+ ep_in_heap = 'p';
}
if (cfp->bp) {
bp = cfp->bp - th->stack;
@@ -133,8 +128,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc);
}
fprintf(stderr, "s:%04"PRIdPTRDIFF" b:%04"PRIdPTRDIFF" ", (cfp->sp - th->stack), bp);
- fprintf(stderr, lfp_in_heap == ' ' ? "l:%06"PRIdPTRDIFF" " : "l:%06"PRIxPTRDIFF" ", lfp % 10000);
- fprintf(stderr, dfp_in_heap == ' ' ? "d:%06"PRIdPTRDIFF" " : "d:%06"PRIxPTRDIFF" ", dfp % 10000);
+ fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "e:%06"PRIxPTRDIFF" ", ep % 10000);
fprintf(stderr, "%-6s", magic);
if (line && !nopos) {
fprintf(stderr, " %s", posbuf);
@@ -152,9 +146,7 @@ void
rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
{
#if 0
- VALUE *sp = cfp->sp, *bp = cfp->bp;
- VALUE *lfp = cfp->lfp;
- VALUE *dfp = cfp->dfp;
+ VALUE *sp = cfp->sp, *bp = cfp->bp, *ep = cfp->ep;
VALUE *p, *st, *t;
fprintf(stderr, "-- stack frame ------------\n");
@@ -166,10 +158,8 @@ rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF(t) - th->stack));
}
- if (p == lfp)
- fprintf(stderr, " <- lfp");
- if (p == dfp)
- fprintf(stderr, " <- dfp");
+ if (p == ep)
+ fprintf(stderr, " <- ep");
if (p == bp)
fprintf(stderr, " <- bp"); /* should not be */
@@ -194,7 +184,7 @@ rb_vmdebug_stack_dump_raw_current(void)
}
void
-rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp)
+rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *ep)
{
int i;
fprintf(stderr, "-- env --------------------\n");
@@ -204,10 +194,8 @@ rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp)
for (i = 0; i < env->env_size; i++) {
fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", -env->local_size + i, env->env[i],
(void *)&env->env[i]);
- if (&env->env[i] == lfp)
- fprintf(stderr, " <- lfp");
- if (&env->env[i] == dfp)
- fprintf(stderr, " <- dfp");
+ if (&env->env[i] == ep)
+ fprintf(stderr, " <- ep");
fprintf(stderr, "\n");
}
@@ -232,7 +220,7 @@ rb_vmdebug_proc_dump_raw(rb_proc_t *proc)
fprintf(stderr, "-- proc -------------------\n");
fprintf(stderr, "self: %s\n", selfstr);
GetEnvPtr(proc->envval, env);
- rb_vmdebug_env_dump_raw(env, proc->block.lfp, proc->block.dfp);
+ rb_vmdebug_env_dump_raw(env, proc->block.ep);
}
void
@@ -251,8 +239,7 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
VALUE rstr;
VALUE *sp = cfp->sp;
- VALUE *lfp = cfp->lfp;
- VALUE *dfp = cfp->dfp;
+ VALUE *ep = cfp->ep;
int argc = 0, local_size = 0;
const char *name;
@@ -287,14 +274,11 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_IFUNC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL) {
- VALUE *ptr = dfp - local_size;
+ VALUE *ptr = ep - local_size;
vm_stack_dump_each(th, cfp + 1);
control_frame_dump(th, cfp);
- if (lfp != dfp) {
- local_size++;
- }
for (i = 0; i < argc; i++) {
rstr = rb_inspect(*ptr);
fprintf(stderr, " arg %2d: %8s (%p)\n", i, StringValueCStr(rstr),
@@ -337,22 +321,20 @@ rb_vmdebug_debug_print_register(rb_thread_t *th)
{
rb_control_frame_t *cfp = th->cfp;
ptrdiff_t pc = -1;
- ptrdiff_t lfp = cfp->lfp - th->stack;
- ptrdiff_t dfp = cfp->dfp - th->stack;
+ ptrdiff_t ep = cfp->ep - th->stack;
ptrdiff_t cfpi;
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
pc = cfp->pc - cfp->iseq->iseq_encoded;
}
- if (lfp < 0 || (size_t)lfp > th->stack_size)
- lfp = -1;
- if (dfp < 0 || (size_t)dfp > th->stack_size)
- dfp = -1;
+ if (ep < 0 || (size_t)ep > th->stack_size) {
+ ep = -1;
+ }
cfpi = ((rb_control_frame_t *)(th->stack + th->stack_size)) - cfp;
- fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [LFP] %04"PRIdPTRDIFF", [DFP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n",
- pc, (cfp->sp - th->stack), lfp, dfp, cfpi);
+ fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n",
+ pc, (cfp->sp - th->stack), ep, cfpi);
}
void
@@ -371,8 +353,13 @@ rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp)
if (iseq != 0 && VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_FINISH) {
VALUE *seq = iseq->iseq;
ptrdiff_t pc = cfp->pc - iseq->iseq_encoded;
+ int i;
- printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp));
+ for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) {
+ printf(" ");
+ }
+ printf("| ");
+ /* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp)); */
if (pc >= 0) {
rb_iseq_disasm_insn(0, seq, (size_t)pc, iseq, 0);
}
@@ -518,11 +505,10 @@ vm_analysis_register(int reg, int isset)
static const char regstrs[][5] = {
"pc", /* 0 */
"sp", /* 1 */
- "cfp", /* 2 */
- "lfp", /* 3 */
- "dfp", /* 4 */
- "self", /* 5 */
- "iseq", /* 6 */
+ "ep", /* 2 */
+ "cfp", /* 3 */
+ "self", /* 4 */
+ "iseq", /* 5 */
};
static const char getsetstr[][4] = {
"get",
@@ -568,7 +554,7 @@ rb_vmdebug_thread_dump_state(VALUE self)
fprintf(stderr, "Thread state dump:\n");
fprintf(stderr, "pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp);
- fprintf(stderr, "cfp: %p, lfp: %p, dfp: %p\n", (void *)cfp, (void *)cfp->lfp, (void *)cfp->dfp);
+ fprintf(stderr, "cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep);
return Qnil;
}
diff --git a/vm_eval.c b/vm_eval.c
index 8ea149c459..31511b986f 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -74,7 +74,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
rb_control_frame_t *reg_cfp = th->cfp;
rb_control_frame_t *cfp =
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
- recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
+ recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1);
cfp->me = me;
val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv);
@@ -896,7 +896,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
blockptr->proc = 0;
}
else {
- blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
+ blockptr = VM_CF_BLOCK_PTR(th->cfp);
}
th->passed_block = blockptr;
}
@@ -905,10 +905,10 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
else {
VALUE err = th->errinfo;
if (state == TAG_BREAK) {
- VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
- VALUE *cdfp = cfp->dfp;
+ VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err);
+ VALUE *cep = cfp->ep;
- if (cdfp == escape_dfp) {
+ if (cep == escape_ep) {
state = 0;
th->state = 0;
th->errinfo = Qnil;
@@ -932,10 +932,10 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
}
}
else if (state == TAG_RETRY) {
- VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
- VALUE *cdfp = cfp->dfp;
+ VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err);
+ VALUE *cep = cfp->ep;
- if (cdfp == escape_dfp) {
+ if (cep == escape_ep) {
state = 0;
th->state = 0;
th->errinfo = Qnil;
@@ -1247,10 +1247,10 @@ yield_under(VALUE under, VALUE self, VALUE values)
rb_block_t block, *blockptr;
NODE *cref;
- if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) {
+ if ((blockptr = VM_CF_BLOCK_PTR(th->cfp)) != 0) {
block = *blockptr;
block.self = self;
- th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
+ VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
}
cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
@@ -1611,15 +1611,15 @@ rb_f_local_variables(void)
}
}
}
- if (cfp->lfp != cfp->dfp) {
+ if (!VM_EP_LEP_P(cfp->ep)) {
/* block */
- VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
+ VALUE *ep = VM_CF_PREV_EP(cfp);
- if (vm_collect_local_variables_in_heap(th, dfp, ary)) {
+ if (vm_collect_local_variables_in_heap(th, ep, ary)) {
break;
}
else {
- while (cfp->dfp != dfp) {
+ while (cfp->ep != ep) {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
}
@@ -1660,7 +1660,7 @@ rb_f_block_given_p(void)
rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
- if (cfp != 0 && RUBY_VM_GET_BLOCK_PTR(cfp)) {
+ if (cfp != 0 && VM_CF_BLOCK_PTR(cfp)) {
return Qtrue;
}
else {
diff --git a/vm_exec.h b/vm_exec.h
index caf752a76b..4f8b030e68 100644
--- a/vm_exec.h
+++ b/vm_exec.h
@@ -38,7 +38,7 @@ typedef rb_iseq_t *ISEQ;
#if VMDEBUG > 0
#define debugs printf
#define DEBUG_ENTER_INSN(insn) \
- debug_print_pre(th, GET_CFP());
+ rb_vmdebug_debug_print_pre(th, GET_CFP());
#if OPT_STACK_CACHING
#define SC_REGS() , reg_a, reg_b
@@ -47,7 +47,7 @@ typedef rb_iseq_t *ISEQ;
#endif
#define DEBUG_END_INSN() \
- debug_print_post(th, GET_CFP() SC_REGS());
+ rb_vmdebug_debug_print_post(th, GET_CFP() SC_REGS());
#else
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index a4b4b8fe78..2e00c0e1de 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -23,53 +23,47 @@
static rb_control_frame_t *vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
static inline rb_control_frame_t *
-vm_push_frame(rb_thread_t * th, const rb_iseq_t * iseq,
- VALUE type, VALUE self, VALUE specval,
- const VALUE *pc, VALUE *sp, VALUE *lfp,
+vm_push_frame(rb_thread_t *th,
+ const rb_iseq_t *iseq,
+ VALUE type,
+ VALUE self,
+ VALUE specval,
+ const VALUE *pc,
+ VALUE *sp,
int local_size)
{
- rb_control_frame_t * const cfp = th->cfp - 1;
+ rb_control_frame_t *const cfp = th->cfp - 1;
int i;
+ /* check stack overflow */
if ((void *)(sp + local_size) >= (void *)cfp) {
rb_exc_raise(sysstack_error);
}
th->cfp = cfp;
+
/* setup vm value stack */
- /* nil initialize */
+ /* initialize local variables */
for (i=0; i < local_size; i++) {
- *sp = Qnil;
- sp++;
+ *sp++ = Qnil;
}
/* set special val */
- *sp = GC_GUARDED_PTR(specval);
-
- if (lfp == 0) {
- lfp = sp;
- }
+ *sp = specval;
/* setup vm control frame stack */
cfp->pc = (VALUE *)pc;
cfp->sp = sp + 1;
cfp->bp = sp + 1;
+ cfp->ep = sp;
cfp->iseq = (rb_iseq_t *) iseq;
cfp->flag = type;
cfp->self = self;
- cfp->lfp = lfp;
- cfp->dfp = sp;
cfp->block_iseq = 0;
cfp->proc = 0;
cfp->me = 0;
-#define COLLECT_PROFILE 0
-#if COLLECT_PROFILE
- cfp->prof_time_self = clock();
- cfp->prof_time_chld = 0;
-#endif
-
if (VMDEBUG == 2) {
SDR();
}
@@ -80,23 +74,6 @@ vm_push_frame(rb_thread_t * th, const rb_iseq_t * iseq,
static inline void
vm_pop_frame(rb_thread_t *th)
{
-#if COLLECT_PROFILE
- rb_control_frame_t *cfp = th->cfp;
-
- if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- VALUE current_time = clock();
- rb_control_frame_t *cfp = th->cfp;
- cfp->prof_time_self = current_time - cfp->prof_time_self;
- (cfp+1)->prof_time_chld += cfp->prof_time_self;
-
- cfp->iseq->profile.count++;
- cfp->iseq->profile.time_cumu = cfp->prof_time_self;
- cfp->iseq->profile.time_self = cfp->prof_time_self - cfp->prof_time_chld;
- }
- else if (0 /* c method? */) {
-
- }
-#endif
th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
if (VMDEBUG == 2) {
@@ -445,8 +422,9 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass);
- cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
- recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1);
+ cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv,
+ VM_ENVVAL_BLOCK_PTR(blockptr), 0, th->cfp->sp, 1);
+
cfp->me = me;
reg_cfp->sp -= num + 1;
@@ -528,9 +506,9 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
*sp++ = Qnil;
}
- vm_push_frame(th, iseq,
- VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
- iseq->iseq_encoded + opt_pc, sp, 0, 0);
+ vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv,
+ VM_ENVVAL_BLOCK_PTR(blockptr),
+ iseq->iseq_encoded + opt_pc, sp, 0);
cfp->sp = rsp - 1 /* recv */;
}
@@ -551,9 +529,9 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
*sp++ = Qnil;
}
- vm_push_frame(th, iseq,
- VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
- iseq->iseq_encoded + opt_pc, sp, 0, 0);
+ vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv,
+ VM_ENVVAL_BLOCK_PTR(blockptr),
+ iseq->iseq_encoded + opt_pc, sp, 0);
}
}
@@ -757,6 +735,7 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
NODE *ifunc = (NODE *) block->iseq;
VALUE val, arg, blockarg;
int lambda = block_proc_is_lambda(block->proc);
+ rb_control_frame_t *cfp;
if (lambda) {
arg = rb_ary_new4(argc, argv);
@@ -780,12 +759,11 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
blockarg = Qnil;
}
- vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC,
- self, (VALUE)block->dfp,
- 0, th->cfp->sp, block->lfp, 1);
+ cfp = vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
+ VM_ENVVAL_PREV_EP_PTR(block->ep), 0, th->cfp->sp, 1);
if (blockargptr) {
- th->cfp->lfp[0] = GC_GUARDED_PTR((VALUE)blockargptr);
+ VM_CF_LEP(cfp)[0] = VM_ENVVAL_BLOCK_PTR(blockargptr);
}
val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg);
@@ -976,7 +954,7 @@ vm_yield_setup_args(rb_thread_t * const th, const rb_iseq_t *iseq,
static VALUE
vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_num_t flag)
{
- const rb_block_t *block = GET_BLOCK_PTR();
+ const rb_block_t *block = VM_CF_BLOCK_PTR(reg_cfp);
rb_iseq_t *iseq;
int argc = (int)num;
VALUE type = GET_ISEQ()->local_iseq->type;
@@ -998,9 +976,10 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n
opt_pc = vm_yield_setup_args(th, iseq, argc, rsp, 0,
block_proc_is_lambda(block->proc));
- vm_push_frame(th, iseq,
- VM_FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
- iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp,
+ vm_push_frame(th, iseq, VM_FRAME_MAGIC_BLOCK, block->self,
+ VM_ENVVAL_PREV_EP_PTR(block->ep),
+ iseq->iseq_encoded + opt_pc,
+ rsp + arg_size,
iseq->local_size - arg_size);
return Qundef;
@@ -1015,15 +994,15 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n
/* svar */
static inline NODE *
-lfp_svar_place(rb_thread_t *th, VALUE *lfp)
+lep_svar_place(rb_thread_t *th, VALUE *lep)
{
VALUE *svar;
- if (lfp && th->local_lfp != lfp) {
- svar = &lfp[-1];
+ if (lep && th->root_lep != lep) {
+ svar = &lep[-1];
}
else {
- svar = &th->local_svar;
+ svar = &th->root_svar;
}
if (NIL_P(*svar)) {
*svar = (VALUE)NEW_IF(Qnil, Qnil, Qnil);
@@ -1032,9 +1011,9 @@ lfp_svar_place(rb_thread_t *th, VALUE *lfp)
}
static VALUE
-lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
+lep_svar_get(rb_thread_t *th, VALUE *lep, VALUE key)
{
- NODE *svar = lfp_svar_place(th, lfp);
+ NODE *svar = lep_svar_place(th, lep);
switch (key) {
case 0:
@@ -1055,9 +1034,9 @@ lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
}
static void
-lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val)
+lep_svar_set(rb_thread_t *th, VALUE *lep, VALUE key, VALUE val)
{
- NODE *svar = lfp_svar_place(th, lfp);
+ NODE *svar = lep_svar_place(th, lep);
switch (key) {
case 0:
@@ -1078,7 +1057,7 @@ lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val)
}
static inline VALUE
-vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
+vm_getspecial(rb_thread_t *th, VALUE *lep, VALUE key, rb_num_t type)
{
VALUE val;
@@ -1087,10 +1066,10 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
if (FIXNUM_P(key)) {
k = FIX2INT(key);
}
- val = lfp_svar_get(th, lfp, k);
+ val = lep_svar_get(th, lep, k);
}
else {
- VALUE backref = lfp_svar_get(th, lfp, 1);
+ VALUE backref = lep_svar_get(th, lep, 1);
if (type & 0x01) {
switch (type >> 1) {
@@ -1118,24 +1097,24 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
}
static NODE *
-vm_get_cref0(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+vm_get_cref0(const rb_iseq_t *iseq, const VALUE *ep)
{
while (1) {
- if (lfp == dfp) {
+ if (VM_EP_LEP_P(ep)) {
if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) return NULL;
return iseq->cref_stack;
}
- else if (dfp[-1] != Qnil) {
- return (NODE *)dfp[-1];
+ else if (ep[-1] != Qnil) {
+ return (NODE *)ep[-1];
}
- dfp = GET_PREV_DFP(dfp);
+ ep = VM_EP_PREV_EP(ep);
}
}
static NODE *
-vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+vm_get_cref(const rb_iseq_t *iseq, const VALUE *ep)
{
- NODE *cref = vm_get_cref0(iseq, lfp, dfp);
+ NODE *cref = vm_get_cref0(iseq, ep);
if (cref == 0) {
rb_bug("vm_get_cref: unreachable");
@@ -1151,19 +1130,19 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
cref->nd_visi = noex;
if (blockptr) {
- cref->nd_next = vm_get_cref0(blockptr->iseq, blockptr->lfp, blockptr->dfp);
+ cref->nd_next = vm_get_cref0(blockptr->iseq, blockptr->ep);
}
else if (cfp) {
- cref->nd_next = vm_get_cref0(cfp->iseq, cfp->lfp, cfp->dfp);
+ cref->nd_next = vm_get_cref0(cfp->iseq, cfp->ep);
}
return cref;
}
static inline VALUE
-vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+vm_get_cbase(const rb_iseq_t *iseq, const VALUE *ep)
{
- NODE *cref = vm_get_cref(iseq, lfp, dfp);
+ NODE *cref = vm_get_cref(iseq, ep);
VALUE klass = Qundef;
while (cref) {
@@ -1177,9 +1156,9 @@ vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
}
static inline VALUE
-vm_get_const_base(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+vm_get_const_base(const rb_iseq_t *iseq, const VALUE *ep)
{
- NODE *cref = vm_get_cref(iseq, lfp, dfp);
+ NODE *cref = vm_get_cref(iseq, ep);
VALUE klass = Qundef;
while (cref) {
@@ -1216,7 +1195,7 @@ vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
if (orig_klass == Qnil) {
/* in current lexical scope */
- const NODE *root_cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp);
+ const NODE *root_cref = vm_get_cref(iseq, th->cfp->ep);
const NODE *cref;
VALUE klass = orig_klass;
@@ -1494,14 +1473,14 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq,
while (lcfp->iseq != iseq) {
rb_thread_t *th = GET_THREAD();
- VALUE *tdfp = GET_PREV_DFP(lcfp->dfp);
+ VALUE *tep = VM_EP_PREV_EP(lcfp->ep);
while (1) {
lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp);
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, lcfp)) {
rb_raise(rb_eNoMethodError,
"super called outside of method");
}
- if (lcfp->dfp == tdfp) {
+ if (lcfp->ep == tep) {
break;
}
}
@@ -1539,7 +1518,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
else {
if (state == TAG_BREAK) {
rb_control_frame_t *cfp = GET_CFP();
- VALUE *dfp = GET_DFP();
+ VALUE *ep = GET_EP();
int is_orphan = 1;
rb_iseq_t *base_iseq = GET_ISEQ();
@@ -1547,14 +1526,14 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
if (cfp->iseq->type != ISEQ_TYPE_BLOCK) {
if (cfp->iseq->type == ISEQ_TYPE_CLASS) {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- dfp = cfp->dfp;
+ ep = cfp->ep;
goto search_parent;
}
- dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp);
+ ep = VM_EP_PREV_EP(ep);
base_iseq = base_iseq->parent_iseq;
while ((VALUE *) cfp < th->stack + th->stack_size) {
- if (cfp->dfp == dfp) {
+ if (cfp->ep == ep) {
goto search_parent;
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
@@ -1565,14 +1544,14 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
/* lambda{... break ...} */
is_orphan = 0;
- pt = cfp->dfp;
+ pt = cfp->ep;
state = TAG_RETURN;
}
else {
- dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp);
+ ep = VM_EP_PREV_EP(ep);
while ((VALUE *)cfp < th->stack + th->stack_size) {
- if (cfp->dfp == dfp) {
+ if (cfp->ep == ep) {
VALUE epc = cfp->pc - cfp->iseq->iseq_encoded;
rb_iseq_t *iseq = cfp->iseq;
int i;
@@ -1593,7 +1572,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
break;
found:
- pt = dfp;
+ pt = ep;
is_orphan = 0;
break;
}
@@ -1607,50 +1586,53 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
}
else if (state == TAG_RETRY) {
rb_num_t i;
- pt = GC_GUARDED_PTR_REF((VALUE *) * GET_DFP());
+ pt = VM_EP_PREV_EP(GET_EP());
for (i = 0; i < level; i++) {
pt = GC_GUARDED_PTR_REF((VALUE *) * pt);
}
}
else if (state == TAG_RETURN) {
rb_control_frame_t *cfp = GET_CFP();
- VALUE *dfp = GET_DFP();
- VALUE *lfp = GET_LFP();
+ VALUE *ep = GET_EP();
+ VALUE *target_lep = VM_CF_LEP(cfp);
int in_class_frame = 0;
/* check orphan and get dfp */
while ((VALUE *) cfp < th->stack + th->stack_size) {
- if (!lfp) {
- lfp = cfp->lfp;
+ VALUE *lep = VM_CF_LEP(cfp);
+
+ if (!target_lep) {
+ target_lep = lep;
}
- if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_CLASS) {
+
+ if (lep == target_lep && cfp->iseq->type == ISEQ_TYPE_CLASS) {
in_class_frame = 1;
- lfp = 0;
+ target_lep = 0;
}
- if (cfp->lfp == lfp) {
+ if (lep == target_lep) {
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
- VALUE *tdfp = dfp;
+ VALUE *tep = ep;
if (in_class_frame) {
/* lambda {class A; ... return ...; end} */
- dfp = cfp->dfp;
+ ep = cfp->ep;
goto valid_return;
}
- while (lfp != tdfp) {
- if (cfp->dfp == tdfp) {
+ while (target_lep != tep) {
+ if (cfp->ep == tep) {
/* in lambda */
- dfp = cfp->dfp;
+ ep = cfp->ep;
goto valid_return;
}
- tdfp = GC_GUARDED_PTR_REF((VALUE *)*tdfp);
+ tep = VM_EP_PREV_EP(tep);
}
}
}
- if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_METHOD) {
- dfp = lfp;
+ if (cfp->ep == target_lep && cfp->iseq->type == ISEQ_TYPE_METHOD) {
+ ep = target_lep;
goto valid_return;
}
@@ -1660,7 +1642,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
rb_vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
valid_return:
- pt = dfp;
+ pt = ep;
}
else {
rb_bug("isns(throw): unsupport throw type");
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 97e2b1e2ba..ffabbda23d 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -81,8 +81,7 @@ extern VALUE ruby_vm_const_missing_count;
#define REG_CFP (reg_cfp)
#define REG_PC (REG_CFP->pc)
#define REG_SP (REG_CFP->sp)
-#define REG_LFP (REG_CFP->lfp)
-#define REG_DFP (REG_CFP->dfp)
+#define REG_EP (REG_CFP->ep)
#define RESTORE_REGS() do { \
REG_CFP = th->cfp; \
@@ -91,16 +90,29 @@ extern VALUE ruby_vm_const_missing_count;
#define REG_A reg_a
#define REG_B reg_b
+enum vm_regan_regtype {
+ VM_REGAN_PC = 0,
+ VM_REGAN_SP = 1,
+ VM_REGAN_EP = 2,
+ VM_REGAN_CFP = 3,
+ VM_REGAN_SELF = 4,
+ VM_REGAN_ISEQ = 5,
+};
+enum vm_regan_acttype {
+ VM_REGAN_ACT_GET = 0,
+ VM_REGAN_ACT_SET = 1,
+};
+
#ifdef COLLECT_USAGE_ANALYSIS
#define USAGE_ANALYSIS_REGISTER_HELPER(a, b, v) \
- (USAGE_ANALYSIS_REGISTER((a), (b)), (v))
+ (USAGE_ANALYSIS_REGISTER((VM_REGAN_#a), (VM_REGAN_ACT_#b)), (v))
#else
#define USAGE_ANALYSIS_REGISTER_HELPER(a, b, v) (v)
#endif
/* PC */
-#define GET_PC() (USAGE_ANALYSIS_REGISTER_HELPER(0, 0, REG_PC))
-#define SET_PC(x) (REG_PC = (USAGE_ANALYSIS_REGISTER_HELPER(0, 1, (x))))
+#define GET_PC() (USAGE_ANALYSIS_REGISTER_HELPER(PC, GET, REG_PC))
+#define SET_PC(x) (REG_PC = (USAGE_ANALYSIS_REGISTER_HELPER(PC, SET, (x))))
#define GET_CURRENT_INSN() (*GET_PC())
#define GET_OPERAND(n) (GET_PC()[(n)])
#define ADD_PC(n) (SET_PC(REG_PC + (n)))
@@ -108,18 +120,17 @@ extern VALUE ruby_vm_const_missing_count;
#define GET_PC_COUNT() (REG_PC - GET_ISEQ()->iseq_encoded)
#define JUMP(dst) (REG_PC += (dst))
-/* FP */
-#define GET_CFP() (USAGE_ANALYSIS_REGISTER_HELPER(2, 0, REG_CFP))
-#define GET_LFP() (USAGE_ANALYSIS_REGISTER_HELPER(3, 0, REG_LFP))
-#define SET_LFP(x) (REG_LFP = (USAGE_ANALYSIS_REGISTER_HELPER(3, 1, (x))))
-#define GET_DFP() (USAGE_ANALYSIS_REGISTER_HELPER(4, 0, REG_DFP))
-#define SET_DFP(x) (REG_DFP = (USAGE_ANALYSIS_REGISTER_HELPER(4, 1, (x))))
+/* frame pointer, environment pointer */
+#define GET_CFP() (USAGE_ANALYSIS_REGISTER_HELPER(CFP, GET, REG_CFP))
+#define GET_EP() (USAGE_ANALYSIS_REGISTER_HELPER(EP, GET, REG_EP))
+#define SET_EP(x) (REG_EP = (USAGE_ANALYSIS_REGISTER_HELPER(EP, SET, (x))))
+#define GET_LEP() (VM_EP_LEP(GET_EP()))
/* SP */
-#define GET_SP() (USAGE_ANALYSIS_REGISTER_HELPER(1, 0, REG_SP))
-#define SET_SP(x) (REG_SP = (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x))))
-#define INC_SP(x) (REG_SP += (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x))))
-#define DEC_SP(x) (REG_SP -= (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x))))
+#define GET_SP() (USAGE_ANALYSIS_REGISTER_HELPER(SP, GET, REG_SP))
+#define SET_SP(x) (REG_SP = (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x))))
+#define INC_SP(x) (REG_SP += (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x))))
+#define DEC_SP(x) (REG_SP -= (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x))))
#define SET_SV(x) (*GET_SP() = (x))
/* set current stack value as x */
@@ -132,7 +143,7 @@ extern VALUE ruby_vm_const_missing_count;
/* deal with variables */
/**********************************************************/
-#define GET_PREV_DFP(dfp) ((VALUE *)((dfp)[0] & ~0x03))
+#define GET_PREV_EP(ep) ((VALUE *)((ep)[0] & ~0x03))
#define GET_GLOBAL(entry) rb_gvar_get((struct rb_global_entry*)(entry))
#define SET_GLOBAL(entry, val) rb_gvar_set((struct rb_global_entry*)(entry), (val))
@@ -170,7 +181,7 @@ extern VALUE ruby_vm_const_missing_count;
} \
} while (0)
-#define GET_BLOCK_PTR() ((rb_block_t *)(GC_GUARDED_PTR_REF(GET_LFP()[0])))
+#define GET_BLOCK_PTR() ((rb_block_t *)(GC_GUARDED_PTR_REF(GET_LEP()[0])))
/**********************************************************/
/* deal with control flow 3: exception */