fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / addrregistry.pmc
blobbd89cd01086b5a82b420514a1962687daea3681a
1 /*
2 Copyright (C) 2005-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/addrregistry.pmc - A GC Registry PMC
9 =head1 DESCRIPTION
11 The AddrRegistry class provides the equivalence of reference counts
12 mainly for extenders and embedders of Parrot. The hash keys are the
13 addresses of the key PMC, values are reference counts, i.e. the
14 difference of (set_pmc_keyed - delete_pmc_keyed). If the reference
15 goes to zero, the entry is deleted physically.
17 Please note that you have to anchor an instance of AddrRegistry yourself with
18 C<Parrot_register_pmc> if it isn't visible to Parrot.
20 =head2 Functions
22 =over 4
24 =cut
28 #include "parrot/hash.h"
29 #include "pmc/pmc_hash.h"
31 /* HEADERIZER HFILE: none */
32 /* HEADERIZER BEGIN: static */
33 /* HEADERIZER END: static */
35 pmclass AddrRegistry extends Hash provides hash auto_attrs {
38 =item C<void init()>
40 Initializes the instance.
42 =cut
46     VTABLE void init() {
47         Hash  *registry = parrot_create_hash(INTERP,
48                 enum_type_int,
49                 Hash_key_type_PMC_ptr);
51         SET_ATTR_hash(INTERP, SELF, registry);
52         PObj_custom_mark_destroy_SETALL(SELF);
54     }
58 =item C<INTVAL get_integer_keyed(PMC *key)>
60 Returns the reference count for C<key> or 0 if the key doesn't exist.
62 =item C<INTVAL elements()>
64 Returns the number of elements in the hash.
66 =item C<INTVAL get_bool()>
68 Returns true if the hash size is not zero.
70 =cut
74     VTABLE INTVAL get_integer_keyed(PMC *key) {
75         Hash       *hash;
76         const void *value;
78         GET_ATTR_hash(INTERP, SELF, hash);
79         value = parrot_hash_get(INTERP, hash, key);
81         if (value)
82             return (INTVAL)value;
84         return 0;
85     }
87     VTABLE INTVAL elements() {
88         const Hash *hash;
90         GET_ATTR_hash(INTERP, SELF, hash);
92         return parrot_hash_size(INTERP, hash);
93     }
95     VTABLE INTVAL get_bool() {
96         const Hash *hash;
98         GET_ATTR_hash(INTERP, SELF, hash);
100         return parrot_hash_size(INTERP, hash) != 0;
101     }
104 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
106 Increment the reference count of C<key>. If the entry doesn't exist
107 create it. The C<value> is always ignored.
109 =item C<void set_integer_keyed(PMC *key, INTVAL value)>
111 Set the given value.
113 =item C<void delete_keyed(PMC *key)>
115 Decrement the reference count of C<key>. If the reference count
116 reaches 0, delete the entry.
119 =cut
123     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
124         const void *oldval;
125         long        newval = 1;
126         Hash       *hash;
127         UNUSED(value);
129         GET_ATTR_hash(INTERP, SELF, hash);
131         oldval = parrot_hash_get(INTERP, hash, key);
133         if (oldval)
134             newval += (long)oldval;
136         parrot_hash_put(INTERP, hash, key, (void *)newval);
137     }
139     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
140         Hash *hash;
141         GET_ATTR_hash(INTERP, SELF, hash);
142         parrot_hash_put(INTERP, hash, key, (void *)value);
143     }
145     VTABLE void delete_keyed(PMC *key) {
146         Hash       *hash;
147         void       *value;
149         GET_ATTR_hash(INTERP, SELF, hash);
150         value = parrot_hash_get(INTERP, hash, key);
152         /* these casts look bad, but they avoid type punning warnings with -O */
153         if (value) {
154             long val = (long)value;
155             if (val == 1L)
156                 parrot_hash_delete(INTERP, hash, key);
157             else {
158                 value = (void *)(--val);
159                 parrot_hash_put(INTERP, hash, key, value);
160             }
161         }
162     }
168 =back
170 =head1 SEE ALSO
172 F<src/pmc.c:gc_register_pmc()>
174 =cut
179  * Local variables:
180  *   c-file-style: "parrot"
181  * End:
182  * vim: expandtab shiftwidth=4:
183  */