From b6d03391ab7a4ed0e1dc9883a90ee10d089ced00 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 30 Aug 2026 13:28:19 +0000 Subject: Start work on the memory manager. It is becomming a burden that it doesn't know how to request more memory, or how to collect garbage. FossilOrigin-Name: 1eb8eb8b8d8fd58a29bbeafa1ebb9f3618a31a5dcb45b860d2a5be6305775583 --- tools/checkcov | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/checkcov b/tools/checkcov index c228c2f..ac3cf91 100755 --- a/tools/checkcov +++ b/tools/checkcov @@ -31,6 +31,7 @@ BEGIN { function miss(t){ printf("%c %s:%d %s\n", t, file, line, src) + missing_count++; } /^condition outcomes covered [0-9]+\/[1-9][0-9]*/ { @@ -70,4 +71,8 @@ function miss(t){ miss("L") next } + +END { + printf("\nMissing coverage: %d\n", missing_count); +} ' -- cgit v1.2.3 From 29479e2c50d41f29b5e21ffcb16416887aa693d2 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 30 Aug 2026 13:34:36 +0000 Subject: Remove APLWC_MIN_MEM constant, and APLWC_MEM environment variable FossilOrigin-Name: affcf2ab9c573820c77778abfb4769fad8a30ce457411b02a9528470994c7a6b --- CMakeLists.txt | 20 -------------------- src/bin/main.c | 10 +++++----- src/include/aplwc.h | 2 -- tests/aplwc_errstr.c | 2 +- tests/aplwc_eval.c | 2 +- tests/aplwc_new.c | 4 +--- tests/aplwc_read.c | 2 +- tests/aplwc_utf8.c | 2 +- 8 files changed, 10 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3450d7..8d2a607 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,26 +113,6 @@ foreach(script ${TEST_SCRIPTS}) ) endforeach() -add_test(NAME "aplwc-repl-tiny" COMMAND "aplwc-repl" "-x") -set_tests_properties("aplwc-repl-tiny" PROPERTIES - ENVIRONMENT "APLWC_MEM=16" - WILL_FAIL TRUE -) - -add_test(NAME "aplwc-repl-large" COMMAND "aplwc-repl" "-x") -set_tests_properties("aplwc-repl-large" PROPERTIES - ENVIRONMENT "APLWC_MEM=64000" -) - -add_test(NAME "aplwc-repl-emptyvar" COMMAND "aplwc-repl" "-x") -set_tests_properties("aplwc-repl-emptyvar" PROPERTIES - ENVIRONMENT "APLWC_MEM=" -) - -add_test(NAME "aplwc-repl-badvar" COMMAND "aplwc-repl" "-x") -set_tests_properties("aplwc-repl-badvar" PROPERTIES - ENVIRONMENT "APLWC_MEM=1M" -) add_test(NAME "aplwc-repl" COMMAND "aplwc-repl" "-x") diff --git a/src/bin/main.c b/src/bin/main.c index 572d170..fb75a9d 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -4,6 +4,8 @@ #include #include "aplwc_repl.h" +#define MEMSIZE 20000 + int main(int argc, char *argv[]) { @@ -13,7 +15,7 @@ main(int argc, char *argv[]) uint8_t *data; char *input, *src; int ret, exit_code, line_number; - size_t memsize, input_size, src_size, i; + size_t input_size, src_size, i; int opt, xflag, input_file; long tmp; FILE *f; @@ -50,15 +52,13 @@ usage: else goto usage; - memsize = getenv_ulong("APLWC_MEM", APLWC_MIN_MEM); - - data = malloc(memsize); + data = malloc(MEMSIZE); if(data == NULL){ fprintf(stderr, "Couldn't allocate memory\n"); return 1; } - ret = aplwc_new(&aplwc, data, memsize); + ret = aplwc_new(&aplwc, data, MEMSIZE); if(ret){ fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr_rc(ret)); free(data); diff --git a/src/include/aplwc.h b/src/include/aplwc.h index 3061500..ad640e4 100644 --- a/src/include/aplwc.h +++ b/src/include/aplwc.h @@ -30,6 +30,4 @@ void aplwc_free_value(struct aplwc_value *); const char *aplwc_value_string(struct aplwc_value *); enum aplwc_rc aplwc_load_module(struct aplwc *, const char *, const char *, int n); -#define APLWC_MIN_MEM (64000) - #endif /* APLWC_H */ diff --git a/tests/aplwc_errstr.c b/tests/aplwc_errstr.c index 8014c1e..2ca14ab 100644 --- a/tests/aplwc_errstr.c +++ b/tests/aplwc_errstr.c @@ -4,7 +4,7 @@ int main(void) { - uint8_t data[APLWC_MIN_MEM]; + uint8_t data[20000]; struct aplwc *aplwc; int ret; const char *err; diff --git a/tests/aplwc_eval.c b/tests/aplwc_eval.c index 8f6abe0..c284189 100644 --- a/tests/aplwc_eval.c +++ b/tests/aplwc_eval.c @@ -5,7 +5,7 @@ int main(int argc, char *argv[]) { - uint8_t data[APLWC_MIN_MEM+1000]; + uint8_t data[64000]; char *input; struct aplwc *aplwc; struct aplwc_line *line; diff --git a/tests/aplwc_new.c b/tests/aplwc_new.c index 8d57ecd..4ed893e 100644 --- a/tests/aplwc_new.c +++ b/tests/aplwc_new.c @@ -4,7 +4,7 @@ int main(void) { struct aplwc *aplwc; - uint8_t data[APLWC_MIN_MEM*2]; + uint8_t data[10000]; int ret; size_t i, j; @@ -15,8 +15,6 @@ main(void) if(ret){ if(ret != APLWC_OUT_OF_MEMORY) return 1; - if(j >= APLWC_MIN_MEM) - return 1; break; } } diff --git a/tests/aplwc_read.c b/tests/aplwc_read.c index c54f598..8c5ce37 100644 --- a/tests/aplwc_read.c +++ b/tests/aplwc_read.c @@ -5,7 +5,7 @@ int main(int argc, char *argv[]) { - uint8_t data[APLWC_MIN_MEM+1000]; + uint8_t data[20000]; char *input; struct aplwc *aplwc; struct aplwc_line *line; diff --git a/tests/aplwc_utf8.c b/tests/aplwc_utf8.c index b97b978..b950580 100644 --- a/tests/aplwc_utf8.c +++ b/tests/aplwc_utf8.c @@ -17,7 +17,7 @@ uint8_t good5[] = {0xef,0xbb,0xbf,0xf0,0xa3,0x8e,0xb4,0}; int main(void) { - uint8_t data[APLWC_MIN_MEM+64000]; + uint8_t data[64000]; struct aplwc *aplwc; struct aplwc_line *line; enum aplwc_rc ret; -- cgit v1.2.3 From 8521b6a69deab8cdabe1c87b09ecdc93d75af98e Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 30 Aug 2026 14:20:55 +0000 Subject: Remove the struct memory struct FossilOrigin-Name: 38568a34f631b2a4eef72542e2988a9fe081f85d3248194c2ff995a9eed6bd5d --- src/lib/aplwc_internal.h | 40 +++++++++++++-------------- src/lib/eval.c | 2 +- src/lib/main.c | 22 +++++++-------- src/lib/memory.c | 71 +++++++++++++++++++++++------------------------- src/lib/module.c | 4 +-- src/lib/string.c | 2 +- src/lib/syntax.c | 4 +-- 7 files changed, 70 insertions(+), 75 deletions(-) diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h index e394bd8..2e3e274 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -8,16 +8,14 @@ #include #include -struct memory { - uint8_t *data; - size_t size; - size_t offset; -}; - struct aplwc { enum aplwc_rc last_error; - struct memory memory; struct aplwc_module *modules; + + /* Memory management */ + uint8_t *data; + size_t size; + size_t offset; }; struct aplwc_line { @@ -81,20 +79,20 @@ struct aplwc_module { struct aplwc_value *eval_line(struct aplwc_line *); /* memory.c */ -struct memory memory_init(uint8_t *, size_t); -struct aplwc *memory_alloc_aplwc(struct memory *); -struct aplwc_line *memory_alloc_aplwc_line(struct memory *); -struct string *memory_alloc_string(struct memory *, size_t); -struct token_list *memory_alloc_token_list(struct memory *, size_t); -struct aplwc_value *memory_alloc_aplwc_value(struct memory *); -struct aplwc_module *memory_alloc_aplwc_module(struct memory *); -struct module_imports *memory_alloc_module_imports(struct memory *, size_t); -void memory_free_aplwc(struct memory *, struct aplwc *); -void memory_free_aplwc_line(struct memory *, struct aplwc_line *); -void memory_free_string(struct memory *, struct string *); -void memory_free_token_list(struct memory *, struct token_list *); -void memory_free_aplwc_value(struct memory *, struct aplwc_value *); -void memory_free_aplwc_module(struct memory *, struct aplwc_module *); +void memory_init(struct aplwc *, uint8_t *, size_t); +struct aplwc *memory_alloc_aplwc(struct aplwc *); +struct aplwc_line *memory_alloc_aplwc_line(struct aplwc *); +struct string *memory_alloc_string(struct aplwc *, size_t); +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); +void memory_free_aplwc(struct aplwc *, struct aplwc *); +void memory_free_aplwc_line(struct aplwc *, struct aplwc_line *); +void memory_free_string(struct aplwc *, struct string *); +void memory_free_token_list(struct aplwc *, struct token_list *); +void memory_free_aplwc_value(struct aplwc *, struct aplwc_value *); +void memory_free_aplwc_module(struct aplwc *, struct aplwc_module *); /* string.c */ struct string *chars_to_string(struct aplwc *, const char *, int len); diff --git a/src/lib/eval.c b/src/lib/eval.c index f0cdc55..649914d 100644 --- a/src/lib/eval.c +++ b/src/lib/eval.c @@ -9,7 +9,7 @@ eval_line(struct aplwc_line *line) aplwc = line->aplwc; assert(aplwc->last_error == APLWC_OK); - value = memory_alloc_aplwc_value(&aplwc->memory); + value = memory_alloc_aplwc_value(aplwc); if(value == NULL) aplwc->last_error = APLWC_OUT_OF_MEMORY; value->aplwc = aplwc; diff --git a/src/lib/main.c b/src/lib/main.c index d6de538..fa7e547 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -4,14 +4,14 @@ enum aplwc_rc aplwc_new(struct aplwc **p, uint8_t *data, size_t size) { - struct memory m; + struct aplwc tmp_aplwc; - m = memory_init(data, size); + memory_init(&tmp_aplwc, data, size); - *p = memory_alloc_aplwc(&m); + *p = memory_alloc_aplwc(&tmp_aplwc); if(*p == NULL) return APLWC_OUT_OF_MEMORY; - (*p)->memory = m; + memcpy(*p, &tmp_aplwc, sizeof(tmp_aplwc)); return aplwc_load_module(*p, "Boot", (const char *)boot_src, boot_src_len); } @@ -20,7 +20,7 @@ void aplwc_destroy(struct aplwc *p) { if(p) - memory_free_aplwc(&p->memory, p); + memory_free_aplwc(p, p); } const char * @@ -83,7 +83,7 @@ aplwc_read(struct aplwc *aplwc, const char *line) if(aplwc->last_error != APLWC_OK) return NULL; - ret = memory_alloc_aplwc_line(&aplwc->memory); + ret = memory_alloc_aplwc_line(aplwc); if(ret == NULL){ aplwc->last_error = APLWC_OUT_OF_MEMORY; return NULL; @@ -101,7 +101,7 @@ aplwc_free_line(struct aplwc_line *line) { if(line == NULL) return; - memory_free_aplwc_line(&line->aplwc->memory, line); + memory_free_aplwc_line(line->aplwc, line); } struct aplwc_value * @@ -116,7 +116,7 @@ aplwc_free_value(struct aplwc_value *value) { if(value == NULL) return; - memory_free_aplwc_value(&value->aplwc->memory, value); + memory_free_aplwc_value(value->aplwc, value); } const char * @@ -157,11 +157,11 @@ aplwc_load_module(struct aplwc *aplwc, const char *name, const char *src, int sr else{ error: if(tokens != NULL) - memory_free_token_list(&aplwc->memory, tokens); + memory_free_token_list(aplwc, tokens); if(text != NULL) - memory_free_string(&aplwc->memory, text); + memory_free_string(aplwc, text); if(namestr != NULL) - memory_free_string(&aplwc->memory, namestr); + memory_free_string(aplwc, namestr); return aplwc_last_error(aplwc); } } diff --git a/src/lib/memory.c b/src/lib/memory.c index a348b93..24d3d68 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -1,24 +1,21 @@ #include "aplwc_internal.h" -struct memory -memory_init(uint8_t *data , size_t size) +void +memory_init(struct aplwc *aplwc, uint8_t *data , size_t size) { - struct memory mem; - - mem.data = data; - mem.size = size; - mem.offset = 0; - return mem; + aplwc->data = data; + aplwc->size = size; + aplwc->offset = 0; } static void * -alloc(struct memory *m, size_t size, size_t align) +alloc(struct aplwc *aplwc, size_t size, size_t align) { uintptr_t ptr; size_t alloc_size, adjust; void *p; - ptr = ((uintptr_t)m->data) + m->offset; + ptr = ((uintptr_t)aplwc->data) + aplwc->offset; alloc_size = size; if(NEVER(align == 0)) @@ -28,10 +25,10 @@ alloc(struct memory *m, size_t size, size_t align) if(adjust) alloc_size += align - adjust; - if((m->size - m->offset) >= alloc_size){ - p = m->data+m->offset+alloc_size-size; + if((aplwc->size - aplwc->offset) >= alloc_size){ + p = aplwc->data+aplwc->offset+alloc_size-size; assert((((uintptr_t)p) % align) == 0); - m->offset += alloc_size; + aplwc->offset += alloc_size; memset(p, 0, size); }else p = NULL; @@ -40,97 +37,97 @@ alloc(struct memory *m, size_t size, size_t align) } struct aplwc * -memory_alloc_aplwc(struct memory *m) +memory_alloc_aplwc(struct aplwc *aplwc) { struct aplwc *p; - p = alloc(m, sizeof(struct aplwc), alignof(struct aplwc)); + p = alloc(aplwc, sizeof(struct aplwc), alignof(struct aplwc)); return p; } void -memory_free_aplwc(struct memory *m, struct aplwc *p) +memory_free_aplwc(struct aplwc *aplwc, struct aplwc *p) { - UNUSED_PARAMETER(m); + UNUSED_PARAMETER(aplwc); UNUSED_PARAMETER(p); } struct aplwc_line * -memory_alloc_aplwc_line(struct memory *m) +memory_alloc_aplwc_line(struct aplwc *aplwc) { struct aplwc_line *p; - p = alloc(m, sizeof(struct aplwc_line), alignof(struct aplwc_line)); + p = alloc(aplwc, sizeof(struct aplwc_line), alignof(struct aplwc_line)); return p; } void -memory_free_aplwc_line(struct memory *m, struct aplwc_line *p) +memory_free_aplwc_line(struct aplwc *aplwc, struct aplwc_line *p) { - UNUSED_PARAMETER(m); + UNUSED_PARAMETER(aplwc); UNUSED_PARAMETER(p); } struct string * -memory_alloc_string(struct memory *m, size_t bytes) +memory_alloc_string(struct aplwc *aplwc, size_t bytes) { struct string *p; - p = alloc(m, sizeof(struct string) + bytes, alignof(struct string)); + p = alloc(aplwc, sizeof(struct string) + bytes, alignof(struct string)); return p; } void -memory_free_string(struct memory *m, struct string *p) +memory_free_string(struct aplwc *aplwc, struct string *p) { - UNUSED_PARAMETER(m); + UNUSED_PARAMETER(aplwc); UNUSED_PARAMETER(p); } struct token_list * -memory_alloc_token_list(struct memory *m, size_t tokens) +memory_alloc_token_list(struct aplwc *aplwc, size_t tokens) { struct token_list *p; - p = alloc(m, sizeof(struct token_list) + (tokens * sizeof(struct token)), alignof(struct token_list)); + p = alloc(aplwc, sizeof(struct token_list) + (tokens * sizeof(struct token)), alignof(struct token_list)); return p; } void -memory_free_token_list(struct memory *m, struct token_list *p) +memory_free_token_list(struct aplwc *aplwc, struct token_list *p) { - UNUSED_PARAMETER(m); + UNUSED_PARAMETER(aplwc); UNUSED_PARAMETER(p); } struct aplwc_value * -memory_alloc_aplwc_value(struct memory *m) +memory_alloc_aplwc_value(struct aplwc *aplwc) { struct aplwc_value *p; - p = alloc(m, sizeof(struct aplwc_value), alignof(struct aplwc_value)); + p = alloc(aplwc, sizeof(struct aplwc_value), alignof(struct aplwc_value)); return p; } void -memory_free_aplwc_value(struct memory *m, struct aplwc_value *p) +memory_free_aplwc_value(struct aplwc *aplwc, struct aplwc_value *p) { - UNUSED_PARAMETER(m); + UNUSED_PARAMETER(aplwc); UNUSED_PARAMETER(p); } struct aplwc_module * -memory_alloc_aplwc_module(struct memory *m) +memory_alloc_aplwc_module(struct aplwc *aplwc) { struct aplwc_module *p; - p = alloc(m, sizeof(struct aplwc_module), alignof(struct aplwc_module)); + p = alloc(aplwc, sizeof(struct aplwc_module), alignof(struct aplwc_module)); return p; } void -memory_free_aplwc_module(struct memory *m, struct aplwc_module *p) +memory_free_aplwc_module(struct aplwc *aplwc, struct aplwc_module *p) { - UNUSED_PARAMETER(m); + UNUSED_PARAMETER(aplwc); UNUSED_PARAMETER(p); } diff --git a/src/lib/module.c b/src/lib/module.c index 9a202f9..4c96f64 100644 --- a/src/lib/module.c +++ b/src/lib/module.c @@ -58,7 +58,7 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) enum aplwc_rc rc; struct aplwc_module *module; - module = memory_alloc_aplwc_module(&aplwc->memory); + module = memory_alloc_aplwc_module(aplwc); if(module == NULL){ aplwc->last_error = APLWC_OUT_OF_MEMORY; return aplwc->last_error; @@ -73,7 +73,7 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) module->link = aplwc->modules; aplwc->modules = module; }else{ - memory_free_aplwc_module(&aplwc->memory, module); + memory_free_aplwc_module(aplwc, module); } return rc; diff --git a/src/lib/string.c b/src/lib/string.c index 24f978c..d10fb1f 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -69,7 +69,7 @@ invalid: if(extra != 0) goto invalid; - string = memory_alloc_string(&aplwc->memory, bytecount); + string = memory_alloc_string(aplwc, bytecount); if(string){ string->bytes = bytecount; string->chars = charcount; diff --git a/src/lib/syntax.c b/src/lib/syntax.c index 395c75e..9888bef 100644 --- a/src/lib/syntax.c +++ b/src/lib/syntax.c @@ -246,7 +246,7 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) return NULL; } - tokens = memory_alloc_token_list(&aplwc->memory, n); + tokens = memory_alloc_token_list(aplwc, n); if(tokens == NULL){ aplwc->last_error = APLWC_OUT_OF_MEMORY; return NULL; @@ -261,7 +261,7 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) for(i++; i < n; i++){ if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE){ - memory_free_token_list(&aplwc->memory, tokens); + memory_free_token_list(aplwc, tokens); return NULL; } } -- cgit v1.2.3 From 2261ffa04ddf30a7c8eae6e64129b293fc8bffd9 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 30 Aug 2026 14:25:56 +0000 Subject: Let the memory allocation code set the last_error to APLWC_OUT_OF_MEMORY, instead of the callers FossilOrigin-Name: 46c74e207a84e861636dbfebc4ba8bb9e7b17401dfd2c4fb9bdeae0fa98fd530 --- src/lib/eval.c | 9 ++++----- src/lib/main.c | 6 ++---- src/lib/memory.c | 4 +++- src/lib/module.c | 4 +--- src/lib/string.c | 3 +-- src/lib/syntax.c | 4 +--- 6 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/lib/eval.c b/src/lib/eval.c index 649914d..21fb223 100644 --- a/src/lib/eval.c +++ b/src/lib/eval.c @@ -10,10 +10,9 @@ eval_line(struct aplwc_line *line) assert(aplwc->last_error == APLWC_OK); value = memory_alloc_aplwc_value(aplwc); - if(value == NULL) - aplwc->last_error = APLWC_OUT_OF_MEMORY; - value->aplwc = aplwc; - value->tag = VALUE_NULL; - + if(value != NULL){ + value->aplwc = aplwc; + value->tag = VALUE_NULL; + } return value; } diff --git a/src/lib/main.c b/src/lib/main.c index fa7e547..2bd374b 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -10,7 +10,7 @@ aplwc_new(struct aplwc **p, uint8_t *data, size_t size) *p = memory_alloc_aplwc(&tmp_aplwc); if(*p == NULL) - return APLWC_OUT_OF_MEMORY; + return tmp_aplwc.last_error; memcpy(*p, &tmp_aplwc, sizeof(tmp_aplwc)); return aplwc_load_module(*p, "Boot", (const char *)boot_src, boot_src_len); @@ -84,10 +84,8 @@ aplwc_read(struct aplwc *aplwc, const char *line) return NULL; ret = memory_alloc_aplwc_line(aplwc); - if(ret == NULL){ - aplwc->last_error = APLWC_OUT_OF_MEMORY; + if(ret == NULL) return NULL; - } ret->aplwc = aplwc; ret->text = text; diff --git a/src/lib/memory.c b/src/lib/memory.c index 24d3d68..ca4babf 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -30,8 +30,10 @@ alloc(struct aplwc *aplwc, size_t size, size_t align) assert((((uintptr_t)p) % align) == 0); aplwc->offset += alloc_size; memset(p, 0, size); - }else + }else{ p = NULL; + aplwc->last_error = APLWC_OUT_OF_MEMORY; + } return p; } diff --git a/src/lib/module.c b/src/lib/module.c index 4c96f64..db5dc78 100644 --- a/src/lib/module.c +++ b/src/lib/module.c @@ -59,10 +59,8 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) struct aplwc_module *module; module = memory_alloc_aplwc_module(aplwc); - if(module == NULL){ - aplwc->last_error = APLWC_OUT_OF_MEMORY; + if(module == NULL) return aplwc->last_error; - } module->aplwc = aplwc; module->name = name; module->tokens = tokens; diff --git a/src/lib/string.c b/src/lib/string.c index d10fb1f..cc6c6cb 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -74,8 +74,7 @@ invalid: string->bytes = bytecount; string->chars = charcount; memcpy(string->utf8, utf8, bytecount); - }else - aplwc->last_error = APLWC_OUT_OF_MEMORY; + } return string; } diff --git a/src/lib/syntax.c b/src/lib/syntax.c index 9888bef..16d0363 100644 --- a/src/lib/syntax.c +++ b/src/lib/syntax.c @@ -247,10 +247,8 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) } tokens = memory_alloc_token_list(aplwc, n); - if(tokens == NULL){ - aplwc->last_error = APLWC_OUT_OF_MEMORY; + if(tokens == NULL) return NULL; - } tokens->text = text; tokens->length = n; scan(text, tokens); -- cgit v1.2.3 From 04827577ea502a9f0edc69e00e008751c8119cbc Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 30 Aug 2026 14:46:38 +0000 Subject: Remove a lot of functions for manually freeing memory (they were not implemented) FossilOrigin-Name: 693765728e62a74a0ab15d657f7d1dd83702a9371fb042dafe6250f84a252959 --- src/lib/aplwc_internal.h | 7 +------ src/lib/main.c | 41 +++++++++++--------------------------- src/lib/memory.c | 51 +++++++++--------------------------------------- src/lib/module.c | 2 -- src/lib/syntax.c | 4 +--- 5 files changed, 22 insertions(+), 83 deletions(-) diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h index 2e3e274..23b26f9 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -87,12 +87,7 @@ 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); -void memory_free_aplwc(struct aplwc *, struct aplwc *); -void memory_free_aplwc_line(struct aplwc *, struct aplwc_line *); -void memory_free_string(struct aplwc *, struct string *); -void memory_free_token_list(struct aplwc *, struct token_list *); -void memory_free_aplwc_value(struct aplwc *, struct aplwc_value *); -void memory_free_aplwc_module(struct aplwc *, struct aplwc_module *); +void memory_free_root(struct aplwc *, void *); /* string.c */ struct string *chars_to_string(struct aplwc *, const char *, int len); diff --git a/src/lib/main.c b/src/lib/main.c index 2bd374b..81cd6bb 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -19,8 +19,7 @@ aplwc_new(struct aplwc **p, uint8_t *data, size_t size) void aplwc_destroy(struct aplwc *p) { - if(p) - memory_free_aplwc(p, p); + UNUSED_PARAMETER(p); } const char * @@ -97,9 +96,8 @@ aplwc_read(struct aplwc *aplwc, const char *line) void aplwc_free_line(struct aplwc_line *line) { - if(line == NULL) - return; - memory_free_aplwc_line(line->aplwc, line); + if(line) + memory_free_root(line->aplwc, line); } struct aplwc_value * @@ -112,9 +110,8 @@ aplwc_eval(struct aplwc_line *line) void aplwc_free_value(struct aplwc_value *value) { - if(value == NULL) - return; - memory_free_aplwc_value(value->aplwc, value); + if(value) + memory_free_root(value->aplwc, value); } const char * @@ -134,32 +131,16 @@ aplwc_load_module(struct aplwc *aplwc, const char *name, const char *src, int sr struct string *text, *namestr; struct token_list *tokens; - namestr = NULL; - text = NULL; - tokens = NULL; - - namestr = chars_to_string(aplwc, name, -1); - if(namestr == NULL) + if((namestr = chars_to_string(aplwc, name, -1)) == NULL) goto error; - - text = chars_to_string(aplwc, src, srclen); - if(text == NULL) + if((text = chars_to_string(aplwc, src, srclen)) == NULL) goto error; - - tokens = scan_string(aplwc, text, 0); - if(tokens == NULL) + if((tokens = scan_string(aplwc, text, 0)) == NULL) goto error; - - if(load_module(aplwc, namestr, tokens) == APLWC_OK) - return APLWC_OK; - else{ + if(load_module(aplwc, namestr, tokens) != APLWC_OK){ error: - if(tokens != NULL) - memory_free_token_list(aplwc, tokens); - if(text != NULL) - memory_free_string(aplwc, text); - if(namestr != NULL) - memory_free_string(aplwc, namestr); return aplwc_last_error(aplwc); } + + return APLWC_OK; } diff --git a/src/lib/memory.c b/src/lib/memory.c index ca4babf..94f903c 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -38,6 +38,15 @@ alloc(struct aplwc *aplwc, size_t size, size_t align) return p; } +void +memory_free_root(struct aplwc *aplwc, void *p) +{ + if(NEVER(p == NULL)) + return; + + UNUSED_PARAMETER(aplwc); +} + struct aplwc * memory_alloc_aplwc(struct aplwc *aplwc) { @@ -47,13 +56,6 @@ memory_alloc_aplwc(struct aplwc *aplwc) return p; } -void -memory_free_aplwc(struct aplwc *aplwc, struct aplwc *p) -{ - UNUSED_PARAMETER(aplwc); - UNUSED_PARAMETER(p); -} - struct aplwc_line * memory_alloc_aplwc_line(struct aplwc *aplwc) { @@ -63,13 +65,6 @@ memory_alloc_aplwc_line(struct aplwc *aplwc) return p; } -void -memory_free_aplwc_line(struct aplwc *aplwc, struct aplwc_line *p) -{ - UNUSED_PARAMETER(aplwc); - UNUSED_PARAMETER(p); -} - struct string * memory_alloc_string(struct aplwc *aplwc, size_t bytes) { @@ -79,13 +74,6 @@ memory_alloc_string(struct aplwc *aplwc, size_t bytes) return p; } -void -memory_free_string(struct aplwc *aplwc, struct string *p) -{ - UNUSED_PARAMETER(aplwc); - UNUSED_PARAMETER(p); -} - struct token_list * memory_alloc_token_list(struct aplwc *aplwc, size_t tokens) { @@ -95,13 +83,6 @@ memory_alloc_token_list(struct aplwc *aplwc, size_t tokens) return p; } -void -memory_free_token_list(struct aplwc *aplwc, struct token_list *p) -{ - UNUSED_PARAMETER(aplwc); - UNUSED_PARAMETER(p); -} - struct aplwc_value * memory_alloc_aplwc_value(struct aplwc *aplwc) { @@ -111,13 +92,6 @@ memory_alloc_aplwc_value(struct aplwc *aplwc) return p; } -void -memory_free_aplwc_value(struct aplwc *aplwc, struct aplwc_value *p) -{ - UNUSED_PARAMETER(aplwc); - UNUSED_PARAMETER(p); -} - struct aplwc_module * memory_alloc_aplwc_module(struct aplwc *aplwc) { @@ -126,10 +100,3 @@ memory_alloc_aplwc_module(struct aplwc *aplwc) p = alloc(aplwc, sizeof(struct aplwc_module), alignof(struct aplwc_module)); return p; } - -void -memory_free_aplwc_module(struct aplwc *aplwc, struct aplwc_module *p) -{ - UNUSED_PARAMETER(aplwc); - UNUSED_PARAMETER(p); -} diff --git a/src/lib/module.c b/src/lib/module.c index db5dc78..f559f00 100644 --- a/src/lib/module.c +++ b/src/lib/module.c @@ -70,8 +70,6 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) if(rc == APLWC_OK){ module->link = aplwc->modules; aplwc->modules = module; - }else{ - memory_free_aplwc_module(aplwc, module); } return rc; diff --git a/src/lib/syntax.c b/src/lib/syntax.c index 16d0363..75d6c14 100644 --- a/src/lib/syntax.c +++ b/src/lib/syntax.c @@ -258,10 +258,8 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) continue; for(i++; i < n; i++){ - if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE){ - memory_free_token_list(aplwc, tokens); + if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE) return NULL; - } } } -- cgit v1.2.3 From 729964bea692f9683860978b89848784a7fc2f46 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 30 Aug 2026 20:52:43 +0000 Subject: Still a lot to be done, but I'm going to bed. Two remaining big issues: * aplwc (the parameter passed "everywhere") - should it move or not? * values returned from the public API should not move. FossilOrigin-Name: 31ab3154b8f3d5ac167218496e9e204324bf0ac9d36b7bada8fe2a6c8f93d51c --- src/bin/main.c | 23 ++--- src/include/aplwc.h | 7 +- src/lib/aplwc_internal.h | 23 ++++- src/lib/eval.c | 1 + src/lib/main.c | 82 +++++++++------- src/lib/memory.c | 241 ++++++++++++++++++++++++++++++++++++++++------- src/lib/module.c | 17 +++- src/lib/syntax.c | 22 +++-- tests/aplwc_errstr.c | 59 +++++++++--- tests/aplwc_eval.c | 25 ++++- tests/aplwc_new.c | 24 ----- tests/aplwc_read.c | 24 ++++- tests/aplwc_utf8.c | 25 ++++- 13 files changed, 437 insertions(+), 136 deletions(-) delete mode 100644 tests/aplwc_new.c diff --git a/src/bin/main.c b/src/bin/main.c index fb75a9d..99149f6 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -4,15 +4,21 @@ #include #include "aplwc_repl.h" -#define MEMSIZE 20000 +static void *my_alloc(size_t min, size_t max, size_t *actual) +{ + UNUSED_PARAMETER(max); + + *actual = min; + return malloc(min); +} int main(int argc, char *argv[]) { + struct aplwc_fns fns; struct aplwc *aplwc; struct aplwc_line *line; struct aplwc_value *value; - uint8_t *data; char *input, *src; int ret, exit_code, line_number; size_t input_size, src_size, i; @@ -28,6 +34,9 @@ main(int argc, char *argv[]) exit_code = 0; line_number = 0; + memset(&fns, 0, sizeof(fns)); + fns.alloc = my_alloc; + while((opt = getopt(argc, argv, "x")) != -1){ switch(opt){ case 'x': @@ -52,16 +61,9 @@ usage: else goto usage; - data = malloc(MEMSIZE); - if(data == NULL){ - fprintf(stderr, "Couldn't allocate memory\n"); - return 1; - } - - ret = aplwc_new(&aplwc, data, MEMSIZE); + ret = aplwc_new(&aplwc, fns); if(ret){ fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr_rc(ret)); - free(data); return 1; } @@ -152,6 +154,5 @@ exit: aplwc_free_value(value); aplwc_destroy(aplwc); - free(data); return exit_code; } diff --git a/src/include/aplwc.h b/src/include/aplwc.h index ad640e4..843fe42 100644 --- a/src/include/aplwc.h +++ b/src/include/aplwc.h @@ -18,7 +18,12 @@ struct aplwc; struct aplwc_line; struct aplwc_value; -enum aplwc_rc aplwc_new(struct aplwc **, uint8_t *, size_t); +struct aplwc_fns { + void *(*alloc)(size_t, size_t, size_t *); + void (*dealloc)(void *); +}; + +enum aplwc_rc aplwc_new(struct aplwc **, struct aplwc_fns); void aplwc_destroy(struct aplwc *); const char *aplwc_errstr_rc(enum aplwc_rc); const char *aplwc_errstr(struct aplwc *); diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h index 23b26f9..a7b7030 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -9,13 +9,21 @@ #include struct aplwc { + struct aplwc_fns fns; enum aplwc_rc last_error; struct aplwc_module *modules; /* Memory management */ uint8_t *data; + uint8_t *unaligned_data; size_t size; - size_t offset; + struct memory_ptr_frame *memptrs; +}; + +struct memory_ptr_frame { + struct memory_ptr_frame *link; + void ***ptrs; + size_t count; }; struct aplwc_line { @@ -79,8 +87,8 @@ struct aplwc_module { struct aplwc_value *eval_line(struct aplwc_line *); /* memory.c */ -void memory_init(struct aplwc *, uint8_t *, size_t); -struct aplwc *memory_alloc_aplwc(struct aplwc *); +void memory_init(struct aplwc *); +void memory_destroy(struct aplwc *); struct aplwc_line *memory_alloc_aplwc_line(struct aplwc *); struct string *memory_alloc_string(struct aplwc *, size_t); struct token_list *memory_alloc_token_list(struct aplwc *, size_t); @@ -88,6 +96,15 @@ 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); void memory_free_root(struct aplwc *, void *); +void memptrs_add(struct aplwc *, struct memory_ptr_frame *, void ***, size_t); +void memptrs_remove(struct aplwc *, struct memory_ptr_frame *); + +#define MEMPTRS(aplwc, n) \ + void **memptrs[n]; \ + struct memory_ptr_frame memptrs_frame; \ + memptrs_add(aplwc, &memptrs_frame, memptrs, n); +#define MEMPTR(n, ptr) memptrs[n] = (void **)&ptr +#define MEMPTRS_EXIT(aplwc) memptrs_remove(aplwc, &memptrs_frame) /* string.c */ struct string *chars_to_string(struct aplwc *, const char *, int len); diff --git a/src/lib/eval.c b/src/lib/eval.c index 21fb223..50c3cda 100644 --- a/src/lib/eval.c +++ b/src/lib/eval.c @@ -14,5 +14,6 @@ eval_line(struct aplwc_line *line) value->aplwc = aplwc; value->tag = VALUE_NULL; } + return value; } diff --git a/src/lib/main.c b/src/lib/main.c index 81cd6bb..03c31a5 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -2,24 +2,32 @@ #include "boot.h" enum aplwc_rc -aplwc_new(struct aplwc **p, uint8_t *data, size_t size) +aplwc_new(struct aplwc **p, struct aplwc_fns fns) { - struct aplwc tmp_aplwc; - - memory_init(&tmp_aplwc, data, size); - - *p = memory_alloc_aplwc(&tmp_aplwc); - if(*p == NULL) - return tmp_aplwc.last_error; - memcpy(*p, &tmp_aplwc, sizeof(tmp_aplwc)); - - return aplwc_load_module(*p, "Boot", (const char *)boot_src, boot_src_len); + struct aplwc *aplwc; + size_t size; + + if(fns.alloc == NULL) + return APLWC_OUT_OF_MEMORY; + aplwc = fns.alloc(sizeof(*aplwc), sizeof(*aplwc), &size); + if(aplwc == NULL) + return APLWC_OUT_OF_MEMORY; + *p = aplwc; + + aplwc->fns = fns; + memory_init(aplwc); + return aplwc_load_module(aplwc, "Boot", (const char *)boot_src, boot_src_len); } void aplwc_destroy(struct aplwc *p) { - UNUSED_PARAMETER(p); + if(p == NULL) + return; + + memory_destroy(p); + if(p->fns.dealloc) + p->fns.dealloc(p); } const char * @@ -70,26 +78,30 @@ aplwc_read(struct aplwc *aplwc, const char *line) struct token_list *tokens; struct aplwc_line *ret; - text = chars_to_string(aplwc, line, -1); - if(text == NULL) - return NULL; + MEMPTRS(aplwc, 2); + + ret = NULL; - tokens = scan_string(aplwc, text, 1); - if(tokens == NULL) - return NULL; + if((text = chars_to_string(aplwc, line, -1)) == NULL) + goto end; + MEMPTR(0, text); - aplwc->last_error = check_tokens(tokens); - if(aplwc->last_error != APLWC_OK) - return NULL; + if((tokens = scan_string(aplwc, text, 1)) == NULL) + goto end; + MEMPTR(1, tokens); - ret = memory_alloc_aplwc_line(aplwc); - if(ret == NULL) - return NULL; + if((aplwc->last_error = check_tokens(tokens)) != APLWC_OK) + goto end; + + if((ret = memory_alloc_aplwc_line(aplwc)) == NULL) + goto end; ret->aplwc = aplwc; ret->text = text; ret->tokens = tokens; +end: + MEMPTRS_EXIT(aplwc); return ret; } @@ -131,16 +143,22 @@ aplwc_load_module(struct aplwc *aplwc, const char *name, const char *src, int sr struct string *text, *namestr; struct token_list *tokens; + MEMPTRS(aplwc, 3); + if((namestr = chars_to_string(aplwc, name, -1)) == NULL) - goto error; + goto end; + MEMPTR(0, namestr); + if((text = chars_to_string(aplwc, src, srclen)) == NULL) - goto error; + goto end; + MEMPTR(1, text); + if((tokens = scan_string(aplwc, text, 0)) == NULL) - goto error; - if(load_module(aplwc, namestr, tokens) != APLWC_OK){ -error: - return aplwc_last_error(aplwc); - } + goto end; + MEMPTR(2, tokens); - return APLWC_OK; + aplwc->last_error = load_module(aplwc, namestr, tokens); +end: + MEMPTRS_EXIT(aplwc); + return aplwc_last_error(aplwc); } diff --git a/src/lib/memory.c b/src/lib/memory.c index 94f903c..8a91d2d 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -1,41 +1,201 @@ #include "aplwc_internal.h" +#define ALIGNMENT 8 +#define HEADER_SIZE (sizeof(struct chunk) + (sizeof(struct chunk) % ALIGNMENT)) + +enum chunk_tag { + CHUNK_TAG_FREE, + CHUNK_TAG_APLWC_LINE, + CHUNK_TAG_STRING, + CHUNK_TAG_TOKEN_LIST, + CHUNK_TAG_APLWC_VALUE, + CHUNK_TAG_APLWC_MODULE +}; + +struct chunk { + struct chunk *next; + size_t size; + enum chunk_tag tag; + uint8_t *data; +}; + void -memory_init(struct aplwc *aplwc, uint8_t *data , size_t size) +memory_init(struct aplwc *aplwc) { - aplwc->data = data; - aplwc->size = size; - aplwc->offset = 0; + aplwc->data = NULL; + aplwc->unaligned_data = NULL; + aplwc->size = 0; + aplwc->memptrs = NULL; } -static void * -alloc(struct aplwc *aplwc, size_t size, size_t align) +void +memory_destroy(struct aplwc *aplwc) { - uintptr_t ptr; - size_t alloc_size, adjust; - void *p; + if(aplwc->fns.dealloc) + aplwc->fns.dealloc(aplwc->unaligned_data); +} - ptr = ((uintptr_t)aplwc->data) + aplwc->offset; - alloc_size = 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); \ + } \ +}while(0) - if(NEVER(align == 0)) - return NULL; - adjust = ptr % align; +#define FIX_DATA(type, ptr) FIX(((type *)c->data)->ptr) - if(adjust) - alloc_size += align - adjust; + struct chunk *c; + struct memory_ptr_frame *frame; + size_t add, sub, i; - if((aplwc->size - aplwc->offset) >= alloc_size){ - p = aplwc->data+aplwc->offset+alloc_size-size; - assert((((uintptr_t)p) % align) == 0); - aplwc->offset += alloc_size; - memset(p, 0, size); + if(new > old){ + add = new-old; + sub = 0; }else{ - p = NULL; - aplwc->last_error = APLWC_OUT_OF_MEMORY; + add = 0; + sub = old-new; } - return p; + for(c = (struct chunk *)new; c; c = c->next){ + FIX(c->next); + FIX(c->data); + + 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]); + +#undef FIX +#undef FIX_DATA +} + +static enum aplwc_rc +grow(struct aplwc *aplwc, size_t extra) +{ + uint8_t *unaligned_data, *aligned_data; + size_t unaligned_newsize, aligned_newsize, adjust; + struct chunk **free; + + if(aplwc->fns.alloc == NULL) + goto error; + + unaligned_data = aplwc->fns.alloc(aplwc->size + extra + HEADER_SIZE + 2*ALIGNMENT, 0, &unaligned_newsize); + if(unaligned_data == NULL) + goto error; + + adjust = ((uintptr_t)unaligned_data) % ALIGNMENT; + if(adjust) + adjust = ALIGNMENT - adjust; + aligned_newsize = unaligned_newsize - adjust; + aligned_data = unaligned_data + adjust; + + aligned_newsize -= aligned_newsize % ALIGNMENT; + + assert(aligned_newsize >= (aplwc->size + extra)); + + if(aplwc->data){ + memmove(aligned_data, aplwc->data, aplwc->size); + fixrefs(aplwc, aligned_data, aplwc->data); + if(aplwc->fns.dealloc) + aplwc->fns.dealloc(aplwc->unaligned_data); + for(free = (struct chunk **)&aligned_data; (*free); free = &(*free)->next) + assert((*free)->tag != CHUNK_TAG_FREE); + }else + free = (struct chunk **)&aligned_data; + + + (*free) = (struct chunk *)(aligned_data + aplwc->size); + (*free)->tag = CHUNK_TAG_FREE; + (*free)->data = NULL; + (*free)->size = aligned_newsize - aplwc->size; + (*free)->next = NULL; + + aplwc->unaligned_data = unaligned_data; + aplwc->data = aligned_data; + aplwc->size = aligned_newsize; + return 1; + +error: + aplwc->last_error = APLWC_OUT_OF_MEMORY; + return 0; +} + +static struct chunk * +find_free(struct aplwc *aplwc, size_t min) +{ + struct chunk *c; + + min += HEADER_SIZE; + + if(aplwc->data == NULL) + return NULL; + + for(c = (struct chunk *)aplwc->data; c; c = c->next){ + if((c->tag == CHUNK_TAG_FREE) && (c->size >= min)) + break; + } + + return c; +} + +static void * +alloc(struct aplwc *aplwc, size_t size, enum chunk_tag tag) +{ + struct chunk *free; + struct chunk *new; + +retry: + free = find_free(aplwc, size); + if(!free){ + if(grow(aplwc, size)) + goto retry; + else + return NULL; + } + + assert(free->data == NULL); + + new = free; + + if(free->size > (size + 2*HEADER_SIZE)){ + free = (struct chunk *)(((uint8_t*)free) + HEADER_SIZE + size); + free->tag = CHUNK_TAG_FREE; + free->size = new->size - (HEADER_SIZE + size); + free->data = NULL; + } + + new->tag = tag; + new->size = sizeof(struct chunk) + size; + new->data = ((uint8_t*)new) + sizeof(struct chunk); + + new->data += ((uintptr_t)new->data) % ALIGNMENT; + + return new->data; } void @@ -47,13 +207,25 @@ memory_free_root(struct aplwc *aplwc, void *p) UNUSED_PARAMETER(aplwc); } -struct aplwc * -memory_alloc_aplwc(struct aplwc *aplwc) +void +memptrs_add(struct aplwc *aplwc, struct memory_ptr_frame *frame, void ***ptrs, size_t count) { - struct aplwc *p; + size_t i; - p = alloc(aplwc, sizeof(struct aplwc), alignof(struct aplwc)); - return p; + frame->ptrs = ptrs; + frame->link = aplwc->memptrs; + frame->count = count; + aplwc->memptrs = frame; + + for(i = 0; i < count; i++) + frame->ptrs[i] = NULL; +} + +void +memptrs_remove(struct aplwc *aplwc, struct memory_ptr_frame *frame) +{ + assert(aplwc->memptrs == frame); + aplwc->memptrs = frame->link; } struct aplwc_line * @@ -61,7 +233,7 @@ memory_alloc_aplwc_line(struct aplwc *aplwc) { struct aplwc_line *p; - p = alloc(aplwc, sizeof(struct aplwc_line), alignof(struct aplwc_line)); + p = alloc(aplwc, sizeof(struct aplwc_line), CHUNK_TAG_APLWC_LINE); return p; } @@ -70,7 +242,8 @@ memory_alloc_string(struct aplwc *aplwc, size_t bytes) { struct string *p; - p = alloc(aplwc, sizeof(struct string) + bytes, alignof(struct string)); + p = alloc(aplwc, sizeof(struct string) + bytes, CHUNK_TAG_STRING); + return p; } @@ -79,7 +252,7 @@ memory_alloc_token_list(struct aplwc *aplwc, size_t tokens) { struct token_list *p; - p = alloc(aplwc, sizeof(struct token_list) + (tokens * sizeof(struct token)), alignof(struct token_list)); + p = alloc(aplwc, sizeof(struct token_list) + (tokens * sizeof(struct token)), CHUNK_TAG_TOKEN_LIST); return p; } @@ -88,7 +261,7 @@ memory_alloc_aplwc_value(struct aplwc *aplwc) { struct aplwc_value *p; - p = alloc(aplwc, sizeof(struct aplwc_value), alignof(struct aplwc_value)); + p = alloc(aplwc, sizeof(struct aplwc_value), CHUNK_TAG_APLWC_VALUE); return p; } @@ -97,6 +270,6 @@ memory_alloc_aplwc_module(struct aplwc *aplwc) { struct aplwc_module *p; - p = alloc(aplwc, sizeof(struct aplwc_module), alignof(struct aplwc_module)); + p = alloc(aplwc, sizeof(struct aplwc_module), CHUNK_TAG_APLWC_MODULE); return p; } diff --git a/src/lib/module.c b/src/lib/module.c index f559f00..3bca396 100644 --- a/src/lib/module.c +++ b/src/lib/module.c @@ -58,9 +58,17 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) enum aplwc_rc rc; struct aplwc_module *module; + MEMPTRS(aplwc, 2); + + MEMPTR(0, name); + MEMPTR(1, tokens); + module = memory_alloc_aplwc_module(aplwc); - if(module == NULL) - return aplwc->last_error; + if(module == NULL){ + rc = aplwc_last_error(aplwc); + goto end; + } + module->aplwc = aplwc; module->name = name; module->tokens = tokens; @@ -70,8 +78,11 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) if(rc == APLWC_OK){ module->link = aplwc->modules; aplwc->modules = module; - } + }else + aplwc->last_error = rc; +end: + MEMPTRS_EXIT(aplwc); return rc; } diff --git a/src/lib/syntax.c b/src/lib/syntax.c index 75d6c14..ae52343 100644 --- a/src/lib/syntax.c +++ b/src/lib/syntax.c @@ -240,15 +240,17 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) struct token_list *tokens; size_t n, i; + MEMPTRS(aplwc, 1); + MEMPTR(0, text); + + tokens = NULL; rc = check(text, &n); - if(rc != APLWC_OK){ - aplwc->last_error = rc; - return NULL; - } + if(rc != APLWC_OK) + goto end; tokens = memory_alloc_token_list(aplwc, n); if(tokens == NULL) - return NULL; + goto end; tokens->text = text; tokens->length = n; scan(text, tokens); @@ -258,11 +260,17 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline) continue; for(i++; i < n; i++){ - if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE) - return NULL; + if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE){ + rc = APLWC_INVALID_SYNTAX; + tokens = NULL; + goto end; + } } } +end: + aplwc->last_error = rc; + MEMPTRS_EXIT(aplwc); return tokens; } diff --git a/tests/aplwc_errstr.c b/tests/aplwc_errstr.c index 2ca14ab..1a5ebc4 100644 --- a/tests/aplwc_errstr.c +++ b/tests/aplwc_errstr.c @@ -1,47 +1,76 @@ -#include +#include #include +#include + +static void * +my_alloc(size_t min, size_t max, size_t *actual) +{ + (void)max; + + *actual = min; + return malloc(min); +} + +static void +my_dealloc(void *p) +{ + free(p); +} int main(void) { - uint8_t data[20000]; + struct aplwc_fns fns; struct aplwc *aplwc; - int ret; + int ret, success; const char *err; - ret = aplwc_new(&aplwc, data, sizeof(data)); + success = 0; + aplwc = NULL; + + memset(&fns, 0, sizeof(fns)); + fns.alloc = my_alloc; + fns.dealloc = my_dealloc; + + ret = aplwc_new(&aplwc, fns); if(ret) - return 1; + goto end; err = aplwc_errstr(aplwc); if(err == NULL) - return 1; + goto end; if(strlen(err) != 0) - return 1; + goto end; err = aplwc_errstr(NULL); if(err == NULL) - return 1; + goto end; if(strcmp(err, "(unable to produce error string)") != 0) - return 1; + goto end; aplwc_destroy(aplwc); + aplwc = NULL; - ret = aplwc_new(&aplwc, data, 0); + fns.alloc = NULL; + ret = aplwc_new(&aplwc, fns); if(ret == 0) - return 1; + goto end; err = aplwc_errstr_rc(ret); if(err == NULL) - return 1; + goto end; for(ret = 0; ret <= APLWC_RC_LAST; ret++){ err = aplwc_errstr_rc(ret); if(err == NULL) - return 1; + goto end; if(strcmp(err, "(unable to produce error string)") == 0) - return 1; + goto end; } - return 0; + success = 1; +end: + if(aplwc) + aplwc_destroy(aplwc); + return !success; } diff --git a/tests/aplwc_eval.c b/tests/aplwc_eval.c index c284189..68ea4a8 100644 --- a/tests/aplwc_eval.c +++ b/tests/aplwc_eval.c @@ -1,15 +1,31 @@ #include #include +#include #include +static void * +my_alloc(size_t min, size_t max, size_t *actual) +{ + (void)max; + + *actual = min; + return malloc(min); +} + +static void +my_dealloc(void *p) +{ + free(p); +} + int main(int argc, char *argv[]) { - uint8_t data[64000]; char *input; struct aplwc *aplwc; struct aplwc_line *line; struct aplwc_value *value; + struct aplwc_fns fns; enum aplwc_rc ret; FILE *f; long input_size; @@ -35,7 +51,12 @@ main(int argc, char *argv[]) return 1; input[input_size] = 0; - ret = aplwc_new(&aplwc, data, sizeof(data)); + + memset(&fns, 0, sizeof(fns)); + fns.alloc = my_alloc; + fns.dealloc = my_dealloc; + + ret = aplwc_new(&aplwc, fns); if(ret) return 1; diff --git a/tests/aplwc_new.c b/tests/aplwc_new.c deleted file mode 100644 index 4ed893e..0000000 --- a/tests/aplwc_new.c +++ /dev/null @@ -1,24 +0,0 @@ -#include - -int -main(void) -{ - struct aplwc *aplwc; - uint8_t data[10000]; - int ret; - size_t i, j; - - for(i = 0; i < 32; i++){ - for(j = 0; j <= sizeof(data)-i; j++){ - ret = aplwc_new(&aplwc, data+i, j); - aplwc_destroy(aplwc); - if(ret){ - if(ret != APLWC_OUT_OF_MEMORY) - return 1; - break; - } - } - } - - return 0; -} diff --git a/tests/aplwc_read.c b/tests/aplwc_read.c index 8c5ce37..42a47c2 100644 --- a/tests/aplwc_read.c +++ b/tests/aplwc_read.c @@ -1,11 +1,27 @@ #include #include +#include #include +static void * +my_alloc(size_t min, size_t max, size_t *actual) +{ + (void)max; + + *actual = min; + return malloc(min); +} + +static void +my_dealloc(void *p) +{ + free(p); +} + int main(int argc, char *argv[]) { - uint8_t data[20000]; + struct aplwc_fns fns; char *input; struct aplwc *aplwc; struct aplwc_line *line; @@ -13,6 +29,10 @@ main(int argc, char *argv[]) FILE *f; long input_size; + memset(&fns, 0, sizeof(fns)); + fns.alloc = my_alloc; + fns.dealloc = my_dealloc; + if(argc != 2) return 1; @@ -33,7 +53,7 @@ main(int argc, char *argv[]) return 1; input[input_size] = 0; - ret = aplwc_new(&aplwc, data, sizeof(data)); + ret = aplwc_new(&aplwc, fns); if(ret) return 1; diff --git a/tests/aplwc_utf8.c b/tests/aplwc_utf8.c index b950580..4f9f2a4 100644 --- a/tests/aplwc_utf8.c +++ b/tests/aplwc_utf8.c @@ -1,3 +1,5 @@ +#include +#include #include uint8_t bad1[] = {0xff,0}; @@ -14,12 +16,27 @@ uint8_t good3[] = {0xed,0x95,0x9c,0xea,0xb5,0xad,0xec,0x96,0xb4,0}; uint8_t good4[] = {0xe6,0x97,0xa5,0xe6,0x9c,0xac,0xe8,0xaa,0x9e,0}; uint8_t good5[] = {0xef,0xbb,0xbf,0xf0,0xa3,0x8e,0xb4,0}; +static void * +my_alloc(size_t min, size_t max, size_t *actual) +{ + (void)max; + + *actual = min; + return malloc(min); +} + +static void +my_dealloc(void *p) +{ + free(p); +} + int main(void) { - uint8_t data[64000]; struct aplwc *aplwc; struct aplwc_line *line; + struct aplwc_fns fns; enum aplwc_rc ret; size_t i; @@ -41,7 +58,11 @@ main(void) good5 }; - ret = aplwc_new(&aplwc, data, sizeof(data)); + memset(&fns, 0, sizeof(fns)); + fns.alloc = my_alloc; + fns.dealloc = my_dealloc; + + ret = aplwc_new(&aplwc, fns); if(ret) return 1; -- cgit v1.2.3 From 7f7a2fb4fb23433e7be3d6953725690c8ea958d2 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 31 Aug 2026 19:44:56 +0000 Subject: The objects returned to the user are now integer-based references, not actual pointers. This means the aplwc internals can update those pointers without the user noticing. FossilOrigin-Name: 654c7d0ec85da295a7fb6ed381500410686b280f342fa81a30481f5e9a20c58a --- src/bin/main.c | 37 +++++++++------- src/include/aplwc.h | 26 ++++++++---- src/lib/aplwc_internal.h | 13 +++++- src/lib/main.c | 107 ++++++++++++++++++++++++++++++++++------------- src/lib/memory.c | 83 ++++++++++++++++++++++++++++++++++-- tests/aplwc_errstr.c | 9 ++-- tests/aplwc_eval.c | 10 ++--- tests/aplwc_read.c | 6 +-- tests/aplwc_utf8.c | 8 ++-- 9 files changed, 226 insertions(+), 73 deletions(-) diff --git a/src/bin/main.c b/src/bin/main.c index 99149f6..42ab963 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -4,7 +4,8 @@ #include #include "aplwc_repl.h" -static void *my_alloc(size_t min, size_t max, size_t *actual) +static void * +my_alloc(size_t min, size_t max, size_t *actual) { UNUSED_PARAMETER(max); @@ -12,23 +13,29 @@ static void *my_alloc(size_t min, size_t max, size_t *actual) return malloc(min); } +static void +my_dealloc(void *p) +{ + free(p); +} + int main(int argc, char *argv[]) { struct aplwc_fns fns; struct aplwc *aplwc; - struct aplwc_line *line; - struct aplwc_value *value; + enum aplwc_rc ret; + AplwcLine line; + AplwcValue value; char *input, *src; - int ret, exit_code, line_number; + int exit_code, line_number; size_t input_size, src_size, i; int opt, xflag, input_file; long tmp; FILE *f; - input = NULL; - line = NULL; - value = NULL; + aplwc_clear_line(&line); + aplwc_clear_value(&value); xflag = 0; input_file = 0; exit_code = 0; @@ -36,6 +43,7 @@ main(int argc, char *argv[]) memset(&fns, 0, sizeof(fns)); fns.alloc = my_alloc; + fns.dealloc = my_dealloc; while((opt = getopt(argc, argv, "x")) != -1){ switch(opt){ @@ -61,7 +69,7 @@ usage: else goto usage; - ret = aplwc_new(&aplwc, fns); + aplwc = aplwc_new(fns, &ret); if(ret){ fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr_rc(ret)); return 1; @@ -117,19 +125,20 @@ file_size: for(;;){ if(input) free(input); - if(line) + if(aplwc_valid_line(line)) aplwc_free_line(line); - if(value) + if(aplwc_valid_value(value)) aplwc_free_value(value); input = NULL; if(getline(&input, &input_size, stdin) < 0){ free(input); + input = NULL; break; }else{ line_number++; line = aplwc_read(aplwc, input); - if(line == NULL){ + 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){ @@ -139,7 +148,7 @@ line_error: continue; } value = aplwc_eval(line); - if(value == NULL) + if(!aplwc_valid_value(value)) goto line_error; fprintf(stdout, "%s\n", aplwc_value_string(value)); } @@ -148,9 +157,9 @@ line_error: exit: if(input) free(input); - if(line) + if(aplwc_valid_line(line)) aplwc_free_line(line); - if(value) + if(aplwc_valid_value(value)) aplwc_free_value(value); aplwc_destroy(aplwc); diff --git a/src/include/aplwc.h b/src/include/aplwc.h index 843fe42..6ba2e35 100644 --- a/src/include/aplwc.h +++ b/src/include/aplwc.h @@ -15,24 +15,34 @@ enum aplwc_rc { }; struct aplwc; -struct aplwc_line; -struct aplwc_value; + +struct aplwc_ref { + struct aplwc *aplwc; + int id; +}; + +typedef struct { struct aplwc_ref ref; } AplwcLine; +typedef struct { struct aplwc_ref ref; } AplwcValue; struct aplwc_fns { void *(*alloc)(size_t, size_t, size_t *); void (*dealloc)(void *); }; -enum aplwc_rc aplwc_new(struct aplwc **, struct aplwc_fns); +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); const char *aplwc_errstr_rc(enum aplwc_rc); const char *aplwc_errstr(struct aplwc *); enum aplwc_rc aplwc_last_error(struct aplwc *); -struct aplwc_line *aplwc_read(struct aplwc *, const char *); -void aplwc_free_line(struct aplwc_line *); -struct aplwc_value *aplwc_eval(struct aplwc_line *); -void aplwc_free_value(struct aplwc_value *); -const char *aplwc_value_string(struct aplwc_value *); +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); 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 a7b7030..5320336 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -18,6 +18,7 @@ struct aplwc { uint8_t *unaligned_data; size_t size; struct memory_ptr_frame *memptrs; + struct root_ptr *rootptrs; }; struct memory_ptr_frame { @@ -26,6 +27,12 @@ struct memory_ptr_frame { size_t count; }; +struct root_ptr { + int id; + void *ptr; + struct root_ptr *link; +}; + struct aplwc_line { struct aplwc *aplwc; struct string *text; @@ -95,9 +102,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); -void memory_free_root(struct aplwc *, void *); +struct aplwc_ref memory_root_new(struct aplwc *, void *); +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); #define MEMPTRS(aplwc, n) \ void **memptrs[n]; \ diff --git a/src/lib/main.c b/src/lib/main.c index 03c31a5..454ad1c 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -1,22 +1,34 @@ #include "aplwc_internal.h" #include "boot.h" -enum aplwc_rc -aplwc_new(struct aplwc **p, struct aplwc_fns fns) +struct aplwc * +aplwc_new(struct aplwc_fns fns, enum aplwc_rc *rcp) { + enum aplwc_rc rc; struct aplwc *aplwc; size_t size; - if(fns.alloc == NULL) - return APLWC_OUT_OF_MEMORY; + aplwc = NULL; + if(fns.alloc == NULL){ + rc = APLWC_OUT_OF_MEMORY; + goto end; + } aplwc = fns.alloc(sizeof(*aplwc), sizeof(*aplwc), &size); - if(aplwc == NULL) - return APLWC_OUT_OF_MEMORY; - *p = aplwc; + if(aplwc == NULL){ + rc = APLWC_OUT_OF_MEMORY; + goto end; + } aplwc->fns = fns; memory_init(aplwc); - return aplwc_load_module(aplwc, "Boot", (const char *)boot_src, boot_src_len); + + rc = aplwc_load_module(aplwc, "Boot", (const char *)boot_src, boot_src_len); +end: + if(rc != APLWC_OK) + aplwc_destroy(aplwc); + if(rcp) + *rcp = rc; + return aplwc; } void @@ -71,18 +83,19 @@ aplwc_last_error(struct aplwc *aplwc) return aplwc->last_error; } -struct aplwc_line * -aplwc_read(struct aplwc *aplwc, const char *line) +AplwcLine +aplwc_read(struct aplwc *aplwc, const char *linestr) { struct string *text; struct token_list *tokens; - struct aplwc_line *ret; + struct aplwc_line *line; + AplwcLine ret; MEMPTRS(aplwc, 2); - ret = NULL; + aplwc_clear_line(&ret); - if((text = chars_to_string(aplwc, line, -1)) == NULL) + if((text = chars_to_string(aplwc, linestr, -1)) == NULL) goto end; MEMPTR(0, text); @@ -93,45 +106,55 @@ aplwc_read(struct aplwc *aplwc, const char *line) if((aplwc->last_error = check_tokens(tokens)) != APLWC_OK) goto end; - if((ret = memory_alloc_aplwc_line(aplwc)) == NULL) + if((line = memory_alloc_aplwc_line(aplwc)) == NULL) goto end; - ret->aplwc = aplwc; - ret->text = text; - ret->tokens = tokens; + line->aplwc = aplwc; + line->text = text; + line->tokens = tokens; + ret.ref = memory_root_new(aplwc, line); end: MEMPTRS_EXIT(aplwc); return ret; } void -aplwc_free_line(struct aplwc_line *line) +aplwc_free_line(AplwcLine line) { - if(line) - memory_free_root(line->aplwc, line); + memory_root_free(line.ref); } -struct aplwc_value * -aplwc_eval(struct aplwc_line *line) +AplwcValue +aplwc_eval(AplwcLine line) { - line->aplwc->last_error = APLWC_OK; - return eval_line(line); + AplwcValue value; + struct aplwc_line *l; + struct aplwc_value *v; + + aplwc_clear_value(&value); + l = memory_root_get(line.ref); + l->aplwc->last_error = APLWC_OK; + v = eval_line(l); + if(v) + value.ref = memory_root_new(line.ref.aplwc, v); + return value; } void -aplwc_free_value(struct aplwc_value *value) +aplwc_free_value(AplwcValue value) { - if(value) - memory_free_root(value->aplwc, value); + memory_root_free(value.ref); } const char * -aplwc_value_string(struct aplwc_value *value) +aplwc_value_string(AplwcValue value) { - assert(value != NULL); + struct aplwc_value *v; + assert(aplwc_valid_value(value)); - switch(value->tag){ + v = memory_root_get(value.ref); + switch(v->tag){ default: return "???"; } @@ -162,3 +185,27 @@ end: MEMPTRS_EXIT(aplwc); return aplwc_last_error(aplwc); } + +void +aplwc_clear_value(AplwcValue *v) +{ + clear_ref(&v->ref); +} + +void +aplwc_clear_line(AplwcLine *l) +{ + clear_ref(&l->ref); +} + +int +aplwc_valid_value(AplwcValue v) +{ + return valid_ref(v.ref); +} + +int +aplwc_valid_line(AplwcLine l) +{ + return valid_ref(l.ref); +} diff --git a/src/lib/memory.c b/src/lib/memory.c index 8a91d2d..b6e044a 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -26,6 +26,7 @@ memory_init(struct aplwc *aplwc) aplwc->unaligned_data = NULL; aplwc->size = 0; aplwc->memptrs = NULL; + aplwc->rootptrs = NULL; } void @@ -49,6 +50,7 @@ fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old) struct chunk *c; struct memory_ptr_frame *frame; + struct root_ptr *root; size_t add, sub, i; if(new > old){ @@ -89,6 +91,10 @@ fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old) 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); #undef FIX #undef FIX_DATA @@ -198,13 +204,71 @@ retry: return new->data; } +struct aplwc_ref +memory_root_new(struct aplwc *aplwc, void *p) +{ + 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; +} + +void * +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; +} + void -memory_free_root(struct aplwc *aplwc, void *p) +memory_root_free(struct aplwc_ref ref) { - if(NEVER(p == NULL)) + struct aplwc *aplwc; + struct root_ptr **root, *tmp; + + if(!valid_ref(ref)) return; - UNUSED_PARAMETER(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); + break; + } + } } void @@ -273,3 +337,16 @@ memory_alloc_aplwc_module(struct aplwc *aplwc) p = alloc(aplwc, sizeof(struct aplwc_module), CHUNK_TAG_APLWC_MODULE); return p; } + +void +clear_ref(struct aplwc_ref *ref) +{ + ref->id = -1; + ref->aplwc = NULL; +} + +int +valid_ref(struct aplwc_ref ref) +{ + return ref.id >= 0; +} diff --git a/tests/aplwc_errstr.c b/tests/aplwc_errstr.c index 1a5ebc4..fe9fa0e 100644 --- a/tests/aplwc_errstr.c +++ b/tests/aplwc_errstr.c @@ -20,19 +20,19 @@ my_dealloc(void *p) int main(void) { + enum aplwc_rc ret; struct aplwc_fns fns; struct aplwc *aplwc; - int ret, success; + int success; const char *err; success = 0; - aplwc = NULL; memset(&fns, 0, sizeof(fns)); fns.alloc = my_alloc; fns.dealloc = my_dealloc; - ret = aplwc_new(&aplwc, fns); + aplwc = aplwc_new(fns, &ret); if(ret) goto end; @@ -50,10 +50,9 @@ main(void) goto end; aplwc_destroy(aplwc); - aplwc = NULL; fns.alloc = NULL; - ret = aplwc_new(&aplwc, fns); + aplwc = aplwc_new(fns, &ret); if(ret == 0) goto end; err = aplwc_errstr_rc(ret); diff --git a/tests/aplwc_eval.c b/tests/aplwc_eval.c index 68ea4a8..3fd8c27 100644 --- a/tests/aplwc_eval.c +++ b/tests/aplwc_eval.c @@ -23,8 +23,8 @@ main(int argc, char *argv[]) { char *input; struct aplwc *aplwc; - struct aplwc_line *line; - struct aplwc_value *value; + AplwcLine line; + AplwcValue value; struct aplwc_fns fns; enum aplwc_rc ret; FILE *f; @@ -56,7 +56,7 @@ main(int argc, char *argv[]) fns.alloc = my_alloc; fns.dealloc = my_dealloc; - ret = aplwc_new(&aplwc, fns); + aplwc = aplwc_new(fns, &ret); if(ret) return 1; @@ -66,11 +66,11 @@ main(int argc, char *argv[]) input[i] = 0; line = aplwc_read(aplwc, &input[j]); - if(line == NULL) + if(!aplwc_valid_line(line)) return 1; value = aplwc_eval(line); - if((value == NULL) && (aplwc_last_error(aplwc) != APLWC_OUT_OF_MEMORY)) + if((!aplwc_valid_value(value)) && (aplwc_last_error(aplwc) != APLWC_OUT_OF_MEMORY)) return 1; aplwc_free_value(value); diff --git a/tests/aplwc_read.c b/tests/aplwc_read.c index 42a47c2..d090494 100644 --- a/tests/aplwc_read.c +++ b/tests/aplwc_read.c @@ -24,7 +24,7 @@ main(int argc, char *argv[]) struct aplwc_fns fns; char *input; struct aplwc *aplwc; - struct aplwc_line *line; + AplwcLine line; enum aplwc_rc ret; FILE *f; long input_size; @@ -53,12 +53,12 @@ main(int argc, char *argv[]) return 1; input[input_size] = 0; - ret = aplwc_new(&aplwc, fns); + aplwc = aplwc_new(fns, &ret); if(ret) return 1; line = aplwc_read(aplwc, input); - if((line == NULL) && (aplwc_last_error(aplwc) != APLWC_OUT_OF_MEMORY)) + if((!aplwc_valid_line(line)) && (aplwc_last_error(aplwc) != APLWC_OUT_OF_MEMORY)) return 1; aplwc_free_line(line); aplwc_destroy(aplwc); diff --git a/tests/aplwc_utf8.c b/tests/aplwc_utf8.c index 4f9f2a4..367db5d 100644 --- a/tests/aplwc_utf8.c +++ b/tests/aplwc_utf8.c @@ -35,7 +35,7 @@ int main(void) { struct aplwc *aplwc; - struct aplwc_line *line; + AplwcLine line; struct aplwc_fns fns; enum aplwc_rc ret; size_t i; @@ -62,13 +62,13 @@ main(void) fns.alloc = my_alloc; fns.dealloc = my_dealloc; - ret = aplwc_new(&aplwc, fns); + aplwc = aplwc_new(fns, &ret); if(ret) return 1; for(i = 0; i < (sizeof(bad_tests)/sizeof(*bad_tests)); i++){ line = aplwc_read(aplwc, (char *)bad_tests[i]); - if(line != NULL) + if(aplwc_valid_line(line)) return 1; if(aplwc_last_error(aplwc) != APLWC_INVALID_UTF8) return 1; @@ -77,7 +77,7 @@ main(void) for(i = 0; i < (sizeof(good_tests)/sizeof(*good_tests)); i++){ line = aplwc_read(aplwc, (char *)good_tests[i]); - if((line == NULL) && (aplwc_last_error(aplwc) == APLWC_INVALID_UTF8)) + if((!aplwc_valid_line(line)) && (aplwc_last_error(aplwc) == APLWC_INVALID_UTF8)) return 1; aplwc_free_line(line); } -- cgit v1.2.3 From 34189c9b67f3427e077152e3a6c8cb21f4ba3441 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 31 Aug 2026 19:49:48 +0000 Subject: Remove some unneeded references to struct aplwc * in various structures. FossilOrigin-Name: 3b4b7806320d604b0df3654896cfe5d885f116d893ae15cfb3422d6d2de7193c --- src/lib/aplwc_internal.h | 5 +---- src/lib/eval.c | 10 ++++------ src/lib/main.c | 10 ++++++---- src/lib/module.c | 1 - 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h index 5320336..b87cfad 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -34,7 +34,6 @@ struct root_ptr { }; struct aplwc_line { - struct aplwc *aplwc; struct string *text; struct token_list *tokens; }; @@ -79,19 +78,17 @@ enum value_tag { }; struct aplwc_value { - struct aplwc *aplwc; enum value_tag tag; }; struct aplwc_module { - struct aplwc *aplwc; struct string *name; struct token_list *tokens; struct aplwc_module *link; }; /* eval.c */ -struct aplwc_value *eval_line(struct aplwc_line *); +struct aplwc_value *eval_line(struct aplwc *, struct aplwc_line *); /* memory.c */ void memory_init(struct aplwc *); diff --git a/src/lib/eval.c b/src/lib/eval.c index 50c3cda..0da90db 100644 --- a/src/lib/eval.c +++ b/src/lib/eval.c @@ -1,19 +1,17 @@ #include "aplwc_internal.h" struct aplwc_value * -eval_line(struct aplwc_line *line) +eval_line(struct aplwc *aplwc, struct aplwc_line *line) { struct aplwc_value *value; - struct aplwc *aplwc; - aplwc = line->aplwc; + UNUSED_PARAMETER(line); + assert(aplwc->last_error == APLWC_OK); value = memory_alloc_aplwc_value(aplwc); - if(value != NULL){ - value->aplwc = aplwc; + if(value != NULL) value->tag = VALUE_NULL; - } return value; } diff --git a/src/lib/main.c b/src/lib/main.c index 454ad1c..dcf4a1c 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -109,7 +109,6 @@ aplwc_read(struct aplwc *aplwc, const char *linestr) if((line = memory_alloc_aplwc_line(aplwc)) == NULL) goto end; - line->aplwc = aplwc; line->text = text; line->tokens = tokens; @@ -131,13 +130,16 @@ aplwc_eval(AplwcLine line) AplwcValue value; struct aplwc_line *l; struct aplwc_value *v; + struct aplwc *aplwc; + + aplwc = line.ref.aplwc; aplwc_clear_value(&value); l = memory_root_get(line.ref); - l->aplwc->last_error = APLWC_OK; - v = eval_line(l); + aplwc->last_error = APLWC_OK; + v = eval_line(aplwc, l); if(v) - value.ref = memory_root_new(line.ref.aplwc, v); + value.ref = memory_root_new(aplwc, v); return value; } diff --git a/src/lib/module.c b/src/lib/module.c index 3bca396..2524eca 100644 --- a/src/lib/module.c +++ b/src/lib/module.c @@ -69,7 +69,6 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens) goto end; } - module->aplwc = aplwc; module->name = name; module->tokens = tokens; module->link = NULL; -- cgit v1.2.3 From 79663b57ce0b1f2da77d4e8bfd831f318aada49b Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 31 Aug 2026 19:51:12 +0000 Subject: Bump the number of required malloc's for the tests FossilOrigin-Name: a2d12252a66efb821c717a1b77ae164de940d52a1cc182de06e2fe5ea1df5772 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d2a607..2cda996 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ endforeach() add_test(NAME "aplwc-repl" COMMAND "aplwc-repl" "-x") -set(REQUIRED_MALLOCS 1) +set(REQUIRED_MALLOCS 3) foreach(i RANGE 0 ${REQUIRED_MALLOCS}) set(name "aplwc-repl-${i}-${REQUIRED_MALLOCS}") add_test(NAME "${name}" COMMAND "aplwc-repl" "-x") -- cgit v1.2.3 From 0091c055edceca2598dfb7dd64cdcb081e4c7507 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 31 Aug 2026 20:04:50 +0000 Subject: Fix problems in release builds FossilOrigin-Name: 98227d25674f373968f51df0dcdccf3cf14d646a13e56a9229103d1aeb3ad73d --- src/bin/main.c | 1 + src/lib/memory.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/bin/main.c b/src/bin/main.c index 42ab963..c3743f2 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -36,6 +36,7 @@ main(int argc, char *argv[]) aplwc_clear_line(&line); aplwc_clear_value(&value); + input = NULL; xflag = 0; input_file = 0; exit_code = 0; diff --git a/src/lib/memory.c b/src/lib/memory.c index b6e044a..694a31b 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -105,7 +105,7 @@ grow(struct aplwc *aplwc, size_t extra) { uint8_t *unaligned_data, *aligned_data; size_t unaligned_newsize, aligned_newsize, adjust; - struct chunk **free; + struct chunk **free, *head; if(aplwc->fns.alloc == NULL) goto error; @@ -123,16 +123,17 @@ grow(struct aplwc *aplwc, size_t extra) aligned_newsize -= aligned_newsize % ALIGNMENT; assert(aligned_newsize >= (aplwc->size + extra)); + head = (struct chunk *)aligned_data; if(aplwc->data){ memmove(aligned_data, aplwc->data, aplwc->size); fixrefs(aplwc, aligned_data, aplwc->data); if(aplwc->fns.dealloc) aplwc->fns.dealloc(aplwc->unaligned_data); - for(free = (struct chunk **)&aligned_data; (*free); free = &(*free)->next) + for(free = &head; (*free); free = &(*free)->next) assert((*free)->tag != CHUNK_TAG_FREE); }else - free = (struct chunk **)&aligned_data; + free = &head; (*free) = (struct chunk *)(aligned_data + aplwc->size); -- cgit v1.2.3 From f9f9b10c1d17077632d7a09e447e629b8d33b23d Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 31 Aug 2026 20:21:54 +0000 Subject: A little bit of testing FossilOrigin-Name: 70deba994bb488d4aa5df36577d1e184d6651a3edeff042e9666f54589cdc6f9 --- CMakeLists.txt | 16 ++++++++++++---- src/lib/main.c | 4 ++-- tests/scripts/1.aplwc | 5 ----- tests/scripts/2.aplwc | 9 --------- tests/scripts/bad/1.aplwc | 1 + tests/scripts/bad/2.aplwc | 1 + tests/scripts/bad/3.aplwc | 1 + tests/scripts/good/1.aplwc | 5 +++++ tests/scripts/good/2.aplwc | 9 +++++++++ 9 files changed, 31 insertions(+), 20 deletions(-) delete mode 100755 tests/scripts/1.aplwc delete mode 100755 tests/scripts/2.aplwc create mode 100755 tests/scripts/bad/1.aplwc create mode 100755 tests/scripts/bad/2.aplwc create mode 100755 tests/scripts/bad/3.aplwc create mode 100755 tests/scripts/good/1.aplwc create mode 100755 tests/scripts/good/2.aplwc diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cda996..9da17b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,19 +100,27 @@ foreach(source ${TEST_SOURCES}) endif() endforeach() -file(GLOB TEST_SCRIPTS CONFIGURE_DEPENDS "tests/scripts/*.aplwc") -foreach(script ${TEST_SCRIPTS}) +file(GLOB TEST_SCRIPTS_GOOD CONFIGURE_DEPENDS "tests/scripts/good/*.aplwc") +foreach(script ${TEST_SCRIPTS_GOOD}) add_test(NAME "${script}" COMMAND "${script}") set_tests_properties("${script}" PROPERTIES - ENVIRONMENT "APLWC_MEM=64000;PATH=$" + ENVIRONMENT "PATH=$" ) add_test(NAME "aplwc-repl ${script}" COMMAND "aplwc-repl" "${script}") set_tests_properties("aplwc-repl ${script}" PROPERTIES - ENVIRONMENT "APLWC_MEM=64000;PATH=$" + ENVIRONMENT "PATH=$" ) endforeach() +file(GLOB TEST_SCRIPTS_BAD CONFIGURE_DEPENDS "tests/scripts/bad/*.aplwc") +foreach(script ${TEST_SCRIPTS_BAD}) + add_test(NAME "aplwc-repl ${script}" COMMAND "aplwc-repl" "${script}") + set_tests_properties("aplwc-repl ${script}" PROPERTIES + ENVIRONMENT "PATH=$" + WILL_FAIL TRUE + ) +endforeach() add_test(NAME "aplwc-repl" COMMAND "aplwc-repl" "-x") diff --git a/src/lib/main.c b/src/lib/main.c index dcf4a1c..4571c78 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -26,8 +26,8 @@ aplwc_new(struct aplwc_fns fns, enum aplwc_rc *rcp) end: if(rc != APLWC_OK) aplwc_destroy(aplwc); - if(rcp) - *rcp = rc; + assert(rcp); + *rcp = rc; return aplwc; } diff --git a/tests/scripts/1.aplwc b/tests/scripts/1.aplwc deleted file mode 100755 index e101d02..0000000 --- a/tests/scripts/1.aplwc +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env aplwc-repl - -∇ run -⎕←40 + 2 -∇ diff --git a/tests/scripts/2.aplwc b/tests/scripts/2.aplwc deleted file mode 100755 index e60e717..0000000 --- a/tests/scripts/2.aplwc +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env aplwc-repl - -∇ run - foo 123 -∇ - -∇ foo x - ⎕←x+x -∇ diff --git a/tests/scripts/bad/1.aplwc b/tests/scripts/bad/1.aplwc new file mode 100755 index 0000000..792d600 --- /dev/null +++ b/tests/scripts/bad/1.aplwc @@ -0,0 +1 @@ +# diff --git a/tests/scripts/bad/2.aplwc b/tests/scripts/bad/2.aplwc new file mode 100755 index 0000000..1e0a14c --- /dev/null +++ b/tests/scripts/bad/2.aplwc @@ -0,0 +1 @@ +!# diff --git a/tests/scripts/bad/3.aplwc b/tests/scripts/bad/3.aplwc new file mode 100755 index 0000000..ba38a01 --- /dev/null +++ b/tests/scripts/bad/3.aplwc @@ -0,0 +1 @@ +## diff --git a/tests/scripts/good/1.aplwc b/tests/scripts/good/1.aplwc new file mode 100755 index 0000000..e101d02 --- /dev/null +++ b/tests/scripts/good/1.aplwc @@ -0,0 +1,5 @@ +#!/usr/bin/env aplwc-repl + +∇ run +⎕←40 + 2 +∇ diff --git a/tests/scripts/good/2.aplwc b/tests/scripts/good/2.aplwc new file mode 100755 index 0000000..e60e717 --- /dev/null +++ b/tests/scripts/good/2.aplwc @@ -0,0 +1,9 @@ +#!/usr/bin/env aplwc-repl + +∇ run + foo 123 +∇ + +∇ foo x + ⎕←x+x +∇ -- cgit v1.2.3