summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpeter <peter@pmikkelsen.com>2026-09-03 19:31:52 +0000
committerpeter <peter@pmikkelsen.com>2026-09-03 19:31:52 +0000
commitfa6a3ee5b24d5e227798330cff5f9ff060d6d863 (patch)
treeb251207d74ae183b0e0bb155e4e0f9f86334c3d3 /src
parent84dd0d9fa985c1c740b3145c6b0d858cca978911 (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.c26
-rw-r--r--src/include/aplwc.h17
-rw-r--r--src/lib/aplwc_internal.h16
-rw-r--r--src/lib/main.c44
-rw-r--r--src/lib/memory.c84
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);
}