summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorpeter <peter@pmikkelsen.com>2026-08-31 20:22:47 +0000
committerpeter <peter@pmikkelsen.com>2026-08-31 20:22:47 +0000
commit8b0beb9e6a57c1d4f1e7b0b06523dd0fc538771a (patch)
tree9bb8b689020d5098ea3c31251ddcd2fbb9524a7c /src/lib
parentd361abaeb8dcf19446a9322737ea600b22568a5b (diff)
parentf9f9b10c1d17077632d7a09e447e629b8d33b23d (diff)
Merge memory manager changes into trunk
FossilOrigin-Name: af583e3ba70b2d10efdead8e03a42fe5c1b94d6b387522833606c138b527a653
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/aplwc_internal.h66
-rw-r--r--src/lib/eval.c16
-rw-r--r--src/lib/main.c190
-rw-r--r--src/lib/memory.c359
-rw-r--r--src/lib/module.c20
-rw-r--r--src/lib/string.c5
-rw-r--r--src/lib/syntax.c26
7 files changed, 485 insertions, 197 deletions
diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h
index e394bd8..b87cfad 100644
--- a/src/lib/aplwc_internal.h
+++ b/src/lib/aplwc_internal.h
@@ -8,20 +8,32 @@
#include <stdbool.h>
#include <string.h>
-struct memory {
+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 root_ptr *rootptrs;
};
-struct aplwc {
- enum aplwc_rc last_error;
- struct memory memory;
- struct aplwc_module *modules;
+struct memory_ptr_frame {
+ struct memory_ptr_frame *link;
+ void ***ptrs;
+ size_t count;
+};
+
+struct root_ptr {
+ int id;
+ void *ptr;
+ struct root_ptr *link;
};
struct aplwc_line {
- struct aplwc *aplwc;
struct string *text;
struct token_list *tokens;
};
@@ -66,35 +78,41 @@ 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 */
-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 *);
+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);
+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 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]; \
+ 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 f0cdc55..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->memory);
- if(value == NULL)
- aplwc->last_error = APLWC_OUT_OF_MEMORY;
- value->aplwc = aplwc;
- value->tag = VALUE_NULL;
-
+ value = memory_alloc_aplwc_value(aplwc);
+ if(value != NULL)
+ value->tag = VALUE_NULL;
+
return value;
}
diff --git a/src/lib/main.c b/src/lib/main.c
index d6de538..4571c78 100644
--- a/src/lib/main.c
+++ b/src/lib/main.c
@@ -1,26 +1,45 @@
#include "aplwc_internal.h"
#include "boot.h"
-enum aplwc_rc
-aplwc_new(struct aplwc **p, uint8_t *data, size_t size)
+struct aplwc *
+aplwc_new(struct aplwc_fns fns, enum aplwc_rc *rcp)
{
- struct memory m;
+ enum aplwc_rc rc;
+ struct aplwc *aplwc;
+ size_t size;
- m = memory_init(data, size);
+ aplwc = NULL;
+ if(fns.alloc == NULL){
+ rc = APLWC_OUT_OF_MEMORY;
+ goto end;
+ }
+ aplwc = fns.alloc(sizeof(*aplwc), sizeof(*aplwc), &size);
+ if(aplwc == NULL){
+ rc = APLWC_OUT_OF_MEMORY;
+ goto end;
+ }
- *p = memory_alloc_aplwc(&m);
- if(*p == NULL)
- return APLWC_OUT_OF_MEMORY;
- (*p)->memory = m;
+ aplwc->fns = fns;
+ memory_init(aplwc);
- return aplwc_load_module(*p, "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);
+ assert(rcp);
+ *rcp = rc;
+ return aplwc;
}
void
aplwc_destroy(struct aplwc *p)
{
- if(p)
- memory_free_aplwc(&p->memory, p);
+ if(p == NULL)
+ return;
+
+ memory_destroy(p);
+ if(p->fns.dealloc)
+ p->fns.dealloc(p);
}
const char *
@@ -64,67 +83,80 @@ 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;
- text = chars_to_string(aplwc, line, -1);
- if(text == NULL)
- return NULL;
+ MEMPTRS(aplwc, 2);
- tokens = scan_string(aplwc, text, 1);
- if(tokens == NULL)
- return NULL;
+ aplwc_clear_line(&ret);
- aplwc->last_error = check_tokens(tokens);
- if(aplwc->last_error != APLWC_OK)
- return NULL;
+ if((text = chars_to_string(aplwc, linestr, -1)) == NULL)
+ goto end;
+ MEMPTR(0, text);
- ret = memory_alloc_aplwc_line(&aplwc->memory);
- if(ret == NULL){
- aplwc->last_error = APLWC_OUT_OF_MEMORY;
- return NULL;
- }
+ if((tokens = scan_string(aplwc, text, 1)) == NULL)
+ goto end;
+ MEMPTR(1, tokens);
+
+ if((aplwc->last_error = check_tokens(tokens)) != APLWC_OK)
+ goto end;
+
+ if((line = memory_alloc_aplwc_line(aplwc)) == NULL)
+ goto end;
- ret->aplwc = aplwc;
- ret->text = text;
- ret->tokens = tokens;
+ 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 == NULL)
- return;
- memory_free_aplwc_line(&line->aplwc->memory, 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;
+ struct aplwc *aplwc;
+
+ aplwc = line.ref.aplwc;
+
+ 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;
}
void
-aplwc_free_value(struct aplwc_value *value)
+aplwc_free_value(AplwcValue value)
{
- if(value == NULL)
- return;
- memory_free_aplwc_value(&value->aplwc->memory, 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 "???";
}
@@ -136,32 +168,46 @@ 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;
+ MEMPTRS(aplwc, 3);
- namestr = chars_to_string(aplwc, name, -1);
- if(namestr == NULL)
- goto error;
+ if((namestr = chars_to_string(aplwc, name, -1)) == NULL)
+ goto end;
+ MEMPTR(0, namestr);
- text = chars_to_string(aplwc, src, srclen);
- if(text == NULL)
- goto error;
-
- tokens = scan_string(aplwc, text, 0);
- if(tokens == NULL)
- goto error;
-
- if(load_module(aplwc, namestr, tokens) == APLWC_OK)
- return APLWC_OK;
- else{
-error:
- if(tokens != NULL)
- memory_free_token_list(&aplwc->memory, tokens);
- if(text != NULL)
- memory_free_string(&aplwc->memory, text);
- if(namestr != NULL)
- memory_free_string(&aplwc->memory, namestr);
- return aplwc_last_error(aplwc);
- }
+ if((text = chars_to_string(aplwc, src, srclen)) == NULL)
+ goto end;
+ MEMPTR(1, text);
+
+ if((tokens = scan_string(aplwc, text, 0)) == NULL)
+ goto end;
+ MEMPTR(2, tokens);
+
+ aplwc->last_error = load_module(aplwc, namestr, tokens);
+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 a348b93..694a31b 100644
--- a/src/lib/memory.c
+++ b/src/lib/memory.c
@@ -1,136 +1,353 @@
#include "aplwc_internal.h"
-struct memory
-memory_init(uint8_t *data , size_t size)
+#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)
{
- struct memory mem;
+ aplwc->data = NULL;
+ aplwc->unaligned_data = NULL;
+ aplwc->size = 0;
+ aplwc->memptrs = NULL;
+ aplwc->rootptrs = NULL;
+}
- mem.data = data;
- mem.size = size;
- mem.offset = 0;
- return mem;
+void
+memory_destroy(struct aplwc *aplwc)
+{
+ if(aplwc->fns.dealloc)
+ aplwc->fns.dealloc(aplwc->unaligned_data);
}
-static void *
-alloc(struct memory *m, size_t size, size_t align)
+static void
+fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old)
{
- uintptr_t ptr;
- size_t alloc_size, adjust;
- void *p;
+#define FIX(ptr) do{ \
+ if(ptr){ \
+ (ptr) = (void*)(((uint8_t*)(ptr))+add); \
+ (ptr) = (void*)(((uint8_t*)(ptr))-sub); \
+ } \
+}while(0)
- ptr = ((uintptr_t)m->data) + m->offset;
- alloc_size = size;
+#define FIX_DATA(type, ptr) FIX(((type *)c->data)->ptr)
- if(NEVER(align == 0))
- return NULL;
- adjust = ptr % align;
+ struct chunk *c;
+ struct memory_ptr_frame *frame;
+ struct root_ptr *root;
+ size_t add, sub, i;
+
+ if(new > old){
+ add = new-old;
+ sub = 0;
+ }else{
+ add = 0;
+ sub = old-new;
+ }
+ 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]);
+
+ for(root = aplwc->rootptrs; root; root = root->link)
+ if(root->ptr)
+ FIX(root->ptr);
+
+#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, *head;
+
+ 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)
- alloc_size += align - adjust;
+ adjust = ALIGNMENT - adjust;
+ aligned_newsize = unaligned_newsize - adjust;
+ aligned_data = unaligned_data + adjust;
+
+ aligned_newsize -= aligned_newsize % ALIGNMENT;
- if((m->size - m->offset) >= alloc_size){
- p = m->data+m->offset+alloc_size-size;
- assert((((uintptr_t)p) % align) == 0);
- m->offset += alloc_size;
- memset(p, 0, size);
+ 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 = &head; (*free); free = &(*free)->next)
+ assert((*free)->tag != CHUNK_TAG_FREE);
}else
- p = NULL;
+ free = &head;
- return p;
+
+ (*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;
}
-struct aplwc *
-memory_alloc_aplwc(struct memory *m)
+static struct chunk *
+find_free(struct aplwc *aplwc, size_t min)
{
- struct aplwc *p;
+ struct chunk *c;
- p = alloc(m, sizeof(struct aplwc), alignof(struct aplwc));
- return p;
+ 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;
}
-void
-memory_free_aplwc(struct memory *m, struct aplwc *p)
+static void *
+alloc(struct aplwc *aplwc, size_t size, enum chunk_tag tag)
{
- UNUSED_PARAMETER(m);
- UNUSED_PARAMETER(p);
+ 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;
}
-struct aplwc_line *
-memory_alloc_aplwc_line(struct memory *m)
+struct aplwc_ref
+memory_root_new(struct aplwc *aplwc, void *p)
{
- struct aplwc_line *p;
+ struct aplwc_ref ref;
+ struct root_ptr *root;
+ size_t size;
- p = alloc(m, sizeof(struct aplwc_line), alignof(struct aplwc_line));
- return p;
+ 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_aplwc_line(struct memory *m, struct aplwc_line *p)
+memory_root_free(struct aplwc_ref ref)
{
- UNUSED_PARAMETER(m);
- UNUSED_PARAMETER(p);
+ struct aplwc *aplwc;
+ struct root_ptr **root, *tmp;
+
+ if(!valid_ref(ref))
+ return;
+
+ 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;
+ }
+ }
}
-struct string *
-memory_alloc_string(struct memory *m, size_t bytes)
+void
+memptrs_add(struct aplwc *aplwc, struct memory_ptr_frame *frame, void ***ptrs, size_t count)
{
- struct string *p;
+ size_t i;
- p = alloc(m, sizeof(struct string) + bytes, alignof(struct string));
- 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
-memory_free_string(struct memory *m, struct string *p)
+memptrs_remove(struct aplwc *aplwc, struct memory_ptr_frame *frame)
{
- UNUSED_PARAMETER(m);
- UNUSED_PARAMETER(p);
+ assert(aplwc->memptrs == frame);
+ aplwc->memptrs = frame->link;
}
-struct token_list *
-memory_alloc_token_list(struct memory *m, size_t tokens)
+struct aplwc_line *
+memory_alloc_aplwc_line(struct aplwc *aplwc)
{
- struct token_list *p;
+ struct aplwc_line *p;
- p = alloc(m, sizeof(struct token_list) + (tokens * sizeof(struct token)), alignof(struct token_list));
+ p = alloc(aplwc, sizeof(struct aplwc_line), CHUNK_TAG_APLWC_LINE);
return p;
}
-void
-memory_free_token_list(struct memory *m, struct token_list *p)
+struct string *
+memory_alloc_string(struct aplwc *aplwc, size_t bytes)
{
- UNUSED_PARAMETER(m);
- UNUSED_PARAMETER(p);
+ struct string *p;
+
+ p = alloc(aplwc, sizeof(struct string) + bytes, CHUNK_TAG_STRING);
+
+ return p;
}
-struct aplwc_value *
-memory_alloc_aplwc_value(struct memory *m)
+struct token_list *
+memory_alloc_token_list(struct aplwc *aplwc, size_t tokens)
{
- struct aplwc_value *p;
+ struct token_list *p;
- p = alloc(m, sizeof(struct aplwc_value), alignof(struct aplwc_value));
+ p = alloc(aplwc, sizeof(struct token_list) + (tokens * sizeof(struct token)), CHUNK_TAG_TOKEN_LIST);
return p;
}
-void
-memory_free_aplwc_value(struct memory *m, struct aplwc_value *p)
+struct aplwc_value *
+memory_alloc_aplwc_value(struct aplwc *aplwc)
{
- UNUSED_PARAMETER(m);
- UNUSED_PARAMETER(p);
+ struct aplwc_value *p;
+
+ p = alloc(aplwc, sizeof(struct aplwc_value), CHUNK_TAG_APLWC_VALUE);
+ return 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), CHUNK_TAG_APLWC_MODULE);
return p;
}
void
-memory_free_aplwc_module(struct memory *m, struct aplwc_module *p)
+clear_ref(struct aplwc_ref *ref)
+{
+ ref->id = -1;
+ ref->aplwc = NULL;
+}
+
+int
+valid_ref(struct aplwc_ref ref)
{
- UNUSED_PARAMETER(m);
- UNUSED_PARAMETER(p);
+ return ref.id >= 0;
}
diff --git a/src/lib/module.c b/src/lib/module.c
index 9a202f9..2524eca 100644
--- a/src/lib/module.c
+++ b/src/lib/module.c
@@ -58,12 +58,17 @@ 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);
+ MEMPTRS(aplwc, 2);
+
+ MEMPTR(0, name);
+ MEMPTR(1, tokens);
+
+ module = memory_alloc_aplwc_module(aplwc);
if(module == NULL){
- aplwc->last_error = APLWC_OUT_OF_MEMORY;
- return aplwc->last_error;
+ rc = aplwc_last_error(aplwc);
+ goto end;
}
- module->aplwc = aplwc;
+
module->name = name;
module->tokens = tokens;
module->link = NULL;
@@ -72,10 +77,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{
- memory_free_aplwc_module(&aplwc->memory, module);
- }
+ }else
+ aplwc->last_error = rc;
+end:
+ MEMPTRS_EXIT(aplwc);
return rc;
}
diff --git a/src/lib/string.c b/src/lib/string.c
index 24f978c..cc6c6cb 100644
--- a/src/lib/string.c
+++ b/src/lib/string.c
@@ -69,13 +69,12 @@ 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;
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 395c75e..ae52343 100644
--- a/src/lib/syntax.c
+++ b/src/lib/syntax.c
@@ -240,17 +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->memory, n);
- if(tokens == NULL){
- aplwc->last_error = APLWC_OUT_OF_MEMORY;
- return NULL;
- }
+ tokens = memory_alloc_token_list(aplwc, n);
+ if(tokens == NULL)
+ goto end;
tokens->text = text;
tokens->length = n;
scan(text, tokens);
@@ -261,12 +261,16 @@ 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);
- return NULL;
+ rc = APLWC_INVALID_SYNTAX;
+ tokens = NULL;
+ goto end;
}
}
}
+end:
+ aplwc->last_error = rc;
+ MEMPTRS_EXIT(aplwc);
return tokens;
}