summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter <peter@pmikkelsen.com>2026-09-01 21:14:43 +0000
committerpeter <peter@pmikkelsen.com>2026-09-01 21:14:43 +0000
commit047b642464442b290ea04f5d07bb3ce57a59fdb8 (patch)
tree378521ffc2d19fa18ed66c46128d2b0628001c78
parent26c3da82eb6f33cce64d218e97e2d44324fb9721 (diff)
Put all the code which visits pointers in memory.c behind a macro, so it can easily be reused.memory-manager
FossilOrigin-Name: 1e911fa0ea41797f445fff6f25df36b6c0f07063b5c6e9936cb243294a2d8a0c
-rw-r--r--src/lib/memory.c177
1 files changed, 56 insertions, 121 deletions
diff --git a/src/lib/memory.c b/src/lib/memory.c
index e95afc5..a53a37e 100644
--- a/src/lib/memory.c
+++ b/src/lib/memory.c
@@ -47,17 +47,49 @@ data(struct chunk *c)
return p + HEADER_SIZE;
}
-static void
-fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old)
-{
-#define FIX(ptr) do{ \
- if(ptr){ \
- (ptr) = (void*)(((uint8_t*)(ptr))+add); \
- (ptr) = (void*)(((uint8_t*)(ptr))-sub); \
+#define VISIT_FIELD(X, tag, ptr) X(((struct tag *)data(c))->ptr)
+#define VISIT_CHUNK_PTRS(X, c) switch(c->tag){ \
+ case CHUNK_TAG_APLWC_LINE: \
+ VISIT_FIELD(X, aplwc_line, text); \
+ VISIT_FIELD(X, aplwc_line, tokens); \
+ break; \
+ case CHUNK_TAG_STRING: \
+ break; \
+ case CHUNK_TAG_TOKEN_LIST: \
+ VISIT_FIELD(X, token_list, text); \
+ break; \
+ case CHUNK_TAG_APLWC_VALUE: \
+ break; \
+ case CHUNK_TAG_APLWC_MODULE: \
+ VISIT_FIELD(X, aplwc_module, name); \
+ VISIT_FIELD(X, aplwc_module, tokens); \
+ VISIT_FIELD(X, aplwc_module, link); \
+ break; \
+ case CHUNK_TAG_FREE: \
+ break; \
+ }
+#define VISIT_ROOT_PTRS(X) do{ \
+ X(aplwc->modules); \
+ for(frame = aplwc->memptrs; frame; frame = frame->link) \
+ for(i = 0; i < frame->count; i++) \
+ if(frame->ptrs[i]) \
+ X(*frame->ptrs[i]); \
+ for(root = aplwc->rootptrs; root; root = root->link) \
+ if(root->ptr) \
+ X(root->ptr); \
+}while(0)
+
+#define VISIT_ALL_PTRS(X, data) do{ \
+ VISIT_ROOT_PTRS(X); \
+ for(c = (struct chunk *)(data); c; c = c->next){ \
+ X(c->next); \
+ VISIT_CHUNK_PTRS(X, c); \
} \
}while(0)
-#define FIX_DATA(type, ptr) FIX(((type *)data(c))->ptr)
+static void
+fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old)
+{
struct chunk *c;
struct memory_ptr_frame *frame;
@@ -72,44 +104,14 @@ fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old)
sub = old-new;
}
- FIX(aplwc->modules);
-
- for(c = (struct chunk *)new; c; c = c->next){
- FIX(c->next);
-
- switch(c->tag){
- case CHUNK_TAG_APLWC_LINE:
- FIX_DATA(struct aplwc_line, text);
- FIX_DATA(struct aplwc_line, tokens);
- break;
- case CHUNK_TAG_STRING:
- break;
- case CHUNK_TAG_TOKEN_LIST:
- FIX_DATA(struct token_list, text);
- break;
- case CHUNK_TAG_APLWC_VALUE:
- break;
- case CHUNK_TAG_APLWC_MODULE:
- FIX_DATA(struct aplwc_module, name);
- FIX_DATA(struct aplwc_module, tokens);
- FIX_DATA(struct aplwc_module, link);
- break;
- case CHUNK_TAG_FREE:
- break;
- }
- }
-
- for(frame = aplwc->memptrs; frame; frame = frame->link)
- for(i = 0; i < frame->count; i++)
- if(frame->ptrs[i])
- FIX(*frame->ptrs[i]);
-
- for(root = aplwc->rootptrs; root; root = root->link)
- if(root->ptr)
- FIX(root->ptr);
-
+#define FIX(ptr) do{ \
+ if(ptr){ \
+ (ptr) = (void*)(((uint8_t*)(ptr))+add); \
+ (ptr) = (void*)(((uint8_t*)(ptr))-sub); \
+ } \
+}while(0)
+ VISIT_ALL_PTRS(FIX, new);
#undef FIX
-#undef FIX_DATA
}
static enum aplwc_rc
@@ -239,40 +241,12 @@ collect(struct aplwc *aplwc)
/* Mark reachable chunks */
stack = NULL;
- push(aplwc, &stack, aplwc->modules);
-
- for(frame = aplwc->memptrs; frame; frame = frame->link)
- for(i = 0; i < frame->count; i++)
- if(frame->ptrs[i])
- push(aplwc, &stack, *frame->ptrs[i]);
-
- for(root = aplwc->rootptrs; root; root = root->link)
- if(root->ptr)
- push(aplwc, &stack, root->ptr);
+#define PUSH(ptr) push(aplwc, &stack, ptr)
+ VISIT_ROOT_PTRS(PUSH);
while(stack){
c = pop(&stack);
-#define PUSH(type, ptr) push(aplwc, &stack, ((type *)data(c))->ptr)
- switch(c->tag){
- case CHUNK_TAG_APLWC_LINE:
- PUSH(struct aplwc_line, text);
- PUSH(struct aplwc_line, tokens);
- break;
- case CHUNK_TAG_STRING:
- break;
- case CHUNK_TAG_TOKEN_LIST:
- PUSH(struct token_list, text);
- break;
- case CHUNK_TAG_APLWC_VALUE:
- break;
- case CHUNK_TAG_APLWC_MODULE:
- PUSH(struct aplwc_module, name);
- PUSH(struct aplwc_module, tokens);
- PUSH(struct aplwc_module, link);
- break;
- case CHUNK_TAG_FREE:
- break;
- }
+ VISIT_CHUNK_PTRS(PUSH, c);
#undef PUSH
}
@@ -286,56 +260,17 @@ collect(struct aplwc *aplwc)
static void
swapptr(struct aplwc *aplwc, void *old, void *new)
{
-#define SWAP(ptr) do{ \
- if((ptr) == old) \
- (ptr) = new; \
-}while(0)
-
-#define SWAP_DATA(type, ptr) SWAP(((type *)data(c))->ptr)
-
struct chunk *c;
struct memory_ptr_frame *frame;
struct root_ptr *root;
size_t i;
- SWAP(aplwc->modules);
-
- for(c = (struct chunk *)new; c; c = c->next){
- SWAP(c->next);
-
- switch(c->tag){
- case CHUNK_TAG_APLWC_LINE:
- SWAP_DATA(struct aplwc_line, text);
- SWAP_DATA(struct aplwc_line, tokens);
- break;
- case CHUNK_TAG_STRING:
- break;
- case CHUNK_TAG_TOKEN_LIST:
- SWAP_DATA(struct token_list, text);
- break;
- case CHUNK_TAG_APLWC_VALUE:
- break;
- case CHUNK_TAG_APLWC_MODULE:
- SWAP_DATA(struct aplwc_module, name);
- SWAP_DATA(struct aplwc_module, tokens);
- SWAP_DATA(struct aplwc_module, link);
- break;
- case CHUNK_TAG_FREE:
- break;
- }
- }
-
- for(frame = aplwc->memptrs; frame; frame = frame->link)
- for(i = 0; i < frame->count; i++)
- if(frame->ptrs[i])
- SWAP(*frame->ptrs[i]);
-
- for(root = aplwc->rootptrs; root; root = root->link)
- if(root->ptr)
- SWAP(root->ptr);
-
-#undef SWAP
-#undef SWAP_DATA
+#define SWAP(ptr) do{ \
+ if((ptr) == old) \
+ (ptr) = new; \
+}while(0)
+ VISIT_ALL_PTRS(SWAP, new);
+#undef SWAP
}
static void