diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-01-28 20:15:13 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-01-29 23:33:07 +0100 |
commit | 2cb627f3ba79bfce98e4cf6ab4b2e8029e8cb09e (patch) | |
tree | d4080e561b42f0ae706efe07b7158e9555eab708 | |
parent | 1094ffa276990fd53abe633e5b14869d7c538a16 (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.c | 2 | ||||
-rw-r--r-- | include/ucode/program.h | 4 | ||||
-rw-r--r-- | include/ucode/source.h | 2 | ||||
-rw-r--r-- | include/ucode/types.h | 2 | ||||
-rw-r--r-- | lib.c | 4 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | program.c | 35 | ||||
-rw-r--r-- | source.c | 13 |
8 files changed, 41 insertions, 23 deletions
@@ -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; @@ -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; } @@ -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; @@ -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; @@ -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); +} |