summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authortake_cheeze <[email protected]>2014-02-25 18:47:28 +0900
committertake_cheeze <[email protected]>2014-03-01 20:05:29 +0900
commit78915f96017a12e8c3c40a4a2714543c10d0d070 (patch)
tree9db022c63ebd09aec5d1164141a0bdb85cc93d3f /src/vm.c
parent5ff9c1d2861609fc98f03ec2d768e0b4f1559a09 (diff)
downloadmruby-78915f96017a12e8c3c40a4a2714543c10d0d070.tar.gz
mruby-78915f96017a12e8c3c40a4a2714543c10d0d070.zip
support c++ exception
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/src/vm.c b/src/vm.c
index 62ac86c90..7aec31909 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -4,7 +4,6 @@
** See Copyright Notice in mruby.h
*/
-#include <setjmp.h>
#include <stddef.h>
#include <stdarg.h>
#include <math.h>
@@ -20,6 +19,7 @@
#include "mruby/error.h"
#include "opcode.h"
#include "value_array.h"
+#include "mrb_throw.h"
#ifndef ENABLE_STDIO
#if defined(__cplusplus)
@@ -328,10 +328,16 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
mrb_value val;
if (!mrb->jmp) {
- jmp_buf c_jmp;
+ struct mrb_jmpbuf c_jmp;
mrb_callinfo *old_ci = mrb->c->ci;
- if (setjmp(c_jmp) != 0) { /* error */
+ MRB_TRY(&c_jmp) {
+ mrb->jmp = &c_jmp;
+ /* recursive call */
+ val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
+ mrb->jmp = 0;
+ }
+ MRB_CATCH(&c_jmp) { /* error */
while (old_ci != mrb->c->ci) {
mrb->c->stack = mrb->c->ci->stackent;
cipop(mrb);
@@ -339,12 +345,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
mrb->jmp = 0;
val = mrb_obj_value(mrb->exc);
}
- else {
- mrb->jmp = &c_jmp;
- /* recursive call */
- val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
- mrb->jmp = 0;
- }
+ MRB_END_EXC(&c_jmp);
}
else {
struct RProc *p;
@@ -629,8 +630,8 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
mrb_value *regs = NULL;
mrb_code i;
int ai = mrb_gc_arena_save(mrb);
- jmp_buf *prev_jmp = (jmp_buf *)mrb->jmp;
- jmp_buf c_jmp;
+ struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+ struct mrb_jmpbuf c_jmp;
#ifdef DIRECT_THREADED
static void *optable[] = {
@@ -657,13 +658,15 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
};
#endif
+ mrb_bool exc_catched = FALSE;
+RETRY_TRY_BLOCK:
- if (setjmp(c_jmp) == 0) {
- mrb->jmp = &c_jmp;
- }
- else {
+ MRB_TRY(&c_jmp) {
+
+ if (exc_catched) {
goto L_RAISE;
}
+ mrb->jmp = &c_jmp;
if (!mrb->c->stack) {
stack_init(mrb);
}
@@ -1353,7 +1356,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
mrb->c->stack = ci[1].stackent;
if (ci[1].acc == CI_ACC_SKIP && prev_jmp) {
mrb->jmp = prev_jmp;
- mrb_longjmp(mrb);
+ MRB_THROW(prev_jmp);
}
if (ci > mrb->c->cibase) {
while (eidx > ci[-1].eidx) {
@@ -2247,6 +2250,13 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
}
}
END_DISPATCH;
+
+ }
+ MRB_CATCH(&c_jmp) {
+ exc_catched = TRUE;
+ goto RETRY_TRY_BLOCK;
+ }
+ MRB_END_EXC(&c_jmp);
}
mrb_value
@@ -2254,9 +2264,3 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
{
return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
}
-
-void
-mrb_longjmp(mrb_state *mrb)
-{
- longjmp(*(jmp_buf*)mrb->jmp, 1);
-}