summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/eval.c b/eval.c
index f225bf47bd..c6c2b98cd3 100644
--- a/eval.c
+++ b/eval.c
@@ -292,10 +292,15 @@ rb_enable_super(klass, name)
ID mid = rb_intern(name);
body = search_method(klass, mid, &origin);
- if (!body || !body->nd_body || origin != klass) {
+ if (!body) {
print_undef(klass, mid);
}
- body->nd_noex &= ~NOEX_UNDEF;
+ if (!body->nd_body) {
+ remove_method(klass, mid);
+ }
+ else {
+ body->nd_noex &= ~NOEX_UNDEF;
+ }
}
static void
@@ -1511,6 +1516,7 @@ is_defined(self, node, buf)
case NODE_SUPER:
case NODE_ZSUPER:
if (ruby_frame->last_func == 0) return 0;
+ else if (ruby_frame->last_class == 0) return 0;
else if (rb_method_boundp(RCLASS(ruby_frame->last_class)->super,
ruby_frame->last_func, 0)) {
if (nd_type(node) == NODE_SUPER) {
@@ -1707,7 +1713,7 @@ call_trace_func(event, file, line, self, id, klass)
prev = ruby_frame;
PUSH_FRAME();
- *ruby_frame = *_frame.prev;
+ *ruby_frame = *prev;
ruby_frame->prev = prev;
if (file) {
@@ -4369,7 +4375,7 @@ rb_f_eval(argc, argv, self)
VALUE *argv;
VALUE self;
{
- VALUE src, scope, vfile, vline;
+ VALUE src, scope, vfile, vline, val;
char *file = "(eval)";
int line = 1;
@@ -4383,6 +4389,19 @@ rb_f_eval(argc, argv, self)
}
Check_SafeStr(src);
+ if (NIL_P(scope) && ruby_frame->prev) {
+ struct FRAME *prev;
+ VALUE val;
+
+ prev = ruby_frame;
+ PUSH_FRAME();
+ *ruby_frame = *prev->prev;
+ ruby_frame->prev = prev;
+ val = eval(self, src, scope, file, line);
+ POP_FRAME();
+
+ return val;
+ }
return eval(self, src, scope, file, line);
}
@@ -5310,6 +5329,7 @@ Init_eval()
rb_define_global_function("untrace_var", rb_f_untrace_var, -1);
rb_define_global_function("set_trace_func", set_trace_func, 1);
+ rb_global_variable(&trace_func);
rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
}
@@ -5475,6 +5495,7 @@ rb_f_binding(self)
frame_dup(&data->frame);
if (ruby_frame->prev) {
data->frame.last_func = ruby_frame->prev->last_func;
+ data->frame.last_class = ruby_frame->prev->last_class;
}
if (data->iter) {
@@ -5549,6 +5570,7 @@ proc_s_new(klass)
data->orig_thread = rb_thread_current();
data->iter = data->prev?Qtrue:Qfalse;
+ data->tag = 0; /* should not point into stack */
frame_dup(&data->frame);
if (data->iter) {
blk_copy_prev(data);
@@ -5589,6 +5611,7 @@ proc_call(proc, args)
VALUE proc, args; /* OK */
{
struct BLOCK * volatile old_block;
+ struct BLOCK _block;
struct BLOCK *data;
volatile VALUE result = Qnil;
int state;
@@ -5600,7 +5623,8 @@ proc_call(proc, args)
/* PUSH BLOCK from data */
old_block = ruby_block;
- ruby_block = data;
+ _block = *data;
+ ruby_block = &_block;
PUSH_ITER(ITER_CUR);
ruby_frame->iter = ITER_CUR;
@@ -5625,6 +5649,7 @@ proc_call(proc, args)
}
PUSH_TAG(PROT_NONE);
+ _block.tag = prot_tag;
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(proc);
@@ -5690,6 +5715,7 @@ block_pass(self, node)
{
VALUE block = rb_eval(self, node->nd_body);
struct BLOCK * volatile old_block;
+ struct BLOCK _block;
struct BLOCK *data;
volatile VALUE result = Qnil;
int state;
@@ -5712,11 +5738,13 @@ block_pass(self, node)
/* PUSH BLOCK from data */
old_block = ruby_block;
- ruby_block = data;
+ _block = *data;
+ ruby_block = &_block;
PUSH_ITER(ITER_PRE);
ruby_frame->iter = ITER_PRE;
PUSH_TAG(PROT_NONE);
+ _block.tag = prot_tag;
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(block);
@@ -5724,7 +5752,7 @@ block_pass(self, node)
}
POP_TAG();
POP_ITER();
- if (ruby_block->tag->dst == state) {
+ if (_block.tag->dst == state) {
state &= TAG_MASK;
orphan = 2;
}
@@ -6085,6 +6113,7 @@ thread_mark(th)
rb_gc_mark(th->errinfo);
rb_gc_mark(th->last_line);
rb_gc_mark(th->last_match);
+ rb_gc_mark(th->trace);
rb_mark_tbl(th->locals);
/* mark data in copied stack */