summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2019-08-01 14:41:21 -0400
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-08-29 20:40:52 +0900
commita4a19b114ba94b8f28d5a91aee5d595a516006d5 (patch)
tree9d4bda06b2877673e598a850b19f5ec5acafefc6 /gc.c
parente4be2fda3dbbfdb1f2ace697c96cf6bdd7dfef21 (diff)
Allow non-finalizable objects in ObjectSpace::WeakMap
[feature #16035] This goes one step farther than what nobu did in [feature #13498] With this patch, special objects such as static symbols, integers, etc can be used as either key or values inside WeakMap. They simply don't have a finalizer defined on them. This is useful if you need to deduplicate value objects
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/2313
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/gc.c b/gc.c
index 18ae189421..c083fbb297 100644
--- a/gc.c
+++ b/gc.c
@@ -2986,18 +2986,12 @@ should_be_callable(VALUE block)
}
static void
-should_be_finalizable_internal(VALUE obj)
+should_be_finalizable(VALUE obj)
{
if (!FL_ABLE(obj)) {
rb_raise(rb_eArgError, "cannot define finalizer for %s",
rb_obj_classname(obj));
}
-}
-
-static void
-should_be_finalizable(VALUE obj)
-{
- should_be_finalizable_internal(obj);
rb_check_frozen(obj);
}
@@ -10253,6 +10247,7 @@ wmap_allocate(VALUE klass)
static int
wmap_live_p(rb_objspace_t *objspace, VALUE obj)
{
+ if (!FL_ABLE(obj)) return TRUE;
if (!is_id_value(objspace, obj)) return FALSE;
if (!is_live_object(objspace, obj)) return FALSE;
return TRUE;
@@ -10510,10 +10505,13 @@ wmap_aset(VALUE self, VALUE wmap, VALUE orig)
struct weakmap *w;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
- should_be_finalizable_internal(orig);
- should_be_finalizable_internal(wmap);
- define_final0(orig, w->final);
- define_final0(wmap, w->final);
+ if (FL_ABLE(orig)) {
+ define_final0(orig, w->final);
+ }
+ if (FL_ABLE(wmap)) {
+ define_final0(wmap, w->final);
+ }
+
st_update(w->obj2wmap, (st_data_t)orig, wmap_aset_update, wmap);
st_insert(w->wmap2obj, (st_data_t)wmap, (st_data_t)orig);
return nonspecial_obj_id(orig);