diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 2 | ||||
| -rw-r--r-- | src/backtrace.c | 11 | ||||
| -rw-r--r-- | src/error.c | 25 | ||||
| -rw-r--r-- | src/gc.c | 43 |
4 files changed, 45 insertions, 36 deletions
diff --git a/src/array.c b/src/array.c index 67cae92eb..3ab74f95d 100644 --- a/src/array.c +++ b/src/array.c @@ -192,7 +192,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, size_t len) if (capa > (size_t)a->aux.capa) { mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); - a->aux.capa = capa; + a->aux.capa = (mrb_int)capa; a->ptr = expanded_ptr; } } diff --git a/src/backtrace.c b/src/backtrace.c index d634123b4..b60c375f3 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -74,14 +74,12 @@ static void get_backtrace_i(mrb_state *mrb, struct backtrace_location *loc, void *data) { mrb_value ary, str; - char buf[32]; int ai = mrb_gc_arena_save(mrb); ary = mrb_obj_value((struct RArray*)data); str = mrb_str_new_cstr(mrb, loc->filename); - snprintf(buf, sizeof(buf), ":%d", loc->lineno); - mrb_str_cat_cstr(mrb, str, buf); + str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(loc->lineno)); if (loc->method) { mrb_str_cat_lit(mrb, str, ":in "); @@ -400,14 +398,13 @@ mrb_restore_backtrace(mrb_state *mrb) int ai; mrb_backtrace_entry *entry; mrb_value mrb_entry; - char buf[32]; ai = mrb_gc_arena_save(mrb); entry = &(mrb->backtrace.entries[i]); - mrb_entry = mrb_str_new_cstr(mrb, entry->filename); - snprintf(buf, sizeof(buf), ":%d", entry->lineno); - mrb_str_cat_cstr(mrb, mrb_entry, buf); + mrb_entry = mrb_format(mrb, "%S:%S", + mrb_str_new_cstr(mrb, entry->filename), + mrb_fixnum_value(entry->lineno)); if (entry->method_id != 0) { mrb_str_cat_lit(mrb, mrb_entry, ":in "); diff --git a/src/error.c b/src/error.c index ac11e4d8d..258a8f7df 100644 --- a/src/error.c +++ b/src/error.c @@ -137,6 +137,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc) { mrb_value str, mesg, file, line; mrb_bool append_mesg; + const char *cname; mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); @@ -148,28 +149,18 @@ exc_inspect(mrb_state *mrb, mrb_value exc) append_mesg = RSTRING_LEN(mesg) > 0; } + cname = mrb_obj_classname(mrb, exc); + str = mrb_str_new_cstr(mrb, cname); if (mrb_string_p(file) && mrb_fixnum_p(line)) { - char buf[32]; - - str = mrb_str_dup(mrb, file); - snprintf(buf, sizeof(buf), ":%" MRB_PRId ": ", mrb_fixnum(line)); - mrb_str_cat_cstr(mrb, str, buf); if (append_mesg) { - mrb_str_cat_str(mrb, str, mesg); - mrb_str_cat_lit(mrb, str, " ("); + str = mrb_format(mrb, "%S:%S:%S (%S)", file, line, mesg, str); } - mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); - if (append_mesg) { - mrb_str_cat_lit(mrb, str, ")"); + else { + str = mrb_format(mrb, "%S:%S:%S", file, line, str); } } - else { - const char *cname = mrb_obj_classname(mrb, exc); - str = mrb_str_new_cstr(mrb, cname); - if (append_mesg) { - mrb_str_cat_lit(mrb, str, ": "); - mrb_str_cat_str(mrb, str, mesg); - } + else if (append_mesg) { + str = mrb_format(mrb, "%S:%S", str, mesg); } return str; } @@ -17,6 +17,7 @@ #include <mruby/variable.h> #include <mruby/gc.h> #include <mruby/error.h> +#include <mruby/throw.h> /* = Tri-color Incremental Garbage Collection @@ -594,8 +595,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c) } /* mark fibers */ mrb_gc_mark(mrb, (struct RBasic*)c->fib); - if (c->prev) { - mark_context(mrb, c->prev); + if (c->prev && c->prev->fib) { + mrb_gc_mark(mrb, (struct RBasic*)c->prev->fib); } } @@ -882,10 +883,10 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); #endif + mark_context(mrb, mrb->root_c); if (mrb->root_c != mrb->c) { mark_context(mrb, mrb->c); } - mark_context(mrb, mrb->root_c); } static size_t @@ -1162,7 +1163,7 @@ mrb_incremental_gc(mrb_state *mrb) { mrb_gc *gc = &mrb->gc; - if (gc->disabled) return; + if (gc->disabled || gc->iterating) return; GC_INVOKE_TIME_REPORT("mrb_incremental_gc()"); GC_TIME_START; @@ -1202,7 +1203,7 @@ mrb_full_gc(mrb_state *mrb) { mrb_gc *gc = &mrb->gc; - if (gc->disabled) return; + if (gc->disabled || gc->iterating) return; GC_INVOKE_TIME_REPORT("mrb_full_gc()"); GC_TIME_START; @@ -1491,9 +1492,7 @@ static void gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, void *data) { mrb_heap_page* page = gc->heaps; - mrb_bool old_disable = gc->disabled; - gc->disabled = TRUE; while (page != NULL) { RVALUE *p, *pend; @@ -1501,18 +1500,40 @@ gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, pend = p + MRB_HEAP_PAGE_SIZE; for (;p < pend; p++) { if ((*callback)(mrb, &p->as.basic, data) == MRB_EACH_OBJ_BREAK) - break; + return; } - page = page->next; } - gc->disabled = old_disable; } void mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data) { - gc_each_objects(mrb, &mrb->gc, callback, data); + mrb_bool iterating = mrb->gc.iterating; + + mrb->gc.iterating = TRUE; + if (iterating) { + gc_each_objects(mrb, &mrb->gc, callback, data); + } + else { + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + gc_each_objects(mrb, &mrb->gc, callback, data); + mrb->jmp = prev_jmp; + mrb->gc.iterating = iterating; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + mrb->gc.iterating = iterating; + if (mrb->exc) { + mrb_value exc = mrb_obj_value(mrb->exc); + mrb->exc = NULL; + mrb_exc_raise(mrb, exc); + } + } MRB_END_EXC(&c_jmp); + } } #ifdef GC_TEST |
