diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-10-12 22:14:11 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-10-12 22:14:11 +0900 |
| commit | 291234c7aa17727d4a2e581330e0eb3c0f388c6b (patch) | |
| tree | ed236208eb00ca16f5be0eedcb599b5b18e1841a | |
| parent | 5004d9a282145488dd8f32668805145b02977be1 (diff) | |
| parent | f77fb11f4e47164c7c6063a20ed0791bf151308f (diff) | |
| download | mruby-291234c7aa17727d4a2e581330e0eb3c0f388c6b.tar.gz mruby-291234c7aa17727d4a2e581330e0eb3c0f388c6b.zip | |
Merge branch 'exc_mesg' of https://github.com/take-cheeze/mruby into take-cheeze-exc_mesg
| -rw-r--r-- | include/mruby/error.h | 2 | ||||
| -rw-r--r-- | src/error.c | 29 | ||||
| -rw-r--r-- | src/gc.c | 16 |
3 files changed, 41 insertions, 6 deletions
diff --git a/include/mruby/error.h b/include/mruby/error.h index 20ca38586..80c21434f 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -17,9 +17,11 @@ MRB_BEGIN_DECL struct RException { MRB_OBJECT_HEADER; struct iv_tbl *iv; + struct RString *mesg; }; #define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) +#define MRB_EXC_MESG_STRING_FLAG 0x100 MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg); MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str); diff --git a/src/error.c b/src/error.c index 5ceff2436..b2ae38295 100644 --- a/src/error.c +++ b/src/error.c @@ -17,6 +17,27 @@ #include <mruby/throw.h> #include <mruby/presym.h> +static void +exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) +{ + if (mrb_string_p(mesg)) { + exc->flags |= MRB_EXC_MESG_STRING_FLAG; + exc->mesg = RSTRING(mesg); + mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); + } + else if (!mrb_nil_p(mesg)) { + exc->flags &= ~MRB_EXC_MESG_STRING_FLAG; + mrb_obj_iv_set(mrb, (struct RObject*)exc, mrb_intern_lit(mrb, "mesg"), mesg); + } +} + +static mrb_value +exc_mesg_get(mrb_state *mrb, struct RException *exc) +{ + return (exc->flags & MRB_EXC_MESG_STRING_FLAG) != 0 + ? mrb_obj_value(exc->mesg) : mrb_obj_iv_get(mrb, (struct RObject*)exc, mrb_intern_lit(mrb, "mesg")); +} + MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) { @@ -48,7 +69,7 @@ exc_initialize(mrb_state *mrb, mrb_value exc) mrb_value mesg; if (mrb_get_args(mrb, "|o", &mesg) == 1) { - mrb_iv_set(mrb, exc, MRB_SYM(mesg), mesg); + exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); } return exc; } @@ -77,7 +98,7 @@ exc_exception(mrb_state *mrb, mrb_value self) if (argc == 0) return self; if (mrb_obj_equal(mrb, self, a)) return self; exc = mrb_obj_clone(mrb, self); - mrb_iv_set(mrb, exc, MRB_SYM(mesg), a); + exc_mesg_set(mrb, mrb_exc_ptr(exc), a); return exc; } @@ -93,7 +114,7 @@ exc_exception(mrb_state *mrb, mrb_value self) static mrb_value exc_to_s(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = mrb_attr_get(mrb, exc, MRB_SYM(mesg)); + mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); struct RObject *p; if (!mrb_string_p(mesg)) { @@ -133,7 +154,7 @@ exc_message(mrb_state *mrb, mrb_value exc) mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = mrb_attr_get(mrb, exc, MRB_SYM(mesg)); + mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc))); mesg = mrb_obj_as_string(mrb, mesg); return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); @@ -686,7 +686,6 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_OBJECT: case MRB_TT_DATA: - case MRB_TT_EXCEPTION: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; @@ -759,6 +758,13 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) } break; + case MRB_TT_EXCEPTION: + mrb_gc_mark_iv(mrb, (struct RObject*)obj); + if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->mesg); + } + break; + default: break; } @@ -989,7 +995,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_OBJECT: case MRB_TT_DATA: - case MRB_TT_EXCEPTION: children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); break; @@ -1042,6 +1047,13 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) children+=2; break; + case MRB_TT_EXCEPTION: + children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); + if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + children++; + } + break; + default: break; } |
