Ticket #18: 02_managedstruct-free_func-attr.patch.txt

File 02_managedstruct-free_func-attr.patch.txt, 2.4 KB (added by Infinoid, 13 years ago)

Implement custom free and clone callback functions (and opaque private pointer arguments).

Line 
1[core] ManagedStruct needs ATTRs for free(void*) and clone(void*) function pointers.
2
3From: 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
12diff --git a/src/pmc/managedstruct.pmc b/src/pmc/managedstruct.pmc
13index 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)