* 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:
ko1 2008-05-19 18:47:56 +00:00
Родитель e07663ec1f
Коммит d457fdad2d
6 изменённых файлов: 105 добавлений и 52 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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,