From e926b532eec971a5822c71cf47dca6c25ee33e6a Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Tue, 22 Jul 2014 23:08:15 +0900 Subject: Store exception message to `mesg` field of `struct RException`. --- src/error.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/error.c') diff --git a/src/error.c b/src/error.c index 223e2137e..9fc6fe468 100644 --- a/src/error.c +++ b/src/error.c @@ -18,6 +18,20 @@ #include "mruby/class.h" #include "mrb_throw.h" +static void +exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) +{ + exc->flags |= MRB_EXC_MESG_INIT_FLAG; + exc->mesg = mesg; + mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); +} + +static mrb_value +exc_mesg_get(mrb_state *mrb, struct RException *exc) +{ + return (exc->flags & MRB_EXC_MESG_INIT_FLAG) != 0 ? exc->mesg : mrb_nil_value(); +} + mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len) { @@ -46,7 +60,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_intern_lit(mrb, "mesg"), mesg); + exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); } return exc; } @@ -75,7 +89,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_intern_lit(mrb, "mesg"), a); + exc_mesg_set(mrb, mrb_exc_ptr(exc), a); return exc; } @@ -91,7 +105,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_intern_lit(mrb, "mesg")); + mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); struct RObject *p; if (!mrb_string_p(mesg)) { @@ -136,7 +150,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc) mrb_value str, mesg, file, line; mrb_bool append_mesg; - mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); + mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); -- cgit v1.2.3 From f77fb11f4e47164c7c6063a20ed0791bf151308f Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 28 Jul 2014 20:30:02 +0900 Subject: Use RString in `mesg` instead. --- include/mruby/error.h | 4 ++-- src/error.c | 15 +++++++++++---- src/gc.c | 6 +++--- 3 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src/error.c') diff --git a/include/mruby/error.h b/include/mruby/error.h index 8b5e9dd37..ea12ef33e 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -14,11 +14,11 @@ extern "C" { struct RException { MRB_OBJECT_HEADER; struct iv_tbl *iv; - mrb_value mesg; + struct RString *mesg; }; #define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) -#define MRB_EXC_MESG_INIT_FLAG 0x100 +#define MRB_EXC_MESG_STRING_FLAG 0x100 void mrb_sys_fail(mrb_state *mrb, const char *mesg); 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 9fc6fe468..2f893a382 100644 --- a/src/error.c +++ b/src/error.c @@ -21,15 +21,22 @@ static void exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) { - exc->flags |= MRB_EXC_MESG_INIT_FLAG; - exc->mesg = mesg; - mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, 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_INIT_FLAG) != 0 ? exc->mesg : mrb_nil_value(); + 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_value diff --git a/src/gc.c b/src/gc.c index 6fcac6c2f..d3fc6d5a2 100644 --- a/src/gc.c +++ b/src/gc.c @@ -582,8 +582,8 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) case MRB_TT_EXCEPTION: mrb_gc_mark_iv(mrb, (struct RObject*)obj); - if ((obj->flags & MRB_EXC_MESG_INIT_FLAG) != 0) { - mrb_gc_mark_value(mrb, ((struct RException*)obj)->mesg); + if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->mesg); } break; @@ -808,7 +808,7 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj) case MRB_TT_EXCEPTION: children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); - if ((obj->flags & MRB_EXC_MESG_INIT_FLAG) != 0) { + if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { children++; } break; -- cgit v1.2.3