summaryrefslogtreecommitdiff
path: root/eval_jump.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-11-19 17:01:10 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-11-19 17:01:10 +0000
commit9d740ddebeaa46f47c9b4529e8b36d72d97f9105 (patch)
treee9de5e9569c0a30413b1fd892c13cc46f6ef0fdc /eval_jump.c
parent1eac0b55c96c2b5b98748a36ee630ef6a12b2fdb (diff)
eval_jump.c: reuse same tag
* eval_jump.c (rb_exec_end_proc): reduce number of pushing/popping and reuse same tag. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval_jump.c')
-rw-r--r--eval_jump.c64
1 files changed, 27 insertions, 37 deletions
diff --git a/eval_jump.c b/eval_jump.c
index 24bf2a2286..30094e9176 100644
--- a/eval_jump.c
+++ b/eval_jump.c
@@ -93,53 +93,43 @@ rb_mark_end_proc(void)
}
}
+static void
+exec_end_procs_chain(struct end_proc_data *volatile *procs)
+{
+ struct end_proc_data volatile endproc;
+ struct end_proc_data *link;
+
+ while ((link = *procs) != 0) {
+ *procs = link->next;
+ endproc = *link;
+ xfree(link);
+ rb_set_safe_level_force(endproc.safe);
+ (*endproc.func) (endproc.data);
+ }
+}
+
void
rb_exec_end_proc(void)
{
- struct end_proc_data volatile endproc;
- struct end_proc_data volatile *link;
int status;
volatile int safe = rb_safe_level();
rb_thread_t *th = GET_THREAD();
volatile VALUE errinfo = th->errinfo;
- while (ephemeral_end_procs) {
- link = ephemeral_end_procs;
- ephemeral_end_procs = link->next;
- endproc = *link;
- xfree((void *)link);
- link = &endproc;
-
- PUSH_TAG();
- if ((status = EXEC_TAG()) == 0) {
- rb_set_safe_level_force(link->safe);
- (*link->func) (link->data);
- }
- POP_TAG();
- if (status) {
- error_handle(status);
- if (!NIL_P(th->errinfo)) errinfo = th->errinfo;
- }
+ PUSH_TAG();
+ if ((status = EXEC_TAG()) == 0) {
+ again:
+ exec_end_procs_chain(&ephemeral_end_procs);
+ exec_end_procs_chain(&end_procs);
}
-
- while (end_procs) {
- link = end_procs;
- end_procs = link->next;
- endproc = *link;
- xfree((void *)link);
- link = &endproc;
-
- PUSH_TAG();
- if ((status = EXEC_TAG()) == 0) {
- rb_set_safe_level_force(link->safe);
- (*link->func) (link->data);
- }
- POP_TAG();
- if (status) {
- error_handle(status);
- if (!NIL_P(th->errinfo)) errinfo = th->errinfo;
- }
+ else {
+ TH_TMPPOP_TAG();
+ error_handle(status);
+ if (!NIL_P(th->errinfo)) errinfo = th->errinfo;
+ TH_REPUSH_TAG();
+ goto again;
}
+ POP_TAG();
rb_set_safe_level_force(safe);
th->errinfo = errinfo;