diff options
| -rw-r--r-- | include/mruby.h | 6 | ||||
| -rw-r--r-- | mrbgems/mruby-hash-ext/mrblib/hash.rb | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-hash-ext/test/hash.rb | 2 | ||||
| -rw-r--r-- | src/gc.c | 48 | ||||
| -rw-r--r-- | src/kernel.c | 2 | ||||
| -rw-r--r-- | src/string.c | 4 |
6 files changed, 60 insertions, 6 deletions
diff --git a/include/mruby.h b/include/mruby.h index 4af607b26..a20693394 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -613,7 +613,13 @@ MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg); MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv); MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c); +/* mrb_gc_protect() leaves the object in the arena */ MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj); +/* mrb_gc_register() keeps the object from GC. */ +MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj); +/* mrb_gc_unregister() removes the object from GC root. */ +MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj); + MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val); #define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val)) MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb index 5056d0720..ec8bd05fb 100644 --- a/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -130,7 +130,7 @@ class Hash elsif none != NONE none else - raise RuntimeError, "Key not found: #{key}" + raise KeyError, "Key not found: #{key}" end else self[key] @@ -156,7 +156,7 @@ class Hash self.each do |k, v| self.delete(k) if block.call(k, v) - end + end self end diff --git a/mrbgems/mruby-hash-ext/test/hash.rb b/mrbgems/mruby-hash-ext/test/hash.rb index 4950ef354..ef25acbe7 100644 --- a/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mrbgems/mruby-hash-ext/test/hash.rb @@ -79,7 +79,7 @@ assert('Hash#fetch') do begin h.fetch("gnu") rescue => e - assert_kind_of(StandardError, e); + assert_kind_of(KeyError, e); end end @@ -385,6 +385,7 @@ gc_protect(mrb_state *mrb, struct RBasic *p) mrb->arena[mrb->arena_idx++] = p; } +/* mrb_gc_protect() leaves the object in the arena */ MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj) { @@ -392,6 +393,53 @@ mrb_gc_protect(mrb_state *mrb, mrb_value obj) gc_protect(mrb, mrb_basic_ptr(obj)); } +#define GC_ROOT_NAME "_gc_root_" + +/* mrb_gc_register() keeps the object from GC. + + Register your object when it's exported to C world, + without reference from Ruby world, e.g. callback + arguments. Don't forget to remove the obejct using + mrb_gc_unregister, otherwise your object will leak. +*/ + +MRB_API void +mrb_gc_register(mrb_state *mrb, mrb_value obj) +{ + mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); + mrb_value table = mrb_gv_get(mrb, root); + + if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) { + table = mrb_ary_new(mrb); + mrb_gv_set(mrb, root, table); + } + mrb_ary_push(mrb, table, obj); +} + +/* mrb_gc_unregister() removes the object from GC root. */ +MRB_API void +mrb_gc_unregister(mrb_state *mrb, mrb_value obj) +{ + mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); + mrb_value table = mrb_gv_get(mrb, root); + struct RArray *a; + mrb_int i, j; + + if (mrb_nil_p(table)) return; + if (mrb_type(table) != MRB_TT_ARRAY) { + mrb_gv_set(mrb, root, mrb_nil_value()); + return; + } + a = mrb_ary_ptr(table); + mrb_ary_modify(mrb, a); + for (i=j=0; i<a->len; i++) { + if (!mrb_obj_eq(mrb, a->ptr[i], obj)) { + a->ptr[j++] = a->ptr[i]; + } + } + a->len = j; +} + MRB_API struct RBasic* mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) { diff --git a/src/kernel.c b/src/kernel.c index 225f7fa54..09d869f9d 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -660,7 +660,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) { MRB_CLASS_ORIGIN(klass); - prepended = 1; + prepended = TRUE; } oldklass = 0; diff --git a/src/string.c b/src/string.c index e93fd4606..12aefa8a0 100644 --- a/src/string.c +++ b/src/string.c @@ -56,7 +56,7 @@ mrb_utf8_from_locale(const char *str, size_t len) if (len == 0) return strdup(""); if (len == -1) - len = strlen(str); + len = strlen(str); wcssize = MultiByteToWideChar(GetACP(), 0, str, len, NULL, 0); wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); if (!wcsp) @@ -86,7 +86,7 @@ mrb_locale_from_utf8(const char *utf8, size_t len) if (len == 0) return strdup(""); if (len == -1) - len = strlen(utf8); + len = strlen(utf8); wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); if (!wcsp) |
