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) |
---|