2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/pmc/object.pmc - An instance of a class
11 Implements an instance of a class.
21 #include "parrot/oo_private.h"
22 #include "pmc/pmc_class.h"
24 /* HEADERIZER HFILE: none */
25 /* HEADERIZER BEGIN: static */
26 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
28 static void cache_method(PARROT_INTERP,
32 __attribute__nonnull__(1)
33 __attribute__nonnull__(2)
34 __attribute__nonnull__(3)
35 __attribute__nonnull__(4);
37 PARROT_WARN_UNUSED_RESULT
38 PARROT_CAN_RETURN_NULL
39 static PMC * find_cached(PARROT_INTERP,
42 __attribute__nonnull__(1)
43 __attribute__nonnull__(2)
44 __attribute__nonnull__(3);
46 PARROT_WARN_UNUSED_RESULT
47 static INTVAL get_attrib_index(PARROT_INTERP,
50 __attribute__nonnull__(1)
51 __attribute__nonnull__(2)
52 __attribute__nonnull__(3);
54 PARROT_WARN_UNUSED_RESULT
55 static INTVAL get_attrib_index_keyed(PARROT_INTERP,
59 __attribute__nonnull__(1)
60 __attribute__nonnull__(2)
61 __attribute__nonnull__(3)
62 __attribute__nonnull__(4);
64 #define ASSERT_ARGS_cache_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
65 PARROT_ASSERT_ARG(interp) \
66 , PARROT_ASSERT_ARG(_class) \
67 , PARROT_ASSERT_ARG(name) \
68 , PARROT_ASSERT_ARG(method))
69 #define ASSERT_ARGS_find_cached __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
70 PARROT_ASSERT_ARG(interp) \
71 , PARROT_ASSERT_ARG(_class) \
72 , PARROT_ASSERT_ARG(name))
73 #define ASSERT_ARGS_get_attrib_index __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
74 PARROT_ASSERT_ARG(interp) \
75 , PARROT_ASSERT_ARG(self) \
76 , PARROT_ASSERT_ARG(name))
77 #define ASSERT_ARGS_get_attrib_index_keyed __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
78 PARROT_ASSERT_ARG(interp) \
79 , PARROT_ASSERT_ARG(self) \
80 , PARROT_ASSERT_ARG(key) \
81 , PARROT_ASSERT_ARG(name))
82 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
83 /* HEADERIZER END: static */
85 /* This finds the index of an attribute in an object's attribute store and
86 * returns it. Returns -1 if the attribute does not exist. */
90 =item C<static INTVAL get_attrib_index(PARROT_INTERP, PMC *self, STRING *name)>
96 PARROT_WARN_UNUSED_RESULT
98 get_attrib_index(PARROT_INTERP, ARGIN(PMC *self), ARGIN(STRING *name))
100 ASSERT_ARGS(get_attrib_index)
101 Parrot_Class_attributes * const _class = PARROT_CLASS(self);
102 const INTVAL cur_hll = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
106 Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), 0);
108 /* First see if we can find it in the cache. */
109 retval = VTABLE_get_integer_keyed_str(interp,
110 _class->attrib_cache, name);
112 /* there's a semi-predicate problem with a retval of 0 */
114 || VTABLE_exists_keyed_str(interp, _class->attrib_cache, name)) {
115 Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
119 /* No hit. We need to walk up the list of parents to try and find the
121 num_classes = VTABLE_elements(interp, _class->all_parents);
123 for (i = 0; i < num_classes; i++) {
124 /* Get the class and its attribute metadata hash. */
125 PMC * const cur_class = VTABLE_get_pmc_keyed_int(interp,
126 _class->all_parents, i);
128 /* Build a string representing the fully qualified attribute name. */
129 STRING *fq_name = VTABLE_get_string(interp, cur_class);
130 fq_name = Parrot_str_concat(interp, fq_name, name);
133 if (VTABLE_exists_keyed_str(interp, _class->attrib_index, fq_name)) {
134 /* Found it. Get value, cache it and we're done. */
135 const INTVAL index = VTABLE_get_integer_keyed_str(interp,
136 _class->attrib_index, fq_name);
137 VTABLE_set_integer_keyed_str(interp, _class->attrib_cache, name,
140 Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
145 Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
151 =item C<static INTVAL get_attrib_index_keyed(PARROT_INTERP, PMC *self, PMC *key,
154 This variation bypasses the cache and finds the index of a particular
155 parent's attribute in an object's attribute store and returns it.
156 Returns C<-1> if the attribute does not exist.
162 PARROT_WARN_UNUSED_RESULT
164 get_attrib_index_keyed(PARROT_INTERP, ARGIN(PMC *self), ARGIN(PMC *key), ARGIN(STRING *name))
166 ASSERT_ARGS(get_attrib_index_keyed)
167 Parrot_Class_attributes * const _class = PARROT_CLASS(self);
168 PMC * const class_cache =
169 VTABLE_get_pmc_keyed_str(interp, _class->attrib_cache,
170 VTABLE_get_string(interp, key));
175 if (!PMC_IS_NULL(class_cache))
176 if (VTABLE_exists_keyed_str(interp, class_cache, name))
177 return VTABLE_get_integer_keyed_str(interp, class_cache, name);
179 /* Build a string representing the fully qualified attribute name. */
180 parent_class = Parrot_oo_get_class(interp, key);
181 fq_name = VTABLE_get_string(interp, parent_class);
182 fq_name = Parrot_str_concat(interp, fq_name, name);
185 if (VTABLE_exists_keyed_str(interp, _class->attrib_index, fq_name)) {
186 /* Found it. Get value and we're done. */
187 const INTVAL index = VTABLE_get_integer_keyed_str(interp,
188 _class->attrib_index, fq_name);
197 =item C<static PMC * find_cached(PARROT_INTERP, PMC *_class, STRING *name)>
203 PARROT_WARN_UNUSED_RESULT
204 PARROT_CAN_RETURN_NULL
206 find_cached(PARROT_INTERP, ARGIN(PMC *_class), ARGIN(STRING *name))
208 ASSERT_ARGS(find_cached)
210 GETATTR_Class_meth_cache(interp, _class, cache);
212 if (PMC_IS_NULL(cache))
215 return VTABLE_get_pmc_keyed_str(interp, cache, name);
220 =item C<static void cache_method(PARROT_INTERP, PMC *_class, STRING *name, PMC
228 cache_method(PARROT_INTERP, ARGIN(PMC *_class), ARGIN(STRING *name),
231 ASSERT_ARGS(cache_method)
233 GETATTR_Class_meth_cache(interp, _class, cache);
235 if (PMC_IS_NULL(cache)) {
236 cache = Parrot_pmc_new(interp, enum_class_Hash);
237 SETATTR_Class_meth_cache(interp, _class, cache);
240 VTABLE_set_pmc_keyed_str(interp, cache, name, method);
243 pmclass Object auto_attrs {
244 ATTR PMC *_class; /* The class this is an instance of. */
245 ATTR PMC *attrib_store; /* The attributes store - a resizable PMC array. */
252 Raises an exception; you can only instantiate objects from a class.
259 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
260 "Object must be created by a class.");
266 =item C<void init_pmc(PMC *class)>
268 Raises an exception; you can only instantiate objects from a class.
274 VTABLE void init_pmc(PMC *worreva) {
275 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
276 "Object must be created by a class.");
282 =item C<void destroy()>
284 Just to avoid the automatic generation of one.
289 VTABLE void destroy() {
295 =item C<STRING *name()>
297 Returns the fully qualified name of the object's class.
303 VTABLE STRING *name() {
304 PMC * const _class = VTABLE_get_class(INTERP, SELF);
305 STRING * const name = CONST_STRING(INTERP, "name");
307 /* If there's a vtable override for 'name' run that instead. */
308 PMC * const method = Parrot_oo_find_vtable_override(INTERP,
311 if (!PMC_IS_NULL(method)) {
312 STRING *result = NULL;
313 Parrot_ext_call(INTERP, method, "Pi->S", SELF, &result);
317 return VTABLE_get_string(INTERP, _class);
325 Mark any referenced strings and PMCs.
331 if (PARROT_OBJECT(SELF)) {
332 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
334 Parrot_gc_mark_PMC_alive(INTERP, obj->_class);
335 Parrot_gc_mark_PMC_alive(INTERP, obj->attrib_store);
342 =item C<PMC *get_attr_str(STRING *name)>
344 Gets the value of an attribute for this object. Will find the first attribute
345 of the given name walking up the inheritance tree.
350 VTABLE PMC *get_attr_str(STRING *name) {
351 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
352 STRING * const get_attr = CONST_STRING(INTERP, "get_attr_str");
356 /* If there's a vtable override for 'get_attr_str' run that first. */
357 PMC * const method = Parrot_oo_find_vtable_override(INTERP,
358 obj->_class, get_attr);
360 if (!PMC_IS_NULL(method)) {
361 PMC *result = PMCNULL;
362 Parrot_ext_call(INTERP, method, "PiS->P", SELF, name, &result);
366 /* Look up the index. */
367 index = get_attrib_index(INTERP, obj->_class, name);
369 /* If lookup failed, exception. */
371 Parrot_ex_throw_from_c_args(INTERP, NULL,
372 EXCEPTION_ATTRIB_NOT_FOUND, "No such attribute '%S'", name);
374 return VTABLE_get_pmc_keyed_int(INTERP, obj->attrib_store, index);
380 =item C<PMC *get_attr_keyed(PMC *key, STRING *name)>
382 Gets the value of an attribute for this object. Will only look for attributes
383 defined in the parent identified by the given key.
388 VTABLE PMC *get_attr_keyed(PMC *key, STRING *name) {
389 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
391 /* Look up the index. */
392 const INTVAL index = get_attrib_index_keyed(INTERP, obj->_class,
395 /* If lookup failed, exception. */
397 Parrot_ex_throw_from_c_args(INTERP, NULL,
398 EXCEPTION_ATTRIB_NOT_FOUND,
399 "No such attribute '%S' in class '%S'", name,
400 VTABLE_get_string(INTERP, key));
402 return VTABLE_get_pmc_keyed_int(INTERP, obj->attrib_store, index);
408 =item C<void set_attr_str(STRING *name, PMC *value)>
410 Sets the value of an attribute for this object. Will set the first attribute
411 of the given name walking up the inheritance tree.
416 VTABLE void set_attr_str(STRING *name, PMC *value) {
417 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
418 STRING * const vtable_meth_name = CONST_STRING(INTERP, "set_attr_str");
421 /* If there's a vtable override for 'set_attr_str' run that first. */
422 PMC * const method = Parrot_oo_find_vtable_override(INTERP,
423 obj->_class, vtable_meth_name);
425 if (!PMC_IS_NULL(method)) {
426 Parrot_ext_call(INTERP, method, "PiSP->", SELF, name, value);
430 index = get_attrib_index(INTERP, obj->_class, name);
432 /* If lookup failed, exception. */
434 Parrot_ex_throw_from_c_args(INTERP, NULL,
435 EXCEPTION_ATTRIB_NOT_FOUND, "No such attribute '%S'", name);
437 VTABLE_set_pmc_keyed_int(INTERP, obj->attrib_store, index, value);
443 =item C<void set_attr_keyed(PMC *key, STRING *name, PMC *value)>
445 Sets the value of an attribute for this object. Will only set attributes
446 defined in the parent identified by the given key.
451 VTABLE void set_attr_keyed(PMC *key, STRING *name, PMC *value) {
452 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
454 get_attrib_index_keyed(INTERP, obj->_class, key, name);
456 /* If lookup failed, exception. */
458 Parrot_ex_throw_from_c_args(INTERP, NULL,
459 EXCEPTION_ATTRIB_NOT_FOUND,
460 "No such attribute '%S' in class '%S'", name,
461 VTABLE_get_string(INTERP, key));
463 VTABLE_set_pmc_keyed_int(INTERP, obj->attrib_store, index, value);
469 =item C<PMC *find_method(STRING *name)>
471 Queries this object's class to find the method with the given name.
476 VTABLE PMC *find_method(STRING *name) {
477 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
478 Parrot_Class_attributes * const _class = PARROT_CLASS(obj->_class);
480 find_cached(INTERP, obj->_class, name);
482 if (!PMC_IS_NULL(method))
485 STRING * const find_method = CONST_STRING(INTERP, "find_method");
486 const int num_classes = VTABLE_elements(INTERP,
487 _class->all_parents);
489 const int all_in_universe =
490 !CLASS_has_alien_parents_TEST(obj->_class);
493 for (i = 0; i < num_classes; i++) {
495 PMC * const cur_class =
496 VTABLE_get_pmc_keyed_int(INTERP, _class->all_parents, i);
498 const Parrot_Class_attributes * const class_info =
499 PARROT_CLASS(cur_class);
501 /* If there's a vtable override for 'find_method' in the
502 * current class, run that first. */
504 method = Parrot_oo_find_vtable_override_for_class(INTERP,
505 cur_class, find_method);
507 if (!PMC_IS_NULL(method)) {
508 PMC *result = PMCNULL;
509 Parrot_ext_call(INTERP, method, "PiS->P", SELF, name, &result);
511 /* break out to the CACHE IF FOUND code */
516 /* If it's from this universe or the class doesn't inherit from
517 * anything outside of it... */
518 if (all_in_universe || VTABLE_isa(INTERP, cur_class, CONST_STRING(INTERP, "Class"))) {
519 method = VTABLE_get_pmc_keyed_str(INTERP,
520 class_info->methods, name);
523 if (!PMC_IS_NULL(method))
527 Parrot_ex_throw_from_c_args(INTERP, NULL, -1,
528 "Class %Ss inherits from alien parents.",
532 if (!PMC_IS_NULL(method))
533 cache_method(INTERP, obj->_class, name, method);
542 =item C<INTVAL get_integer()>
544 Invoke the PIR-defined vtable override, or call the default get_integer.
549 VTABLE INTVAL get_integer() {
550 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
551 Parrot_Class_attributes * const _class = PARROT_CLASS(obj->_class);
552 STRING * const meth_name = CONST_STRING(INTERP, "get_integer");
554 /* Walk and search for the vtable. */
555 const int num_classes = VTABLE_elements(INTERP, _class->all_parents);
558 for (i = 0; i < num_classes; i++) {
560 PMC * const cur_class =
561 VTABLE_get_pmc_keyed_int(INTERP, _class->all_parents, i);
563 PMC * const meth = Parrot_oo_find_vtable_override_for_class(INTERP,
564 cur_class, meth_name);
566 if (!PMC_IS_NULL(meth)) {
568 Parrot_ext_call(INTERP, meth, "Pi->I", SELF, &result);
573 if (cur_class->vtable->base_type == enum_class_PMCProxy) {
574 /* Get the PMC instance and call the vtable function on that. */
575 STRING * const proxy = CONST_STRING(INTERP, "proxy");
576 PMC * const del_object =
577 VTABLE_get_attr_str(INTERP, SELF, proxy);
579 if (!PMC_IS_NULL(del_object))
580 return (INTVAL)VTABLE_get_integer(INTERP, del_object);
583 return INTERP->vtables[enum_class_default]->get_integer(INTERP, SELF);
589 =item C<PMC *get_class()>
591 Get the class PMC representing the class that this object is an instance of.
596 VTABLE PMC *get_class() {
597 return PARROT_OBJECT(SELF)->_class;
603 =item C<PMC *get_namespace()>
605 Get the namespace PMC associated with the class that this object is an instance of.
611 VTABLE PMC *get_namespace() {
612 PMC * const classobj = VTABLE_get_class(INTERP, SELF);
613 STRING * const get_namespace = CONST_STRING(INTERP, "get_namespace");
615 /* If there's a vtable override for 'get_namespace' run that instead */
616 PMC * const method = Parrot_oo_find_vtable_override(INTERP,
617 classobj, get_namespace);
619 if (!PMC_IS_NULL(method)) {
621 Parrot_ext_call(INTERP, method, "Pi->P", SELF, &result);
625 return VTABLE_inspect_str(INTERP, classobj, CONST_STRING(INTERP, "namespace"));
631 =item C<INTVAL can(STRING *method_name)>
633 Returns 0 if the class does not have a method with the given name and a
634 non-zero value if it does.
639 VTABLE INTVAL can(STRING *method_name) {
640 /* Just use find_method and see it if finds anything. */
641 const PMC * const method =
642 VTABLE_find_method(INTERP, SELF, method_name);
643 return !PMC_IS_NULL(method);
649 =item C<INTVAL isa_pmc(PMC *classname)>
651 Returns whether the object's class is or inherits from C<*classname>.
657 VTABLE INTVAL isa_pmc(PMC *lookup) {
658 if (PMC_IS_NULL(lookup))
664 /* Dispatch isa to the object's class */
665 return VTABLE_isa_pmc(INTERP, VTABLE_get_class(INTERP, SELF), lookup);
671 =item C<INTVAL isa(STRING *classname)>
673 Returns whether the class is or inherits from C<*classname>.
679 VTABLE INTVAL isa(STRING *classname) {
680 if (SELF->vtable->whoami == classname
681 || Parrot_str_equal(INTERP, SELF->vtable->whoami, classname))
684 PMC *_class = PARROT_OBJECT(SELF)->_class;
685 return VTABLE_isa(INTERP, _class, classname);
692 =item C<INTVAL does(STRING *role_name)>
694 Returns whether the object's class does the role with name C<*role_name>.
700 VTABLE INTVAL does(STRING *role_name) {
701 /* If it's a null string, return false */
705 PMC * const classobj = VTABLE_get_class(INTERP, SELF);
706 STRING * const meth_name = CONST_STRING(INTERP, "does");
708 PMC * const method = Parrot_oo_find_vtable_override(INTERP,
709 classobj, meth_name);
711 if (!PMC_IS_NULL(method)) {
713 Parrot_ext_call(INTERP, method, "PiS->I", SELF, role_name, &result);
719 /* Check the superclass's vtable interface, if any. */
720 if (SUPER(role_name))
723 /* Dispatch to the object's class */
724 return VTABLE_does(INTERP, VTABLE_get_class(INTERP, SELF), role_name);
730 =item C<INTVAL does_pmc(PMC *role)>
732 Returns whether the object's class does C<*role>.
738 VTABLE INTVAL does_pmc(PMC *role) {
739 if (PMC_IS_NULL(role))
745 /* Dispatch to the object's class */
746 return VTABLE_does_pmc(INTERP, VTABLE_get_class(INTERP, SELF), role);
752 =item C<opcode_t *invoke(void *next)>
754 Invokes the object (if this vtable function is overridden).
760 opcode_t * invoke(void *next) {
761 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
762 Parrot_Class_attributes * const _class = PARROT_CLASS(obj->_class);
764 /* Walk and search for the vtable. */
765 const int num_classes = VTABLE_elements(INTERP, _class->all_parents);
768 for (i = 0; i < num_classes; i++) {
770 STRING * const meth_name = CONST_STRING(INTERP, "invoke");
771 STRING * const proxy = CONST_STRING(INTERP, "proxy");
772 PMC * const cur_class =
773 VTABLE_get_pmc_keyed_int(INTERP, _class->all_parents, i);
776 Parrot_oo_find_vtable_override_for_class(INTERP, cur_class,
778 if (!PMC_IS_NULL(meth)) {
779 /* Experimental code. See DEPRECATED.pod */
781 Parrot_pcc_get_signature(INTERP, CURRENT_CONTEXT(INTERP));
783 if ((VTABLE_elements(INTERP, call_sig) == 0
784 || VTABLE_get_pmc_keyed_int(INTERP, call_sig, 0) != SELF))
785 VTABLE_unshift_pmc(INTERP, call_sig, SELF);
787 return VTABLE_invoke(INTERP, meth, next);
790 if (cur_class->vtable->base_type == enum_class_PMCProxy) {
791 /* Get the PMC instance and call the vtable function on that. */
792 PMC * const del_object =
793 VTABLE_get_attr_keyed(INTERP, SELF, cur_class, proxy);
795 if (!PMC_IS_NULL(del_object))
796 return VTABLE_invoke(INTERP, del_object, next);
800 return (opcode_t *)INTERP->vtables[enum_class_default]->invoke(INTERP, SELF, next);
806 =item C<INTVAL type()>
808 Returns the integer type of the object's class.
814 VTABLE INTVAL type() {
815 PMC * const _class = VTABLE_get_class(INTERP, SELF);
816 return VTABLE_type(INTERP, _class);
822 =item C<PMC * clone()>
824 Creates a clone of the object.
830 VTABLE PMC * clone() {
831 Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
832 /* If we have a custom override, invoke it.
833 * If not, use the oo function. */
834 STRING * const meth_name = CONST_STRING(INTERP, "clone");
836 Parrot_oo_find_vtable_override(INTERP, obj->_class, meth_name);
838 if (!PMC_IS_NULL(meth)) {
840 Parrot_ext_call(INTERP, meth, "Pi->P", SELF, &result);
844 return Parrot_oo_clone_object(INTERP, SELF, NULL);
850 =item C<void visit(PMC *info)>
852 This is used by freeze/thaw to visit the contents of the object.
854 C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
860 VTABLE void visit(PMC *info) {
861 Parrot_Object_attributes * const obj_data = PARROT_OBJECT(SELF);
864 VISIT_PMC(INTERP, info, obj_data->_class);
866 /* 2) visit the attributes */
867 VISIT_PMC(INTERP, info, obj_data->attrib_store);
873 =item C<void freeze(PMC *info)>
875 =item C<void thaw(PMC *info)>
877 Realias magically generated methods so they don't wreak havoc.
883 VTABLE void freeze(PMC *info) {
886 VTABLE void thaw(PMC *info) {
892 =item C<void thawfinish(PMC *info)>
894 Called after the object has been thawed.
900 VTABLE void thawfinish(PMC *info) {
901 /* Set custom GC mark and destroy on the object. */
902 PObj_custom_mark_SET(SELF);
903 PObj_custom_destroy_SET(SELF);
905 /* Flag that it is an object */
906 PObj_is_object_SET(SELF);
912 =item C<PMC * share_ro()>
914 Used to mark a PMC as read-only shared.
919 VTABLE PMC *share_ro() {
920 PMC *ret, *_true, *data;
923 Parrot_Interp master;
926 if (PObj_is_PMC_shared_TEST(SELF))
929 master = interpreter_array[0];
930 classobj = VTABLE_get_class(INTERP, SELF);
931 type_num = SELF->vtable->base_type;
933 /* make sure metadata doesn't go away unexpectedly */
934 if (PMC_metadata(SELF))
935 PMC_metadata(SELF) = pt_shared_fixup(INTERP, PMC_metadata(SELF));
937 PARROT_ASSERT(master->vtables[type_num]->pmc_class);
938 /* don't want the referenced class disappearing on us */
939 LOCK_INTERPRETER(master);
940 SELF->vtable->pmc_class = master->vtables[type_num]->pmc_class;
941 UNLOCK_INTERPRETER(master);
944 /* Setting the '_ro' property switches to the read-only vtable */
945 _true = Parrot_pmc_new_init_int(INTERP, enum_class_Integer, 1);
946 VTABLE_setprop(INTERP, ret, CONST_STRING(INTERP, "_ro"), _true);
948 SELF->vtable->pmc_class = master->vtables[type_num]->pmc_class;
949 PObj_is_PMC_shared_SET(ret);
951 data = PARROT_CLASS(classobj)->parents;
952 n = VTABLE_elements(INTERP, data);
954 for (i = 0; i < n; ++i) {
955 PMC * const cur_class = VTABLE_get_pmc_keyed_int(INTERP, data, i);
956 VTABLE_set_pmc_keyed_int(INTERP, data, i, VTABLE_share_ro(INTERP, cur_class));
959 /* XXX This is perhaps not the best way to fix this up, but we
960 * need to ensure that the class object won't go away when
961 * this interpreter dies.
963 PARROT_ASSERT(ret->vtable->pmc_class);
964 PARROT_ASSERT(ret->vtable->share_ro == Parrot_Object_share_ro);
972 =item C<void morph(PMC* type)>
974 Changes the PMC to a PMC of a new type
980 VTABLE void morph(PMC* type) {
981 PMC * const classobj = VTABLE_get_class(INTERP, SELF);
982 STRING * const meth_name = CONST_STRING(INTERP, "morph");
983 /* If there's a vtable override for 'morph' run that instead. */
985 Parrot_oo_find_vtable_override(INTERP, classobj, meth_name);
987 if (!PMC_IS_NULL(method))
988 Parrot_ext_call(INTERP, method, "PiP->", SELF, type);
1000 F<docs/pdds/pdd15_objects.pod>.
1008 * c-file-style: "parrot"
1010 * vim: expandtab shiftwidth=4: