summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h3
-rw-r--r--src/error.c23
2 files changed, 26 insertions, 0 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 52bcd58bf..4bbffb189 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -1293,6 +1293,9 @@ MRB_API void mrb_print_backtrace(mrb_state *mrb);
MRB_API void mrb_print_error(mrb_state *mrb);
/* function for `raisef` formatting */
MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap);
+/* function to protect errors during execution */
+MRB_API mrb_value mrb_exc_protect(mrb_state *mrb, mrb_value (*body)(mrb_state*, void*), void *a, mrb_value (*resc)(mrb_state*, void*, mrb_value), void *b);
+
/* macros to get typical exception objects
note:
diff --git a/src/error.c b/src/error.c
index b19f0ea43..c077c8663 100644
--- a/src/error.c
+++ b/src/error.c
@@ -555,6 +555,29 @@ mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max)
#undef FMT
}
+MRB_API mrb_value
+mrb_exc_protect(mrb_state *mrb, mrb_value (*body)(mrb_state*, void*), void *a,
+ mrb_value (*resc)(mrb_state*, void*, mrb_value), void *b)
+{
+ struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+ struct mrb_jmpbuf c_jmp;
+ mrb_value v = mrb_undef_value();
+
+ MRB_TRY(&c_jmp) {
+ mrb->jmp = &c_jmp;
+ v = body(mrb, a);
+ } MRB_CATCH(&c_jmp) {
+ if (mrb->exc) {
+ v = resc(mrb, b, mrb_obj_value(mrb->exc));
+ mrb->exc = NULL;
+ }
+ } MRB_END_EXC(&c_jmp);
+
+ mrb->jmp = prev_jmp;
+
+ return v;
+}
+
void mrb_core_init_printabort(void);
int