mirror of
https://github.com/janet-lang/janet
synced 2024-12-29 09:50:27 +00:00
Add simple tracing functionality to VM.
Also disable debugger for normal errors.
This commit is contained in:
parent
4fa1b28cad
commit
88b8418253
@ -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*`.
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user