* eval.c (rb_rescue2): restore cfp ([ruby-dev:30582]).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12172 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2007-04-12 08:13:20 +00:00
parent cc3871f9dc
commit e0943c481a
2 changed files with 38 additions and 28 deletions

View File

@ -1,3 +1,7 @@
Thu Apr 12 17:11:54 2007 Koichi Sasada <ko1@atdot.net>
* eval.c (rb_rescue2): restore cfp ([ruby-dev:30582]).
Thu Apr 12 16:06:48 2007 Koichi Sasada <ko1@atdot.net> Thu Apr 12 16:06:48 2007 Koichi Sasada <ko1@atdot.net>
* eval.c (rb_protect): restore cfp ([ruby-dev:30671]). * eval.c (rb_protect): restore cfp ([ruby-dev:30671]).

62
eval.c
View File

@ -1327,8 +1327,10 @@ rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1, VALUE (*r_proc) (ANYARGS),
VALUE data2, ...) VALUE data2, ...)
{ {
int state; int state;
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
volatile VALUE result; volatile VALUE result;
volatile VALUE e_info = GET_THREAD()->errinfo; volatile VALUE e_info = th->errinfo;
va_list args; va_list args;
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
@ -1336,38 +1338,42 @@ rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1, VALUE (*r_proc) (ANYARGS),
retry_entry: retry_entry:
result = (*b_proc) (data1); result = (*b_proc) (data1);
} }
else if (state == TAG_RAISE) { else {
int handle = Qfalse; th->cfp = cfp; /* restore */
VALUE eclass;
va_init_list(args, data2); if (state == TAG_RAISE) {
while (eclass = va_arg(args, VALUE)) { int handle = Qfalse;
if (rb_obj_is_kind_of(GET_THREAD()->errinfo, eclass)) { VALUE eclass;
handle = Qtrue;
break;
}
}
va_end(args);
if (handle) { va_init_list(args, data2);
if (r_proc) { while (eclass = va_arg(args, VALUE)) {
PUSH_TAG(PROT_NONE); if (rb_obj_is_kind_of(th->errinfo, eclass)) {
if ((state = EXEC_TAG()) == 0) { handle = Qtrue;
result = (*r_proc) (data2, GET_THREAD()->errinfo); break;
} }
POP_TAG(); }
if (state == TAG_RETRY) { va_end(args);
if (handle) {
if (r_proc) {
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
result = (*r_proc) (data2, th->errinfo);
}
POP_TAG();
if (state == TAG_RETRY) {
state = 0;
th->errinfo = Qnil;
goto retry_entry;
}
}
else {
result = Qnil;
state = 0; state = 0;
GET_THREAD()->errinfo = Qnil;
goto retry_entry;
} }
} if (state == 0) {
else { th->errinfo = e_info;
result = Qnil; }
state = 0;
}
if (state == 0) {
GET_THREAD()->errinfo = e_info;
} }
} }
} }