summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-01-28 20:15:13 +0100
committerJo-Philipp Wich <jo@mein.io>2022-01-29 23:33:07 +0100
commit2cb627f3ba79bfce98e4cf6ab4b2e8029e8cb09e (patch)
treed4080e561b42f0ae706efe07b7158e9555eab708
parent1094ffa276990fd53abe633e5b14869d7c538a16 (diff)
program: rename bytecode load/write functions, track path of executed file
Extend source objects with a `runpath` field which contains the original path of the source being executed by the VM. When instantiating source objects from file paths, the `runpath` will be set to the `filename`. When instantiating source buffers using `uc_source_new_buffer()`, the runpath is initially unset. A new function `uc_source_runpath_set()` can be used to adjust the runtime path being associated with a source object. Extend bytecode loading logic to set the source buffer runtime path to the precompiled bytecode file path being loaded and executed. This is required for `sourcepath()` and relative paths in `include()` to function correctly when executing precompiled programs. Finally rename `uc_program_from_file()` and `uc_program_to_file()` to `uc_program_load()` and `uc_program_write()` respectively since the load part now operates on an `uc_source_t` input buffer instead of a plain `FILE *` handle. Adjust users of these API functions accordingly. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--compiler.c2
-rw-r--r--include/ucode/program.h4
-rw-r--r--include/ucode/source.h2
-rw-r--r--include/ucode/types.h2
-rw-r--r--lib.c4
-rw-r--r--main.c2
-rw-r--r--program.c35
-rw-r--r--source.c13
8 files changed, 41 insertions, 23 deletions
diff --git a/compiler.c b/compiler.c
index 818576b..c29d80a 100644
--- a/compiler.c
+++ b/compiler.c
@@ -2881,7 +2881,7 @@ uc_compile_from_bytecode(uc_parse_config_t *config, uc_source_t *source, char **
uc_function_t *fn = NULL;
uc_program_t *prog;
- prog = uc_program_from_file(source->fp, errp);
+ prog = uc_program_load(source, errp);
if (prog) {
fn = uc_program_entry(prog);
diff --git a/include/ucode/program.h b/include/ucode/program.h
index 9a5c553..39131eb 100644
--- a/include/ucode/program.h
+++ b/include/ucode/program.h
@@ -31,8 +31,8 @@ uc_value_t *uc_program_function_load(uc_program_t *, size_t);
uc_value_t *uc_program_get_constant(uc_program_t *, size_t);
ssize_t uc_program_add_constant(uc_program_t *, uc_value_t *);
-void uc_program_to_file(uc_program_t *, FILE *, bool);
-uc_program_t *uc_program_from_file(FILE *file, char **);
+void uc_program_write(uc_program_t *, FILE *, bool);
+uc_program_t *uc_program_load(uc_source_t *, char **);
uc_function_t *uc_program_entry(uc_program_t *);
diff --git a/include/ucode/source.h b/include/ucode/source.h
index ac0b487..b05e84b 100644
--- a/include/ucode/source.h
+++ b/include/ucode/source.h
@@ -45,4 +45,6 @@ uc_source_type_t uc_source_type_test(uc_source_t *source);
void uc_source_line_next(uc_source_t *source);
void uc_source_line_update(uc_source_t *source, size_t off);
+void uc_source_runpath_set(uc_source_t *source, const char *runpath);
+
#endif /* __SOURCE_H_ */
diff --git a/include/ucode/types.h b/include/ucode/types.h
index 66db5ea..cc55150 100644
--- a/include/ucode/types.h
+++ b/include/ucode/types.h
@@ -66,7 +66,7 @@ typedef struct {
uc_declare_vector(uc_lineinfo_t, uint8_t);
typedef struct {
- char *filename, *buffer;
+ char *filename, *runpath, *buffer;
FILE *fp;
size_t usecount, off;
uc_lineinfo_t lineinfo;
diff --git a/lib.c b/lib.c
index c211f78..e204ded 100644
--- a/lib.c
+++ b/lib.c
@@ -2141,7 +2141,7 @@ uc_include(uc_vm_t *vm, size_t nargs)
if (!closure)
return NULL;
- p = include_path(closure->function->program->source->filename, ucv_string_get(path));
+ p = include_path(closure->function->program->source->runpath, ucv_string_get(path));
if (!p) {
uc_vm_raise_exception(vm, EXCEPTION_RUNTIME,
@@ -2553,7 +2553,7 @@ uc_sourcepath(uc_vm_t *vm, size_t nargs)
continue;
}
- path = realpath(frame->closure->function->program->source->filename, NULL);
+ path = realpath(frame->closure->function->program->source->runpath, NULL);
break;
}
diff --git a/main.c b/main.c
index aba9989..4b6738d 100644
--- a/main.c
+++ b/main.c
@@ -95,7 +95,7 @@ compile(uc_vm_t *vm, uc_source_t *src, FILE *precompile, bool strip)
}
if (precompile) {
- uc_program_to_file(entry->program, precompile, !strip);
+ uc_program_write(entry->program, precompile, !strip);
uc_program_free(entry->program);
fclose(precompile);
goto out;
diff --git a/program.c b/program.c
index f3b90b4..de7e747 100644
--- a/program.c
+++ b/program.c
@@ -292,7 +292,7 @@ write_function(uc_function_t *func, FILE *file, bool debug)
}
void
-uc_program_to_file(uc_program_t *prog, FILE *file, bool debug)
+uc_program_write(uc_program_t *prog, FILE *file, bool debug)
{
uint32_t flags = 0;
uc_weakref_t *ref;
@@ -533,29 +533,31 @@ out:
}
static uc_source_t *
-read_sourceinfo(FILE *file, uint32_t flags, char **errp)
+read_sourceinfo(uc_source_t *input, uint32_t flags, char **errp)
{
char *path = NULL, *code = NULL;
uc_source_t *source = NULL;
size_t len;
if (flags & UC_PROGRAM_F_SOURCEINFO) {
- if (!read_size_t(file, &len, sizeof(uint32_t), "sourceinfo filename length", errp))
+ if (!read_size_t(input->fp, &len, sizeof(uint32_t), "sourceinfo filename length", errp))
goto out;
path = xalloc(len);
- if (!read_string(file, path, len, "sourceinfo filename", errp))
+ if (!read_string(input->fp, path, len, "sourceinfo filename", errp))
goto out;
if (flags & UC_PROGRAM_F_SOURCEBUF) {
- if (!read_size_t(file, &len, sizeof(uint32_t), "sourceinfo code buffer length", errp))
+ if (!read_size_t(input->fp, &len, sizeof(uint32_t), "sourceinfo code buffer length", errp))
goto out;
code = xalloc(len);
- if (!read_string(file, code, len, "sourceinfo code buffer data", errp))
+ if (!read_string(input->fp, code, len, "sourceinfo code buffer data", errp)) {
+ free(code);
goto out;
+ }
source = uc_source_new_buffer(path, code, len);
}
@@ -564,11 +566,11 @@ read_sourceinfo(FILE *file, uint32_t flags, char **errp)
if (!source) {
fprintf(stderr, "Unable to open source file %s: %s\n", path, strerror(errno));
- source = uc_source_new_buffer(path, "", 0);
+ source = uc_source_new_buffer(path, xstrdup(""), 0);
}
}
- if (!read_vector(file, &source->lineinfo, "sourceinfo lineinfo", errp)) {
+ if (!read_vector(input->fp, &source->lineinfo, "sourceinfo lineinfo", errp)) {
uc_source_put(source);
source = NULL;
goto out;
@@ -578,9 +580,10 @@ read_sourceinfo(FILE *file, uint32_t flags, char **errp)
source = uc_source_new_buffer("[no source]", xstrdup(""), 0);
}
+ uc_source_runpath_set(source, input->runpath);
+
out:
free(path);
- free(code);
return source;
}
@@ -737,13 +740,13 @@ out:
}
uc_program_t *
-uc_program_from_file(FILE *file, char **errp)
+uc_program_load(uc_source_t *input, char **errp)
{
uc_program_t *program = NULL;
uc_source_t *source = NULL;
uint32_t flags, nfuncs, i;
- if (!read_u32(file, &i, "file magic", errp))
+ if (!read_u32(input->fp, &i, "file magic", errp))
goto out;
if (i != UC_PRECOMPILED_BYTECODE_MAGIC) {
@@ -751,10 +754,10 @@ uc_program_from_file(FILE *file, char **errp)
goto out;
}
- if (!read_u32(file, &flags, "program flags", errp))
+ if (!read_u32(input->fp, &flags, "program flags", errp))
goto out;
- source = read_sourceinfo(file, flags, errp);
+ source = read_sourceinfo(input, flags, errp);
if (!source)
goto out;
@@ -763,14 +766,14 @@ uc_program_from_file(FILE *file, char **errp)
uc_source_put(source);
- if (!read_vallist(file, &program->constants, "constants", errp))
+ if (!read_vallist(input->fp, &program->constants, "constants", errp))
goto out;
- if (!read_u32(file, &nfuncs, "function count", errp))
+ if (!read_u32(input->fp, &nfuncs, "function count", errp))
goto out;
for (i = 0; i < nfuncs; i++)
- if (!read_function(file, program, i, errp))
+ if (!read_function(input->fp, program, i, errp))
goto out;
return program;
diff --git a/source.c b/source.c
index 3b35b70..f2bd8bf 100644
--- a/source.c
+++ b/source.c
@@ -34,6 +34,7 @@ uc_source_new_file(const char *path)
src->fp = fp;
src->buffer = NULL;
src->filename = strcpy((char *)src + ALIGN(sizeof(*src)), path);
+ src->runpath = src->filename;
src->usecount = 1;
@@ -113,6 +114,9 @@ uc_source_put(uc_source_t *source)
return;
}
+ if (source->runpath != source->filename)
+ free(source->runpath);
+
uc_vector_clear(&source->lineinfo);
fclose(source->fp);
free(source->buffer);
@@ -211,3 +215,12 @@ uc_source_line_update(uc_source_t *source, size_t off)
}
}
}
+
+void
+uc_source_runpath_set(uc_source_t *source, const char *runpath)
+{
+ if (source->runpath != source->filename)
+ free(source->runpath);
+
+ source->runpath = xstrdup(runpath);
+}