[t][TT #1119] Convert t/op/bitwise.t to PIR
[parrot.git] / src / vtables.c
blob13cd193a96128e0f215dc4d33460d6c2afab3432
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/vtables.c - Functions to build and manipulate vtables
9 =head1 DESCRIPTION
11 =head2 Functions
13 =over 4
15 =cut
19 #include "parrot/parrot.h"
20 #include "parrot/vtables.h"
22 /* This function is defined in the auto-generated file core_pmcs.c */
23 /* XXX Get it into some public place */
24 extern void Parrot_initialize_core_pmcs(PARROT_INTERP, int pass);
26 /* HEADERIZER HFILE: include/parrot/vtables.h */
30 =item C<VTABLE * Parrot_new_vtable(PARROT_INTERP)>
32 Creates and returns a pointer to the new C<VTABLE>.
34 =cut
38 PARROT_EXPORT
39 PARROT_MALLOC
40 PARROT_CANNOT_RETURN_NULL
41 VTABLE *
42 Parrot_new_vtable(SHIM_INTERP)
44 ASSERT_ARGS(Parrot_new_vtable)
45 return mem_allocate_zeroed_typed(VTABLE);
50 =item C<VTABLE * Parrot_clone_vtable(PARROT_INTERP, const VTABLE *base_vtable)>
52 Clones C<*base_vtable> and returns a pointer to the new C<VTABLE>.
54 =cut
58 PARROT_EXPORT
59 PARROT_MALLOC
60 PARROT_CANNOT_RETURN_NULL
61 VTABLE *
62 Parrot_clone_vtable(PARROT_INTERP, ARGIN(const VTABLE *base_vtable))
64 ASSERT_ARGS(Parrot_clone_vtable)
65 VTABLE * const new_vtable = mem_allocate_typed(VTABLE);
67 STRUCT_COPY(new_vtable, base_vtable);
69 /* when called from global PMC initialization, not all vtables have isa_hash
70 * when called at runtime, they do */
71 if (base_vtable->isa_hash) {
72 new_vtable->isa_hash = parrot_new_hash(interp);
73 parrot_hash_clone(interp, base_vtable->isa_hash, new_vtable->isa_hash);
77 return new_vtable;
83 =item C<void Parrot_destroy_vtable(PARROT_INTERP, VTABLE *vtable)>
85 Destroys C<*vtable>.
87 =cut
91 PARROT_EXPORT
92 void
93 Parrot_destroy_vtable(PARROT_INTERP, ARGMOD(VTABLE *vtable))
95 ASSERT_ARGS(Parrot_destroy_vtable)
96 /* We sometimes get a type number allocated without any corresponding
97 * vtable. E.g. if you load perl_group, perlscalar is this way. */
99 if (vtable->ro_variant_vtable) {
100 VTABLE *ro_vtable = vtable->ro_variant_vtable;
102 if (ro_vtable->isa_hash) {
103 parrot_hash_destroy(interp, ro_vtable->isa_hash);
104 if (ro_vtable->isa_hash == vtable->isa_hash)
105 vtable->isa_hash = NULL;
107 ro_vtable->isa_hash = NULL;
110 mem_sys_free(ro_vtable);
111 vtable->ro_variant_vtable = NULL;
114 if (vtable->isa_hash) {
115 parrot_hash_destroy(interp, vtable->isa_hash);
116 vtable->isa_hash = NULL;
119 mem_sys_free(vtable);
124 =item C<void parrot_alloc_vtables(PARROT_INTERP)>
126 Allocate memory for the vtables for all known classes (PMC types).
128 =cut
132 void
133 parrot_alloc_vtables(PARROT_INTERP)
135 ASSERT_ARGS(parrot_alloc_vtables)
136 interp->vtables = mem_allocate_n_zeroed_typed(PARROT_MAX_CLASSES, VTABLE *);
137 interp->n_vtable_max = enum_class_core_max;
138 interp->n_vtable_alloced = PARROT_MAX_CLASSES - 1;
143 =item C<void parrot_realloc_vtables(PARROT_INTERP)>
145 Reallocate memory for vtables, increasing the number of vtables by 16.
147 =cut
151 void
152 parrot_realloc_vtables(PARROT_INTERP)
154 ASSERT_ARGS(parrot_realloc_vtables)
155 /* 16 bigger seems reasonable, though it's only a pointer
156 table and we could get bigger without blowing much memory
158 const INTVAL new_max = interp->n_vtable_alloced + 16;
159 const INTVAL new_size = new_max * sizeof (VTABLE *);
160 const INTVAL old_size = interp->n_vtable_max * sizeof (VTABLE *);
162 /* arrays start at zero, but we compare type numbers starting at 1 */
163 interp->n_vtable_alloced = new_max - 1;
164 interp->vtables = (VTABLE **)mem_sys_realloc_zeroed(
165 interp->vtables, new_size, old_size);
170 =item C<void parrot_free_vtables(PARROT_INTERP)>
172 Free memory allocated for the vtables. Each vtable is destroyed
173 through its destructor Parrot_destroy_vtable, after which the list
174 of pointers to these vtables is freed.
176 =cut
180 void
181 parrot_free_vtables(PARROT_INTERP)
183 ASSERT_ARGS(parrot_free_vtables)
184 int i;
186 for (i = 0; i < interp->n_vtable_max; i++)
187 Parrot_destroy_vtable(interp, interp->vtables[i]);
189 mem_sys_free(interp->vtables);
194 =item C<void mark_vtables(PARROT_INTERP)>
196 Mark all vtables as being alive for the garbage collector.
198 =cut
202 void
203 mark_vtables(PARROT_INTERP)
205 ASSERT_ARGS(mark_vtables)
206 INTVAL i;
208 for (i = 1; i < interp->n_vtable_max; i++) {
209 const VTABLE * const vtable = interp->vtables[i];
211 /* XXX dynpmc groups have empty slots for abstract objects */
212 if (!vtable)
213 continue;
215 Parrot_gc_mark_PMC_alive(interp, vtable->mro);
216 Parrot_gc_mark_PMC_alive(interp, vtable->_namespace);
217 Parrot_gc_mark_STRING_alive(interp, vtable->whoami);
218 Parrot_gc_mark_STRING_alive(interp, vtable->provides_str);
219 Parrot_gc_mark_PMC_alive(interp, vtable->pmc_class);
225 =item C<void Parrot_initialize_core_vtables(PARROT_INTERP)>
227 Initialize vtables for the core PMCs.
229 =cut
233 PARROT_EXPORT
234 void
235 Parrot_initialize_core_vtables(PARROT_INTERP)
237 ASSERT_ARGS(Parrot_initialize_core_vtables)
239 if (! interp->vtables) {
240 parrot_alloc_vtables(interp);
241 Parrot_initialize_core_pmcs(interp, 0);
246 * Local variables:
247 * c-file-style: "parrot"
248 * End:
249 * vim: expandtab shiftwidth=4: