summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-05-19 15:45:46 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-05-19 15:45:46 +0000
commit7e35911e105409fabe48dc2a6214479b6a6ffa24 (patch)
tree5b28440687c1701389b14598454e99aee9a925ba /eval.c
parente08bc0a22ae6c2d2ac0664d82675ca81a30df607 (diff)
* ext/pty/pty.c (pty_finalize_syswait): join (using Thread#value)
before detach pid. [ruby-talk:71519] * eval.c (PUSH_FRAME): save outer ruby_block. [ruby-list:37677], [ruby-dev:20202] * eval.c (BEGIN_CALLARGS): restore outer block by using ruby_block->outer. * eval.c (block_pass): do not alter block->prev, but block->outer. * array.c (get_inspect_tbl): warning on wrong condition. * eval.c (localjump_xvalue): renamed exitstatus to exit_value since it's not exit "status" after all. * eval.c (localjump_error): add reason to LocalJumpError. * compar.c (rb_cmpint): raise error via rb_cmperr(), if cmp value is nil. now take new 2 arguments. * time.c (time_cmp): 2003-05-16 fix was incomplete. (ruby-bugs-ja:PR#458) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3823 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/eval.c b/eval.c
index c1538301b7..0bc1fea016 100644
--- a/eval.c
+++ b/eval.c
@@ -628,6 +628,7 @@ struct BLOCK {
struct RVarmap *dyna_vars;
VALUE orig_thread;
VALUE wrapper;
+ struct BLOCK *outer;
struct BLOCK *prev;
};
@@ -658,6 +659,7 @@ new_blktag()
_block.frame.node = ruby_current_node;\
_block.scope = ruby_scope; \
_block.prev = ruby_block; \
+ _block.outer = ruby_block; \
_block.iter = ruby_iter->iter; \
_block.vmode = scope_vmode; \
_block.flags = BLOCK_D_SCOPE; \
@@ -1477,20 +1479,45 @@ rb_eval_string_wrap(str, state)
}
static void
-localjump_error(mesg, status)
+localjump_error(mesg, status, reason)
const char *mesg;
VALUE status;
+ int reason;
{
VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
- rb_iv_set(exc, "@status", status);
+ VALUE id;
+
+ rb_iv_set(exc, "@exit_value", status);
+ switch (reason) {
+ case TAG_BREAK:
+ id = rb_intern("break"); break;
+ case TAG_REDO:
+ id = rb_intern("redo"); break;
+ case TAG_RETRY:
+ id = rb_intern("retry"); break;
+ case TAG_NEXT:
+ id = rb_intern("next"); break;
+ case TAG_RETURN:
+ id = rb_intern("return"); break;
+ default:
+ id = rb_intern("noreason"); break;
+ }
+ rb_iv_set(exc, "@reason", ID2SYM(id));
rb_exc_raise(exc);
}
static VALUE
-localjump_exitstatus(exc)
+localjump_xvalue(exc)
+ VALUE exc;
+{
+ return rb_iv_get(exc, "@exit_value");
+}
+
+static VALUE
+localjump_reason(exc)
VALUE exc;
{
- return rb_iv_get(exc, "@status");
+ return rb_iv_get(exc, "@reason");
}
static void
@@ -1505,19 +1532,19 @@ jump_tag_but_local_jump(state)
case 0:
break;
case TAG_RETURN:
- localjump_error("unexpected return", val);
+ localjump_error("unexpected return", val, state);
break;
case TAG_NEXT:
- localjump_error("unexpected next", val);
+ localjump_error("unexpected next", val, state);
break;
case TAG_BREAK:
- localjump_error("unexpected break", val);
+ localjump_error("unexpected break", val, state);
break;
case TAG_REDO:
- localjump_error("unexpected redo", Qnil);
+ localjump_error("unexpected redo", Qnil, state);
break;
case TAG_RETRY:
- localjump_error("retry outside of rescue clause", Qnil);
+ localjump_error("retry outside of rescue clause", Qnil, state);
break;
default:
JUMP_TAG(state);
@@ -1897,7 +1924,7 @@ copy_node_scope(node, rval)
#define BEGIN_CALLARGS do {\
struct BLOCK *tmp_block = ruby_block;\
if (ruby_iter->iter == ITER_PRE) {\
- ruby_block = ruby_block->prev;\
+ ruby_block = ruby_block->outer;\
}\
PUSH_ITER(ITER_NOT)
@@ -3967,7 +3994,7 @@ rb_yield_0(val, self, klass, pcall, avalue)
static unsigned serial = 1;
if (!rb_block_given_p()) {
- localjump_error("no block given", Qnil);
+ localjump_error("no block given", Qnil, 0);
}
PUSH_VARS();
@@ -6805,7 +6832,7 @@ proc_invoke(proc, args, pcall, self)
break;
case TAG_RETRY:
if (pcall || orphan) {
- localjump_error("retry from proc-closure", Qnil);
+ localjump_error("retry from proc-closure", Qnil, state);
}
/* fall through */
case TAG_BREAK:
@@ -6813,7 +6840,7 @@ proc_invoke(proc, args, pcall, self)
result = prot_tag->retval;
}
else if (orphan) {
- localjump_error("break from proc-closure", prot_tag->retval);
+ localjump_error("break from proc-closure", prot_tag->retval, state);
}
else {
ruby_block->tag->dst = incoming_state;
@@ -6822,7 +6849,7 @@ proc_invoke(proc, args, pcall, self)
break;
case TAG_RETURN:
if (orphan) { /* orphan procedure */
- localjump_error("return from proc-closure", prot_tag->retval);
+ localjump_error("return from proc-closure", prot_tag->retval, state);
}
/* fall through */
default:
@@ -6988,7 +7015,7 @@ block_pass(self, node)
/* PUSH BLOCK from data */
old_block = ruby_block;
_block = *data;
- _block.prev = old_block;
+ _block.outer = ruby_block;
ruby_block = &_block;
PUSH_ITER(ITER_PRE);
ruby_frame->iter = ITER_PRE;
@@ -7035,7 +7062,7 @@ block_pass(self, node)
goto retry;
case TAG_RETURN:
if (orphan) {
- localjump_error("return from proc-closure", prot_tag->retval);
+ localjump_error("return from proc-closure", prot_tag->retval, state);
}
default:
JUMP_TAG(state);
@@ -7445,7 +7472,8 @@ void
Init_Proc()
{
rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
- rb_define_method(rb_eLocalJumpError, "exitstatus", localjump_exitstatus, 0);
+ rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
+ rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError);