2 Copyright (C) 2001-2009, Parrot Foundation.
7 src/pmc.c - The base vtable calling functions
19 #include "parrot/parrot.h"
21 #include "pmc/pmc_class.h"
22 #include "pmc/pmc_context.h"
24 /* HEADERIZER HFILE: include/parrot/pmc.h */
26 /* HEADERIZER BEGIN: static */
27 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
29 static void check_pmc_reuse_flags(PARROT_INTERP
,
32 __attribute__nonnull__(1);
34 PARROT_WARN_UNUSED_RESULT
35 PARROT_CANNOT_RETURN_NULL
36 static PMC
* create_class_pmc(PARROT_INTERP
, INTVAL type
)
37 __attribute__nonnull__(1);
39 PARROT_WARN_UNUSED_RESULT
40 PARROT_CANNOT_RETURN_NULL
41 static PMC
* get_new_pmc_header(PARROT_INTERP
,
44 __attribute__nonnull__(1);
46 PARROT_CANNOT_RETURN_NULL
47 static PMC
* pmc_reuse_no_init(PARROT_INTERP
,
51 __attribute__nonnull__(1)
52 __attribute__nonnull__(2);
54 #define ASSERT_ARGS_check_pmc_reuse_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
55 PARROT_ASSERT_ARG(interp))
56 #define ASSERT_ARGS_create_class_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
57 PARROT_ASSERT_ARG(interp))
58 #define ASSERT_ARGS_get_new_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
59 PARROT_ASSERT_ARG(interp))
60 #define ASSERT_ARGS_pmc_reuse_no_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
61 PARROT_ASSERT_ARG(interp) \
62 , PARROT_ASSERT_ARG(pmc))
63 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
64 /* HEADERIZER END: static */
73 =item C<INTVAL PMC_is_null(PARROT_INTERP, const PMC *pmc)>
75 Tests if the given pmc is null.
83 PMC_is_null(SHIM_INTERP
, ARGIN_NULLOK(const PMC
*pmc
))
85 ASSERT_ARGS(PMC_is_null
)
87 return pmc
== PMCNULL
|| pmc
== NULL
;
95 =item C<void Parrot_pmc_destroy(PARROT_INTERP, PMC *pmc)>
97 Destroy a PMC. Call his destroy vtable function if needed, and deallocate
98 his attributes if they are automatically allocated.
100 For internal usage of the PMC handling functions and garbage collection
109 Parrot_pmc_destroy(PARROT_INTERP
, ARGMOD(PMC
*pmc
))
111 ASSERT_ARGS(Parrot_pmc_destroy
)
113 if (PObj_custom_destroy_TEST(pmc
)) {
114 VTABLE_destroy(interp
, pmc
);
115 /* Prevent repeated calls. */
116 PObj_custom_destroy_CLEAR(pmc
);
119 PObj_custom_mark_CLEAR(pmc
);
120 PObj_live_CLEAR(pmc
);
122 if (PObj_is_PMC_shared_TEST(pmc
) && PMC_sync(pmc
))
123 Parrot_gc_free_pmc_sync(interp
, pmc
);
125 if (pmc
->vtable
->attr_size
)
126 Parrot_gc_free_pmc_attributes(interp
, pmc
);
128 PMC_data(pmc
) = NULL
;
132 pmc
->vtable
= (VTABLE
*)0xdeadbeef;
140 =item C<PMC * pmc_new(PARROT_INTERP, INTVAL base_type)>
142 Creates a new PMC of type C<base_type> (which is an index into the list of PMC
143 types declared in C<vtables> in F<include/parrot/pmc.h>). Once the PMC has been
144 successfully created and its vtable pointer initialized, we call its C<init>
145 method to perform any other necessary initialization.
152 PARROT_CANNOT_RETURN_NULL
153 PARROT_WARN_UNUSED_RESULT
155 pmc_new(PARROT_INTERP
, INTVAL base_type
)
158 PARROT_ASSERT(interp
->vtables
[base_type
]);
160 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
162 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
163 return VTABLE_instantiate(interp
, classobj
, PMCNULL
);
165 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
166 VTABLE_init(interp
, pmc
);
174 =item C<PMC * pmc_reuse(PARROT_INTERP, PMC *pmc, INTVAL new_type, UINTVAL
177 Reuse an existing PMC, turning it into an empty PMC of the new type. Any
178 required internal structure will be put in place (such as the extension area)
179 and the PMC will be ready to go.
181 Cannot currently handle converting a non-Object PMC into an Object. Use
182 C<pmc_reuse_by_class> for that.
190 PARROT_CANNOT_RETURN_NULL
191 PARROT_IGNORABLE_RESULT
193 pmc_reuse(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
,
196 ASSERT_ARGS(pmc_reuse
)
197 pmc
= pmc_reuse_no_init(interp
, pmc
, new_type
, flags
);
199 /* Call the base init for the redone pmc. Warning, this should not
200 be called on Object PMCs. */
201 VTABLE_init(interp
, pmc
);
208 =item C<PMC * pmc_reuse_init(PARROT_INTERP, PMC *pmc, INTVAL new_type, PMC
209 *init, UINTVAL flags)>
211 Reuse an existing PMC, turning it into an PMC of the new type. Any
212 required internal structure will be put in place (such as the extension area)
213 and the PMC will be inited.
215 Cannot currently handle converting a non-Object PMC into an Object. Use
216 C<pmc_reuse_by_class> for that.
224 PARROT_CANNOT_RETURN_NULL
225 PARROT_IGNORABLE_RESULT
227 pmc_reuse_init(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
, ARGIN(PMC
*init
),
230 ASSERT_ARGS(pmc_reuse_init
)
231 pmc
= pmc_reuse_no_init(interp
, pmc
, new_type
, flags
);
233 /* Call the base init for the redone pmc. Warning, this should not
234 be called on Object PMCs. */
235 VTABLE_init_pmc(interp
, pmc
, init
);
242 =item C<static PMC* pmc_reuse_no_init(PARROT_INTERP, PMC *pmc, INTVAL new_type,
245 Prepare pmc for reuse. Do all scuffolding except initing.
250 PARROT_CANNOT_RETURN_NULL
252 pmc_reuse_no_init(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
,
253 SHIM(UINTVAL flags
)) {
255 ASSERT_ARGS(pmc_reuse_no_init
)
257 INTVAL has_ext
, new_flags
= 0;
259 if (pmc
->vtable
->base_type
== new_type
)
262 new_vtable
= interp
->vtables
[new_type
];
264 /* Singleton/const PMCs/types are not eligible */
265 check_pmc_reuse_flags(interp
, pmc
->vtable
->flags
, new_vtable
->flags
);
267 /* Free the old PMC resources. */
268 Parrot_pmc_destroy(interp
, pmc
);
270 PObj_flags_SETTO(pmc
, PObj_is_PMC_FLAG
| new_flags
);
272 /* Set the right vtable */
273 pmc
->vtable
= new_vtable
;
275 if (new_vtable
->attr_size
)
276 Parrot_gc_allocate_pmc_attributes(interp
, pmc
);
279 PMC_data(pmc
) = NULL
;
286 =item C<PMC * pmc_reuse_by_class(PARROT_INTERP, PMC *pmc, PMC *class_, UINTVAL
289 Reuse an existing PMC. Convert it to the type specified by the given Class
290 PMC. At the moment, this means we can only use this function to reuse PMCs
291 into types with Classes (not built-in PMCs). Use C<pmc_reuse> if you need
292 to convert to a built-in PMC type.
299 PARROT_CANNOT_RETURN_NULL
300 PARROT_IGNORABLE_RESULT
302 pmc_reuse_by_class(PARROT_INTERP
, ARGMOD(PMC
*pmc
), ARGIN(PMC
*class_
),
305 ASSERT_ARGS(pmc_reuse_by_class
)
306 const INTVAL new_type
= PARROT_CLASS(class_
)->id
;
307 VTABLE
* const new_vtable
= interp
->vtables
[new_type
];
308 INTVAL new_flags
= flags
;
310 if (pmc
->vtable
->base_type
== new_type
)
313 /* Singleton/const PMCs/types are not eligible */
314 check_pmc_reuse_flags(interp
, pmc
->vtable
->flags
, new_vtable
->flags
);
316 Parrot_pmc_destroy(interp
, pmc
);
318 PObj_flags_SETTO(pmc
, PObj_is_PMC_FLAG
| new_flags
);
320 /* Set the right vtable */
321 pmc
->vtable
= new_vtable
;
323 if (new_vtable
->attr_size
)
324 Parrot_gc_allocate_pmc_attributes(interp
, pmc
);
326 PMC_data(pmc
) = NULL
;
334 =item C<static void check_pmc_reuse_flags(PARROT_INTERP, UINTVAL srcflags,
337 We're converting one PMC type to another, either in C<pmc_reuse> or
338 C<pmc_reuse_by_class>. Check to make sure that neither the existing PMC
339 or the intended target PMC type are singletons or constants. We throw an
340 exception if we are attempting an illegal operation.
347 check_pmc_reuse_flags(PARROT_INTERP
, UINTVAL srcflags
, UINTVAL destflags
)
349 ASSERT_ARGS(check_pmc_reuse_flags
)
350 if ((srcflags
| destflags
) & (VTABLE_PMC_IS_SINGLETON
| VTABLE_IS_CONST_FLAG
))
352 /* First, is the destination a singleton? No joy for us there */
353 if (destflags
& VTABLE_PMC_IS_SINGLETON
)
354 Parrot_ex_throw_from_c_args(interp
, NULL
,
355 EXCEPTION_ALLOCATION_ERROR
,
356 "Parrot VM: Can't turn to a singleton type!\n");
358 /* Is the destination a constant? No joy for us there */
359 if (destflags
& VTABLE_IS_CONST_FLAG
)
360 Parrot_ex_throw_from_c_args(interp
, NULL
,
361 EXCEPTION_ALLOCATION_ERROR
,
362 "Parrot VM: Can't turn to a constant type!\n");
364 /* Is the source a singleton? */
365 if (srcflags
& VTABLE_PMC_IS_SINGLETON
)
366 Parrot_ex_throw_from_c_args(interp
, NULL
,
367 EXCEPTION_ALLOCATION_ERROR
,
368 "Parrot VM: Can't modify a singleton\n");
370 /* Is the source constant? */
371 if (srcflags
& VTABLE_IS_CONST_FLAG
)
372 Parrot_ex_throw_from_c_args(interp
, NULL
,
373 EXCEPTION_ALLOCATION_ERROR
,
374 "Parrot VM: Can't modify a constant\n");
380 =item C<static PMC * get_new_pmc_header(PARROT_INTERP, INTVAL base_type, UINTVAL
383 Gets a new PMC header of the given integer type. Initialize the pmc if
384 necessary. In the case of singleton PMC types, get the existing singleton
385 instead of allocating a new one.
391 PARROT_WARN_UNUSED_RESULT
392 PARROT_CANNOT_RETURN_NULL
394 get_new_pmc_header(PARROT_INTERP
, INTVAL base_type
, UINTVAL flags
)
396 ASSERT_ARGS(get_new_pmc_header
)
398 VTABLE
*vtable
= interp
->vtables
[base_type
];
399 UINTVAL vtable_flags
;
401 /* This is usually because you either didn't call init_world early enough,
402 * you added a new PMC class without adding Parrot_(classname)_class_init
403 * to init_world, or you forgot to run 'make realclean' after adding a new
406 PANIC(interp
, "Null vtable used; did you add a new PMC?");
408 vtable_flags
= vtable
->flags
;
410 /* we only have one global Env object, living in the interp */
411 if (vtable_flags
& VTABLE_PMC_IS_SINGLETON
) {
413 * singletons (monadic objects) exist only once
414 * the interface * with the class is:
415 * - get_pointer: return NULL or a pointer to the single instance
416 * - set_pointer: set the only instance once
418 * - singletons are created in the constant pmc pool
420 PMC
*pmc
= (PMC
*)(vtable
->get_pointer
)(interp
, NULL
);
424 pmc
= Parrot_gc_new_pmc_header(interp
, PObj_constant_FLAG
);
427 pmc
->vtable
= vtable
;
428 VTABLE_set_pointer(interp
, pmc
, pmc
);
434 if (vtable_flags
& VTABLE_IS_CONST_PMC_FLAG
)
435 flags
|= PObj_constant_FLAG
;
436 else if (vtable_flags
& VTABLE_IS_CONST_FLAG
) {
437 /* put the normal vtable in, so that the pmc can be initialized first
438 * parrot or user code has to set the _ro property then,
439 * to morph the PMC to the const variant
440 * This assumes that a constant PMC enum is one bigger then
445 * XXX not yet we can't assure that all contents in the
446 * const PMC is const too
447 * see e.g. t/pmc/sarray_13.pir
450 flags
|= PObj_constant_FLAG
;
453 vtable
= interp
->vtables
[base_type
];
456 if (vtable_flags
& VTABLE_IS_SHARED_FLAG
)
457 flags
|= PObj_is_PMC_shared_FLAG
;
459 pmc
= Parrot_gc_new_pmc_header(interp
, flags
);
460 pmc
->vtable
= vtable
;
462 if (vtable
->attr_size
)
463 Parrot_gc_allocate_pmc_attributes(interp
, pmc
);
466 if (Interp_flags_TEST(interp
, PARROT_TRACE_FLAG
)) {
467 /* XXX make a more verbose trace flag */
468 fprintf(stderr
, "\t=> new %p type %d\n", pmc
, (int)base_type
);
478 =item C<PMC * pmc_new_noinit(PARROT_INTERP, INTVAL base_type)>
480 Creates a new PMC of type C<base_type> (which is an index into the list of PMC
481 types declared in C<vtables> in F<include/parrot/pmc.h>). Unlike C<pmc_new()>,
482 C<pmc_new_noinit()> does not call its C<init> method. This allows separate
483 allocation and initialization for continuations.
490 PARROT_CANNOT_RETURN_NULL
492 pmc_new_noinit(PARROT_INTERP
, INTVAL base_type
)
494 ASSERT_ARGS(pmc_new_noinit
)
495 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
497 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
498 return VTABLE_instantiate(interp
, classobj
, PMCNULL
);
500 return get_new_pmc_header(interp
, base_type
, 0);
506 =item C<PMC * constant_pmc_new_noinit(PARROT_INTERP, INTVAL base_type)>
508 Creates a new constant PMC of type C<base_type>.
515 PARROT_CANNOT_RETURN_NULL
517 constant_pmc_new_noinit(PARROT_INTERP
, INTVAL base_type
)
519 ASSERT_ARGS(constant_pmc_new_noinit
)
520 return get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
526 =item C<PMC * constant_pmc_new(PARROT_INTERP, INTVAL base_type)>
528 Creates a new constant PMC of type C<base_type>, then calls its C<init>.
535 PARROT_CANNOT_RETURN_NULL
537 constant_pmc_new(PARROT_INTERP
, INTVAL base_type
)
539 ASSERT_ARGS(constant_pmc_new
)
540 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
541 VTABLE_init(interp
, pmc
);
548 =item C<PMC * pmc_new_init(PARROT_INTERP, INTVAL base_type, PMC *init)>
550 As C<pmc_new()>, but passes C<init> to the PMC's C<init_pmc()> vtable entry.
557 PARROT_CANNOT_RETURN_NULL
559 pmc_new_init(PARROT_INTERP
, INTVAL base_type
, ARGOUT(PMC
*init
))
561 ASSERT_ARGS(pmc_new_init
)
562 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
564 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
565 return VTABLE_instantiate(interp
, classobj
, init
);
567 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
568 VTABLE_init_pmc(interp
, pmc
, init
);
576 =item C<PMC * constant_pmc_new_init(PARROT_INTERP, INTVAL base_type, PMC *init)>
578 As C<constant_pmc_new>, but passes C<init> to the PMC's C<init_pmc> vtable
586 PARROT_CANNOT_RETURN_NULL
588 constant_pmc_new_init(PARROT_INTERP
, INTVAL base_type
, ARGIN_NULLOK(PMC
*init
))
590 ASSERT_ARGS(constant_pmc_new_init
)
591 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
592 VTABLE_init_pmc(interp
, pmc
, init
);
599 =item C<PMC * temporary_pmc_new(PARROT_INTERP, INTVAL base_type)>
601 Creates a new temporary PMC of type C<base_type>, then call C<init>. Cannot
602 be used to create PMC Objects which have been defined from PIR.
604 B<You> are responsible for freeing this PMC when it goes out of scope with
605 C<free_temporary_pmc()>. B<Do not> store this PMC in any other PMCs, or
606 allow it to be stored. B<Do not> store any regular PMC in this PMC, or
607 allow the storage of any regular PMC in this PMC. Temporary PMCs do not
608 participate in garbage collection, and mixing them with PMCs that are
609 garbage-collected will cause bugs.
611 If you don't know what this means means, or you can't tell if either case
612 will happen as the result of any call you make on or with this PMC,
613 B<DO NOT> use this function, lest you cause weird crashes and memory errors.
614 Use C<pmc_new()> instead.
616 (Why do these functions even exist? Used judiciously, they can reduce GC
617 pressure in hotspots tremendously. If you haven't audited the code carefully
618 -- including profiling and benchmarking -- then use C<pmc_new()> instead, and
619 never B<ever> add C<PARROT_EXPORT> to either function.)
625 PARROT_CANNOT_RETURN_NULL
627 temporary_pmc_new(PARROT_INTERP
, INTVAL base_type
)
629 ASSERT_ARGS(temporary_pmc_new
)
630 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
631 VTABLE_init(interp
, pmc
);
638 =item C<void temporary_pmc_free(PARROT_INTERP, PMC *pmc)>
640 Frees a new temporary PMC created by C<temporary_pmc_new()>. Do not call
641 this with any other type of PMC. Do not forget to call this (or you'll leak
642 PMCs). Read and I<understand> the warnings for C<temporary_pmc_new()> before
643 you're tempted to use this.
650 temporary_pmc_free(PARROT_INTERP
, ARGMOD(PMC
*pmc
))
652 ASSERT_ARGS(temporary_pmc_free
)
653 Parrot_gc_free_pmc_header(interp
, pmc
);
659 =item C<INTVAL get_new_vtable_index(PARROT_INTERP)>
661 Get a new unique identifier number and allocate a new vtable structure for a
669 get_new_vtable_index(PARROT_INTERP
)
671 ASSERT_ARGS(get_new_vtable_index
)
672 const INTVAL type_id
= interp
->n_vtable_max
++;
674 /* Have we overflowed the table? */
675 if (type_id
>= interp
->n_vtable_alloced
)
676 parrot_realloc_vtables(interp
);
683 =item C<INTVAL pmc_register(PARROT_INTERP, STRING *name)>
685 Registers the name of a new PMC type with Parrot, returning the INTVAL
686 representing that type.
694 pmc_register(PARROT_INTERP
, ARGIN(STRING
*name
))
696 ASSERT_ARGS(pmc_register
)
697 /* If they're looking to register an existing class, return that
698 class' type number */
699 INTVAL type
= pmc_type(interp
, name
);
701 if (type
> enum_type_undef
)
704 if (type
< enum_type_undef
)
705 Parrot_ex_throw_from_c_args(interp
, NULL
, 1,
706 "undefined type already exists - can't register PMC");
708 type
= get_new_vtable_index(interp
);
710 /* set entry in name->type hash */
711 VTABLE_set_integer_keyed_str(interp
, interp
->class_hash
, name
, type
);
719 =item C<INTVAL pmc_type(PARROT_INTERP, STRING *name)>
721 Returns the PMC type for C<name>.
728 PARROT_WARN_UNUSED_RESULT
730 pmc_type(PARROT_INTERP
, ARGIN_NULLOK(STRING
*name
))
732 ASSERT_ARGS(pmc_type
)
734 return enum_type_undef
;
736 PMC
* const classname_hash
= interp
->class_hash
;
738 (PMC
*)VTABLE_get_pointer_keyed_str(interp
, classname_hash
, name
);
740 if (!PMC_IS_NULL(item
)) {
741 /* nested namespace with same name */
742 if (item
->vtable
->base_type
== enum_class_NameSpace
)
743 return enum_type_undef
;
745 return VTABLE_get_integer(interp
, item
);
748 return Parrot_get_datatype_enum(interp
, name
);
755 =item C<INTVAL pmc_type_p(PARROT_INTERP, PMC *name)>
757 Returns the PMC type for C<name>.
765 pmc_type_p(PARROT_INTERP
, ARGIN(PMC
*name
))
767 ASSERT_ARGS(pmc_type_p
)
768 PMC
* const classname_hash
= interp
->class_hash
;
771 item
= (PMC
*)VTABLE_get_pointer_keyed(interp
, classname_hash
, name
);
773 if (!PMC_IS_NULL(item
))
774 return VTABLE_get_integer(interp
, item
);
782 =item C<static PMC * create_class_pmc(PARROT_INTERP, INTVAL type)>
784 Create a class object for this interpreter. Takes an interpreter name and type
785 as arguments. Returns a pointer to the class object.
791 PARROT_WARN_UNUSED_RESULT
792 PARROT_CANNOT_RETURN_NULL
794 create_class_pmc(PARROT_INTERP
, INTVAL type
)
796 ASSERT_ARGS(create_class_pmc
)
798 * class interface - a PMC is its own class
799 * put an instance of this PMC into class
801 * create a constant PMC
803 PMC
* const _class
= get_new_pmc_header(interp
, type
,
806 /* If we are a second thread, we may get the same object as the
807 * original because we have a singleton. Just set the singleton to
808 * be our class object, but don't mess with its vtable. */
809 if ((interp
->vtables
[type
]->flags
& VTABLE_PMC_IS_SINGLETON
)
810 && (_class
== _class
->vtable
->pmc_class
))
811 interp
->vtables
[type
]->pmc_class
= _class
;
813 Parrot_gc_free_pmc_sync(interp
, _class
);
814 gc_flag_CLEAR(is_special_PMC
, _class
);
815 PObj_is_PMC_shared_CLEAR(_class
);
816 interp
->vtables
[type
]->pmc_class
= _class
;
825 =item C<void Parrot_create_mro(PARROT_INTERP, INTVAL type)>
827 Create the MRO (method resolution order) array for this type.
835 Parrot_create_mro(PARROT_INTERP
, INTVAL type
)
837 ASSERT_ARGS(Parrot_create_mro
)
839 VTABLE
*vtable
= interp
->vtables
[type
];
840 PMC
*mro_list
= vtable
->mro
;
843 /* this should never be PMCNULL */
844 PARROT_ASSERT(!PMC_IS_NULL(mro_list
));
846 /* multithreaded: has already mro */
847 if (mro_list
->vtable
->base_type
!= enum_class_ResizableStringArray
)
850 mro
= pmc_new(interp
, enum_class_ResizablePMCArray
);
853 if (vtable
->ro_variant_vtable
)
854 vtable
->ro_variant_vtable
->mro
= mro
;
856 count
= VTABLE_elements(interp
, mro_list
);
858 for (i
= 0; i
< count
; ++i
) {
859 STRING
*class_name
= VTABLE_get_string_keyed_int(interp
, mro_list
, i
);
860 INTVAL parent_type
= pmc_type(interp
, class_name
);
862 /* abstract classes don't have a vtable */
866 vtable
= interp
->vtables
[parent_type
];
868 if (!vtable
->_namespace
) {
869 /* need a namespace Hash, anchor at parent, name it */
870 PMC
* const ns
= pmc_new(interp
,
871 Parrot_get_ctx_HLL_type(interp
, enum_class_NameSpace
));
872 vtable
->_namespace
= ns
;
874 /* anchor at parent, aka current_namespace, that is 'parrot' */
875 VTABLE_set_pmc_keyed_str(interp
,
876 Parrot_pcc_get_namespace(interp
, CURRENT_CONTEXT(interp
)), class_name
, ns
);
879 _class
= vtable
->pmc_class
;
881 _class
= create_class_pmc(interp
, parent_type
);
883 VTABLE_push_pmc(interp
, mro
, _class
);
892 =head2 GC registry interface
896 =item C<void gc_register_pmc(PARROT_INTERP, PMC *pmc)>
898 Registers the PMC with the interpreter's GC registry.
906 gc_register_pmc(PARROT_INTERP
, ARGIN(PMC
*pmc
))
908 ASSERT_ARGS(gc_register_pmc
)
909 /* Better not trigger a GC run with a potentially unanchored PMC */
910 Parrot_block_GC_mark(interp
);
912 PARROT_ASSERT(interp
->gc_registry
);
914 VTABLE_set_pmc_keyed(interp
, interp
->gc_registry
, pmc
, PMCNULL
);
915 Parrot_unblock_GC_mark(interp
);
921 =item C<void gc_unregister_pmc(PARROT_INTERP, PMC *pmc)>
923 Unregisters the PMC from the interpreter's GC registry.
931 gc_unregister_pmc(PARROT_INTERP
, ARGIN(PMC
*pmc
))
933 ASSERT_ARGS(gc_unregister_pmc
)
934 PARROT_ASSERT(interp
->gc_registry
);
936 VTABLE_delete_keyed(interp
, interp
->gc_registry
, pmc
);
946 F<include/parrot/vtable.h>.
948 C<5.1.0.14.2.20011008152120.02158148@pop.sidhe.org>
949 (http://www.nntp.perl.org/group/perl.perl6.internals/5516).
953 Initial version by Simon on 2001.10.20.
962 * c-file-style: "parrot"
964 * vim: expandtab shiftwidth=4: