Use RString in `mesg` instead.
authortake_cheeze <[email protected]>
Mon, 28 Jul 2014 11:30:02 +0000 (28 20:30 +0900)
committertake_cheeze <[email protected]>
Mon, 28 Jul 2014 11:30:02 +0000 (28 20:30 +0900)
include/mruby/error.h
src/error.c
src/gc.c

index 8b5e9dd..ea12ef3 100644 (file)
@@ -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);
index 9fc6fe4..2f893a3 100644 (file)
 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
index 6fcac6c..d3fc6d5 100644 (file)
--- 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;