/* Copies to the body of one object to another. */ static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) { KnowHOWREPRBody *src_body = (KnowHOWREPRBody *)src; KnowHOWREPRBody *dest_body = (KnowHOWREPRBody *)dest; UNUSED(st); dest_body->name = src_body->name; dest_body->methods = VTABLE_clone(interp, src_body->methods); dest_body->attributes = VTABLE_clone(interp, src_body->attributes); }
/* Clones the current object. This involves cloning the method and * attribute lists and copying the (immutable string) name. */ static PMC * repr_clone(PARROT_INTERP, PMC *to_clone) { KnowHOWREPRInstance *obj = mem_allocate_zeroed_typed(KnowHOWREPRInstance); obj->common.stable = STABLE_PMC(to_clone); obj->methods = VTABLE_clone(interp, ((KnowHOWREPRInstance *)PMC_data(to_clone))->methods); obj->attributes = VTABLE_clone(interp, ((KnowHOWREPRInstance *)PMC_data(to_clone))->attributes); obj->name = ((KnowHOWREPRInstance *)PMC_data(to_clone))->name; return wrap_object(interp, obj); }
/* Clone. Clone object body and the attribute storage hash. */ static PMC * repr_clone(PARROT_INTERP, PMC *to_clone) { HashAttrStoreInstance *obj; /* Allocate and set up object instance. */ obj = (HashAttrStoreInstance *) Parrot_gc_allocate_fixed_size_storage(interp, sizeof(HashAttrStoreInstance)); obj->common.stable = STABLE_PMC(to_clone); obj->store = VTABLE_clone(interp, ((HashAttrStoreInstance *)PMC_data(to_clone))->store); return wrap_object(interp, obj); }
/* Clones the current object. */ static PMC * repr_clone(PARROT_INTERP, PMC *to_clone) { P6opaqueInstance *obj; P6opaqueREPRData *repr_data = (P6opaqueREPRData *)STABLE(to_clone)->REPR_data; if (defined(interp, to_clone)) { obj = (P6opaqueInstance *)Parrot_gc_allocate_fixed_size_storage(interp, repr_data->allocation_size); memcpy(obj, PMC_data(to_clone), repr_data->allocation_size); if (!PMC_IS_NULL(obj->spill)) obj->spill = VTABLE_clone(interp, obj->spill); } else { obj = mem_allocate_zeroed_typed(P6opaqueInstance); memcpy(obj, PMC_data(to_clone), sizeof(P6opaqueInstance)); } return wrap_object(interp, obj); }
PARROT_CANNOT_RETURN_NULL PMC * Parrot_oo_clone_object(PARROT_INTERP, ARGIN(PMC *pmc), ARGMOD_NULLOK(PMC *dest)) { ASSERT_ARGS(Parrot_oo_clone_object) Parrot_Object_attributes *obj = PARROT_OBJECT(pmc); Parrot_Object_attributes *cloned_guts; Parrot_Class_attributes *_class; PMC *cloned; INTVAL num_classes; INTVAL i, num_attrs; if (!PMC_IS_NULL(dest)) { cloned = dest; } else { cloned = Parrot_pmc_new_noinit(interp, enum_class_Object); } _class = PARROT_CLASS(obj->_class); PARROT_ASSERT(_class); num_classes = VTABLE_elements(interp, _class->all_parents); /* Set custom GC mark and destroy on the object. */ PObj_custom_mark_SET(cloned); PObj_custom_destroy_SET(cloned); /* Flag that it is an object */ PObj_is_object_SET(cloned); /* Now clone attributes list.class. */ cloned_guts = (Parrot_Object_attributes *) PMC_data(cloned); cloned_guts->_class = obj->_class; cloned_guts->attrib_store = VTABLE_clone(interp, obj->attrib_store); num_attrs = VTABLE_elements(interp, cloned_guts->attrib_store); for (i = 0; i < num_attrs; ++i) { PMC * const to_clone = VTABLE_get_pmc_keyed_int(interp, cloned_guts->attrib_store, i); if (!PMC_IS_NULL(to_clone)) { VTABLE_set_pmc_keyed_int(interp, cloned_guts->attrib_store, i, VTABLE_clone(interp, to_clone)); } } /* Some of the attributes may have been the PMCs providing storage for any * PMCs we inherited from; also need to clone those. */ if (CLASS_has_alien_parents_TEST(obj->_class)) { int j; /* Locate any PMC parents. */ for (j = 0; j < num_classes; ++j) { PMC * const cur_class = VTABLE_get_pmc_keyed_int(interp, _class->all_parents, j); if (cur_class->vtable->base_type == enum_class_PMCProxy) { /* Clone this PMC too. */ STRING * const proxy = CONST_STRING(interp, "proxy"); VTABLE_set_attr_keyed(interp, cloned, cur_class, proxy, VTABLE_clone(interp, VTABLE_get_attr_keyed(interp, cloned, cur_class, proxy))); } } } /* And we have ourselves a clone. */ return cloned; }