summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-eval/src/eval.c2
-rw-r--r--src/error.c9
-rw-r--r--src/gc.c5
3 files changed, 13 insertions, 3 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index b3ac4c786..9c5a531bb 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -133,7 +133,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest)
void mrb_codedump_all(mrb_state*, struct RProc*);
static struct RProc*
-create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, char *file, mrb_int line)
+create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line)
{
mrbc_context *cxt;
struct mrb_parser_state *p;
diff --git a/src/error.c b/src/error.c
index 14e4ab4d3..13032b136 100644
--- a/src/error.c
+++ b/src/error.c
@@ -255,17 +255,22 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc)
{
if (!mrb->gc.out_of_memory && mrb->backtrace.n > 0) {
mrb_value target_exc = mrb_nil_value();
+ int ai;
+
+ ai = mrb_gc_arena_save(mrb);
if ((mrb->exc && !have_backtrace(mrb, mrb->exc))) {
target_exc = mrb_obj_value(mrb->exc);
}
- else if (!mrb_nil_p(exc) && mrb_obj_ptr(exc) == mrb->backtrace.exc) {
- target_exc = exc;
+ else if (!mrb_nil_p(exc) && mrb->backtrace.exc) {
+ target_exc = mrb_obj_value(mrb->backtrace.exc);
+ mrb_gc_protect(mrb, target_exc);
}
if (!mrb_nil_p(target_exc)) {
mrb_value backtrace;
backtrace = mrb_restore_backtrace(mrb);
set_backtrace(mrb, target_exc, backtrace);
}
+ mrb_gc_arena_restore(mrb, ai);
}
mrb->backtrace.n = 0;
diff --git a/src/gc.c b/src/gc.c
index b23e4869e..e7948e4f5 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -695,8 +695,13 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
#endif
case MRB_TT_OBJECT:
+ mrb_gc_free_iv(mrb, (struct RObject*)obj);
+ break;
+
case MRB_TT_EXCEPTION:
mrb_gc_free_iv(mrb, (struct RObject*)obj);
+ if ((struct RObject*)obj == mrb->backtrace.exc)
+ mrb->backtrace.exc = 0;
break;
case MRB_TT_CLASS: