2 Copyright (C) 2001-2008, The Perl Foundation.
7 src/pmc.c - The base vtable calling functions
19 #include "parrot/parrot.h"
22 /* HEADERIZER HFILE: include/parrot/pmc.h */
24 /* HEADERIZER BEGIN: static */
26 PARROT_WARN_UNUSED_RESULT
27 PARROT_CANNOT_RETURN_NULL
28 static PMC
* create_class_pmc(PARROT_INTERP
, INTVAL type
)
29 __attribute__nonnull__(1);
31 PARROT_WARN_UNUSED_RESULT
32 PARROT_CANNOT_RETURN_NULL
33 static PMC
* get_new_pmc_header(PARROT_INTERP
,
36 __attribute__nonnull__(1);
38 /* HEADERIZER END: static */
42 PARROT_API PMC
* PMCNULL
;
47 =item C<PMC * pmc_new>
49 Creates a new PMC of type C<base_type> (which is an index into the list of PMC
50 types declared in C<vtables> in F<include/parrot/pmc.h>). Once the PMC has been
51 successfully created and its vtable pointer initialized, we call its C<init>
52 method to perform any other necessary initialization.
59 PARROT_CANNOT_RETURN_NULL
62 pmc_new(PARROT_INTERP
, INTVAL base_type
)
64 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
66 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
67 return VTABLE_instantiate(interp
, classobj
, PMCNULL
);
69 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
70 VTABLE_init(interp
, pmc
);
77 =item C<PMC* pmc_reuse>
79 Reuse an existing PMC, turning it into an empty PMC of the new type. Any
80 required internal structure will be put in place (such as the extension area)
81 and the PMC will be ready to go. This will throw an exception if the PMC is
82 constant or of a singleton type (such as the environment PMC) or is being
83 turned into a PMC of a singleton type.
90 PARROT_CANNOT_RETURN_NULL
92 pmc_reuse(PARROT_INTERP
, ARGIN(PMC
*pmc
), INTVAL new_type
,
95 INTVAL has_ext
, new_flags
;
98 if (pmc
->vtable
->base_type
== new_type
)
101 new_vtable
= interp
->vtables
[new_type
];
103 /* Singleton/const PMCs/types are not eligible */
105 if ((pmc
->vtable
->flags
| new_vtable
->flags
)
106 & (VTABLE_PMC_IS_SINGLETON
| VTABLE_IS_CONST_FLAG
))
108 /* First, is the destination a singleton? No joy for us there */
109 if (new_vtable
->flags
& VTABLE_PMC_IS_SINGLETON
)
110 real_exception(interp
, NULL
, ALLOCATION_ERROR
,
111 "Parrot VM: Can't turn to a singleton type!\n");
113 /* First, is the destination a constant? No joy for us there */
114 if (new_vtable
->flags
& VTABLE_IS_CONST_FLAG
)
115 real_exception(interp
, NULL
, ALLOCATION_ERROR
,
116 "Parrot VM: Can't turn to a constant type!\n");
118 /* Is the source a singleton? */
119 if (pmc
->vtable
->flags
& VTABLE_PMC_IS_SINGLETON
)
120 real_exception(interp
, NULL
, ALLOCATION_ERROR
,
121 "Parrot VM: Can't modify a singleton\n");
123 /* Is the source constant? */
124 if (pmc
->vtable
->flags
& VTABLE_IS_CONST_FLAG
)
125 real_exception(interp
, NULL
, ALLOCATION_ERROR
,
126 "Parrot VM: Can't modify a constant\n");
129 /* Do we have an extension area? */
130 has_ext
= (PObj_is_PMC_EXT_TEST(pmc
) && pmc
->pmc_ext
);
132 /* Do we need one? */
133 if (new_vtable
->flags
& VTABLE_PMC_NEEDS_EXT
) {
135 /* If we need an ext area, go allocate one */
136 add_pmc_ext(interp
, pmc
);
138 new_flags
= PObj_is_PMC_EXT_FLAG
;
142 Parrot_free_pmc_ext(interp
, pmc
);
144 #if ! PMC_DATA_IN_EXT
145 PMC_data(pmc
) = NULL
;
150 /* we are a PMC + maybe is_PMC_EXT */
151 PObj_flags_SETTO(pmc
, PObj_is_PMC_FLAG
| new_flags
);
153 /* Set the right vtable */
154 pmc
->vtable
= new_vtable
;
156 /* Call the base init for the redone pmc */
157 VTABLE_init(interp
, pmc
);
164 =item C<static PMC* get_new_pmc_header>
166 Gets a new PMC header.
172 PARROT_WARN_UNUSED_RESULT
173 PARROT_CANNOT_RETURN_NULL
175 get_new_pmc_header(PARROT_INTERP
, INTVAL base_type
, UINTVAL flags
)
178 VTABLE
*vtable
= interp
->vtables
[base_type
];
180 /* This is usually because you either didn't call init_world early enough,
181 * you added a new PMC class without adding Parrot_(classname)_class_init
182 * to init_world, or you forgot to run 'make realclean' after adding a new
185 PANIC(interp
, "Null vtable used; did you add a new PMC?");
187 /* we only have one global Env object, living in the interp */
188 if (vtable
->flags
& VTABLE_PMC_IS_SINGLETON
) {
190 * singletons (monadic objects) exist only once, the interface
192 * - get_pointer: return NULL or a pointer to the single instance
193 * - set_pointer: set the only instance once
195 * - singletons are created in the constant pmc pool
197 PMC
*pmc
= (PMC
*)(vtable
->get_pointer
)(interp
, NULL
);
201 pmc
= new_pmc_header(interp
, PObj_constant_FLAG
);
204 pmc
->vtable
= vtable
;
205 pmc
->real_self
= pmc
;
206 VTABLE_set_pointer(interp
, pmc
, pmc
);
212 if (vtable
->flags
& VTABLE_IS_CONST_PMC_FLAG
) {
213 flags
|= PObj_constant_FLAG
;
215 else if (vtable
->flags
& VTABLE_IS_CONST_FLAG
) {
216 /* put the normal vtable in, so that the pmc can be initialized first
217 * parrot or user code has to set the _ro property then,
218 * to morph the PMC to the const variant
219 * This assumes that a constant PMC enum is one bigger then
224 * XXX not yet we can't assure that all contents in the
225 * const PMC is const too
226 * see e.g. t/pmc/sarray_13.pir
229 flags
|= PObj_constant_FLAG
;
232 vtable
= interp
->vtables
[base_type
];
235 if (vtable
->flags
& VTABLE_PMC_NEEDS_EXT
) {
236 flags
|= PObj_is_PMC_EXT_FLAG
;
237 if (vtable
->flags
& VTABLE_IS_SHARED_FLAG
)
238 flags
|= PObj_is_PMC_shared_FLAG
;
241 pmc
= new_pmc_header(interp
, flags
);
244 real_exception(interp
, NULL
, ALLOCATION_ERROR
,
245 "Parrot VM: PMC allocation failed!\n");
247 pmc
->vtable
= vtable
;
248 pmc
->real_self
= pmc
;
251 if (Interp_flags_TEST(interp
, PARROT_TRACE_FLAG
)) {
252 /* XXX make a more verbose trace flag */
253 fprintf(stderr
, "\t=> new %p type %d\n", pmc
, (int)base_type
);
263 =item C<PMC * pmc_new_noinit>
265 Creates a new PMC of type C<base_type> (which is an index into the list of PMC
266 types declared in C<vtables> in F<include/parrot/pmc.h>). Unlike C<pmc_new()>,
267 C<pmc_new_noinit()> does not call its C<init> method. This allows separate
268 allocation and initialization for continuations.
275 PARROT_CANNOT_RETURN_NULL
277 pmc_new_noinit(PARROT_INTERP
, INTVAL base_type
)
279 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
281 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
282 return VTABLE_instantiate(interp
, classobj
, PMCNULL
);
284 return get_new_pmc_header(interp
, base_type
, 0);
289 =item C<PMC * constant_pmc_new_noinit>
291 Creates a new constant PMC of type C<base_type>.
298 PARROT_CANNOT_RETURN_NULL
300 constant_pmc_new_noinit(PARROT_INTERP
, INTVAL base_type
)
302 return get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
307 =item C<PMC * constant_pmc_new>
309 Creates a new constant PMC of type C<base_type>, the call C<init>.
316 PARROT_CANNOT_RETURN_NULL
318 constant_pmc_new(PARROT_INTERP
, INTVAL base_type
)
320 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
,
322 VTABLE_init(interp
, pmc
);
328 =item C<PMC * pmc_new_init>
330 As C<pmc_new()>, but passes C<init> to the PMC's C<init_pmc()> method.
337 PARROT_CANNOT_RETURN_NULL
339 pmc_new_init(PARROT_INTERP
, INTVAL base_type
, ARGOUT(PMC
*init
))
341 PMC
*const classobj
= interp
->vtables
[base_type
]->pmc_class
;
343 if (!PMC_IS_NULL(classobj
) && PObj_is_class_TEST(classobj
))
344 return VTABLE_instantiate(interp
, classobj
, init
);
346 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, 0);
347 VTABLE_init_pmc(interp
, pmc
, init
);
354 =item C<PMC * constant_pmc_new_init>
356 As C<constant_pmc_new>, but passes C<init> to the PMC's C<init_pmc> method.
363 PARROT_CANNOT_RETURN_NULL
365 constant_pmc_new_init(PARROT_INTERP
, INTVAL base_type
, ARGIN_NULLOK(PMC
*init
))
367 PMC
* const pmc
= get_new_pmc_header(interp
, base_type
, PObj_constant_FLAG
);
368 VTABLE_init_pmc(interp
, pmc
, init
);
374 =item C<INTVAL pmc_register>
376 This segment handles PMC registration and such.
384 pmc_register(PARROT_INTERP
, ARGIN(STRING
*name
))
388 /* If they're looking to register an existing class, return that
389 class' type number */
390 type
= pmc_type(interp
, name
);
392 if (type
> enum_type_undef
)
395 if (type
< enum_type_undef
) {
397 real_exception(interp
, NULL
, 1,
398 "undefined type already exists - can't register PMC");
400 real_exception(interp
, NULL
, 1,
401 "native type with name '%s' already exists - can't register PMC",
402 data_types
[type
].name
);
405 classname_hash
= interp
->class_hash
;
406 type
= interp
->n_vtable_max
++;
408 /* Have we overflowed the table? */
409 if (type
>= interp
->n_vtable_alloced
)
410 parrot_realloc_vtables(interp
);
412 /* set entry in name->type hash */
413 VTABLE_set_integer_keyed_str(interp
, classname_hash
, name
, type
);
420 =item C<INTVAL pmc_type>
422 Returns the PMC type for C<name>.
429 PARROT_WARN_UNUSED_RESULT
431 pmc_type(PARROT_INTERP
, ARGIN(STRING
*name
))
433 PMC
* const classname_hash
= interp
->class_hash
;
435 (PMC
*)VTABLE_get_pointer_keyed_str(interp
, classname_hash
, name
);
437 /* nested namespace with same name */
438 if (item
->vtable
->base_type
== enum_class_NameSpace
)
441 if (!PMC_IS_NULL(item
))
442 return VTABLE_get_integer(interp
, item
);
444 return Parrot_get_datatype_enum(interp
, name
);
449 =item C<INTVAL pmc_type_p>
451 Returns the PMC type for C<name>.
459 pmc_type_p(PARROT_INTERP
, ARGIN(PMC
*name
))
461 PMC
* const classname_hash
= interp
->class_hash
;
463 (PMC
*)VTABLE_get_pointer_keyed(interp
, classname_hash
, name
);
465 if (!PMC_IS_NULL(item
))
466 return VTABLE_get_integer(interp
, item
);
473 =item C<static PMC* create_class_pmc>
475 Create a class object for this interpreter. Takes an interpreter
476 name and type as arguments. Returns a pointer to the class object.
482 PARROT_WARN_UNUSED_RESULT
483 PARROT_CANNOT_RETURN_NULL
485 create_class_pmc(PARROT_INTERP
, INTVAL type
)
488 * class interface - a PMC is its own class
489 * put an instance of this PMC into class
491 * create a constant PMC
493 PMC
* const _class
= get_new_pmc_header(interp
, type
,
496 /* If we are a second thread, we may get the same object as the
497 * original because we have a singleton. Just set the singleton to
498 * be our class object, but don't mess with its vtable.
500 if ((interp
->vtables
[type
]->flags
& VTABLE_PMC_IS_SINGLETON
)
501 && (_class
== _class
->vtable
->pmc_class
)) {
502 interp
->vtables
[type
]->pmc_class
= _class
;
505 if (PObj_is_PMC_EXT_TEST(_class
))
506 Parrot_free_pmc_ext(interp
, _class
);
508 DOD_flag_CLEAR(is_special_PMC
, _class
);
510 PMC_pmc_val(_class
) = (PMC
*)0xdeadbeef;
511 PMC_struct_val(_class
) = (void *)0xdeadbeef;
513 PObj_is_PMC_shared_CLEAR(_class
);
515 interp
->vtables
[type
]->pmc_class
= _class
;
523 =item C<void Parrot_create_mro>
525 Create the MRO (method resolution order) array for this type.
533 Parrot_create_mro(PARROT_INTERP
, INTVAL type
)
535 STRING
*class_name
, *isa
;
536 INTVAL pos
, parent_type
, total
;
539 VTABLE
*vtable
= interp
->vtables
[type
];
541 /* multithreaded: has already mro */
545 mro
= pmc_new(interp
, enum_class_ResizablePMCArray
);
548 if (vtable
->ro_variant_vtable
)
549 vtable
->ro_variant_vtable
->mro
= mro
;
551 class_name
= vtable
->whoami
;
552 isa
= vtable
->isa_str
;
553 total
= (INTVAL
)string_length(interp
, isa
);
556 INTVAL len
= string_length(interp
, class_name
);
558 parent_type
= pmc_type(interp
, class_name
);
560 /* abstract classes don't have a vtable */
564 vtable
= interp
->vtables
[parent_type
];
566 if (!vtable
->_namespace
) {
567 /* need a namespace Hash, anchor at parent, name it */
568 PMC
* const ns
= pmc_new(interp
,
569 Parrot_get_ctx_HLL_type(interp
, enum_class_NameSpace
));
570 vtable
->_namespace
= ns
;
572 /* anchor at parent, aka current_namespace, that is 'parrot' */
573 VTABLE_set_pmc_keyed_str(interp
,
574 CONTEXT(interp
->ctx
)->current_namespace
, class_name
, ns
);
577 _class
= vtable
->pmc_class
;
579 _class
= create_class_pmc(interp
, parent_type
);
581 VTABLE_push_pmc(interp
, mro
, _class
);
586 len
= string_str_index(interp
, isa
, CONST_STRING(interp
, " "), pos
);
591 class_name
= string_substr(interp
, isa
, pos
, len
- pos
, NULL
, 0);
599 =head2 DOD registry interface
603 =item C<void dod_register_pmc>
605 Registers the PMC with the interpreter's DOD registery.
613 dod_register_pmc(PARROT_INTERP
, ARGIN(PMC
* pmc
))
615 /* Better not trigger a DOD run with a potentially unanchored PMC */
616 Parrot_block_DOD(interp
);
618 if (!interp
->DOD_registry
)
619 interp
->DOD_registry
= pmc_new(interp
, enum_class_AddrRegistry
);
621 VTABLE_set_pmc_keyed(interp
, interp
->DOD_registry
, pmc
, PMCNULL
);
622 Parrot_unblock_DOD(interp
);
627 =item C<void dod_unregister_pmc>
629 Unregisters the PMC from the interpreter's DOD registry.
636 dod_unregister_pmc(PARROT_INTERP
, ARGIN(PMC
* pmc
))
638 /* XXX or signal exception? */
639 if (!interp
->DOD_registry
)
642 VTABLE_delete_keyed(interp
, interp
->DOD_registry
, pmc
);
653 F<include/parrot/vtable.h>.
655 C<5.1.0.14.2.20011008152120.02158148@pop.sidhe.org>
656 (http://www.nntp.perl.org/group/perl.perl6.internals/5516).
660 Initial version by Simon on 2001.10.20.
669 * c-file-style: "parrot"
671 * vim: expandtab shiftwidth=4: