summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-30 00:04:02 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-30 00:04:02 +0000
commit8e9fbbf6d6f4c47286a6fbc4e2c4e77189be119b (patch)
tree2018232d06deec66076a9ddff0988f737c367366 /eval.c
parentda84ad63ee95265dfbdd51c370cdfe5f91e58d59 (diff)
* eval.c (struct BLOCK): remove BLOCKTAG, use scope instead.
* eval.c (POP_TAG): no longer propagate retval. retval is now set directly by localjump_destination(). * eval.c (localjump_destination): new function to cast return/break local jump. * eval.c (rb_yield_0): stop TAG_RETURN/TAG_BREAK escaping. * variable.c (rb_autoload_load): call const_missing if autoloading constant is not defined to allow hook. * eval.c (rb_eval): use rb_const_get_from() instead of rb_const_get_at(). * eval.c (is_defined): forgot to check NODE_COLON3. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c343
1 files changed, 129 insertions, 214 deletions
diff --git a/eval.c b/eval.c
index 5ee4158b27..15911679c4 100644
--- a/eval.c
+++ b/eval.c
@@ -602,19 +602,12 @@ static struct SCOPE *top_scope;
ruby_frame = _frame.prev; \
} while (0)
-struct BLOCKTAG {
- struct RBasic super;
- long dst;
- long flags;
-};
-
struct BLOCK {
NODE *var;
NODE *body;
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
- struct BLOCKTAG *tag;
VALUE klass;
NODE *cref;
int iter;
@@ -629,26 +622,12 @@ struct BLOCK {
};
#define BLOCK_D_SCOPE 1
-#define BLOCK_DYNAMIC 2
-#define BLOCK_ORPHAN 4
-#define BLOCK_LAMBDA 8
-#define BLOCK_LEFT 16
+#define BLOCK_LAMBDA 2
static struct BLOCK *ruby_block;
-static struct BLOCKTAG*
-new_blktag()
-{
- NEWOBJ(blktag, struct BLOCKTAG);
- OBJSETUP(blktag, 0, T_BLKTAG);
- blktag->dst = 0;
- blktag->flags = 0;
- return blktag;
-}
-
#define PUSH_BLOCK(v,b) do { \
struct BLOCK _block; \
- _block.tag = new_blktag(); \
_block.var = v; \
_block.body = b; \
_block.self = self; \
@@ -668,12 +647,7 @@ new_blktag()
ruby_block = &_block
#define POP_BLOCK() \
- if (_block.tag->flags & (BLOCK_DYNAMIC)) \
- _block.tag->flags |= BLOCK_ORPHAN; \
- else if (!(_block.scope->flags & SCOPE_DONT_RECYCLE)) \
- rb_gc_force_recycle((VALUE)_block.tag); \
ruby_block = _block.prev; \
- _block.tag->flags |= BLOCK_LEFT; \
} while (0)
struct RVarmap *ruby_dyna_vars;
@@ -845,7 +819,7 @@ struct tag {
jmp_buf buf;
struct FRAME *frame;
struct iter *iter;
- ID tag;
+ VALUE tag;
VALUE retval;
struct SCOPE *scope;
int dst;
@@ -864,9 +838,12 @@ static struct tag *prot_tag;
_tag.dst = 0; \
prot_tag = &_tag
-#define PROT_NONE 0
-#define PROT_FUNC -1
-#define PROT_THREAD -2
+#define PROT_NONE Qfalse /* 0 */
+#define PROT_THREAD Qtrue /* 2 */
+#define PROT_FUNC INT2FIX(0) /* 1 */
+#define PROT_ITER INT2FIX(1) /* 3 */
+#define PROT_CALL INT2FIX(2) /* 5 */
+#define PROT_PCALL INT2FIX(3) /* 7 */
#define EXEC_TAG() (FLUSH_REGISTER_WINDOWS, setjmp(prot_tag->buf))
@@ -877,14 +854,10 @@ static struct tag *prot_tag;
} while (0)
#define POP_TAG() \
- if (_tag.prev) \
- _tag.prev->retval = _tag.retval;\
prot_tag = _tag.prev; \
} while (0)
-#define POP_TMPTAG() \
- prot_tag = _tag.prev; \
-} while (0)
+#define TAG_DST(t) (_tag.dst == (VALUE)_tag.scope)
#define TAG_RETURN 0x1
#define TAG_BREAK 0x2
@@ -1561,12 +1534,12 @@ jump_tag_but_local_jump(state)
case TAG_RETURN:
localjump_error("unexpected return", val, state);
break;
- case TAG_NEXT:
- localjump_error("unexpected next", val, state);
- break;
case TAG_BREAK:
localjump_error("unexpected break", val, state);
break;
+ case TAG_NEXT:
+ localjump_error("unexpected next", val, state);
+ break;
case TAG_REDO:
localjump_error("unexpected redo", Qnil, state);
break;
@@ -1574,9 +1547,9 @@ jump_tag_but_local_jump(state)
localjump_error("retry outside of rescue clause", Qnil, state);
break;
default:
- JUMP_TAG(state);
break;
}
+ JUMP_TAG(state);
}
VALUE
@@ -2163,6 +2136,12 @@ is_defined(self, node, buf)
}
break;
+ case NODE_COLON3:
+ if (rb_const_defined_from(rb_cObject, node->nd_mid)) {
+ return "constant";
+ }
+ break;
+
case NODE_NTH_REF:
if (RTEST(rb_reg_nth_defined(node->nd_nth, MATCH_DATA))) {
sprintf(buf, "$%d", (int)node->nd_nth);
@@ -2279,7 +2258,7 @@ call_trace_func(event, node, self, id, klass)
Qundef, 0);
}
if (raised) thread_set_raised();
- POP_TMPTAG(); /* do not propagate retval */
+ POP_TAG();
POP_FRAME();
tracing = 0;
@@ -2434,12 +2413,12 @@ class_prefix(self, cpath)
}
}
-static void return_check _((void));
#define return_value(v) do {\
if ((prot_tag->retval = (v)) == Qundef) {\
prot_tag->retval = Qnil;\
}\
} while (0)
+static void localjump_destination _((int, struct SCOPE*, VALUE));
static VALUE
rb_eval(self, n)
@@ -2508,7 +2487,7 @@ rb_eval(self, n)
/* node for speed-up(top-level loop for -n/-p) */
case NODE_OPT_N:
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(PROT_ITER);
switch (state = EXEC_TAG()) {
case 0:
opt_n_next:
@@ -2640,7 +2619,7 @@ rb_eval(self, n)
RETURN(Qnil);
case NODE_WHILE:
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(PROT_ITER);
result = Qnil;
switch (state = EXEC_TAG()) {
case 0:
@@ -2672,7 +2651,7 @@ rb_eval(self, n)
RETURN(result);
case NODE_UNTIL:
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(PROT_ITER);
result = Qnil;
switch (state = EXEC_TAG()) {
case 0:
@@ -2710,7 +2689,7 @@ rb_eval(self, n)
case NODE_ITER:
case NODE_FOR:
{
- PUSH_TAG(PROT_FUNC);
+ PUSH_TAG(PROT_ITER);
PUSH_BLOCK(node->nd_var, node->nd_body);
state = EXEC_TAG();
@@ -2733,30 +2712,19 @@ rb_eval(self, n)
}
POP_ITER();
}
- else {
- if (_block.tag->dst == state) {
- state &= TAG_MASK;
- if (state == TAG_RETURN || state == TAG_BREAK) {
- result = prot_tag->retval;
- }
- }
- if (state == TAG_RETRY) {
- state = 0;
- goto iter_retry;
- }
+ else if (state == TAG_BREAK && TAG_DST()) {
+ result = prot_tag->retval;
+ state = 0;
+ }
+ else if (state == TAG_RETRY) {
+ state = 0;
+ goto iter_retry;
}
POP_BLOCK();
POP_TAG();
switch (state) {
case 0:
break;
-
- case TAG_BREAK:
- break;
-
- case TAG_RETURN:
- return_value(result);
- /* fall through */
default:
JUMP_TAG(state);
}
@@ -2764,8 +2732,7 @@ rb_eval(self, n)
break;
case NODE_BREAK:
- return_value(rb_eval(self, node->nd_stts));
- JUMP_TAG(TAG_BREAK);
+ localjump_destination(TAG_BREAK, ruby_scope, rb_eval(self, node->nd_stts));
break;
case NODE_NEXT:
@@ -2938,9 +2905,7 @@ rb_eval(self, n)
break;
case NODE_RETURN:
- return_value(rb_eval(self, node->nd_stts));
- return_check();
- JUMP_TAG(TAG_RETURN);
+ localjump_destination(TAG_RETURN, ruby_scope, rb_eval(self, node->nd_stts));
break;
case NODE_ARGSCAT:
@@ -3048,13 +3013,14 @@ rb_eval(self, n)
{
struct FRAME frame;
NODE *saved_cref = 0;
+ int jump_chain = Qfalse;
frame = *ruby_frame;
frame.tmp = ruby_frame;
ruby_frame = &frame;
PUSH_SCOPE();
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(PROT_PCALL);
if (node->nd_rval) {
saved_cref = ruby_cref;
ruby_cref = (NODE*)node->nd_rval;
@@ -3073,12 +3039,24 @@ rb_eval(self, n)
if ((state = EXEC_TAG()) == 0) {
result = rb_eval(self, node->nd_next);
}
+ else if (TAG_DST()) {
+ result = prot_tag->retval;
+ jump_chain = Qtrue;
+ }
POP_TAG();
POP_SCOPE();
ruby_frame = frame.tmp;
if (saved_cref)
ruby_cref = saved_cref;
- if (state) JUMP_TAG(state);
+ switch (state) {
+ case 0:
+ break;
+ case TAG_RETURN:
+ case TAG_BREAK:
+ localjump_destination(state, ruby_scope, result);
+ default:
+ JUMP_TAG(state);
+ }
}
break;
@@ -3271,7 +3249,7 @@ rb_eval(self, n)
break;
case NODE_COLON3:
- result = rb_const_get_at(rb_cObject, node->nd_mid);
+ result = rb_const_get_from(rb_cObject, node->nd_mid);
break;
case NODE_NTH_REF:
@@ -4024,6 +4002,37 @@ rb_f_block_given_p()
return Qfalse;
}
+static VALUE rb_eThreadError;
+
+static void
+localjump_destination(state, scope, retval)
+ int state;
+ struct SCOPE *scope;
+ VALUE retval;
+{
+ struct tag *tt = prot_tag;
+ VALUE tag = (state == TAG_BREAK) ? PROT_ITER : PROT_FUNC;
+
+ if (retval == Qundef) retval = Qnil;
+ while (tt) {
+ if (tt->tag == PROT_PCALL ||
+ (tt->tag == PROT_CALL || tt->tag == tag) && tt->scope == scope) {
+ tt->dst = (VALUE)scope;
+ tt->retval = retval;
+ break;
+ }
+ if (tt->tag == PROT_THREAD) {
+ rb_raise(rb_eThreadError, "%s jump can't across threads",
+ (state == TAG_BREAK) ? "break" : "return");
+ }
+ tt = tt->prev;
+ }
+ if (!tt) {
+ jump_tag_but_local_jump(state);
+ }
+ JUMP_TAG(state);
+}
+
static VALUE
rb_yield_0(val, self, klass, flags, avalue)
VALUE val, self, klass; /* OK */
@@ -4163,12 +4172,6 @@ rb_yield_0(val, self, klass, flags, avalue)
state = 0;
result = prot_tag->retval;
break;
- case TAG_BREAK:
- case TAG_RETURN:
- state |= (serial++ << 8);
- state |= 0x10;
- block->tag->dst = state;
- break;
default:
break;
}
@@ -4201,17 +4204,7 @@ rb_yield_0(val, self, klass, flags, avalue)
ruby_scope = old_scope;
scope_vmode = old_vmode;
ruby_current_node = cnode;
- if (state) {
- if (!block->tag) {
- switch (state & TAG_MASK) {
- case TAG_BREAK:
- case TAG_RETURN:
- jump_tag_but_local_jump(state & TAG_MASK);
- break;
- }
- }
- JUMP_TAG(state);
- }
+ if (state) JUMP_TAG(state);
return result;
}
@@ -4430,24 +4423,20 @@ rb_iterate(it_proc, data1, bl_proc, data2)
PUSH_ITER(ITER_PRE);
PUSH_BLOCK(0, node);
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(PROT_ITER);
state = EXEC_TAG();
if (state == 0) {
iter_retry:
retval = (*it_proc)(data1);
}
- else {
- if (ruby_block->tag->dst == state) {
- state &= TAG_MASK;
- if (state == TAG_RETURN || state == TAG_BREAK) {
- retval = prot_tag->retval;
- }
- }
- if (state == TAG_RETRY) {
- state = 0;
- goto iter_retry;
- }
+ else if (state == TAG_BREAK && TAG_DST()) {
+ retval = prot_tag->retval;
+ state = 0;
+ }
+ else if (state == TAG_RETRY) {
+ state = 0;
+ goto iter_retry;
}
POP_TAG();
POP_BLOCK();
@@ -4456,13 +4445,6 @@ rb_iterate(it_proc, data1, bl_proc, data2)
switch (state) {
case 0:
break;
-
- case TAG_BREAK:
- break;
-
- case TAG_RETURN:
- return_value(retval);
- /* fall through */
default:
JUMP_TAG(state);
}
@@ -4607,7 +4589,6 @@ rb_ensure(b_proc, data1, e_proc, data2)
retval = prot_tag ? prot_tag->retval : Qnil; /* save retval */
(*e_proc)(data2);
if (prot_tag) return_value(retval);
-
if (state) JUMP_TAG(state);
return result;
}
@@ -5051,7 +5032,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
}
result = rb_eval(recv, body);
}
- else if (state == TAG_RETURN) {
+ else if (state == TAG_RETURN && TAG_DST()) {
result = prot_tag->retval;
state = 0;
}
@@ -5067,10 +5048,13 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
case 0:
break;
+ case TAG_BREAK:
+ case TAG_RETURN:
+ JUMP_TAG(state);
+ break;
+
case TAG_RETRY:
- if (rb_block_given_p()) {
- JUMP_TAG(state);
- }
+ if (rb_block_given_p()) JUMP_TAG(state);
/* fall through */
default:
jump_tag_but_local_jump(state);
@@ -5482,13 +5466,6 @@ eval(self, src, scope, file, line)
for (tag=prot_tag; tag; tag=tag->prev) {
scope_dup(tag->scope);
}
- if (ruby_block) {
- struct BLOCK *block = ruby_block;
- while (block) {
- block->tag->flags |= BLOCK_DYNAMIC;
- block = block->prev;
- }
- }
for (vars = ruby_dyna_vars; vars; vars = vars->next) {
FL_SET(vars, DVAR_DONT_RECYCLE);
}
@@ -6708,7 +6685,6 @@ blk_mark(data)
rb_gc_mark((VALUE)data->self);
rb_gc_mark((VALUE)data->dyna_vars);
rb_gc_mark((VALUE)data->cref);
- rb_gc_mark((VALUE)data->tag);
rb_gc_mark(data->wrapper);
rb_gc_mark(data->block_obj);
data = data->prev;
@@ -6755,7 +6731,6 @@ blk_copy_prev(block)
tmp->frame.flags |= FRAME_MALLOC;
}
scope_dup(tmp->scope);
- tmp->tag->flags |= BLOCK_DYNAMIC;
for (vars = tmp->dyna_vars; vars; vars = vars->next) {
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
@@ -6840,8 +6815,6 @@ rb_f_binding(self)
else {
data->prev = 0;
}
- data->flags |= BLOCK_DYNAMIC;
- data->tag->flags |= BLOCK_DYNAMIC;
for (p = data; p; p = p->prev) {
for (vars = p->dyna_vars; vars; vars = vars->next) {
@@ -6940,8 +6913,6 @@ proc_alloc(klass, proc)
else {
data->prev = 0;
}
- data->flags |= BLOCK_DYNAMIC;
- data->tag->flags |= BLOCK_DYNAMIC;
for (p = data; p; p = p->prev) {
for (vars = p->dyna_vars; vars; vars = vars->next) {
@@ -6996,8 +6967,7 @@ static int
block_orphan(data)
struct BLOCK *data;
{
- if ((data->tag->flags & BLOCK_ORPHAN) &&
- (data->scope->flags & SCOPE_NOSTACK)) {
+ if (data->scope->flags & SCOPE_NOSTACK) {
return 1;
}
if (data->orig_thread != rb_thread_current()) {
@@ -7014,8 +6984,8 @@ proc_invoke(proc, args, self, klass)
struct BLOCK * volatile old_block;
struct BLOCK _block;
struct BLOCK *data;
- volatile VALUE result = Qnil;
- int state, incoming_state;
+ volatile VALUE result = Qundef;
+ int state;
volatile int orphan;
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;
@@ -7043,21 +7013,17 @@ proc_invoke(proc, args, self, klass)
PUSH_ITER(ITER_CUR);
ruby_frame->iter = ITER_CUR;
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(pcall ? PROT_PCALL : PROT_CALL);
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(proc);
result = rb_yield_0(args, self, self!=Qundef?CLASS_OF(self):0, pcall, Qtrue);
}
+ else if (TAG_DST()) {
+ result = prot_tag->retval;
+ }
POP_TAG();
-
POP_ITER();
- incoming_state = state;
- if (orphan || pcall ||
- ((ruby_block->tag->flags & BLOCK_LEFT) &&
- ruby_block->tag->dst == state)) {
- state &= TAG_MASK;
- }
ruby_block = old_block;
ruby_wrapper = old_wrapper;
ruby_dyna_vars = old_dvars;
@@ -7073,18 +7039,15 @@ proc_invoke(proc, args, self, klass)
/* fall through */
case TAG_BREAK:
case TAG_RETURN:
- if (pcall) {
- result = prot_tag->retval;
- break;
- }
- else if (orphan) { /* orphan block */
+ if (pcall) break;
+ if (orphan) { /* orphan block */
char mesg[32];
snprintf(mesg, sizeof mesg, "%s from proc-closure",
state == TAG_BREAK ? "break" : "return");
localjump_error(mesg, prot_tag->retval, state);
}
- else if (state == incoming_state) {
- ruby_block->tag->dst = incoming_state;
+ if (result != Qundef) {
+ localjump_destination(state, ruby_scope, result);
}
default:
JUMP_TAG(state);
@@ -7147,7 +7110,7 @@ proc_eq(self, other)
if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;
Data_Get_Struct(self, struct BLOCK, data);
Data_Get_Struct(other, struct BLOCK, data2);
- if (data->tag == data2->tag) return Qtrue;
+ if (data->body == data2->body) return Qtrue;
return Qfalse;
}
@@ -7166,12 +7129,12 @@ proc_to_s(self, other)
if ((node = data->frame.node) || (node = data->body)) {
len += strlen(node->nd_file) + 2 + (SIZEOF_LONG*CHAR_BIT-NODE_LSHIFT)/3;
str = rb_str_new(0, len);
- sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->tag,
+ sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->body,
node->nd_file, nd_line(node));
}
else {
str = rb_str_new(0, len);
- sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx>", cname, w, (VALUE)data->tag);
+ sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx>", cname, w, (VALUE)data->body);
}
RSTRING(str)->len = strlen(RSTRING(str)->ptr);
if (OBJ_TAINTED(self)) OBJ_TAINT(str);
@@ -7262,7 +7225,7 @@ block_pass(self, node)
PUSH_ITER(ITER_PRE);
ruby_frame->iter = ITER_PRE;
- PUSH_TAG(PROT_NONE);
+ PUSH_TAG(PROT_ITER);
state = EXEC_TAG();
if (state == 0) {
retry:
@@ -7271,26 +7234,11 @@ block_pass(self, node)
ruby_safe_level = safe;
result = rb_eval(self, node->nd_iter);
}
- if (_block.tag->dst == state) {
- if (orphan) {
- state &= TAG_MASK;
- }
- else {
- struct BLOCK *ptr = old_block;
-
- while (ptr) {
- if (ptr->scope == _block.scope) {
- ptr->tag->dst = state;
- break;
- }
- ptr = ptr->prev;
- }
- if (!ptr) {
- state &= TAG_MASK;
- }
- }
+ else if (state == TAG_BREAK && TAG_DST()) {
+ result = prot_tag->retval;
+ state = 0;
}
- if (state == TAG_RETRY) {
+ else if (state == TAG_RETRY) {
state = 0;
goto retry;
}
@@ -7302,9 +7250,6 @@ block_pass(self, node)
switch (state) {/* escape from orphan block */
case 0:
break;
- case TAG_BREAK:
- result = prot_tag->retval;
- break;
case TAG_RETURN:
if (orphan) {
localjump_error("return from proc-closure", prot_tag->retval, state);
@@ -7833,8 +7778,6 @@ win32_set_exception_list(p)
#endif
#endif
-static VALUE rb_eThreadError;
-
int rb_thread_pending = 0;
VALUE rb_cThread;
@@ -9932,14 +9875,6 @@ rb_callcc(self)
for (tag=prot_tag; tag; tag=tag->prev) {
scope_dup(tag->scope);
}
- if (ruby_block) {
- struct BLOCK *block = ruby_block;
-
- while (block) {
- block->tag->flags |= BLOCK_DYNAMIC;
- block = block->prev;
- }
- }
th->thread = curr_thread->thread;
for (vars = th->dyna_vars; vars; vars = vars->next) {
@@ -10160,15 +10095,14 @@ rb_f_catch(dmy, tag)
VALUE dmy, tag;
{
int state;
- ID t;
VALUE val = Qnil; /* OK */
- t = rb_to_id(tag);
- PUSH_TAG(t);
+ tag = ID2SYM(rb_to_id(tag));
+ PUSH_TAG(tag);
if ((state = EXEC_TAG()) == 0) {
val = rb_yield_0(tag, 0, 0, Qfalse, Qfalse);
}
- else if (state == TAG_THROW && t == prot_tag->dst) {
+ else if (state == TAG_THROW && tag == prot_tag->dst) {
val = prot_tag->retval;
state = 0;
}
@@ -10180,9 +10114,9 @@ rb_f_catch(dmy, tag)
static VALUE
catch_i(tag)
- ID tag;
+ VALUE tag;
{
- return rb_funcall(Qnil, rb_intern("catch"), 1, ID2SYM(tag));
+ return rb_funcall(Qnil, rb_intern("catch"), 1, tag);
}
VALUE
@@ -10191,7 +10125,7 @@ rb_catch(tag, func, data)
VALUE (*func)();
VALUE data;
{
- return rb_iterate((VALUE(*)_((VALUE)))catch_i, rb_intern(tag), func, data);
+ return rb_iterate((VALUE(*)_((VALUE)))catch_i, ID2SYM(rb_intern(tag)), func, data);
}
static VALUE
@@ -10200,28 +10134,27 @@ rb_f_throw(argc, argv)
VALUE *argv;
{
VALUE tag, value;
- ID t;
struct tag *tt = prot_tag;
rb_scan_args(argc, argv, "11", &tag, &value);
- t = rb_to_id(tag);
+ tag = ID2SYM(rb_to_id(tag));
while (tt) {
- if (tt->tag == t) {
- tt->dst = t;
+ if (tt->tag == tag) {
+ tt->dst = tag;
+ tt->retval = value;
break;
}
if (tt->tag == PROT_THREAD) {
rb_raise(rb_eThreadError, "uncaught throw `%s' in thread 0x%lx",
- rb_id2name(t),
+ rb_id2name(SYM2ID(tag)),
curr_thread);
}
tt = tt->prev;
}
if (!tt) {
- rb_name_error(t, "uncaught throw `%s'", rb_id2name(t));
+ rb_name_error(SYM2ID(tag), "uncaught throw `%s'", rb_id2name(SYM2ID(tag)));
}
- return_value(value);
rb_trap_restore_mask();
JUMP_TAG(TAG_THROW);
#ifndef __GNUC__
@@ -10235,26 +10168,8 @@ rb_throw(tag, val)
VALUE val;
{
VALUE argv[2];
- ID t = rb_intern(tag);
- argv[0] = ID2SYM(t);
+ argv[0] = ID2SYM(rb_intern(tag));
argv[1] = val;
rb_f_throw(2, argv);
}
-
-static void
-return_check()
-{
- struct tag *tt = prot_tag;
-
- while (tt) {
- if (tt->tag == PROT_FUNC) {
- break;
- }
- if (tt->tag == PROT_THREAD) {
- rb_raise(rb_eThreadError, "return from within thread 0x%lx",
- curr_thread);
- }
- tt = tt->prev;
- }
-}