| 1 | [core] ManagedStruct needs ATTRs for free(void*) and clone(void*) function pointers. |
|---|
| 2 | |
|---|
| 3 | From: Mark Glines <mark@glines.org> |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | --- |
|---|
| 7 | |
|---|
| 8 | src/pmc/managedstruct.pmc | 34 +++++++++++++++++++++++++++++++--- |
|---|
| 9 | 1 files changed, 31 insertions(+), 3 deletions(-) |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | diff --git a/src/pmc/managedstruct.pmc b/src/pmc/managedstruct.pmc |
|---|
| 13 | index 36fe392..5221ea7 100644 |
|---|
| 14 | --- a/src/pmc/managedstruct.pmc |
|---|
| 15 | +++ b/src/pmc/managedstruct.pmc |
|---|
| 16 | @@ -21,8 +21,21 @@ C<struct> values that Parrot is responsible for disposing of. |
|---|
| 17 | |
|---|
| 18 | #include "parrot/parrot.h" |
|---|
| 19 | |
|---|
| 20 | +typedef void (*custom_free_func_t)(PARROT_INTERP, void *ptr, void *priv); |
|---|
| 21 | +typedef PMC * (*custom_clone_func_t)(PARROT_INTERP, PMC *ptr, void *priv); |
|---|
| 22 | |
|---|
| 23 | pmclass ManagedStruct extends UnManagedStruct need_ext { |
|---|
| 24 | + /* if custom_free_func and ptr (inherited from UnManagedStruct) are both set, |
|---|
| 25 | + * custom_free_func is called before the normal destroy() function does any |
|---|
| 26 | + * work. |
|---|
| 27 | + */ |
|---|
| 28 | + ATTR void *custom_free_func; |
|---|
| 29 | + ATTR void *custom_free_priv; |
|---|
| 30 | + /* if custom_clone_func is set, it will be called *instead* of the normal |
|---|
| 31 | + * clone() function logic. |
|---|
| 32 | + */ |
|---|
| 33 | + ATTR void *custom_clone_func; |
|---|
| 34 | + ATTR void *custom_clone_priv; |
|---|
| 35 | |
|---|
| 36 | /* |
|---|
| 37 | |
|---|
| 38 | @@ -68,8 +81,16 @@ Destroys the struct, freeing the allocated memory. |
|---|
| 39 | */ |
|---|
| 40 | |
|---|
| 41 | VTABLE void destroy() { |
|---|
| 42 | - if (PARROT_MANAGEDSTRUCT(SELF)->ptr) |
|---|
| 43 | - mem_sys_free(PARROT_MANAGEDSTRUCT(SELF)->ptr); |
|---|
| 44 | + void *ptr = PARROT_MANAGEDSTRUCT(SELF)->ptr; |
|---|
| 45 | + if (ptr) { |
|---|
| 46 | + custom_free_func_t free_func = |
|---|
| 47 | + (custom_free_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_free_func; |
|---|
| 48 | + if (free_func) { |
|---|
| 49 | + void *free_data = PARROT_MANAGEDSTRUCT(SELF)->custom_free_priv; |
|---|
| 50 | + free_func(interp, ptr, free_data); |
|---|
| 51 | + } else |
|---|
| 52 | + mem_sys_free(ptr); |
|---|
| 53 | + } |
|---|
| 54 | mem_sys_free(PMC_data(SELF)); |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | @@ -118,7 +139,14 @@ how to clone I<that> data. |
|---|
| 58 | */ |
|---|
| 59 | |
|---|
| 60 | VTABLE PMC *clone() { |
|---|
| 61 | - PMC *dest = pmc_new_init(interp, SELF->vtable->base_type, |
|---|
| 62 | + custom_clone_func_t clone_func = |
|---|
| 63 | + (custom_clone_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_clone_func; |
|---|
| 64 | + PMC *dest; |
|---|
| 65 | + if (clone_func) { |
|---|
| 66 | + void *clone_data = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_priv; |
|---|
| 67 | + return clone_func(interp, SELF, clone_data); |
|---|
| 68 | + } |
|---|
| 69 | + dest = pmc_new_init(interp, SELF->vtable->base_type, |
|---|
| 70 | PARROT_MANAGEDSTRUCT(SELF)->init); |
|---|
| 71 | |
|---|
| 72 | if (PARROT_MANAGEDSTRUCT(SELF)->ptr) |
|---|