summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-06-14 01:47:31 +0900
committerYukihiro Matsumoto <[email protected]>2012-06-14 01:47:31 +0900
commit6adaf3b80fd255668f4fe500afc4fd1d0dfad50b (patch)
tree98d6648c92c8fcb121e5fa66d3ffb7afea271e97 /src
parent3b2ff6145e86d071ff99e552223e3b0eebee0fb0 (diff)
downloadmruby-6adaf3b80fd255668f4fe500afc4fd1d0dfad50b.tar.gz
mruby-6adaf3b80fd255668f4fe500afc4fd1d0dfad50b.zip
should invoke ensure clauses just before terminating mrb_sun; close #270
Diffstat (limited to 'src')
-rw-r--r--src/vm.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/vm.c b/src/vm.c
index 3d4d0370b..ef3535d53 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -164,6 +164,7 @@ ecall(mrb_state *mrb, int i)
struct RProc *p;
mrb_callinfo *ci;
mrb_value *self = mrb->stack;
+ struct RObject *exc;
p = mrb->ensure[i];
ci = cipush(mrb);
@@ -175,7 +176,9 @@ ecall(mrb_state *mrb, int i)
ci->nregs = p->body.irep->nregs;
ci->target_class = p->target_class;
mrb->stack = mrb->stack + ci[-1].nregs;
+ exc = mrb->exc; mrb->exc = 0;
mrb_run(mrb, p, *self);
+ mrb->exc = exc;
}
mrb_value
@@ -999,13 +1002,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
L_RETURN:
if (mrb->exc) {
mrb_callinfo *ci;
+ int eidx;
L_RAISE:
ci = mrb->ci;
+ eidx = mrb->ci->eidx;
if (ci == mrb->cibase) goto L_STOP;
while (ci[0].ridx == ci[-1].ridx) {
cipop(mrb);
ci = mrb->ci;
+ while (eidx > mrb->ci->eidx) {
+ ecall(mrb, --eidx);
+ }
if (ci == mrb->cibase) {
if (ci->ridx == 0) {
mrb->stack = mrb->stbase;
@@ -1569,6 +1577,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_STOP) {
/* stop VM */
L_STOP:
+ {
+ int n = mrb->ci->eidx;
+
+ while (n--) {
+ ecall(mrb, n);
+ }
+ }
mrb->jmp = prev_jmp;
if (mrb->exc) {
return mrb_obj_value(mrb->exc);