Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: RELEASE_2_11_0
Fetching contributors…

Cannot retrieve contributors at this time

183 lines (126 sloc) 4.193 kb
/*
Copyright (C) 2001-2009, Parrot Foundation.
=head1 DESCRIPTION
src/pmc/managedstruct.pmc - Memory-managed C struct
=head1 DESCRIPTION
C<ManagedStruct> extends C<UnManagedStruct> to provide a class to hold C
C<struct> values that Parrot is responsible for disposing of.
=head2 Methods
=over 4
=cut
*/
typedef void (*custom_free_func_t)(PARROT_INTERP, void *ptr, void *priv);
typedef PMC * (*custom_clone_func_t)(PARROT_INTERP, PMC *ptr, void *priv);
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass ManagedStruct extends UnManagedStruct auto_attrs {
/* if custom_free_func and ptr (inherited from UnManagedStruct) are both set,
* custom_free_func is called before the normal destroy() function does any
* work.
*/
ATTR void (*custom_free_func)(PARROT_INTERP, void *, void *);
ATTR void *custom_free_priv;
/* if custom_clone_func is set, it will be called *instead* of the normal
* clone() function logic.
*/
ATTR PMC * (*custom_clone_func)(PARROT_INTERP, PMC *ptr, void *priv);
ATTR void *custom_clone_priv;
/*
=item C<void init()>
Initializes an empty struct.
=cut
*/
VTABLE void init() {
PObj_custom_destroy_SET(SELF);
}
/*
=item C<void init_pmc(PMC *value)>
Initializes the struct with C<*value>.
=cut
*/
VTABLE void init_pmc(PMC *value) {
SELF.init();
SELF.set_pmc(value);
}
/*
=item C<void destroy()>
Destroys the struct, freeing the allocated memory.
If the "custom_free_func" attribute is set, it is called to free the pointer.
Otherwise, mem_gc_free() is used.
=cut
*/
VTABLE void destroy() {
void *ptr = PARROT_MANAGEDSTRUCT(SELF)->ptr;
if (ptr) {
custom_free_func_t free_func = PARROT_MANAGEDSTRUCT(SELF)->custom_free_func;
if (free_func) {
void *free_data = PARROT_MANAGEDSTRUCT(SELF)->custom_free_priv;
free_func(INTERP, ptr, free_data);
} else
mem_gc_free(INTERP, ptr);
}
}
/*
=item C<void set_integer_native(INTVAL value)>
(Re)allocates C<value> bytes for the struct.
=cut
*/
VTABLE void set_integer_native(INTVAL value) {
Parrot_ManagedStruct_attributes * attrs = PARROT_MANAGEDSTRUCT(SELF);
if (attrs->ptr && !value) {
mem_gc_free(INTERP, attrs->ptr);
attrs->ptr = NULL;
attrs->size = 0;
}
else if (value && !attrs->ptr) {
attrs->ptr = Parrot_gc_allocate_memory_chunk_with_interior_pointers(
INTERP, (size_t)value);
attrs->size = value;
}
else if (value && attrs->ptr) {
if (attrs->size != value) {
attrs->ptr =
Parrot_gc_reallocate_memory_chunk_with_interior_pointers(INTERP,
attrs->ptr, (size_t)value, attrs->size);
attrs->size = value;
}
}
return;
}
/*
=item C<PMC * clone()>
Creates a clone of this PMC; clones any unmanaged memory it holds too.
If the "custom_clone_func" attribute is set, it is called to clone the PMC.
Otherwise, a basic (shallow copy) clone is performed, as there's no general way
of knowing how to make a deep copy of the pointer contents.
=cut
*/
VTABLE PMC *clone() {
custom_clone_func_t clone_func = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_func;
PMC *dest;
if (clone_func) {
void *clone_data = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_priv;
return clone_func(INTERP, SELF, clone_data);
}
dest = Parrot_pmc_new_init(INTERP, SELF->vtable->base_type,
PARROT_MANAGEDSTRUCT(SELF)->init);
if (PARROT_MANAGEDSTRUCT(SELF)->ptr)
memmove(PARROT_MANAGEDSTRUCT(dest)->ptr,
PARROT_MANAGEDSTRUCT(SELF)->ptr,
PARROT_MANAGEDSTRUCT(SELF)->size);
return dest;
}
}
/*
=back
=head1 HISTORY
Initial revision by sean 2002/08/04.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
Jump to Line
Something went wrong with that request. Please try again.