summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-02-07 00:20:16 +0100
committerJo-Philipp Wich <jo@mein.io>2022-02-07 00:22:12 +0100
commit11adf0c4ea91e63ec523849c2846fd07bf4348f5 (patch)
treed2c3aed28eb7c043c73b84ea3af0837225ee02a5
parent3a49192f3a1e8a5d348cdbfccd0a16d74ba61e3d (diff)
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 <jo@mein.io>
-rw-r--r--include/ucode/source.h11
-rw-r--r--include/ucode/types.h6
-rw-r--r--source.c44
-rw-r--r--types.c33
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<source %p>%s",
+ json ? "\"" : "",
+ uv,
+ json ? "\"" : "");
}
ucv_clear_mark(uv);