Merge branch 'exc_mesg' of https://github.com/take-cheeze/mruby into take-cheeze-exc_mesg

parents 5004d9a2 f77fb11f
...@@ -17,9 +17,11 @@ MRB_BEGIN_DECL ...@@ -17,9 +17,11 @@ MRB_BEGIN_DECL
struct RException { struct RException {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
struct iv_tbl *iv; struct iv_tbl *iv;
struct RString *mesg;
}; };
#define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) #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 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); MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str);
......
...@@ -17,6 +17,27 @@ ...@@ -17,6 +17,27 @@
#include <mruby/throw.h> #include <mruby/throw.h>
#include <mruby/presym.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_API mrb_value
mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) 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) ...@@ -48,7 +69,7 @@ exc_initialize(mrb_state *mrb, mrb_value exc)
mrb_value mesg; mrb_value mesg;
if (mrb_get_args(mrb, "|o", &mesg) == 1) { 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; return exc;
} }
...@@ -77,7 +98,7 @@ exc_exception(mrb_state *mrb, mrb_value self) ...@@ -77,7 +98,7 @@ exc_exception(mrb_state *mrb, mrb_value self)
if (argc == 0) return self; if (argc == 0) return self;
if (mrb_obj_equal(mrb, self, a)) return self; if (mrb_obj_equal(mrb, self, a)) return self;
exc = mrb_obj_clone(mrb, 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; return exc;
} }
...@@ -93,7 +114,7 @@ exc_exception(mrb_state *mrb, mrb_value self) ...@@ -93,7 +114,7 @@ exc_exception(mrb_state *mrb, mrb_value self)
static mrb_value static mrb_value
exc_to_s(mrb_state *mrb, mrb_value exc) 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; struct RObject *p;
if (!mrb_string_p(mesg)) { if (!mrb_string_p(mesg)) {
...@@ -133,7 +154,7 @@ exc_message(mrb_state *mrb, mrb_value exc) ...@@ -133,7 +154,7 @@ exc_message(mrb_state *mrb, mrb_value exc)
mrb_value mrb_value
mrb_exc_inspect(mrb_state *mrb, mrb_value exc) 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))); mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc)));
mesg = mrb_obj_as_string(mrb, mesg); mesg = mrb_obj_as_string(mrb, mesg);
return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); 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) ...@@ -686,7 +686,6 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
case MRB_TT_OBJECT: case MRB_TT_OBJECT:
case MRB_TT_DATA: case MRB_TT_DATA:
case MRB_TT_EXCEPTION:
mrb_gc_mark_iv(mrb, (struct RObject*)obj); mrb_gc_mark_iv(mrb, (struct RObject*)obj);
break; break;
...@@ -759,6 +758,13 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -759,6 +758,13 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
} }
break; 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: default:
break; break;
} }
...@@ -989,7 +995,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -989,7 +995,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
case MRB_TT_OBJECT: case MRB_TT_OBJECT:
case MRB_TT_DATA: case MRB_TT_DATA:
case MRB_TT_EXCEPTION:
children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj);
break; break;
...@@ -1042,6 +1047,13 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -1042,6 +1047,13 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
children+=2; children+=2;
break; 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: default:
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment