fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / vtables.c
blobb452497f90f99825c56e74f29fe079bc6c7fca94
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/vtables.c
9 =head1 DESCRIPTION
11 Functions to build and manipulate vtables
13 =head2 Functions
15 =over 4
17 =cut
21 #include "parrot/parrot.h"
23 /* This function is defined in the auto-generated file core_pmcs.c */
24 /* XXX Get it into some public place */
25 extern void Parrot_initialize_core_pmcs(PARROT_INTERP, int pass);
27 /* HEADERIZER HFILE: include/parrot/vtables.h */
31 =item C<VTABLE * Parrot_new_vtable(PARROT_INTERP)>
33 Creates and returns a pointer to the new C<VTABLE>.
35 =cut
39 PARROT_EXPORT
40 PARROT_MALLOC
41 PARROT_CANNOT_RETURN_NULL
42 VTABLE *
43 Parrot_new_vtable(SHIM_INTERP)
45 ASSERT_ARGS(Parrot_new_vtable)
46 return mem_internal_allocate_zeroed_typed(VTABLE);
51 =item C<VTABLE * Parrot_clone_vtable(PARROT_INTERP, const VTABLE *base_vtable)>
53 Clones C<*base_vtable> and returns a pointer to the new C<VTABLE>.
55 =cut
59 PARROT_EXPORT
60 PARROT_MALLOC
61 PARROT_CANNOT_RETURN_NULL
62 VTABLE *
63 Parrot_clone_vtable(PARROT_INTERP, ARGIN(const VTABLE *base_vtable))
65 ASSERT_ARGS(Parrot_clone_vtable)
66 VTABLE * const new_vtable = mem_internal_allocate_typed(VTABLE);
68 STRUCT_COPY(new_vtable, base_vtable);
70 /* when called from global PMC initialization, not all vtables have isa_hash
71 * when called at runtime, they do */
72 if (base_vtable->isa_hash) {
73 new_vtable->isa_hash = parrot_new_hash(interp);
74 parrot_hash_clone(interp, base_vtable->isa_hash, new_vtable->isa_hash);
78 return new_vtable;
84 =item C<void Parrot_destroy_vtable(PARROT_INTERP, VTABLE *vtable)>
86 Destroys C<*vtable>.
88 =cut
92 PARROT_EXPORT
93 void
94 Parrot_destroy_vtable(PARROT_INTERP, ARGFREE_NOTNULL(VTABLE *vtable))
96 ASSERT_ARGS(Parrot_destroy_vtable)
97 /* We sometimes get a type number allocated without any corresponding
98 * vtable. E.g. if you load perl_group, perlscalar is this way. */
100 if (vtable->ro_variant_vtable) {
101 VTABLE * const ro_vtable = vtable->ro_variant_vtable;
103 if (ro_vtable->isa_hash) {
104 parrot_hash_destroy(interp, ro_vtable->isa_hash);
105 if (ro_vtable->isa_hash == vtable->isa_hash)
106 vtable->isa_hash = NULL;
108 ro_vtable->isa_hash = NULL;
111 mem_internal_free(ro_vtable);
112 vtable->ro_variant_vtable = NULL;
115 if (vtable->isa_hash) {
116 parrot_hash_destroy(interp, vtable->isa_hash);
117 vtable->isa_hash = NULL;
120 mem_internal_free(vtable);
125 =item C<void parrot_alloc_vtables(PARROT_INTERP)>
127 Allocate memory for the vtables for all known classes (PMC types).
129 =cut
133 void
134 parrot_alloc_vtables(PARROT_INTERP)
136 ASSERT_ARGS(parrot_alloc_vtables)
137 interp->vtables = mem_internal_allocate_n_zeroed_typed(PARROT_MAX_CLASSES, VTABLE *);
138 interp->n_vtable_max = enum_class_core_max;
139 interp->n_vtable_alloced = PARROT_MAX_CLASSES - 1;
144 =item C<void parrot_realloc_vtables(PARROT_INTERP)>
146 Reallocate memory for vtables, increasing the number of vtables by 16.
148 =cut
152 void
153 parrot_realloc_vtables(PARROT_INTERP)
155 ASSERT_ARGS(parrot_realloc_vtables)
156 /* 16 bigger seems reasonable, though it's only a pointer
157 table and we could get bigger without blowing much memory
159 const INTVAL new_max = interp->n_vtable_alloced + 16;
160 const INTVAL new_size = new_max * sizeof (VTABLE *);
161 const INTVAL old_size = interp->n_vtable_max * sizeof (VTABLE *);
163 /* arrays start at zero, but we compare type numbers starting at 1 */
164 interp->n_vtable_alloced = new_max - 1;
165 interp->vtables = (VTABLE **)mem_internal_realloc_zeroed(
166 interp->vtables, new_size, old_size);
171 =item C<void parrot_free_vtables(PARROT_INTERP)>
173 Free memory allocated for the vtables. Each vtable is destroyed
174 through its destructor Parrot_destroy_vtable, after which the list
175 of pointers to these vtables is freed.
177 =cut
181 void
182 parrot_free_vtables(PARROT_INTERP)
184 ASSERT_ARGS(parrot_free_vtables)
185 int i;
187 for (i = 0; i < interp->n_vtable_max; ++i)
188 Parrot_destroy_vtable(interp, interp->vtables[i]);
190 mem_internal_free(interp->vtables);
195 =item C<void mark_vtables(PARROT_INTERP)>
197 Mark all vtables as being alive for the garbage collector.
199 =cut
203 void
204 mark_vtables(PARROT_INTERP)
206 ASSERT_ARGS(mark_vtables)
207 INTVAL i;
209 for (i = 1; i < interp->n_vtable_max; ++i) {
210 const VTABLE * const vtable = interp->vtables[i];
212 /* XXX dynpmc groups have empty slots for abstract objects */
213 if (!vtable)
214 continue;
216 Parrot_gc_mark_PMC_alive(interp, vtable->mro);
217 Parrot_gc_mark_PMC_alive(interp, vtable->_namespace);
218 Parrot_gc_mark_STRING_alive(interp, vtable->whoami);
219 Parrot_gc_mark_STRING_alive(interp, vtable->provides_str);
220 Parrot_gc_mark_PMC_alive(interp, vtable->pmc_class);
226 =item C<void Parrot_initialize_core_vtables(PARROT_INTERP)>
228 Initialize vtables for the core PMCs.
230 =cut
234 PARROT_EXPORT
235 void
236 Parrot_initialize_core_vtables(PARROT_INTERP)
238 ASSERT_ARGS(Parrot_initialize_core_vtables)
240 if (! interp->vtables) {
241 parrot_alloc_vtables(interp);
242 Parrot_initialize_core_pmcs(interp, 0);
247 * Local variables:
248 * c-file-style: "parrot"
249 * End:
250 * vim: expandtab shiftwidth=4: