[t] Refactor some namespace pmc tests to use throws_like
[parrot.git] / src / pmc / addrregistry.pmc
blob9c2c1943ce769c11d925cf11e666d5a3852f025e
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 /* included manually to prevent breaking C++ builds -- see RT #56534 */
29 #include "parrot/hash.h"
30 #include "pmc_hash.h"
32 pmclass AddrRegistry extends Hash provides hash auto_attrs {
35 =item C<void init()>
37 Initializes the instance.
39 =cut
43     VTABLE void init() {
44         Hash  *registry = parrot_create_hash(INTERP,
45                 enum_type_int,
46                 Hash_key_type_PMC,
47                 int_compare,
48                 key_hash_int);
50         Parrot_AddrRegistry_attributes *attrs =
51             (Parrot_AddrRegistry_attributes *) PMC_data(SELF);
53         SELF.set_pointer(registry);
54         PObj_custom_mark_destroy_SETALL(SELF);
56     }
60 =item C<INTVAL get_integer_keyed(PMC *key)>
62 Returns the reference count for C<key> or 0 if the key doesn't exist.
64 =item C<INTVAL elements()>
66 Returns the number of elements in the hash.
68 =item C<INTVAL get_bool()>
70 Returns true if the hash size is not zero.
72 =cut
76     VTABLE INTVAL get_integer_keyed(PMC *key) {
77         Hash   *hash  = (Hash *)SELF.get_pointer();
78         void   *value = parrot_hash_get(INTERP, hash, key);
80         if (value)
81             return (INTVAL)value;
83         return 0;
84     }
86     VTABLE INTVAL elements() {
87         return parrot_hash_size(INTERP, (Hash *)SELF.get_pointer());
88     }
90     VTABLE INTVAL get_bool() {
91         return parrot_hash_size(INTERP, (Hash *)SELF.get_pointer()) != 0;
92     }
95 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
97 Increment the reference count of C<key>. If the entry doesn't exist
98 create it. The C<value> is always ignored.
100 =item C<void set_integer_keyed(PMC *key, INTVAL value)>
102 Set the given value.
104 =item C<void delete_keyed(PMC *key)>
106 Decrement the reference count of C<key>. If the reference count
107 reaches 0, delete the entry.
110 =cut
114     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
115         Hash       * const hash = (Hash *)SELF.get_pointer();
116         void       *oldval      = parrot_hash_get(INTERP, hash, key);
117         long        newval      = 1;
118         UNUSED(value);
120         if (oldval)
121             newval += (long)oldval;
123         parrot_hash_put(INTERP, hash, key, (void *)newval);
124     }
126     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
127         Hash *hash = (Hash *)SELF.get_pointer();
128         parrot_hash_put(INTERP, hash, key, (void *)value);
129     }
131     VTABLE void delete_keyed(PMC *key) {
132         Hash       * const hash  = (Hash *)SELF.get_pointer();
133         void              *value = parrot_hash_get(INTERP, hash, key);
135         /* these casts look bad, but they avoid type punning warnings with -O */
136         if (value) {
137             long val = (long)value;
138             if (val == 1L)
139                 parrot_hash_delete(INTERP, hash, key);
140             else {
141                 value = (void *)(--val);
142                 parrot_hash_put(INTERP, hash, key, value);
143             }
144         }
145     }
151 =back
153 =head1 SEE ALSO
155 F<src/pmc.c:gc_register_pmc()>
157 =cut
162  * Local variables:
163  *   c-file-style: "parrot"
164  * End:
165  * vim: expandtab shiftwidth=4:
166  */