summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--eval_intern.h36
-rw-r--r--insns.def2
-rw-r--r--vm.c56
-rw-r--r--vm_eval.c19
-rw-r--r--vm_insnhelper.c21
-rw-r--r--vm_insnhelper.h19
7 files changed, 92 insertions, 86 deletions
diff --git a/ChangeLog b/ChangeLog
index 12cd77e..9bab213 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+Sat Nov 14 04:55:36 2015 Koichi Sasada <ko1@atdot.net>
+
+ * refactoring CREF related code.
+
+ * eval_intern.h: remove unused setter functions.
+ CREF_CLASS_SET()
+ CREF_NEXT_SET()
+ CREF_SCOPE_VISI_COPY()
+
+ * eval_intern.h: rename flags:
+ * NODE_FL_CREF_PUSHED_BY_EVAL_ -> CREF_FL_PUSHED_BY_EVAL
+ * NODE_FL_CREF_OMOD_SHARED_ -> CREF_FL_OMOD_SHARED
+ and use IMEMO_FL_USER1/2.
+
+ * vm.c (vm_cref_new): accept push_by_eval parameter.
+
+ * vm.c (vm_cref_new_use_prev): added for rb_vm_rewrite_cref().
+
+ * vm_insnhelper.c (vm_cref_push): accept pushed_by_eval parameter.
+
+ * vm_insnhelper.h: remove unused macros:
+ COPY_CREF_OMOD() and COPY_CREF().
+
+ * vm_eval.c, insns.def: catch up this fix.
+
Sat Nov 14 02:58:03 2015 Koichi Sasada <ko1@atdot.net>
* vm.c (vm_define_method): refactoring.
diff --git a/eval_intern.h b/eval_intern.h
index d78bb39..5dbdf00 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -179,8 +179,8 @@ rb_threadptr_tag_jump(rb_thread_t *th, int st)
/* CREF operators */
-#define NODE_FL_CREF_PUSHED_BY_EVAL_ (((VALUE)1)<<15)
-#define NODE_FL_CREF_OMOD_SHARED_ (((VALUE)1)<<16)
+#define CREF_FL_PUSHED_BY_EVAL IMEMO_FL_USER1
+#define CREF_FL_OMOD_SHARED IMEMO_FL_USER2
static inline VALUE
CREF_CLASS(const rb_cref_t *cref)
@@ -188,40 +188,18 @@ CREF_CLASS(const rb_cref_t *cref)
return cref->klass;
}
-static inline void
-CREF_CLASS_SET(rb_cref_t *cref, VALUE klass)
-{
- RB_OBJ_WRITE(cref, &cref->klass, klass);
-}
-
static inline rb_cref_t *
CREF_NEXT(const rb_cref_t *cref)
{
return cref->next;
}
-static inline void
-CREF_NEXT_SET(rb_cref_t *cref, const rb_cref_t *next_cref)
-{
- RB_OBJ_WRITE(cref, &cref->next, next_cref);
-}
-
static inline const rb_scope_visibility_t *
CREF_SCOPE_VISI(const rb_cref_t *cref)
{
return &cref->scope_visi;
}
-static inline void
-CREF_SCOPE_VISI_COPY(rb_cref_t *dst_cref, const rb_cref_t *src_cref)
-{
- const rb_scope_visibility_t *src = &src_cref->scope_visi;
- rb_scope_visibility_t *dst = (rb_scope_visibility_t *)&dst_cref->scope_visi; /* OK for const cast */
-
- dst->method_visi = src->method_visi;
- dst->module_func = src->module_func;
-}
-
static inline VALUE
CREF_REFINEMENTS(const rb_cref_t *cref)
{
@@ -237,31 +215,31 @@ CREF_REFINEMENTS_SET(rb_cref_t *cref, VALUE refs)
static inline int
CREF_PUSHED_BY_EVAL(const rb_cref_t *cref)
{
- return cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL_;
+ return cref->flags & CREF_FL_PUSHED_BY_EVAL;
}
static inline void
CREF_PUSHED_BY_EVAL_SET(rb_cref_t *cref)
{
- cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL_;
+ cref->flags |= CREF_FL_PUSHED_BY_EVAL;
}
static inline int
CREF_OMOD_SHARED(const rb_cref_t *cref)
{
- return cref->flags & NODE_FL_CREF_OMOD_SHARED_;
+ return cref->flags & CREF_FL_OMOD_SHARED;
}
static inline void
CREF_OMOD_SHARED_SET(rb_cref_t *cref)
{
- cref->flags |= NODE_FL_CREF_OMOD_SHARED_;
+ cref->flags |= CREF_FL_OMOD_SHARED;
}
static inline void
CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
{
- cref->flags &= ~NODE_FL_CREF_OMOD_SHARED_;
+ cref->flags &= ~CREF_FL_OMOD_SHARED;
}
void rb_thread_cleanup(void);
diff --git a/insns.def b/insns.def
index 563266b..33aedfc 100644
--- a/insns.def
+++ b/insns.def
@@ -914,7 +914,7 @@ defineclass
/* enter scope */
vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, klass,
VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
- (VALUE)vm_cref_push(th, klass, NULL),
+ (VALUE)vm_cref_push(th, klass, NULL, FALSE),
class_iseq->body->iseq_encoded, GET_SP(),
class_iseq->body->local_size, class_iseq->body->stack_max);
diff --git a/vm.c b/vm.c
index 81de1a2..929144d 100644
--- a/vm.c
+++ b/vm.c
@@ -86,25 +86,69 @@ rb_vm_control_frame_block_ptr(const rb_control_frame_t *cfp)
}
static rb_cref_t *
-vm_cref_new(VALUE klass, rb_method_visibility_t visi, const rb_cref_t *prev_cref)
+vm_cref_new0(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int use_prev_prev)
{
+ VALUE refinements = Qnil;
+ int omod_shared = FALSE;
+ rb_cref_t *cref;
+
+ /* scope */
union {
rb_scope_visibility_t visi;
VALUE value;
} scope_visi;
+
scope_visi.visi.method_visi = visi;
- scope_visi.visi.module_func = 0;
+ scope_visi.visi.module_func = module_func;
+
+ /* refinements */
+ if (prev_cref != NULL && prev_cref != (void *)1 /* TODO: why CREF_NEXT(cref) is 1? */) {
+ refinements = CREF_REFINEMENTS(prev_cref);
+
+ if (!NIL_P(refinements)) {
+ omod_shared = TRUE;
+ CREF_OMOD_SHARED_SET(prev_cref);
+ }
+ }
+
+ cref = (rb_cref_t *)rb_imemo_new(imemo_cref, klass, (VALUE)(use_prev_prev ? CREF_NEXT(prev_cref) : prev_cref), scope_visi.value, refinements);
+
+ if (pushed_by_eval) CREF_PUSHED_BY_EVAL_SET(cref);
+ if (omod_shared) CREF_OMOD_SHARED_SET(cref);
+
+ return cref;
+}
+
+static rb_cref_t *
+vm_cref_new(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
+{
+ return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, FALSE);
+}
+
+static rb_cref_t *
+vm_cref_new_use_prev(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
+{
+ return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, TRUE);
+}
+
+static rb_cref_t *
+vm_cref_dup(const rb_cref_t *cref)
+{
+ VALUE klass = CREF_CLASS(cref);
+ const rb_scope_visibility_t *visi = CREF_SCOPE_VISI(cref);
+ rb_cref_t *next_cref = CREF_NEXT(cref);
+ int pushed_by_eval = CREF_PUSHED_BY_EVAL(cref);
- return (rb_cref_t *)rb_imemo_new(imemo_cref, klass, (VALUE)prev_cref, scope_visi.value, Qnil);
+ return vm_cref_new(klass, visi->method_visi, visi->module_func, next_cref, pushed_by_eval);
}
static rb_cref_t *
vm_cref_new_toplevel(rb_thread_t *th)
{
- rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE /* toplevel visibility is private */, NULL);
+ rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE /* toplevel visibility is private */, FALSE, NULL, FALSE);
if (th->top_wrapper) {
- cref = vm_cref_new(th->top_wrapper, METHOD_VISI_PRIVATE, cref);
+ cref = vm_cref_new(th->top_wrapper, METHOD_VISI_PRIVATE, FALSE, cref, FALSE);
}
return cref;
@@ -2844,7 +2888,7 @@ Init_VM(void)
th->cfp->pc = iseq->body->iseq_encoded;
th->cfp->self = th->top_self;
- th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, NULL);
+ th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, FALSE, NULL, FALSE);
/*
* The Binding of the top level scope
diff --git a/vm_eval.c b/vm_eval.c
index ed44c29..1bc91f5 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1272,7 +1272,6 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
volatile int parse_in_eval;
volatile int mild_compile_error;
rb_cref_t *orig_cref;
- VALUE crefval;
volatile VALUE file;
volatile int line;
@@ -1339,16 +1338,13 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
if (!cref && base_block->iseq) {
if (NIL_P(scope)) {
orig_cref = rb_vm_get_cref(base_block->ep);
- cref = vm_cref_new(Qnil, METHOD_VISI_PUBLIC, NULL);
- crefval = (VALUE) cref;
- COPY_CREF(cref, orig_cref);
+ cref = vm_cref_dup(orig_cref);
}
else {
cref = rb_vm_get_cref(base_block->ep);
}
}
vm_set_eval_stack(th, iseq, cref, base_block);
- RB_GC_GUARD(crefval);
if (0) { /* for debug */
VALUE disasm = rb_iseq_disasm(iseq);
@@ -1595,8 +1591,7 @@ yield_under(VALUE under, VALUE self, VALUE values)
block.self = self;
VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
}
- cref = vm_cref_push(th, under, blockptr);
- CREF_PUSHED_BY_EVAL_SET(cref);
+ cref = vm_cref_push(th, under, blockptr, TRUE);
if (values == Qundef) {
return vm_yield_with_cref(th, 1, &self, cref);
@@ -1618,8 +1613,7 @@ rb_yield_refine_block(VALUE refinement, VALUE refinements)
block.self = refinement;
VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
}
- cref = vm_cref_push(th, refinement, blockptr);
- CREF_PUSHED_BY_EVAL_SET(cref);
+ cref = vm_cref_push(th, refinement, blockptr, TRUE);
CREF_REFINEMENTS_SET(cref, refinements);
return vm_yield_with_cref(th, 0, NULL, cref);
@@ -1629,13 +1623,8 @@ rb_yield_refine_block(VALUE refinement, VALUE refinements)
static VALUE
eval_under(VALUE under, VALUE self, VALUE src, VALUE file, int line)
{
- rb_cref_t *cref = vm_cref_push(GET_THREAD(), under, NULL);
-
- if (SPECIAL_CONST_P(self) && !NIL_P(under)) {
- CREF_PUSHED_BY_EVAL_SET(cref);
- }
+ rb_cref_t *cref = vm_cref_push(GET_THREAD(), under, NULL, SPECIAL_CONST_P(self) && !NIL_P(under));
SafeStringValue(src);
-
return eval_string_with_cref(self, src, Qnil, cref, file, line);
}
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 4130c17..ecf203c 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -524,14 +524,11 @@ rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass, rb_cref_t
while (cref) {
if (CREF_CLASS(cref) == old_klass) {
- new_cref = vm_cref_new(new_klass, METHOD_VISI_UNDEF, NULL);
- COPY_CREF_OMOD(new_cref, cref);
- CREF_NEXT_SET(new_cref, CREF_NEXT(cref));
+ new_cref = vm_cref_new_use_prev(new_klass, METHOD_VISI_UNDEF, FALSE, cref, FALSE);
*new_cref_ptr = new_cref;
return;
}
- new_cref = vm_cref_new(CREF_CLASS(cref), METHOD_VISI_UNDEF, NULL);
- COPY_CREF_OMOD(new_cref, cref);
+ new_cref = vm_cref_new_use_prev(CREF_CLASS(cref), METHOD_VISI_UNDEF, FALSE, cref, FALSE);
cref = CREF_NEXT(cref);
*new_cref_ptr = new_cref;
new_cref_ptr = (rb_cref_t **)&new_cref->next;
@@ -540,10 +537,9 @@ rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass, rb_cref_t
}
static rb_cref_t *
-vm_cref_push(rb_thread_t *th, VALUE klass, rb_block_t *blockptr)
+vm_cref_push(rb_thread_t *th, VALUE klass, rb_block_t *blockptr, int pushed_by_eval)
{
- const rb_cref_t *prev_cref = NULL;
- rb_cref_t *cref = NULL;
+ rb_cref_t *prev_cref = NULL;
if (blockptr) {
prev_cref = vm_env_cref(blockptr->ep);
@@ -555,15 +551,8 @@ vm_cref_push(rb_thread_t *th, VALUE klass, rb_block_t *blockptr)
prev_cref = vm_env_cref(cfp->ep);
}
}
- cref = vm_cref_new(klass, METHOD_VISI_PUBLIC, prev_cref);
- /* TODO: why CREF_NEXT(cref) is 1? */
- if (CREF_NEXT(cref) && CREF_NEXT(cref) != (void *) 1 &&
- !NIL_P(CREF_REFINEMENTS(CREF_NEXT(cref)))) {
- COPY_CREF_OMOD(cref, CREF_NEXT(cref));
- }
-
- return cref;
+ return vm_cref_new(klass, METHOD_VISI_PUBLIC, FALSE, prev_cref, pushed_by_eval);
}
static inline VALUE
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index b70f731..fbd3a76 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -121,25 +121,6 @@ enum vm_regan_acttype {
/* deal with control flow 2: method/iterator */
/**********************************************************/
-#define COPY_CREF_OMOD(c1, c2) do { \
- CREF_REFINEMENTS_SET(c1, CREF_REFINEMENTS(c2)); \
- if (!NIL_P(CREF_REFINEMENTS(c2))) { \
- CREF_OMOD_SHARED_SET(c1); \
- CREF_OMOD_SHARED_SET(c2); \
- } \
-} while (0)
-
-#define COPY_CREF(c1, c2) do { \
- rb_cref_t *__tmp_c2 = (c2); \
- COPY_CREF_OMOD((c1), __tmp_c2); \
- CREF_CLASS_SET((c1), CREF_CLASS(__tmp_c2));\
- CREF_SCOPE_VISI_COPY((c1), __tmp_c2);\
- CREF_NEXT_SET((c1), CREF_NEXT(__tmp_c2));\
- if (CREF_PUSHED_BY_EVAL(__tmp_c2)) { \
- CREF_PUSHED_BY_EVAL_SET(c1); \
- } \
-} while (0)
-
#define CALL_METHOD(calling, ci, cc) do { \
VALUE v = (*(cc)->call)(th, GET_CFP(), (calling), (ci), (cc)); \
if (v == Qundef) { \