Add simple tracing functionality to VM.

Also disable debugger for normal errors.
This commit is contained in:
Calvin Rose 2019-05-04 15:03:41 -04:00
parent 4fa1b28cad
commit 88b8418253
5 changed files with 53 additions and 8 deletions

View File

@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file.
## 0.5.0 - ??
- Add `trace` and `untrace` to the core library.
- Add `string/has-prefix?` and `string/has-suffix?` to string module.
- Add simple debugger to repl that activates on errors or debug signal
- Remove `*env*` and `*doc-width*`.

View File

@ -1732,16 +1732,14 @@
:dead (do
(pp x)
(put env '_ @{:value x}))
(let [nextenv (make-env env)]
(put nextenv '_fiber @{:value f})
(put nextenv '_signal @{:value x})
(setdyn :debug-level level)
(debug/stacktrace f x)
(print ```
:debug (let [nextenv (make-env env)]
(put nextenv '_fiber @{:value f})
(setdyn :debug-level level)
(debug/stacktrace f x)
(print ```
entering debugger - Ctrl-D to exit
_fiber is bound to the suspended fiber
_signal is the error or signal value
```)
(repl (fn [buf p]
@ -1749,7 +1747,8 @@ _signal is the error or signal value
(def c (parser/where p))
(def prompt (string "debug[" level "]:" c ":" status "> "))
(getline prompt buf))
onsignal nextenv)))))
onsignal nextenv))
(debug/stacktrace f x))))
(run-context {:env env
:chunks chunks
:on-status onsignal

View File

@ -273,6 +273,20 @@ static Janet janet_core_getline(int32_t argc, Janet *argv) {
return janet_wrap_buffer(buf);
}
static Janet janet_core_trace(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetFunction *func = janet_getfunction(argv, 0);
func->gc.flags |= JANET_FUNCFLAG_TRACE;
return argv[0];
}
static Janet janet_core_untrace(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetFunction *func = janet_getfunction(argv, 0);
func->gc.flags &= ~JANET_FUNCFLAG_TRACE;
return argv[0];
}
static const JanetReg corelib_cfuns[] = {
{
"native", janet_core_native,
@ -432,6 +446,16 @@ static const JanetReg corelib_cfuns[] = {
JDOC("(setdyn key value)\n\n"
"Set a dynamic binding. Returns value.")
},
{
"trace", janet_core_trace,
JDOC("(trace func)\n\n"
"Enable tracing on a function. Returns the function.")
},
{
"untrace", janet_core_untrace,
JDOC("(untrace func)\n\n"
"Disables tracing on a function. Returns the function.")
},
{NULL, NULL, NULL}
};

View File

@ -224,6 +224,23 @@ static void *op_lookup[255] = {
#define vm_bitop(op) _vm_bitop(op, int32_t)
#define vm_bitopu(op) _vm_bitop(op, uint32_t)
/* Trace a function call */
static void vm_do_trace(JanetFunction *func) {
Janet *stack = janet_vm_fiber->data + janet_vm_fiber->stackstart;
int32_t start = janet_vm_fiber->stackstart;
int32_t end = janet_vm_fiber->stacktop;
int32_t argc = end - start;
if (func->def->name) {
janet_printf("trace (%S", func->def->name);
} else {
janet_printf("trace (%p", janet_wrap_function(func));
}
for (int32_t i = 0; i < argc; i++) {
janet_printf(" %p", stack[i]);
}
printf(")\n");
}
/* Call a non function type */
static Janet call_nonfn(JanetFiber *fiber, Janet callee) {
int32_t argn = fiber->stacktop - fiber->stackstart;
@ -563,6 +580,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
}
if (janet_checktype(callee, JANET_FUNCTION)) {
func = janet_unwrap_function(callee);
if (func->gc.flags & JANET_FUNCFLAG_TRACE) vm_do_trace(func);
janet_stack_frame(stack)->pc = pc;
if (janet_fiber_funcframe(fiber, func)) {
int32_t n = fiber->stacktop - fiber->stackstart;
@ -598,6 +616,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
}
if (janet_checktype(callee, JANET_FUNCTION)) {
func = janet_unwrap_function(callee);
if (func->gc.flags & JANET_FUNCFLAG_TRACE) vm_do_trace(func);
if (janet_fiber_funcframe_tail(fiber, func)) {
janet_stack_frame(fiber->data + fiber->frame)->pc = pc;
int32_t n = fiber->stacktop - fiber->stackstart;

View File

@ -805,6 +805,8 @@ struct JanetFuncEnv {
environment is no longer on the stack. */
};
#define JANET_FUNCFLAG_TRACE (1 << 16)
/* A function */
struct JanetFunction {
JanetGCObject gc;