2 Copyright (C) 2001-2010, Parrot Foundation.
11 The base vtable calling functions
21 #include "parrot/parrot.h"
23 #include "pmc/pmc_class.h"
24 #include "pmc/pmc_callcontext.h"
26 /* HEADERIZER HFILE: include/parrot/pmc.h */
28 /* HEADERIZER BEGIN: static */
29 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
31 static void check_pmc_reuse_flags(PARROT_INTERP
,
34 __attribute__nonnull__(1);
36 PARROT_WARN_UNUSED_RESULT
37 PARROT_CANNOT_RETURN_NULL
38 static PMC
* create_class_pmc(PARROT_INTERP
, INTVAL type
)
39 __attribute__nonnull__(1);
41 PARROT_WARN_UNUSED_RESULT
42 PARROT_CANNOT_RETURN_NULL
43 static PMC
* get_new_pmc_header(PARROT_INTERP
,
46 __attribute__nonnull__(1);
48 PARROT_CANNOT_RETURN_NULL
49 static PMC
* Parrot_pmc_reuse_noinit(PARROT_INTERP
,
53 __attribute__nonnull__(1)
54 __attribute__nonnull__(2);
56 #define ASSERT_ARGS_check_pmc_reuse_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
57 PARROT_ASSERT_ARG(interp))
58 #define ASSERT_ARGS_create_class_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
59 PARROT_ASSERT_ARG(interp))
60 #define ASSERT_ARGS_get_new_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
61 PARROT_ASSERT_ARG(interp))
62 #define ASSERT_ARGS_Parrot_pmc_reuse_noinit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
63 PARROT_ASSERT_ARG(interp) \
64 , PARROT_ASSERT_ARG(pmc))
65 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
66 /* HEADERIZER END: static */
75 =item C<INTVAL Parrot_pmc_is_null(PARROT_INTERP, const PMC *pmc)>
77 Tests if the given pmc is null.
85 Parrot_pmc_is_null(SHIM_INTERP
, ARGIN_NULLOK(const PMC
*pmc
))
87 ASSERT_ARGS(Parrot_pmc_is_null
)
89 return pmc
== PMCNULL
|| pmc
== NULL
;
97 =item C<void Parrot_pmc_destroy(PARROT_INTERP, PMC *pmc)>
99 Destroy a PMC. Call his destroy vtable function if needed, and deallocate
100 his attributes if they are automatically allocated.
102 For internal usage of the PMC handling functions and garbage collection
111 Parrot_pmc_destroy(PARROT_INTERP
, ARGMOD(PMC
*pmc
))
113 ASSERT_ARGS(Parrot_pmc_destroy
)
115 if (PObj_custom_destroy_TEST(pmc
))
116 VTABLE_destroy(interp
, pmc
);
120 if (PObj_is_PMC_shared_TEST(pmc
) && PMC_sync(pmc
))
121 Parrot_gc_free_pmc_sync(interp
, pmc
);
123 if (pmc
->vtable
->attr_size
)
124 Parrot_gc_free_pmc_attributes(interp
, pmc
);
126 PMC_data(pmc
) = NULL
;
130 pmc
->vtable
= (VTABLE
*)0xdeadbeef;
138 =item C<PMC * Parrot_pmc_new(PARROT_INTERP, INTVAL base_type)>
140 Creates a new PMC of type C<base_type> (which is an index into the list of PMC
141 types declared in C<vtables> in F<include/parrot/pmc.h>). Once the PMC has been
142 successfully created and its vtable pointer initialized, we call its C<init>
143 method to perform any other necessary initialization.
150 PARROT_CANNOT_RETURN_NULL
151 PARROT_WARN_UNUSED_RESULT
153 Parrot_pmc_new(PARROT_INTERP
, INTVAL base_type
)
155 ASSERT_ARGS(Parrot_pmc_new
)
156 PARROT_ASSERT(interp
->vtables
[base_type
]);
158 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
160 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
161 return VTABLE_instantiate(interp
, classobj
, PMCNULL
);
163 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
164 VTABLE_init(interp
, pmc
);
172 =item C<PMC * Parrot_pmc_reuse(PARROT_INTERP, PMC *pmc, INTVAL new_type, UINTVAL
175 Reuse an existing PMC, turning it into an empty PMC of the new type. Any
176 required internal structure will be put in place (such as the extension area)
177 and the PMC will be ready to go.
179 Cannot currently handle converting a non-Object PMC into an Object. Use
180 C<pmc_reuse_by_class> for that.
188 PARROT_CANNOT_RETURN_NULL
189 PARROT_IGNORABLE_RESULT
191 Parrot_pmc_reuse(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
,
194 ASSERT_ARGS(Parrot_pmc_reuse
)
195 pmc
= Parrot_pmc_reuse_noinit(interp
, pmc
, new_type
, flags
);
197 /* Call the base init for the redone pmc. Warning, this should not
198 be called on Object PMCs. */
199 VTABLE_init(interp
, pmc
);
206 =item C<PMC * Parrot_pmc_reuse_init(PARROT_INTERP, PMC *pmc, INTVAL new_type,
207 PMC *init, UINTVAL flags)>
209 Reuse an existing PMC, turning it into an PMC of the new type. Any
210 required internal structure will be put in place (such as the extension area)
211 and the PMC will be inited.
213 Cannot currently handle converting a non-Object PMC into an Object. Use
214 C<pmc_reuse_by_class> for that.
222 PARROT_CANNOT_RETURN_NULL
223 PARROT_IGNORABLE_RESULT
225 Parrot_pmc_reuse_init(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
, ARGIN(PMC
*init
),
228 ASSERT_ARGS(Parrot_pmc_reuse_init
)
229 pmc
= Parrot_pmc_reuse_noinit(interp
, pmc
, new_type
, flags
);
231 /* Call the base init for the redone pmc. Warning, this should not
232 be called on Object PMCs. */
233 VTABLE_init_pmc(interp
, pmc
, init
);
240 =item C<static PMC* Parrot_pmc_reuse_noinit(PARROT_INTERP, PMC *pmc, INTVAL
241 new_type, UINTVAL flags)>
243 Prepare pmc for reuse. Do all scuffolding except initing.
248 PARROT_CANNOT_RETURN_NULL
250 Parrot_pmc_reuse_noinit(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
,
251 SHIM(UINTVAL flags
)) {
253 ASSERT_ARGS(Parrot_pmc_reuse_noinit
)
255 INTVAL new_flags
= 0;
257 if (pmc
->vtable
->base_type
== new_type
)
260 new_vtable
= interp
->vtables
[new_type
];
262 /* Singleton/const PMCs/types are not eligible */
263 check_pmc_reuse_flags(interp
, pmc
->vtable
->flags
, new_vtable
->flags
);
265 /* Free the old PMC resources. */
266 Parrot_pmc_destroy(interp
, pmc
);
268 PObj_flags_SETTO(pmc
, PObj_is_PMC_FLAG
| new_flags
);
270 /* Set the right vtable */
271 pmc
->vtable
= new_vtable
;
273 if (new_vtable
->attr_size
)
274 Parrot_gc_allocate_pmc_attributes(interp
, pmc
);
277 PMC_data(pmc
) = NULL
;
284 =item C<PMC * Parrot_pmc_reuse_by_class(PARROT_INTERP, PMC *pmc, PMC *class_,
287 Reuse an existing PMC. Convert it to the type specified by the given Class
288 PMC. At the moment, this means we can only use this function to reuse PMCs
289 into types with Classes (not built-in PMCs). Use C<pmc_reuse> if you need
290 to convert to a built-in PMC type.
297 PARROT_CANNOT_RETURN_NULL
298 PARROT_IGNORABLE_RESULT
300 Parrot_pmc_reuse_by_class(PARROT_INTERP
, ARGMOD(PMC
*pmc
), ARGIN(PMC
*class_
),
303 ASSERT_ARGS(Parrot_pmc_reuse_by_class
)
304 const INTVAL new_type
= PARROT_CLASS(class_
)->id
;
305 VTABLE
* const new_vtable
= interp
->vtables
[new_type
];
306 INTVAL new_flags
= flags
;
308 if (pmc
->vtable
->base_type
== new_type
)
311 /* Singleton/const PMCs/types are not eligible */
312 check_pmc_reuse_flags(interp
, pmc
->vtable
->flags
, new_vtable
->flags
);
314 Parrot_pmc_destroy(interp
, pmc
);
316 PObj_flags_SETTO(pmc
, PObj_is_PMC_FLAG
| new_flags
);
318 /* Set the right vtable */
319 pmc
->vtable
= new_vtable
;
321 if (new_vtable
->attr_size
)
322 Parrot_gc_allocate_pmc_attributes(interp
, pmc
);
324 PMC_data(pmc
) = NULL
;
332 =item C<static void check_pmc_reuse_flags(PARROT_INTERP, UINTVAL srcflags,
335 We're converting one PMC type to another, either in C<pmc_reuse> or
336 C<pmc_reuse_by_class>. Check to make sure that neither the existing PMC
337 or the intended target PMC type are singletons or constants. We throw an
338 exception if we are attempting an illegal operation.
345 check_pmc_reuse_flags(PARROT_INTERP
, UINTVAL srcflags
, UINTVAL destflags
)
347 ASSERT_ARGS(check_pmc_reuse_flags
)
348 if ((srcflags
| destflags
) & (VTABLE_PMC_IS_SINGLETON
| VTABLE_IS_CONST_FLAG
))
350 /* First, is the destination a singleton? No joy for us there */
351 if (destflags
& VTABLE_PMC_IS_SINGLETON
)
352 Parrot_ex_throw_from_c_args(interp
, NULL
,
353 EXCEPTION_ALLOCATION_ERROR
,
354 "Parrot VM: Can't turn to a singleton type!\n");
356 /* Is the destination a constant? No joy for us there */
357 if (destflags
& VTABLE_IS_CONST_FLAG
)
358 Parrot_ex_throw_from_c_args(interp
, NULL
,
359 EXCEPTION_ALLOCATION_ERROR
,
360 "Parrot VM: Can't turn to a constant type!\n");
362 /* Is the source a singleton? */
363 if (srcflags
& VTABLE_PMC_IS_SINGLETON
)
364 Parrot_ex_throw_from_c_args(interp
, NULL
,
365 EXCEPTION_ALLOCATION_ERROR
,
366 "Parrot VM: Can't modify a singleton\n");
368 /* Is the source constant? */
369 if (srcflags
& VTABLE_IS_CONST_FLAG
)
370 Parrot_ex_throw_from_c_args(interp
, NULL
,
371 EXCEPTION_ALLOCATION_ERROR
,
372 "Parrot VM: Can't modify a constant\n");
378 =item C<static PMC * get_new_pmc_header(PARROT_INTERP, INTVAL base_type, UINTVAL
381 Gets a new PMC header of the given integer type. Initialize the pmc if
382 necessary. In the case of singleton PMC types, get the existing singleton
383 instead of allocating a new one.
389 PARROT_WARN_UNUSED_RESULT
390 PARROT_CANNOT_RETURN_NULL
392 get_new_pmc_header(PARROT_INTERP
, INTVAL base_type
, UINTVAL flags
)
394 ASSERT_ARGS(get_new_pmc_header
)
396 VTABLE
*vtable
= interp
->vtables
[base_type
];
397 UINTVAL vtable_flags
;
399 /* This is usually because you either didn't call init_world early enough,
400 * you added a new PMC class without adding Parrot_(classname)_class_init
401 * to init_world, or you forgot to run 'make realclean' after adding a new
404 PANIC(interp
, "Null vtable used; did you add a new PMC?");
406 vtable_flags
= vtable
->flags
;
408 /* we only have one global Env object, living in the interp */
409 if (vtable_flags
& VTABLE_PMC_IS_SINGLETON
) {
411 * singletons (monadic objects) exist only once
412 * the interface * with the class is:
413 * - get_pointer: return NULL or a pointer to the single instance
414 * - set_pointer: set the only instance once
416 * - singletons are created in the constant pmc pool
418 PMC
*pmc
= (PMC
*)(vtable
->get_pointer
)(interp
, NULL
);
422 pmc
= Parrot_gc_new_pmc_header(interp
, PObj_constant_FLAG
);
425 pmc
->vtable
= vtable
;
426 VTABLE_set_pointer(interp
, pmc
, pmc
);
432 if (vtable_flags
& VTABLE_IS_CONST_PMC_FLAG
)
433 flags
|= PObj_constant_FLAG
;
434 else if (vtable_flags
& VTABLE_IS_CONST_FLAG
) {
435 /* put the normal vtable in, so that the pmc can be initialized first
436 * parrot or user code has to set the _ro property then,
437 * to morph the PMC to the const variant
438 * This assumes that a constant PMC enum is one bigger then
443 * XXX not yet we can't assure that all contents in the
444 * const PMC is const too
445 * see e.g. t/pmc/sarray_13.pir
448 flags
|= PObj_constant_FLAG
;
451 vtable
= interp
->vtables
[base_type
];
454 if (vtable_flags
& VTABLE_IS_SHARED_FLAG
)
455 flags
|= PObj_is_PMC_shared_FLAG
;
457 pmc
= Parrot_gc_new_pmc_header(interp
, flags
);
458 pmc
->vtable
= vtable
;
460 if (vtable
->attr_size
)
461 Parrot_gc_allocate_pmc_attributes(interp
, pmc
);
469 =item C<PMC * Parrot_pmc_new_noinit(PARROT_INTERP, INTVAL base_type)>
471 Creates a new PMC of type C<base_type> (which is an index into the list of PMC
472 types declared in C<vtables> in F<include/parrot/pmc.h>). Unlike C<Parrot_pmc_new()>,
473 C<Parrot_pmc_new_noinit()> does not call its C<init> method. This allows separate
474 allocation and initialization for continuations.
481 PARROT_CANNOT_RETURN_NULL
483 Parrot_pmc_new_noinit(PARROT_INTERP
, INTVAL base_type
)
485 ASSERT_ARGS(Parrot_pmc_new_noinit
)
486 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
488 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
489 return VTABLE_instantiate(interp
, classobj
, PMCNULL
);
491 return get_new_pmc_header(interp
, base_type
, 0);
497 =item C<PMC * Parrot_pmc_new_constant_noinit(PARROT_INTERP, INTVAL base_type)>
499 Creates a new constant PMC of type C<base_type>.
506 PARROT_CANNOT_RETURN_NULL
508 Parrot_pmc_new_constant_noinit(PARROT_INTERP
, INTVAL base_type
)
510 ASSERT_ARGS(Parrot_pmc_new_constant_noinit
)
511 return get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
517 =item C<PMC * Parrot_pmc_new_constant(PARROT_INTERP, INTVAL base_type)>
519 Creates a new constant PMC of type C<base_type>, then calls its C<init>.
526 PARROT_CANNOT_RETURN_NULL
528 Parrot_pmc_new_constant(PARROT_INTERP
, INTVAL base_type
)
530 ASSERT_ARGS(Parrot_pmc_new_constant
)
531 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
532 VTABLE_init(interp
, pmc
);
539 =item C<PMC * Parrot_pmc_new_init(PARROT_INTERP, INTVAL base_type, PMC *init)>
541 As C<Parrot_pmc_new()>, but passes C<init> to the PMC's C<init_pmc()> vtable entry.
548 PARROT_CANNOT_RETURN_NULL
550 Parrot_pmc_new_init(PARROT_INTERP
, INTVAL base_type
, ARGOUT(PMC
*init
))
552 ASSERT_ARGS(Parrot_pmc_new_init
)
553 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
555 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
556 return VTABLE_instantiate(interp
, classobj
, init
);
558 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
559 VTABLE_init_pmc(interp
, pmc
, init
);
567 =item C<PMC * Parrot_pmc_new_init_int(PARROT_INTERP, INTVAL base_type, INTVAL
570 As C<Parrot_pmc_new()>, but passes C<init> to the PMC's C<init_int()> vtable entry.
577 PARROT_CANNOT_RETURN_NULL
579 Parrot_pmc_new_init_int(PARROT_INTERP
, INTVAL base_type
, INTVAL init
)
581 ASSERT_ARGS(Parrot_pmc_new_init
)
582 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
584 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
)) {
585 PMC
*initial
= Parrot_pmc_new(interp
, Parrot_get_ctx_HLL_type(interp
, enum_class_Integer
));
586 VTABLE_set_integer_native(interp
, initial
, init
);
587 VTABLE_instantiate(interp
, classobj
, initial
);
590 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
591 VTABLE_init_int(interp
, pmc
, init
);
600 =item C<PMC * Parrot_pmc_new_constant_init(PARROT_INTERP, INTVAL base_type, PMC
603 As C<Parrot_pmc_new_constant>, but passes C<init> to the PMC's C<init_pmc> vtable
611 PARROT_CANNOT_RETURN_NULL
613 Parrot_pmc_new_constant_init(PARROT_INTERP
, INTVAL base_type
, ARGIN_NULLOK(PMC
*init
))
615 ASSERT_ARGS(Parrot_pmc_new_constant_init
)
616 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
617 VTABLE_init_pmc(interp
, pmc
, init
);
624 =item C<PMC * Parrot_pmc_new_temporary(PARROT_INTERP, INTVAL base_type)>
626 Creates a new temporary PMC of type C<base_type>, then call C<init>. Cannot
627 be used to create PMC Objects which have been defined from PIR.
629 B<You> are responsible for freeing this PMC when it goes out of scope with
630 C<free_temporary_pmc()>. B<Do not> store this PMC in any other PMCs, or
631 allow it to be stored. B<Do not> store any regular PMC in this PMC, or
632 allow the storage of any regular PMC in this PMC. Temporary PMCs do not
633 participate in garbage collection, and mixing them with PMCs that are
634 garbage-collected will cause bugs.
636 If you don't know what this means means, or you can't tell if either case
637 will happen as the result of any call you make on or with this PMC,
638 B<DO NOT> use this function, lest you cause weird crashes and memory errors.
639 Use C<Parrot_pmc_new()> instead.
641 (Why do these functions even exist? Used judiciously, they can reduce GC
642 pressure in hotspots tremendously. If you haven't audited the code carefully
643 -- including profiling and benchmarking -- then use C<Parrot_pmc_new()> instead, and
644 never B<ever> add C<PARROT_EXPORT> to either function.)
650 PARROT_CANNOT_RETURN_NULL
652 Parrot_pmc_new_temporary(PARROT_INTERP
, INTVAL base_type
)
654 ASSERT_ARGS(Parrot_pmc_new_temporary
)
655 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
656 VTABLE_init(interp
, pmc
);
663 =item C<void Parrot_pmc_free_temporary(PARROT_INTERP, PMC *pmc)>
665 Frees a new temporary PMC created by C<temporary_Parrot_pmc_new()>. Do not call
666 this with any other type of PMC. Do not forget to call this (or you'll leak
667 PMCs). Read and I<understand> the warnings for C<temporary_Parrot_pmc_new()> before
668 you're tempted to use this.
675 Parrot_pmc_free_temporary(PARROT_INTERP
, ARGMOD(PMC
*pmc
))
677 ASSERT_ARGS(Parrot_pmc_free_temporary
)
678 Parrot_gc_free_pmc_header(interp
, pmc
);
684 =item C<INTVAL Parrot_pmc_get_new_vtable_index(PARROT_INTERP)>
686 Get a new unique identifier number and allocate a new vtable structure for a
694 Parrot_pmc_get_new_vtable_index(PARROT_INTERP
)
696 ASSERT_ARGS(Parrot_pmc_get_new_vtable_index
)
697 const INTVAL type_id
= interp
->n_vtable_max
++;
699 /* Have we overflowed the table? */
700 if (type_id
>= interp
->n_vtable_alloced
)
701 parrot_realloc_vtables(interp
);
708 =item C<INTVAL Parrot_pmc_register_new_type(PARROT_INTERP, STRING *name)>
710 Registers the name of a new PMC type with Parrot, returning the INTVAL
711 representing that type.
719 Parrot_pmc_register_new_type(PARROT_INTERP
, ARGIN(STRING
*name
))
721 ASSERT_ARGS(Parrot_pmc_register_new_type
)
722 /* If they're looking to register an existing class, return that
723 class' type number */
724 INTVAL type
= Parrot_pmc_get_type_str(interp
, name
);
726 if (type
> enum_type_undef
)
729 if (type
< enum_type_undef
)
730 Parrot_ex_throw_from_c_args(interp
, NULL
, 1,
731 "undefined type already exists - can't register PMC");
733 type
= Parrot_pmc_get_new_vtable_index(interp
);
735 /* set entry in name->type hash */
736 VTABLE_set_integer_keyed_str(interp
, interp
->class_hash
, name
, type
);
744 =item C<INTVAL Parrot_pmc_get_type_str(PARROT_INTERP, STRING *name)>
746 Returns the PMC type for C<name>.
753 PARROT_WARN_UNUSED_RESULT
755 Parrot_pmc_get_type_str(PARROT_INTERP
, ARGIN_NULLOK(STRING
*name
))
757 ASSERT_ARGS(Parrot_pmc_get_type_str
)
759 return enum_type_undef
;
761 PMC
* const classname_hash
= interp
->class_hash
;
763 (PMC
*)VTABLE_get_pointer_keyed_str(interp
, classname_hash
, name
);
765 if (!PMC_IS_NULL(item
)) {
766 /* nested namespace with same name */
767 if (item
->vtable
->base_type
== enum_class_NameSpace
)
768 return enum_type_undef
;
770 return VTABLE_get_integer(interp
, item
);
773 return Parrot_get_datatype_enum(interp
, name
);
780 =item C<INTVAL Parrot_pmc_get_type(PARROT_INTERP, PMC *name)>
782 Returns the PMC type for C<name>.
790 Parrot_pmc_get_type(PARROT_INTERP
, ARGIN(PMC
*name
))
792 ASSERT_ARGS(Parrot_pmc_get_type
)
793 PMC
* const classname_hash
= interp
->class_hash
;
796 item
= (PMC
*)VTABLE_get_pointer_keyed(interp
, classname_hash
, name
);
798 if (!PMC_IS_NULL(item
))
799 return VTABLE_get_integer(interp
, item
);
807 =item C<static PMC * create_class_pmc(PARROT_INTERP, INTVAL type)>
809 Create a class object for this interpreter. Takes an interpreter name and type
810 as arguments. Returns a pointer to the class object.
816 PARROT_WARN_UNUSED_RESULT
817 PARROT_CANNOT_RETURN_NULL
819 create_class_pmc(PARROT_INTERP
, INTVAL type
)
821 ASSERT_ARGS(create_class_pmc
)
823 * class interface - a PMC is its own class
824 * put an instance of this PMC into class
826 * create a constant PMC
828 PMC
* const _class
= get_new_pmc_header(interp
, type
,
831 /* If we are a second thread, we may get the same object as the
832 * original because we have a singleton. Just set the singleton to
833 * be our class object, but don't mess with its vtable. */
834 if ((interp
->vtables
[type
]->flags
& VTABLE_PMC_IS_SINGLETON
)
835 && (_class
== _class
->vtable
->pmc_class
))
836 interp
->vtables
[type
]->pmc_class
= _class
;
838 Parrot_gc_free_pmc_sync(interp
, _class
);
839 gc_flag_CLEAR(is_special_PMC
, _class
);
840 PObj_is_PMC_shared_CLEAR(_class
);
841 interp
->vtables
[type
]->pmc_class
= _class
;
850 =item C<void Parrot_pmc_create_mro(PARROT_INTERP, INTVAL type)>
852 Create the MRO (method resolution order) array for this type.
860 Parrot_pmc_create_mro(PARROT_INTERP
, INTVAL type
)
862 ASSERT_ARGS(Parrot_pmc_create_mro
)
864 VTABLE
*vtable
= interp
->vtables
[type
];
865 PMC
*mro_list
= vtable
->mro
;
868 /* this should never be PMCNULL */
869 PARROT_ASSERT(!PMC_IS_NULL(mro_list
));
871 /* multithreaded: has already mro */
872 if (mro_list
->vtable
->base_type
!= enum_class_ResizableStringArray
)
875 mro
= Parrot_pmc_new(interp
, enum_class_ResizablePMCArray
);
878 if (vtable
->ro_variant_vtable
)
879 vtable
->ro_variant_vtable
->mro
= mro
;
881 count
= VTABLE_elements(interp
, mro_list
);
883 for (i
= 0; i
< count
; ++i
) {
884 STRING
*class_name
= VTABLE_get_string_keyed_int(interp
, mro_list
, i
);
885 INTVAL parent_type
= Parrot_pmc_get_type_str(interp
, class_name
);
887 /* abstract classes don't have a vtable */
891 vtable
= interp
->vtables
[parent_type
];
893 if (!vtable
->_namespace
) {
894 /* need a namespace Hash, anchor at parent, name it */
895 PMC
* const ns
= Parrot_pmc_new(interp
,
896 Parrot_get_ctx_HLL_type(interp
, enum_class_NameSpace
));
897 vtable
->_namespace
= ns
;
899 /* anchor at parent, aka current_namespace, that is 'parrot' */
900 VTABLE_set_pmc_keyed_str(interp
,
901 Parrot_pcc_get_namespace(interp
, CURRENT_CONTEXT(interp
)), class_name
, ns
);
904 _class
= vtable
->pmc_class
;
906 _class
= create_class_pmc(interp
, parent_type
);
908 VTABLE_push_pmc(interp
, mro
, _class
);
917 =head2 GC registry interface
921 =item C<void Parrot_pmc_gc_register(PARROT_INTERP, PMC *pmc)>
923 Registers the PMC with the interpreter's GC registry.
931 Parrot_pmc_gc_register(PARROT_INTERP
, ARGIN(PMC
*pmc
))
933 ASSERT_ARGS(Parrot_pmc_gc_register
)
934 /* Better not trigger a GC run with a potentially unanchored PMC */
935 Parrot_block_GC_mark(interp
);
937 PARROT_ASSERT(interp
->gc_registry
);
939 VTABLE_set_pmc_keyed(interp
, interp
->gc_registry
, pmc
, PMCNULL
);
940 Parrot_unblock_GC_mark(interp
);
945 =item C<void Parrot_pmc_gc_unregister(PARROT_INTERP, PMC *pmc)>
947 Unregisters the PMC from the interpreter's GC registry.
955 Parrot_pmc_gc_unregister(PARROT_INTERP
, ARGIN(PMC
*pmc
))
957 ASSERT_ARGS(Parrot_pmc_gc_unregister
)
958 PARROT_ASSERT(interp
->gc_registry
);
960 VTABLE_delete_keyed(interp
, interp
->gc_registry
, pmc
);
969 F<include/parrot/vtable.h>.
971 C<5.1.0.14.2.20011008152120.02158148@pop.sidhe.org>
972 (http://www.nntp.perl.org/group/perl.perl6.internals/5516).
976 Initial version by Simon on 2001.10.20.
984 * c-file-style: "parrot"
986 * vim: expandtab shiftwidth=4: