From 11adf0c4ea91e63ec523849c2846fd07bf4348f5 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 7 Feb 2022 00:20:16 +0100 Subject: source: convert source objects into proper uc_value_t type Instead of implementing a custom limited refcount logic, turn uc_source_t instances into proper uc_value_t objects. Signed-off-by: Jo-Philipp Wich --- include/ucode/source.h | 11 +++++++++-- include/ucode/types.h | 6 ++++-- source.c | 44 ++++++++------------------------------------ types.c | 33 ++++++++++++++++++++++++++++++++- 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/include/ucode/source.h b/include/ucode/source.h index b05e84b..e0339a4 100644 --- a/include/ucode/source.h +++ b/include/ucode/source.h @@ -37,8 +37,15 @@ uc_source_t *uc_source_new_buffer(const char *name, char *buf, size_t len); size_t uc_source_get_line(uc_source_t *source, size_t *offset); -uc_source_t *uc_source_get(uc_source_t *source); -void uc_source_put(uc_source_t *source); +static inline uc_source_t * +uc_source_get(uc_source_t *source) { + return (uc_source_t *)ucv_get(source ? &source->header : NULL); +} + +static inline void +uc_source_put(uc_source_t *source) { + ucv_put(source ? &source->header : NULL); +} uc_source_type_t uc_source_type_test(uc_source_t *source); diff --git a/include/ucode/types.h b/include/ucode/types.h index ff87ca7..8e2030a 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -40,7 +40,8 @@ typedef enum uc_type { UC_CLOSURE, UC_UPVALUE, UC_RESOURCE, - UC_PROGRAM + UC_PROGRAM, + UC_SOURCE } uc_type_t; typedef struct uc_value { @@ -66,9 +67,10 @@ typedef struct { uc_declare_vector(uc_lineinfo_t, uint8_t); typedef struct { + uc_value_t header; char *filename, *runpath, *buffer; FILE *fp; - size_t usecount, off; + size_t off; uc_lineinfo_t lineinfo; } uc_source_t; diff --git a/source.c b/source.c index c4060eb..b8f2e91 100644 --- a/source.c +++ b/source.c @@ -31,13 +31,15 @@ uc_source_new_file(const char *path) return NULL; src = xalloc(ALIGN(sizeof(*src)) + strlen(path) + 1); + + src->header.type = UC_SOURCE; + src->header.refcount = 1; + src->fp = fp; src->buffer = NULL; src->filename = strcpy((char *)src + ALIGN(sizeof(*src)), path); src->runpath = src->filename; - src->usecount = 1; - src->lineinfo.count = 0; src->lineinfo.entries = NULL; @@ -54,12 +56,14 @@ uc_source_new_buffer(const char *name, char *buf, size_t len) return NULL; src = xalloc(ALIGN(sizeof(*src)) + strlen(name) + 1); + + src->header.type = UC_SOURCE; + src->header.refcount = 1; + src->fp = fp; src->buffer = buf; src->filename = strcpy((char *)src + ALIGN(sizeof(*src)), name); - src->usecount = 1; - src->lineinfo.count = 0; src->lineinfo.entries = NULL; @@ -91,38 +95,6 @@ uc_source_get_line(uc_source_t *source, size_t *offset) return 0; } -uc_source_t * -uc_source_get(uc_source_t *source) -{ - if (!source) - return NULL; - - source->usecount++; - - return source; -} - -void -uc_source_put(uc_source_t *source) -{ - if (!source) - return; - - if (source->usecount > 1) { - source->usecount--; - - return; - } - - if (source->runpath != source->filename) - free(source->runpath); - - uc_vector_clear(&source->lineinfo); - fclose(source->fp); - free(source->buffer); - free(source); -} - uc_source_type_t uc_source_type_test(uc_source_t *source) { diff --git a/types.c b/types.c index b096b71..a8de8e4 100644 --- a/types.c +++ b/types.c @@ -56,6 +56,7 @@ ucv_typename(uc_value_t *uv) case UC_UPVALUE: return "upvalue"; case UC_RESOURCE: return "resource"; case UC_PROGRAM: return "program"; + case UC_SOURCE: return "source"; } return "unknown"; @@ -124,6 +125,7 @@ ucv_gc_mark(uc_value_t *uv) uc_object_t *object; uc_array_t *array; uc_resource_t *resource; + uc_program_t *program; struct lh_entry *entry; size_t i; @@ -184,6 +186,14 @@ ucv_gc_mark(uc_value_t *uv) break; + case UC_PROGRAM: + program = (uc_program_t *)uv; + + if (program->source) + ucv_gc_mark(&program->source->header); + + break; + default: break; } @@ -198,6 +208,7 @@ ucv_free(uc_value_t *uv, bool retain) uc_closure_t *closure; uc_program_t *program; uc_upvalref_t *upval; + uc_source_t *source; uc_regexp_t *regexp; uc_object_t *object; uc_array_t *array; @@ -270,7 +281,18 @@ ucv_free(uc_value_t *uv, bool retain) uc_program_function_free(func); uc_vallist_free(&program->constants); - uc_source_put(program->source); + ucv_put_value(&program->source->header, retain); + break; + + case UC_SOURCE: + source = (uc_source_t *)uv; + + if (source->runpath != source->filename) + free(source->runpath); + + uc_vector_clear(&source->lineinfo); + fclose(source->fp); + free(source->buffer); break; } @@ -1329,6 +1351,7 @@ ucv_to_json(uc_value_t *uv) case UC_RESOURCE: case UC_UPVALUE: case UC_PROGRAM: + case UC_SOURCE: case UC_NULL: return NULL; } @@ -1672,6 +1695,14 @@ ucv_to_stringbuf_formatted(uc_vm_t *vm, uc_stringbuf_t *pb, uc_value_t *uv, size json ? "\"" : "", uv, json ? "\"" : ""); + + break; + + case UC_SOURCE: + ucv_stringbuf_printf(pb, "%s%s", + json ? "\"" : "", + uv, + json ? "\"" : ""); } ucv_clear_mark(uv); -- cgit v1.2.3