2 Copyright (C) 2005-2008, The Perl Foundation.
7 src/pmc/addrregistry.pmc - A DOD Registry PMC
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.
28 #include "parrot/parrot.h"
30 /* included manually to prevent breaking C++ builds -- see RT #56534 */
31 #include "parrot/hash.h"
34 pmclass AddrRegistry need_ext provides hash {
35 ATTR Hash *hash; /* a PMC Hash */
40 Initializes the instance.
42 =item C<void destroy()>
52 Parrot_AddrRegistry_attributes * const addr_registry =
53 mem_allocate_zeroed_typed(Parrot_AddrRegistry_attributes);
55 PMC_data(SELF) = addr_registry;
56 PObj_custom_mark_destroy_SETALL(SELF);
58 parrot_new_pmc_hash_x(SELF, enum_type_int, Hash_key_type_PMC,
59 int_compare, key_hash_int);
61 registry = (Hash*)PMC_struct_val(SELF);
63 /* this hack can go away when parrot_new_pmc_hash_x behaves */
64 addr_registry->hash = registry;
65 registry->container = SELF;
68 VTABLE void destroy() {
70 Parrot_AddrRegistry_attributes * const registry = PARROT_ADDRREGISTRY(SELF);
72 parrot_hash_destroy(INTERP, registry->hash);
73 PMC_data(SELF) = NULL;
81 Marks the hash as live.
89 parrot_mark_hash(INTERP, PARROT_ADDRREGISTRY(SELF)->hash);
94 =item C<INTVAL get_integer_keyed(PMC *key)>
96 Returns the reference count for C<key> or 0 if the key doesn't exist.
98 =item C<INTVAL elements()>
100 Returns the number of elements in the hash.
102 =item C<INTVAL get_bool()>
104 Returns true if the hash size is not zero.
110 VTABLE INTVAL get_integer_keyed(PMC *key) {
111 Hash *hash = PARROT_ADDRREGISTRY(SELF)->hash;
112 void *value = parrot_hash_get(INTERP, hash, key);
115 return (INTVAL)value;
120 VTABLE INTVAL elements() {
121 return parrot_hash_size(INTERP, PARROT_ADDRREGISTRY(SELF)->hash);
124 VTABLE INTVAL get_bool() {
125 return parrot_hash_size(INTERP, PARROT_ADDRREGISTRY(SELF)->hash) != 0;
129 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
131 Increment the reference count of C<key>. If the entry doesn't exist
132 create it. The C<value> is always ignored.
134 =item C<void set_integer_keyed(PMC *key, INTVAL value)>
138 =item C<void delete_keyed(PMC *key)>
140 Decrement the reference count of C<key>. If the reference count
141 reaches 0, delete the entry.
148 VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
149 Hash * const hash = PARROT_ADDRREGISTRY(SELF)->hash;
150 void *oldval = parrot_hash_get(INTERP, hash, key);
155 newval += (long)oldval;
157 parrot_hash_put(INTERP, hash, key, (void *)newval);
160 VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
161 Hash *hash = PARROT_ADDRREGISTRY(SELF)->hash;
162 parrot_hash_put(INTERP, hash, key, (void *)value);
165 VTABLE void delete_keyed(PMC *key) {
166 Hash * const hash = PARROT_ADDRREGISTRY(SELF)->hash;
167 void *value = parrot_hash_get(INTERP, hash, key);
169 /* these casts look bad, but they avoid type punning warnings with -O */
171 long val = (long)value;
173 parrot_hash_delete(INTERP, hash, key);
175 value = (void *)(--val);
176 parrot_hash_put(INTERP, hash, key, value);
183 =item C<PMC *get_iter ()>
185 Return a new iterator for the PMC.
187 =item C<PMC *get_pmc_keyed(PMC *key)>
189 If called from iteration, return the key PMC, else PMCNULL is returned.
195 VTABLE PMC *get_iter() {
196 return Parrot_Hash_get_iter(INTERP, SELF);
199 VTABLE PMC *get_pmc_keyed(PMC *key) {
200 Hash * const hash = PARROT_ADDRREGISTRY(SELF)->hash;
202 if (KEY_IS_HASH_ITERATOR(key))
203 return (PMC *)parrot_hash_get_idx(INTERP, hash, key);
215 F<src/pmc.c:dod_register_pmc()>
223 * c-file-style: "parrot"
225 * vim: expandtab shiftwidth=4: