summaryrefslogtreecommitdiffstats
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-12-03 18:25:57 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-12-03 18:25:57 +0000
commit4aa8e0f64f649c152d35d1f606249304a7749a24 (patch)
treee6bb9639b21f89e4f250fe523e3602e6abc05bc5 /vm_insnhelper.c
parentc5f7e80d46bffa843afbb8df8369c843ccfa30ae (diff)
downloadruby-4aa8e0f64f649c152d35d1f606249304a7749a24.tar.gz
ruby-4aa8e0f64f649c152d35d1f606249304a7749a24.tar.xz
ruby-4aa8e0f64f649c152d35d1f606249304a7749a24.zip
* compile.c (compile_cpath, iseq_compile_each): reverted
constant/class variable lookup in instance_eval etc. to the behavior of 1.8. * eval.c (rb_mod_nesting): ditto. * insns.def (putspecialobject, defineclass): ditto. * node.h (NODE_FL_CREF_PUSHED_BY_EVAL): ditto. * vm_core.h (VM_SPECIAL_OBJECT_CONST_BASE): ditto. * vm_eval.c (yield_under, eval_under): ditto. * vm_insnhelper.c (vm_cref_push, vm_get_const_base, vm_get_ev_const, vm_get_cvar_base): ditto. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@25984 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index a05574f1d..8f992d2a8 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1066,14 +1066,17 @@ vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
}
static NODE *
-vm_cref_push(rb_thread_t *th, VALUE klass, int noex)
+vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
{
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
NODE *cref = NEW_BLOCK(klass);
cref->nd_file = 0;
cref->nd_visi = noex;
- if (cfp) {
+ if (blockptr) {
+ cref->nd_next = vm_get_cref(blockptr->iseq, blockptr->lfp, blockptr->dfp);
+ }
+ else if (cfp) {
cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
@@ -1096,6 +1099,23 @@ vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
return klass;
}
+static inline VALUE
+vm_get_const_base(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+{
+ NODE *cref = vm_get_cref(iseq, lfp, dfp);
+ VALUE klass = Qundef;
+
+ while (cref) {
+ if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) &&
+ (klass = cref->nd_clss) != 0) {
+ break;
+ }
+ cref = cref->nd_next;
+ }
+
+ return klass;
+}
+
static inline void
vm_check_if_namespace(VALUE klass)
{
@@ -1117,12 +1137,16 @@ 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 *cref = root_cref;
+ const NODE *cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp);
+ const NODE *root_cref = NULL;
VALUE klass = orig_klass;
while (cref && cref->nd_next) {
- klass = cref->nd_clss;
+ if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL)) {
+ klass = cref->nd_clss;
+ if (root_cref == NULL)
+ root_cref = cref;
+ }
cref = cref->nd_next;
if (!NIL_P(klass)) {
@@ -1149,8 +1173,10 @@ vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
}
/* search self */
- klass = root_cref->nd_clss;
- if (NIL_P(klass)) {
+ if (root_cref && !NIL_P(root_cref->nd_clss)) {
+ klass = root_cref->nd_clss;
+ }
+ else {
klass = CLASS_OF(th->cfp->self);
}
@@ -1178,7 +1204,8 @@ vm_get_cvar_base(NODE *cref)
VALUE klass;
while (cref && cref->nd_next &&
- (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) {
+ (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON) ||
+ (cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL))) {
cref = cref->nd_next;
if (!cref->nd_next) {