diff options
| author | peter <peter@pmikkelsen.com> | 2026-09-03 19:31:52 +0000 |
|---|---|---|
| committer | peter <peter@pmikkelsen.com> | 2026-09-03 19:31:52 +0000 |
| commit | fa6a3ee5b24d5e227798330cff5f9ff060d6d863 (patch) | |
| tree | b251207d74ae183b0e0bb155e4e0f9f86334c3d3 /src | |
| parent | 84dd0d9fa985c1c740b3145c6b0d858cca978911 (diff) | |
Don't dynamically allocate external reference counted pointers, just use what the user puts on the stack.
FossilOrigin-Name: 270cf0d72050bea15fc40a1e2811ba642e3ef26cbe1fa6231c5aa6f1872ccb34
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/main.c | 26 | ||||
| -rw-r--r-- | src/include/aplwc.h | 17 | ||||
| -rw-r--r-- | src/lib/aplwc_internal.h | 16 | ||||
| -rw-r--r-- | src/lib/main.c | 44 | ||||
| -rw-r--r-- | src/lib/memory.c | 84 |
5 files changed, 74 insertions, 113 deletions
diff --git a/src/bin/main.c b/src/bin/main.c index 00fd88b..516fb51 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -145,10 +145,10 @@ file_size: for(;;){ if(input) free(input); - if(aplwc_valid_line(line)) - aplwc_free_line(line); - if(aplwc_valid_value(value)) - aplwc_free_value(value); + if(aplwc_valid_line(&line)) + aplwc_free_line(&line); + if(aplwc_valid_value(&value)) + aplwc_free_value(&value); input = NULL; if(getline(&input, &input_size, stdin) < 0){ @@ -157,8 +157,8 @@ file_size: break; }else{ line_number++; - line = aplwc_read(aplwc, input); - if(!aplwc_valid_line(line)){ + aplwc_read(aplwc, input, &line); + if(!aplwc_valid_line(&line)){ line_error: fprintf(stderr, "error on line %d: %s: %s\n", line_number, aplwc_errstr(aplwc), input); if(input_file){ @@ -167,20 +167,20 @@ line_error: } continue; } - value = aplwc_eval(line); - if(!aplwc_valid_value(value)) + aplwc_eval(&line, &value); + if(!aplwc_valid_value(&value)) goto line_error; - fprintf(stdout, "%s\n", aplwc_value_string(value)); + fprintf(stdout, "%s\n", aplwc_value_string(&value)); } } exit: if(input) free(input); - if(aplwc_valid_line(line)) - aplwc_free_line(line); - if(aplwc_valid_value(value)) - aplwc_free_value(value); + if(aplwc_valid_line(&line)) + aplwc_free_line(&line); + if(aplwc_valid_value(&value)) + aplwc_free_value(&value); aplwc_destroy(aplwc); return exit_code; diff --git a/src/include/aplwc.h b/src/include/aplwc.h index 5bd2d89..cb4fe84 100644 --- a/src/include/aplwc.h +++ b/src/include/aplwc.h @@ -37,7 +37,8 @@ struct aplwc; struct aplwc_ref { struct aplwc *aplwc; - int id; + void *ptr; + struct aplwc_ref *link; }; typedef struct { struct aplwc_ref ref; } AplwcLine; @@ -52,16 +53,16 @@ struct aplwc *aplwc_new(struct aplwc_fns, enum aplwc_rc *); void aplwc_destroy(struct aplwc *); void aplwc_clear_line(AplwcLine *); void aplwc_clear_value(AplwcValue *); -int aplwc_valid_line(AplwcLine); -int aplwc_valid_value(AplwcValue); +int aplwc_valid_line(AplwcLine *); +int aplwc_valid_value(AplwcValue *); const char *aplwc_errstr_rc(enum aplwc_rc); const char *aplwc_errstr(struct aplwc *); enum aplwc_rc aplwc_last_error(struct aplwc *); -AplwcLine aplwc_read(struct aplwc *, const char *); -void aplwc_free_line(AplwcLine); -AplwcValue aplwc_eval(AplwcLine); -void aplwc_free_value(AplwcValue); -const char *aplwc_value_string(AplwcValue); +void aplwc_read(struct aplwc *, const char *, AplwcLine *); +void aplwc_free_line(AplwcLine *); +void aplwc_eval(AplwcLine *, AplwcValue *); +void aplwc_free_value(AplwcValue *); +const char *aplwc_value_string(AplwcValue *); enum aplwc_rc aplwc_load_module(struct aplwc *, const char *, const char *, int n); #endif /* APLWC_H */ diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h index 0a52bb1..d72c289 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -37,7 +37,7 @@ struct aplwc { uint8_t *unaligned_data; size_t size; struct memory_ptr_frame *memptrs; - struct root_ptr *rootptrs; + struct aplwc_ref *refs; unsigned int reachable_bit:1; }; @@ -47,12 +47,6 @@ struct memory_ptr_frame { size_t count; }; -struct root_ptr { - int id; - void *ptr; - struct root_ptr *link; -}; - struct aplwc_line { struct string *text; struct token_list *tokens; @@ -120,13 +114,13 @@ struct token_list *memory_alloc_token_list(struct aplwc *, size_t); struct aplwc_value *memory_alloc_aplwc_value(struct aplwc *); struct aplwc_module *memory_alloc_aplwc_module(struct aplwc *); struct module_imports *memory_alloc_module_imports(struct aplwc *, size_t); -struct aplwc_ref memory_root_new(struct aplwc *, void *); -void *memory_root_get(struct aplwc_ref); -void memory_root_free(struct aplwc_ref); +void memory_root_new(struct aplwc *, void *, struct aplwc_ref *); +void *memory_root_get(struct aplwc_ref *); +void memory_root_free(struct aplwc_ref *); void memptrs_add(struct aplwc *, struct memory_ptr_frame *, void ***, size_t); void memptrs_remove(struct aplwc *, struct memory_ptr_frame *); void clear_ref(struct aplwc_ref *); -int valid_ref(struct aplwc_ref); +int valid_ref(struct aplwc_ref *); #define MEMPTRS(aplwc, n) \ void **memptrs[n]; \ diff --git a/src/lib/main.c b/src/lib/main.c index 3ea08e5..d2c353f 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -103,17 +103,16 @@ aplwc_last_error(struct aplwc *aplwc) return aplwc->last_error; } -AplwcLine -aplwc_read(struct aplwc *aplwc, const char *linestr) +void +aplwc_read(struct aplwc *aplwc, const char *linestr, AplwcLine *lineptr) { struct string *text; struct token_list *tokens; struct aplwc_line *line; - AplwcLine ret; MEMPTRS(aplwc, 2); - aplwc_clear_line(&ret); + aplwc_clear_line(lineptr); if((text = chars_to_string(aplwc, linestr, -1)) == NULL) goto end; @@ -132,50 +131,47 @@ aplwc_read(struct aplwc *aplwc, const char *linestr) line->text = text; line->tokens = tokens; - ret.ref = memory_root_new(aplwc, line); + memory_root_new(aplwc, line, &lineptr->ref); end: MEMPTRS_EXIT(aplwc); - return ret; } void -aplwc_free_line(AplwcLine line) +aplwc_free_line(AplwcLine *line) { - memory_root_free(line.ref); + memory_root_free(&line->ref); } -AplwcValue -aplwc_eval(AplwcLine line) +void +aplwc_eval(AplwcLine *line, AplwcValue *value) { - AplwcValue value; struct aplwc_line *l; struct aplwc_value *v; struct aplwc *aplwc; - aplwc = line.ref.aplwc; + aplwc = line->ref.aplwc; - aplwc_clear_value(&value); - l = memory_root_get(line.ref); + aplwc_clear_value(value); + l = memory_root_get(&line->ref); aplwc->last_error = APLWC_OK; v = eval_line(aplwc, l); if(v) - value.ref = memory_root_new(aplwc, v); - return value; + memory_root_new(aplwc, v, &value->ref); } void -aplwc_free_value(AplwcValue value) +aplwc_free_value(AplwcValue *value) { - memory_root_free(value.ref); + memory_root_free(&value->ref); } const char * -aplwc_value_string(AplwcValue value) +aplwc_value_string(AplwcValue *value) { struct aplwc_value *v; assert(aplwc_valid_value(value)); - v = memory_root_get(value.ref); + v = memory_root_get(&value->ref); switch(v->tag){ default: return "???"; @@ -221,13 +217,13 @@ aplwc_clear_line(AplwcLine *l) } int -aplwc_valid_value(AplwcValue v) +aplwc_valid_value(AplwcValue *v) { - return valid_ref(v.ref); + return valid_ref(&v->ref); } int -aplwc_valid_line(AplwcLine l) +aplwc_valid_line(AplwcLine *l) { - return valid_ref(l.ref); + return valid_ref(&l->ref); } diff --git a/src/lib/memory.c b/src/lib/memory.c index fbc0af7..b5bb82a 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -46,7 +46,7 @@ memory_init(struct aplwc *aplwc) aplwc->unaligned_data = NULL; aplwc->size = 0; aplwc->memptrs = NULL; - aplwc->rootptrs = NULL; + aplwc->refs = NULL; aplwc->reachable_bit = 0; } @@ -106,9 +106,9 @@ next(struct chunk *c) 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); \ + for(ref = aplwc->refs; ref; ref = ref->link) \ + if(ref->ptr) \ + X(ref->ptr); \ }while(0) #define VISIT_ALL_PTRS(X, data) do{ \ @@ -123,7 +123,7 @@ fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old) struct chunk *c; struct memory_ptr_frame *frame; - struct root_ptr *root; + struct aplwc_ref *ref; size_t add, sub, i; if(new > old){ @@ -263,7 +263,7 @@ collect(struct aplwc *aplwc) struct chunk *c, *prev; struct chunk *stack; struct memory_ptr_frame *frame; - struct root_ptr *root; + struct aplwc_ref *ref; size_t i; aplwc->reachable_bit = ~aplwc->reachable_bit; @@ -300,7 +300,7 @@ swapptr(struct aplwc *aplwc, void *old, void *new) { struct chunk *c; struct memory_ptr_frame *frame; - struct root_ptr *root; + struct aplwc_ref *ref; size_t i; #define SWAP(ptr) do{ \ @@ -427,71 +427,40 @@ retry: return data(new); } -struct aplwc_ref -memory_root_new(struct aplwc *aplwc, void *p) +void +memory_root_new(struct aplwc *aplwc, void *p, struct aplwc_ref *ref) { - struct aplwc_ref ref; - struct root_ptr *root; - size_t size; - - clear_ref(&ref); - if(aplwc->fns.alloc == NULL){ - aplwc->last_error = APLWC_OUT_OF_MEMORY; - goto end; - } - - root = aplwc->fns.alloc(sizeof(*root), sizeof(*root), &size); - if(root == NULL){ - aplwc->last_error = APLWC_OUT_OF_MEMORY; - goto end; - } - - root->id = aplwc->rootptrs ? (aplwc->rootptrs->id+1) : 0; - root->ptr = p; - root->link = aplwc->rootptrs; - aplwc->rootptrs = root; - - ref.id = root->id; - ref.aplwc = aplwc; -end: - return ref; + ref->ptr = p; + ref->link = aplwc->refs; + ref->aplwc = aplwc; + aplwc->refs = ref; } void * -memory_root_get(struct aplwc_ref ref) +memory_root_get(struct aplwc_ref *ref) { - struct root_ptr *root; - - if(!valid_ref(ref)) - return NULL; - - for(root = ref.aplwc->rootptrs; root; root = root->link) - if(root->id == ref.id) - return root->ptr; - - return NULL; + return ref->ptr; } void -memory_root_free(struct aplwc_ref ref) +memory_root_free(struct aplwc_ref *ref) { struct aplwc *aplwc; - struct root_ptr **root, *tmp; + struct aplwc_ref **root; if(!valid_ref(ref)) return; - aplwc = ref.aplwc; + aplwc = ref->aplwc; - for(root = &aplwc->rootptrs; (*root); root = &(*root)->link){ - if((*root)->id == ref.id){ - tmp = *root; - *root = tmp->link; - if(aplwc->fns.dealloc) - aplwc->fns.dealloc(tmp); + for(root = &aplwc->refs; (*root); root = &(*root)->link){ + if((*root) == ref){ + *root = (*root)->link; break; } } + + clear_ref(ref); } void @@ -564,12 +533,13 @@ memory_alloc_aplwc_module(struct aplwc *aplwc) void clear_ref(struct aplwc_ref *ref) { - ref->id = -1; ref->aplwc = NULL; + ref->ptr = NULL; + ref->link = NULL; } int -valid_ref(struct aplwc_ref ref) +valid_ref(struct aplwc_ref *ref) { - return ref.id >= 0; + return (ref->aplwc != NULL) && (ref->ptr != NULL); } |