Add a new function mrb_exc_protect().

`mrb_exc_protect()` takes two C functions, `body` to be executed first,
and `resc` to be executed when an error happens during `body` execution.
Since `mrb_exc_protect()` should be compiled with the proper compiler,
we will not see the problem like #5088 that was caused by `setjmp()` and
`throw` mixture.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2020-09-29 10:21:10 +09:00
parent 5069fb15e4
commit 3d6adccfbe
2 changed files with 26 additions and 0 deletions
+23
View File
@@ -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