1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include <mruby.h>
#include <mruby/error.h>
struct protect_data {
mrb_func_t body;
mrb_value data;
};
static mrb_value
protect_body(mrb_state *mrb, void *p)
{
struct protect_data *dp = (struct protect_data*)p;
return dp->body(mrb, dp->data);
}
MRB_API mrb_value
mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state)
{
struct protect_data protect_data = { body, data };
return mrb_protect_error(mrb, protect_body, &protect_data, state);
}
MRB_API mrb_value
mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data)
{
int ai = mrb_gc_arena_save(mrb);
struct protect_data protect_data = { body, b_data };
mrb_bool error;
mrb_value result = mrb_protect_error(mrb, protect_body, &protect_data, &error);
ensure(mrb, e_data);
mrb_gc_arena_restore(mrb, ai);
mrb_gc_protect(mrb, result);
if (error) {
mrb_exc_raise(mrb, result); /* rethrow catched exceptions */
}
return result;
}
MRB_API mrb_value
mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t rescue, mrb_value r_data)
{
return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, 1, &mrb->eStandardError_class);
}
MRB_API mrb_value
mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data,
mrb_int len, struct RClass **classes)
{
int ai = mrb_gc_arena_save(mrb);
struct protect_data protect_data = { body, b_data };
mrb_bool error;
mrb_value result = mrb_protect_error(mrb, protect_body, &protect_data, &error);
if (error) {
mrb_bool error_matched = FALSE;
for (mrb_int i = 0; i < len; ++i) {
if (mrb_obj_is_kind_of(mrb, result, classes[i])) {
error_matched = TRUE;
break;
}
}
if (!error_matched) { mrb_exc_raise(mrb, result); }
mrb->exc = NULL;
result = rescue(mrb, r_data);
mrb_gc_arena_restore(mrb, ai);
mrb_gc_protect(mrb, result);
}
return result;
}
void
mrb_mruby_error_gem_init(mrb_state *mrb)
{
}
void
mrb_mruby_error_gem_final(mrb_state *mrb)
{
}
|