From 1d60418132460c23b216a2f8a9e0ea8897d32ea4 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 9 Jul 2021 19:35:19 +0200 Subject: vm: add API to control trace mode Add a public getter and setter to read and set the VM trace level respectively. Use the new API to control the trace mode with a newly introduced `-t` command line switch. Drop support for honouring the `TRACE` environment variable as host programs embedding ucode might want to prevent that behaviour or handle it differently. Signed-off-by: Jo-Philipp Wich --- main.c | 18 ++++++++++++------ tests/cram/test_basic.t | 4 ++-- vm.c | 19 ++++++++++++++----- vm.h | 3 +++ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index b420051..a71e053 100644 --- a/main.c +++ b/main.c @@ -40,11 +40,11 @@ print_usage(const char *app) { printf( "== Usage ==\n\n" - " # %s [-d] [-l] [-r] [-S] [-R] [-e '[prefix=]{\"var\": ...}'] [-E [prefix=]env.json] {-i | -s \"ucode script...\"}\n" + " # %s [-t] [-l] [-r] [-S] [-R] [-e '[prefix=]{\"var\": ...}'] [-E [prefix=]env.json] {-i | -s \"ucode script...\"}\n" " -h, --help Print this help\n" " -i file Specify an ucode script to parse\n" " -s \"ucode script...\" Specify an ucode fragment to parse\n" - " -d Instead of executing the script, dump the resulting AST as dot\n" + " -t Enable VM execution tracing\n" " -l Do not strip leading block whitespace\n" " -r Do not trim trailing block newlines\n" " -S Enable strict mode\n" @@ -76,7 +76,7 @@ register_variable(uc_value_t *scope, const char *key, uc_value_t *val) static int parse(uc_parse_config *config, uc_source *src, uc_value_t *env, uc_value_t *modules, - int argc, char **argv) + int argc, char **argv, int trace) { uc_value_t *globals = NULL, *res = NULL, *arr, *name, *mod; uc_function_t *entry; @@ -87,6 +87,8 @@ parse(uc_parse_config *config, uc_source *src, uc_vm_init(&vm, config); + uc_vm_trace_set(&vm, trace); + entry = uc_compile(config, src, &err); if (!entry) { @@ -224,8 +226,8 @@ main(int argc, char **argv) { uc_value_t *env = NULL, *modules = NULL, *o, *p; uc_source *source = NULL, *envfile = NULL; + int opt, rv = 0, trace = 0; char *stdin = NULL, *c; - int opt, rv = 0; uc_parse_config config = { .strict_declarations = false, @@ -239,7 +241,7 @@ main(int argc, char **argv) goto out; } - while ((opt = getopt(argc, argv, "hlrSRe:E:i:s:m:")) != -1) + while ((opt = getopt(argc, argv, "hlrtSRe:E:i:s:m:")) != -1) { switch (opt) { case 'h': @@ -358,6 +360,10 @@ main(int argc, char **argv) ucv_array_push(modules, ucv_string_new(optarg)); break; + + case 't': + trace = 1; + break; } } @@ -377,7 +383,7 @@ main(int argc, char **argv) goto out; } - rv = parse(&config, source, env, modules, argc, argv); + rv = parse(&config, source, env, modules, argc, argv, trace); out: ucv_put(modules); diff --git a/tests/cram/test_basic.t b/tests/cram/test_basic.t index d866c49..940f1d1 100644 --- a/tests/cram/test_basic.t +++ b/tests/cram/test_basic.t @@ -12,11 +12,11 @@ check that ucode provides exepected help: $ ucode | sed 's/ucode-san/ucode/' == Usage == - # ucode [-d] [-l] [-r] [-S] [-R] [-e '[prefix=]{"var": ...}'] [-E [prefix=]env.json] {-i | -s "ucode script..."} + # ucode [-t] [-l] [-r] [-S] [-R] [-e '[prefix=]{"var": ...}'] [-E [prefix=]env.json] {-i | -s "ucode script..."} -h, --help\tPrint this help (esc) -i file\tSpecify an ucode script to parse (esc) -s "ucode script..."\tSpecify an ucode fragment to parse (esc) - -d Instead of executing the script, dump the resulting AST as dot + -t Enable VM execution tracing -l Do not strip leading block whitespace -r Do not trim trailing block newlines -S Enable strict mode diff --git a/vm.c b/vm.c index 99e07bb..82d2f1c 100644 --- a/vm.c +++ b/vm.c @@ -14,7 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include #include #include @@ -137,13 +136,9 @@ uc_vm_output_exception(uc_vm *vm, uc_exception *ex); void uc_vm_init(uc_vm *vm, uc_parse_config *config) { - char *s = getenv("TRACE"); - vm->exception.type = EXCEPTION_NONE; vm->exception.message = NULL; - vm->trace = s ? strtoul(s, NULL, 0) : 0; - vm->config = config; vm->open_upvals = NULL; @@ -160,6 +155,8 @@ void uc_vm_init(uc_vm *vm, uc_parse_config *config) uc_vm_alloc_global_scope(vm); uc_vm_exception_handler_set(vm, uc_vm_output_exception); + + uc_vm_trace_set(vm, 0); } void uc_vm_free(uc_vm *vm) @@ -2409,3 +2406,15 @@ uc_vm_exception_handler_set(uc_vm *vm, uc_exception_handler_t *exhandler) { vm->exhandler = exhandler; } + +uint32_t +uc_vm_trace_get(uc_vm *vm) +{ + return vm->trace; +} + +void +uc_vm_trace_set(uc_vm *vm, uint32_t level) +{ + vm->trace = level; +} diff --git a/vm.h b/vm.h index 84b42fe..3d22105 100644 --- a/vm.h +++ b/vm.h @@ -123,6 +123,9 @@ uc_value_t *uc_vm_stack_peek(uc_vm *vm, size_t offset); uc_exception_handler_t *uc_vm_exception_handler_get(uc_vm *vm); void uc_vm_exception_handler_set(uc_vm *vm, uc_exception_handler_t *exhandler); +uint32_t uc_vm_trace_get(uc_vm *vm); +void uc_vm_trace_set(uc_vm *vm, uint32_t level); + uc_exception_type_t uc_vm_call(uc_vm *vm, bool mcall, size_t nargs); void __attribute__((format(printf, 3, 0))) -- cgit v1.2.3