summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-07-09 19:35:19 +0200
committerJo-Philipp Wich <jo@mein.io>2021-07-11 15:49:14 +0200
commit1d60418132460c23b216a2f8a9e0ea8897d32ea4 (patch)
treefe1640e8d9b2f2a00f9113c971c86a7c5eb28fcd
parent48f33ad70bf584a97a2e2d3870b04bbc970194b7 (diff)
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 <jo@mein.io>
-rw-r--r--main.c18
-rw-r--r--tests/cram/test_basic.t4
-rw-r--r--vm.c19
-rw-r--r--vm.h3
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 <file> | -s \"ucode script...\"}\n"
+ " # %s [-t] [-l] [-r] [-S] [-R] [-e '[prefix=]{\"var\": ...}'] [-E [prefix=]env.json] {-i <file> | -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 <file> | -s "ucode script..."}
+ # ucode [-t] [-l] [-r] [-S] [-R] [-e '[prefix=]{"var": ...}'] [-E [prefix=]env.json] {-i <file> | -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 <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
@@ -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)))