зеркало из https://github.com/github/ruby.git
* eval.c, vm_insnhelper.c: fix cref in instance_eval
and cvar_base search protocol. * bootstraptest/test_knownbug.rb, test_eval.rb: move soleved test and add new tests. * test/ruby/test_eval.rb: fix tests for spec. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16486 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
e07663ec1f
Коммит
d457fdad2d
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Tue May 20 03:42:43 2008 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* eval.c, vm_insnhelper.c: fix cref in instance_eval
|
||||
and cvar_base search protocol.
|
||||
|
||||
* bootstraptest/test_knownbug.rb, test_eval.rb: move soleved test
|
||||
and add new tests.
|
||||
|
||||
* test/ruby/test_eval.rb: fix tests for spec.
|
||||
|
||||
Tue May 20 01:43:44 2008 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* bootstraptest/test_knownbug.rb: fix a test.
|
||||
|
|
|
@ -236,3 +236,49 @@ assert_equal 'ok', %q{
|
|||
:ok
|
||||
end
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
begin
|
||||
0.instance_eval { def m() :m end }
|
||||
1.m
|
||||
:ng
|
||||
rescue Exception
|
||||
:ok
|
||||
end
|
||||
}, '[ruby-dev:34579]'
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
begin
|
||||
12.instance_eval { @@a }
|
||||
rescue NameError
|
||||
:ok
|
||||
end
|
||||
}, '[ruby-core:16794]'
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
begin
|
||||
12.instance_exec { @@a }
|
||||
rescue NameError
|
||||
:ok
|
||||
end
|
||||
}, '[ruby-core:16794]'
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
begin
|
||||
nil.instance_eval {
|
||||
def a() :a end
|
||||
}
|
||||
rescue => TypeError
|
||||
:ok
|
||||
end
|
||||
}, '[ruby-core:16796]'
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
begin
|
||||
nil.instance_exec {
|
||||
def a() :a end
|
||||
}
|
||||
rescue => TypeError
|
||||
:ok
|
||||
end
|
||||
}, '[ruby-core:16796]'
|
||||
|
|
|
@ -91,16 +91,6 @@ assert_equal 'ok', %q{
|
|||
}.call
|
||||
}, '[ruby-dev:34646]'
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
begin
|
||||
0.instance_eval { def m() :m end }
|
||||
1.m
|
||||
:ng
|
||||
rescue Exception
|
||||
:ok
|
||||
end
|
||||
}, '[ruby-dev:34579]'
|
||||
|
||||
assert_normal_exit %q{
|
||||
eval("", method(:proc).call {}.binding)
|
||||
}
|
||||
|
|
2
eval.c
2
eval.c
|
@ -1933,7 +1933,7 @@ rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
|
|||
VALUE klass;
|
||||
|
||||
if (SPECIAL_CONST_P(self)) {
|
||||
klass = CLASS_OF(self); /* klass = Qnil; */
|
||||
klass = Qnil;
|
||||
}
|
||||
else {
|
||||
klass = rb_singleton_class(self);
|
||||
|
|
|
@ -139,7 +139,7 @@ class TestEval < Test::Unit::TestCase
|
|||
|
||||
assert_equal 11, o.instance_eval("11")
|
||||
assert_equal 12, o.instance_eval("@ivar")
|
||||
assert_raise(NameError) {o.instance_eval("@@cvar")}
|
||||
assert_equal 13, o.instance_eval("@@cvar")
|
||||
assert_equal 14, o.instance_eval("$gvar__eval")
|
||||
assert_equal 15, o.instance_eval("Const")
|
||||
assert_equal 16, o.instance_eval("7 + 9")
|
||||
|
@ -149,7 +149,7 @@ class TestEval < Test::Unit::TestCase
|
|||
|
||||
1.times {
|
||||
assert_equal 12, o.instance_eval("@ivar")
|
||||
assert_raise(NameError) {o.instance_eval("@@cvar")}
|
||||
assert_equal 13, o.instance_eval("@@cvar")
|
||||
assert_equal 14, o.instance_eval("$gvar__eval")
|
||||
assert_equal 15, o.instance_eval("Const")
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ class TestEval < Test::Unit::TestCase
|
|||
|
||||
assert_equal 11, o.instance_eval { 11 }
|
||||
assert_equal 12, o.instance_eval { @ivar }
|
||||
assert_raise(NameError) {o.instance_eval{ @@cvar }}
|
||||
assert_equal 13, o.instance_eval { @@cvar }
|
||||
assert_equal 14, o.instance_eval { $gvar__eval }
|
||||
assert_equal 15, o.instance_eval { Const }
|
||||
assert_equal 16, o.instance_eval { 7 + 9 }
|
||||
|
@ -179,7 +179,7 @@ class TestEval < Test::Unit::TestCase
|
|||
|
||||
1.times {
|
||||
assert_equal 12, o.instance_eval { @ivar }
|
||||
assert_raise(NameError) {o.instance_eval{ @@cvar }}
|
||||
assert_equal 13, o.instance_eval { @@cvar }
|
||||
assert_equal 14, o.instance_eval { $gvar__eval }
|
||||
assert_equal 15, o.instance_eval { Const }
|
||||
}
|
||||
|
@ -187,8 +187,10 @@ class TestEval < Test::Unit::TestCase
|
|||
|
||||
def test_instance_eval_cvar
|
||||
[Object.new, [], 7, :sym, true, false, nil].each do |obj|
|
||||
assert_raise(NameError){obj.instance_eval("@@cvar")}
|
||||
assert_raise(NameError){obj.instance_eval{@@cvar}}
|
||||
assert_equal(13, obj.instance_eval("@@cvar"))
|
||||
assert_equal(13, obj.instance_eval{@@cvar})
|
||||
# assert_raise(NameError){obj.instance_eval("@@cvar")}
|
||||
# assert_raise(NameError){obj.instance_eval{@@cvar}}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -339,9 +341,10 @@ class TestEval < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_cvar_scope_with_instance_eval
|
||||
# TODO: check
|
||||
Fixnum.class_eval "@@test_cvar_scope_with_instance_eval = 1" # depends on [ruby-dev:24229]
|
||||
@@test_cvar_scope_with_instance_eval = 4
|
||||
assert_equal(1, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
|
||||
assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
|
||||
Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval)
|
||||
end
|
||||
|
||||
|
|
|
@ -21,9 +21,10 @@
|
|||
#endif
|
||||
|
||||
static inline rb_control_frame_t *
|
||||
vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type,
|
||||
VALUE self, VALUE specval, VALUE *pc,
|
||||
VALUE *sp, VALUE *lfp, int local_size)
|
||||
vm_push_frame(rb_thread_t * const th, const rb_iseq_t * const iseq,
|
||||
const VALUE type, const VALUE self, const VALUE specval,
|
||||
const VALUE * const pc, VALUE *sp, VALUE *lfp,
|
||||
int const local_size)
|
||||
{
|
||||
VALUE *dfp;
|
||||
rb_control_frame_t *cfp;
|
||||
|
@ -48,14 +49,14 @@ vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type,
|
|||
/* setup vm control frame stack */
|
||||
|
||||
cfp = th->cfp = th->cfp - 1;
|
||||
cfp->pc = pc;
|
||||
cfp->pc = (VALUE *)pc;
|
||||
cfp->sp = sp + 1;
|
||||
cfp->bp = sp + 1;
|
||||
cfp->iseq = iseq;
|
||||
cfp->iseq = (rb_iseq_t *) iseq;
|
||||
cfp->flag = type;
|
||||
cfp->self = self;
|
||||
cfp->lfp = lfp;
|
||||
cfp->dfp = dfp;
|
||||
cfp->dfp = (VALUE *)dfp;
|
||||
cfp->proc = 0;
|
||||
|
||||
#define COLLECT_PROFILE 0
|
||||
|
@ -72,7 +73,7 @@ vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type,
|
|||
}
|
||||
|
||||
static inline void
|
||||
vm_pop_frame(rb_thread_t *th)
|
||||
vm_pop_frame(rb_thread_t * const th)
|
||||
{
|
||||
#if COLLECT_PROFILE
|
||||
rb_control_frame_t *cfp = th->cfp;
|
||||
|
@ -990,37 +991,32 @@ vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq,
|
|||
klass = cref->nd_clss;
|
||||
cref = cref->nd_next;
|
||||
|
||||
if (klass == 0) {
|
||||
continue;
|
||||
}
|
||||
if (NIL_P(klass)) {
|
||||
if (is_defined) {
|
||||
/* TODO: check */
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
klass = CLASS_OF(th->cfp->self);
|
||||
return rb_const_get(klass, id);
|
||||
}
|
||||
}
|
||||
search_continue:
|
||||
if (RCLASS_IV_TBL(klass) &&
|
||||
st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
|
||||
if (val == Qundef) {
|
||||
rb_autoload_load(klass, id);
|
||||
goto search_continue;
|
||||
}
|
||||
else {
|
||||
if (is_defined) {
|
||||
return 1;
|
||||
if (!NIL_P(klass)) {
|
||||
search_continue:
|
||||
if (RCLASS_IV_TBL(klass) &&
|
||||
st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
|
||||
if (val == Qundef) {
|
||||
rb_autoload_load(klass, id);
|
||||
goto search_continue;
|
||||
}
|
||||
else {
|
||||
return val;
|
||||
if (is_defined) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* search self */
|
||||
klass = root_cref->nd_clss;
|
||||
if (NIL_P(klass)) {
|
||||
klass = CLASS_OF(th->cfp->self);
|
||||
}
|
||||
|
||||
if (is_defined) {
|
||||
return rb_const_defined(klass, id);
|
||||
}
|
||||
|
@ -1042,14 +1038,18 @@ vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq,
|
|||
static inline VALUE
|
||||
vm_get_cvar_base(NODE *cref)
|
||||
{
|
||||
VALUE klass = Qnil;
|
||||
VALUE klass;
|
||||
|
||||
while (cref && cref->nd_next && (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) {
|
||||
cref = cref->nd_next;
|
||||
|
||||
if (cref) {
|
||||
klass = cref->nd_clss;
|
||||
if (!cref->nd_next) {
|
||||
rb_warn("class variable access from toplevel");
|
||||
}
|
||||
}
|
||||
|
||||
klass = cref->nd_clss;
|
||||
|
||||
if (NIL_P(klass)) {
|
||||
rb_raise(rb_eTypeError, "no class variables available");
|
||||
}
|
||||
|
@ -1064,6 +1064,10 @@ vm_define_method(rb_thread_t *th, VALUE obj,
|
|||
VALUE klass = cref->nd_clss;
|
||||
int noex = cref->nd_visi;
|
||||
|
||||
if (NIL_P(klass)) {
|
||||
rb_raise(rb_eTypeError, "no class/module to add method");
|
||||
}
|
||||
|
||||
if (is_singleton) {
|
||||
if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
|
||||
rb_raise(rb_eTypeError,
|
||||
|
|
Загрузка…
Ссылка в новой задаче