summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-13 16:32:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-13 16:32:00 +0000
commitb2f9a0f5cb30242a7a2d3aafed911c0929bc115e (patch)
treee5d8ea6a4be37873d3ec089d8774f85495667d41
parent71286e3770b86a11f554ee1eacd13e30dd47bd08 (diff)
eval.c: reuse tag
* eval.c (rb_rescue2): reuse tags pushed for body proc to protect rescue proc too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44186 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--eval.c32
2 files changed, 19 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 5dea9355e2..48c4203e74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Dec 14 01:31:52 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (rb_rescue2): reuse tags pushed for body proc to protect
+ rescue proc too.
+
Sat Dec 14 01:15:51 2013 Masaya Tarui <tarui@ruby-lang.org>
* gc.c (wmap_final_func): Bugfix. Should update *value to new pointer.
diff --git a/eval.c b/eval.c
index 2882c57295..3a0206f24a 100644
--- a/eval.c
+++ b/eval.c
@@ -741,7 +741,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
int state;
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
- volatile VALUE result;
+ volatile VALUE result = Qfalse;
volatile VALUE e_info = th->errinfo;
va_list args;
@@ -750,6 +750,15 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
retry_entry:
result = (*b_proc) (data1);
}
+ else if (result) {
+ /* escape from r_proc */
+ if (state == TAG_RETRY) {
+ state = 0;
+ th->errinfo = Qnil;
+ result = Qfalse;
+ goto retry_entry;
+ }
+ }
else {
th->cfp = cfp; /* restore */
@@ -767,25 +776,12 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
va_end(args);
if (handle) {
+ result = Qnil;
+ state = 0;
if (r_proc) {
- PUSH_TAG();
- 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;
- }
- if (state == 0) {
- th->errinfo = e_info;
+ result = (*r_proc) (data2, th->errinfo);
}
+ th->errinfo = e_info;
}
}
}