@@ -74,18 +74,27 @@ struct Dee_serial_type {
7474 (DCALL * set_addr2mem )(DeeSerial * __restrict self , Dee_seraddr_t addr );
7575
7676 /* Allocate generic heap memory (as per "Dee_Malloc()")
77+ * @param: ref: When non-NULL, a reference pointer describing where data originates from.
78+ * This should **ONLY** be given when serializing "[owned][const]" fields of
79+ * a containing object (e.g. "DeeClassDescriptorObject::cd_clsop_list"), but
80+ * **MUST** be "NULL" when serializing "[owned][lock(...)]" fields (e.g.
81+ * "DeeListObject::l_list::ol_elemv").
82+ * The reason why this is needed is to allow later "DeeSerial_PutPointer()"
83+ * calls to connect the dots and understand that a given pointer actually
84+ * points into a block previously returned by `DeeSerial_Malloc()', similar
85+ * to how it can do so for `DeeSerial_ObjectMalloc()'
7786 * @return: * : Serialized address of heap buffer
7887 * @return: Dee_SERADDR_INVALID: Allocation failed (for "set_malloc" and "set_calloc": error was thrown) */
79- WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_malloc )(DeeSerial * __restrict self , size_t num_bytes );
80- WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_calloc )(DeeSerial * __restrict self , size_t num_bytes );
81- WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_trymalloc )(DeeSerial * __restrict self , size_t num_bytes );
82- WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_trycalloc )(DeeSerial * __restrict self , size_t num_bytes );
88+ WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_malloc )(DeeSerial * __restrict self , size_t num_bytes , /*0..1*/ void * ref );
89+ WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_calloc )(DeeSerial * __restrict self , size_t num_bytes , /*0..1*/ void * ref );
90+ WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_trymalloc )(DeeSerial * __restrict self , size_t num_bytes , /*0..1*/ void * ref );
91+ WUNUSED_T NONNULL_T ((1 )) Dee_seraddr_t (DCALL * set_trycalloc )(DeeSerial * __restrict self , size_t num_bytes , /*0..1*/ void * ref );
8392
8493 /* Free generic heap memory (as per "Dee_Free()")
8594 * Only allowed to be called for the most-recent non-Dee_SERADDR_INVALID
8695 * return value of one of the allocation functions above. Behavior is hard
8796 * undefined if you try to free a buffer that isn't the most recent one. */
88- NONNULL_T ((1 )) void (DCALL * set_free )(DeeSerial * __restrict self , Dee_seraddr_t addr );
97+ NONNULL_T ((1 )) void (DCALL * set_free )(DeeSerial * __restrict self , Dee_seraddr_t addr , /*0..1*/ void * ref );
8998
9099 /* Allocate generic object heap memory (as per "DeeObject_Malloc()")
91100 * These functions will have automatically pre-initialized:
@@ -100,7 +109,7 @@ struct Dee_serial_type {
100109
101110 /* Free generic heap memory (as per "DeeObject_Free()")
102111 * Same restrictions of `set_free' regarding order of free() operations also apply to this */
103- NONNULL_T ((1 )) void (DCALL * set_object_free )(DeeSerial * __restrict self , Dee_seraddr_t addr );
112+ NONNULL_T ((1 , 3 )) void (DCALL * set_object_free )(DeeSerial * __restrict self , Dee_seraddr_t addr , DeeObject * __restrict ref );
104113
105114 /* Same as above, but must be used for GC-objects (as per "DeeGCObject_Malloc()") */
106115 WUNUSED_T NONNULL_T ((1 , 3 )) Dee_seraddr_t (DCALL * set_gcobject_malloc )(DeeSerial * __restrict self , size_t num_bytes , DeeObject * __restrict ref );
@@ -109,7 +118,7 @@ struct Dee_serial_type {
109118 WUNUSED_T NONNULL_T ((1 , 3 )) Dee_seraddr_t (DCALL * set_gcobject_trycalloc )(DeeSerial * __restrict self , size_t num_bytes , DeeObject * __restrict ref );
110119
111120 /* Free generic heap memory (as per "DeeGCObject_Free()") */
112- NONNULL_T ((1 )) void (DCALL * set_gcobject_free )(DeeSerial * __restrict self , Dee_seraddr_t addr );
121+ NONNULL_T ((1 , 3 )) void (DCALL * set_gcobject_free )(DeeSerial * __restrict self , Dee_seraddr_t addr , DeeObject * __restrict ref );
113122
114123 /* Serialize a `void *' field at `addrof_pointer' as being populated with the
115124 * effectively final value of `DeeSerial_Addr2Mem(self, addrof_target, void)'
@@ -166,12 +175,25 @@ struct Dee_serial {
166175 ((T *)(*(self)->ser_type->set_addr2mem)(self, addr))
167176
168177/* Allocate generic heap memory (as per "Dee_Malloc()")
178+ * @param: ref: When non-NULL, a reference pointer describing where data originates from.
179+ * This should **ONLY** be given when serializing "[owned][const]" fields of
180+ * a containing object (e.g. "DeeClassDescriptorObject::cd_clsop_list"), but
181+ * **MUST** be "NULL" when serializing "[owned][lock(...)]" fields (e.g.
182+ * "DeeListObject::l_list::ol_elemv").
183+ * The reason why this is needed is to allow later "DeeSerial_PutPointer()"
184+ * calls to connect the dots and understand that a given pointer actually
185+ * points into a block previously returned by `DeeSerial_Malloc()', similar
186+ * to how it can do so for `DeeSerial_ObjectMalloc()'
187+ * TLDR:
188+ * - If you use "DeeSerial_TryMalloc()" because of a lock, you probably want to pass "NULL"
189+ * - Otherwise, pass the [const] source pointer
190+ *
169191 * @return: * : Serialized address of heap buffer
170192 * @return: Dee_SERADDR_INVALID: Allocation failed (for "DeeSerial_Malloc" and "DeeSerial_Calloc": error was thrown) */
171- #define DeeSerial_Malloc (self , num_bytes ) (*(self)->ser_type->set_malloc)(self, num_bytes)
172- #define DeeSerial_Calloc (self , num_bytes ) (*(self)->ser_type->set_calloc)(self, num_bytes)
173- #define DeeSerial_TryMalloc (self , num_bytes ) (*(self)->ser_type->set_trymalloc)(self, num_bytes)
174- #define DeeSerial_TryCalloc (self , num_bytes ) (*(self)->ser_type->set_trycalloc)(self, num_bytes)
193+ #define DeeSerial_Malloc (self , num_bytes , ref ) (*(self)->ser_type->set_malloc)(self, num_bytes, ref )
194+ #define DeeSerial_Calloc (self , num_bytes , ref ) (*(self)->ser_type->set_calloc)(self, num_bytes, ref )
195+ #define DeeSerial_TryMalloc (self , num_bytes , ref ) (*(self)->ser_type->set_trymalloc)(self, num_bytes, ref )
196+ #define DeeSerial_TryCalloc (self , num_bytes , ref ) (*(self)->ser_type->set_trycalloc)(self, num_bytes, ref )
175197
176198/* Free generic heap memory (as per "Dee_Free()")
177199 * Only allowed to be called for the most-recent non-Dee_SERADDR_INVALID
@@ -180,7 +202,7 @@ struct Dee_serial {
180202 *
181203 * NOTE: DON'T call this method for error-cleanup -- On error, the
182204 * owner of the serializer will free all allocated memory! */
183- #define DeeSerial_Free (self , addr ) (*(self)->ser_type->set_free)(self, addr)
205+ #define DeeSerial_Free (self , addr , ref ) (*(self)->ser_type->set_free)(self, addr, ref )
184206
185207/* Allocate generic object heap memory (as per "DeeObject_Malloc()")
186208 * These functions will have automatically pre-initialized:
@@ -198,7 +220,7 @@ struct Dee_serial {
198220 *
199221 * NOTE: DON'T call this method for error-cleanup -- On error, the
200222 * owner of the serializer will free all allocated memory! */
201- #define DeeSerial_ObjectFree (self , addr ) (*(self)->ser_type->set_object_free)(self, addr)
223+ #define DeeSerial_ObjectFree (self , addr , ref ) (*(self)->ser_type->set_object_free)(self, addr, ref )
202224
203225/* Same as above, but must be used for GC-objects (as per "DeeGCObject_Malloc()") */
204226#define DeeSerial_GCObjectMalloc (self , num_bytes , ref ) (*(self)->ser_type->set_gcobject_malloc)(self, num_bytes, Dee_AsObject(ref))
@@ -210,7 +232,7 @@ struct Dee_serial {
210232 *
211233 * NOTE: DON'T call this method for error-cleanup -- On error, the
212234 * owner of the serializer will free all allocated memory! */
213- #define DeeSerial_GCObjectFree (self , addr ) (*(self)->ser_type->set_gcobject_free)(self, addr)
235+ #define DeeSerial_GCObjectFree (self , addr , ref ) (*(self)->ser_type->set_gcobject_free)(self, addr, ref )
214236
215237
216238/* Serialize a `void *' field at `addrof_pointer' as being populated with the
0 commit comments