1
0
mirror of https://github.com/janet-lang/janet synced 2025-07-26 13:52:52 +00:00

More work on improving stacktraces slightly.

Add extra information about when we change fibers. The janet
stack is really a spaghetti stack, where each fiber represents
a group of stack frames as well as a place where we can longjmp to. It
is therefor useful information for the programmer to know where each
stack frame is.

However, an argument could be made that this clutters the stackframe
and is more of a hindrance than a help.
This commit is contained in:
Calvin Rose 2024-05-26 08:45:38 -05:00
parent cb529bbd63
commit 1844beecc3
4 changed files with 48 additions and 40 deletions

View File

@ -2405,6 +2405,33 @@
(defdyn *err-color* (defdyn *err-color*
"Whether or not to turn on error coloring in stacktraces and other error messages.") "Whether or not to turn on error coloring in stacktraces and other error messages.")
(defdyn *err-line-col*
"Whether or not to print the line of source code that caused an error.")
(defn- print-line-col
``Print the source code at a line, column in a source file. If unable to open
the file, prints nothing.``
[where line col]
(if-not line (break))
(unless (string? where) (break))
(unless (dyn *err-line-col*) (break))
(def ec (dyn *err-color*))
(when-with [f (file/open where :r)]
(def source-code (file/read f :all))
(var index 0)
(repeat (dec line)
(if-not index (break))
(set index (string/find "\n" source-code index))
(if index (++ index)))
(when index
(def line-end (string/find "\n" source-code index))
(def s (if ec "\e[31m"))
(def e (if ec "\e[0m"))
(eprint s " " (string/slice source-code index line-end) e)
(when col
(+= index col)
(eprint s (string/repeat " " (inc col)) "^" e)))))
(defn bad-parse (defn bad-parse
"Default handler for a parse error." "Default handler for a parse error."
[p where] [p where]
@ -2419,29 +2446,10 @@
col col
": parse error: " ": parse error: "
(:error p) (:error p)
(if ec "\e[0m" "")) (if ec "\e[0m"))
(print-line-col where line col)
(eflush)) (eflush))
(defn- print-line-col
``Print the source code at a line, column in a source file. If unable to open
the file, prints nothing.``
[where line col]
(if-not line (break))
(unless (string? where) (break))
(when-with [f (file/open where :r)]
(def source-code (file/read f :all))
(var index 0)
(repeat (dec line)
(if-not index (break))
(set index (string/find "\n" source-code index))
(if index (++ index)))
(when index
(def line-end (string/find "\n" source-code index))
(eprint " " (string/slice source-code index line-end))
(when col
(+= index col)
(eprint (string/repeat " " (inc col)) "^")))))
(defn warn-compile (defn warn-compile
"Default handler for a compile warning." "Default handler for a compile warning."
[msg level where &opt line col] [msg level where &opt line col]
@ -2454,10 +2462,8 @@
":" ":"
col col
": compile warning (" level "): ") ": compile warning (" level "): ")
(eprint msg) (eprint msg (if ec "\e[0m"))
(when ec (print-line-col where line col)
(print-line-col where line col)
(eprin "\e[0m"))
(eflush)) (eflush))
(defn bad-compile (defn bad-compile
@ -2474,10 +2480,8 @@
": compile error: ") ": compile error: ")
(if macrof (if macrof
(debug/stacktrace macrof msg "") (debug/stacktrace macrof msg "")
(eprint msg)) (eprint msg (if ec "\e[0m")))
(when ec (print-line-col where line col)
(print-line-col where line col)
(eprin "\e[0m"))
(eflush)) (eflush))
(defn curenv (defn curenv
@ -3049,7 +3053,7 @@
``A table of loading method names to loading functions. ``A table of loading method names to loading functions.
This table lets `require` and `import` load many different kinds This table lets `require` and `import` load many different kinds
of files as modules.`` of files as modules.``
@{:native (fn native-loader [path &] (native path (make-env))) @{:native (fn native-loader [path &] (native path ((dyn *module-make-env* make-env))))
:source (fn source-loader [path args] :source (fn source-loader [path args]
(def ml (dyn *module-loading* module/loading)) (def ml (dyn *module-loading* module/loading))
(put ml path true) (put ml path true)
@ -3996,18 +4000,19 @@
(compwhen (dyn 'os/stat) (compwhen (dyn 'os/stat)
(defn- bundle-dir
[&opt bundle-name]
(string (dyn *syspath*) "/bundle/" bundle-name))
(defn- bundle-file
[bundle-name filename]
(string (dyn *syspath*) "/bundle/" bundle-name "/" filename))
(defn- bundle-rpath (defn- bundle-rpath
[path] [path]
(string/replace-all "\\" "/" (os/realpath path))) (string/replace-all "\\" "/" (os/realpath path)))
(defn- bundle-dir
[&opt bundle-name]
(string (bundle-rpath (dyn *syspath*)) "/bundle/" bundle-name))
(defn- bundle-file
[bundle-name filename]
(string (bundle-rpath (dyn *syspath*)) "/bundle/" bundle-name "/" filename))
(defn- get-manifest-filename (defn- get-manifest-filename
[bundle-name] [bundle-name]
(bundle-file bundle-name "manifest.jdn")) (bundle-file bundle-name "manifest.jdn"))

View File

@ -1056,7 +1056,7 @@ JanetCompileResult janet_compile_lint(Janet source,
if (c.result.status == JANET_COMPILE_OK) { if (c.result.status == JANET_COMPILE_OK) {
JanetFuncDef *def = janetc_pop_funcdef(&c); JanetFuncDef *def = janetc_pop_funcdef(&c);
def->name = janet_cstring("_thunk"); def->name = janet_cstring("thunk");
janet_def_addflags(def); janet_def_addflags(def);
c.result.funcdef = def; c.result.funcdef = def;
} else { } else {

View File

@ -164,7 +164,7 @@ void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *prefix) {
} }
} }
if (frame->flags & JANET_STACKFRAME_TAILCALL) if (frame->flags & JANET_STACKFRAME_TAILCALL)
janet_eprintf(" (tailcall)"); janet_eprintf(" (tail call)");
if (frame->func && frame->pc) { if (frame->func && frame->pc) {
int32_t off = (int32_t)(frame->pc - def->bytecode); int32_t off = (int32_t)(frame->pc - def->bytecode);
if (def->sourcemap) { if (def->sourcemap) {
@ -180,6 +180,9 @@ void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *prefix) {
} }
} }
janet_eprintf("\n"); janet_eprintf("\n");
if (i <= 0 && fi > 0) { /* no next frame, first stack frame in fiber. First fiber is trivial. */
janet_eprintf(" in parent fiber\n");
}
} }
} }

View File

@ -318,7 +318,7 @@ static Janet janet_binop_call(const char *lmethod, const char *rmethod, Janet lh
Janet lr = janet_method_lookup(rhs, rmethod); Janet lr = janet_method_lookup(rhs, rmethod);
Janet argv[2] = { rhs, lhs }; Janet argv[2] = { rhs, lhs };
if (janet_checktype(lr, JANET_NIL)) { if (janet_checktype(lr, JANET_NIL)) {
janet_panicf("could not find method :%s for %v, or :%s for %v", janet_panicf("could not find method :%s for %v or :%s for %v",
lmethod, lhs, lmethod, lhs,
rmethod, rhs); rmethod, rhs);
} }