an interface approximating stack traces
This commit is contained in:
parent
fb34909b4e
commit
7b2d39b8d4
|
@ -49,3 +49,26 @@ $check-stack:end:
|
||||||
89/<- %esp 5/r32/ebp
|
89/<- %esp 5/r32/ebp
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
|
# Helper for debugging deeply recursive calls without logs or traces.
|
||||||
|
# Turn it on, insert calls in the right places, and you get a terse sense of
|
||||||
|
# important parts of the call stack. A poor sophont's stack trace.
|
||||||
|
debug-print: # x: (addr array byte), fg: int, bg: int # x is very short; usually a single character
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
#
|
||||||
|
{
|
||||||
|
81 7/subop/compare *Really-debug-print 0/imm32/false
|
||||||
|
74/jump-if-= break/disp8
|
||||||
|
(draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+8) *(ebp+0xc) *(ebp+0x10))
|
||||||
|
}
|
||||||
|
$debug-print:end:
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
|
== data
|
||||||
|
Really-debug-print:
|
||||||
|
0/imm32/false
|
||||||
|
|
1
400.mu
1
400.mu
|
@ -26,6 +26,7 @@ sig check-strings-equal s: (addr array byte), expected: (addr array byte), msg:
|
||||||
# debugging
|
# debugging
|
||||||
sig check-stack
|
sig check-stack
|
||||||
sig show-stack-state
|
sig show-stack-state
|
||||||
|
sig debug-print x: (addr array byte), fg: int, bg: int
|
||||||
|
|
||||||
# streams
|
# streams
|
||||||
sig clear-stream f: (addr stream _)
|
sig clear-stream f: (addr stream _)
|
||||||
|
|
|
@ -497,6 +497,7 @@ Entry:
|
||||||
eb/jump $mu-main:end/disp8
|
eb/jump $mu-main:end/disp8
|
||||||
}
|
}
|
||||||
# otherwise convert Stdin
|
# otherwise convert Stdin
|
||||||
|
(write-buffered Stdout "== code\n")
|
||||||
(convert-mu Stdin Stdout Stderr 0)
|
(convert-mu Stdin Stdout Stderr 0)
|
||||||
(flush Stdout)
|
(flush Stdout)
|
||||||
# syscall(exit, 0)
|
# syscall(exit, 0)
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
# we never modify `in` or `env`
|
# we never modify `in` or `env`
|
||||||
# ignore 'screen-cell' on a first reading; it's a hack for sandboxes
|
# ignore 'screen-cell' on a first reading; it's a hack for sandboxes
|
||||||
fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
|
fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
|
||||||
# stack overflow?
|
# stack overflow? # disable when enabling Really-debug-print
|
||||||
#? check-stack
|
check-stack
|
||||||
#? show-stack-state
|
show-stack-state
|
||||||
# errors? skip
|
# errors? skip
|
||||||
{
|
{
|
||||||
compare trace, 0
|
compare trace, 0
|
||||||
|
@ -41,7 +41,6 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
var nil?/eax: boolean <- nil? in-addr
|
var nil?/eax: boolean <- nil? in-addr
|
||||||
compare nil?, 0/false
|
compare nil?, 0/false
|
||||||
break-if-=
|
break-if-=
|
||||||
#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "nil|", 7/fg, 0/bg
|
|
||||||
# nil is a literal
|
# nil is a literal
|
||||||
trace-text trace, "eval", "nil"
|
trace-text trace, "eval", "nil"
|
||||||
copy-object _in, out
|
copy-object _in, out
|
||||||
|
@ -53,7 +52,6 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
# numbers are literals
|
# numbers are literals
|
||||||
#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "number|", 7/fg, 0/bg
|
|
||||||
trace-text trace, "eval", "number"
|
trace-text trace, "eval", "number"
|
||||||
copy-object _in, out
|
copy-object _in, out
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
|
@ -63,9 +61,9 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
trace-text trace, "eval", "symbol"
|
trace-text trace, "eval", "symbol"
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "a", 7/fg, 0/bg
|
debug-print "a", 7/fg, 0/bg
|
||||||
lookup-symbol in-addr, out, env-h, globals, trace, screen-cell, keyboard-cell
|
lookup-symbol in-addr, out, env-h, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "z", 7/fg, 0/bg
|
debug-print "z", 7/fg, 0/bg
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -124,7 +122,6 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
break-if-=
|
break-if-=
|
||||||
#
|
#
|
||||||
trace-text trace, "eval", "quote"
|
trace-text trace, "eval", "quote"
|
||||||
#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "quote|", 7/fg, 0/bg
|
|
||||||
copy-object rest-ah, out
|
copy-object rest-ah, out
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
return
|
return
|
||||||
|
@ -145,7 +142,6 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
compare set?, 0/false
|
compare set?, 0/false
|
||||||
break-if-=
|
break-if-=
|
||||||
#
|
#
|
||||||
#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "set|", 7/fg, 0/bg
|
|
||||||
trace-text trace, "eval", "set"
|
trace-text trace, "eval", "set"
|
||||||
trace-text trace, "eval", "evaluating second arg"
|
trace-text trace, "eval", "evaluating second arg"
|
||||||
var rest/eax: (addr cell) <- lookup *rest-ah
|
var rest/eax: (addr cell) <- lookup *rest-ah
|
||||||
|
@ -162,8 +158,9 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
rest-ah <- get rest, right
|
rest-ah <- get rest, right
|
||||||
rest <- lookup *rest-ah
|
rest <- lookup *rest-ah
|
||||||
var second-arg-ah/edx: (addr handle cell) <- get rest, left
|
var second-arg-ah/edx: (addr handle cell) <- get rest, left
|
||||||
|
debug-print "P", 4/fg, 0/bg
|
||||||
evaluate second-arg-ah, out, env-h, globals, trace, screen-cell, keyboard-cell
|
evaluate second-arg-ah, out, env-h, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "Q", 4/fg, 0/bg
|
debug-print "Q", 4/fg, 0/bg
|
||||||
trace-text trace, "eval", "saving global binding"
|
trace-text trace, "eval", "saving global binding"
|
||||||
var first-arg/eax: (addr cell) <- lookup *first-arg-ah
|
var first-arg/eax: (addr cell) <- lookup *first-arg-ah
|
||||||
var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data
|
var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data
|
||||||
|
@ -200,8 +197,9 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
var first-arg-ah/ecx: (addr handle cell) <- get rest, left
|
var first-arg-ah/ecx: (addr handle cell) <- get rest, left
|
||||||
var guard-h: (handle cell)
|
var guard-h: (handle cell)
|
||||||
var guard-ah/esi: (addr handle cell) <- address guard-h
|
var guard-ah/esi: (addr handle cell) <- address guard-h
|
||||||
|
debug-print "R", 4/fg, 0/bg
|
||||||
evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell
|
evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "R", 4/fg, 0/bg
|
debug-print "S", 4/fg, 0/bg
|
||||||
rest-ah <- get rest, right
|
rest-ah <- get rest, right
|
||||||
rest <- lookup *rest-ah
|
rest <- lookup *rest-ah
|
||||||
var branch-ah/edi: (addr handle cell) <- get rest, left
|
var branch-ah/edi: (addr handle cell) <- get rest, left
|
||||||
|
@ -216,8 +214,9 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
rest <- lookup *rest-ah
|
rest <- lookup *rest-ah
|
||||||
branch-ah <- get rest, left
|
branch-ah <- get rest, left
|
||||||
}
|
}
|
||||||
|
debug-print "T", 4/fg, 0/bg
|
||||||
evaluate branch-ah, out, env-h, globals, trace, screen-cell, keyboard-cell
|
evaluate branch-ah, out, env-h, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "S", 4/fg, 0/bg
|
debug-print "U", 4/fg, 0/bg
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -237,9 +236,9 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
var curr-out/eax: (addr cell) <- lookup *curr-out-ah
|
var curr-out/eax: (addr cell) <- lookup *curr-out-ah
|
||||||
var left-out-ah/edi: (addr handle cell) <- get curr-out, left
|
var left-out-ah/edi: (addr handle cell) <- get curr-out, left
|
||||||
var left-ah/esi: (addr handle cell) <- get curr, left
|
var left-ah/esi: (addr handle cell) <- get curr, left
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "A", 4/fg, 0/bg
|
debug-print "A", 4/fg, 0/bg
|
||||||
evaluate left-ah, left-out-ah, env-h, globals, trace, screen-cell, keyboard-cell
|
evaluate left-ah, left-out-ah, env-h, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "B", 4/fg, 0/bg
|
debug-print "B", 4/fg, 0/bg
|
||||||
#
|
#
|
||||||
curr-out-ah <- get curr-out, right
|
curr-out-ah <- get curr-out, right
|
||||||
var right-ah/eax: (addr handle cell) <- get curr, right
|
var right-ah/eax: (addr handle cell) <- get curr, right
|
||||||
|
@ -251,9 +250,9 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
var evaluated-list/eax: (addr cell) <- lookup *evaluated-list-ah
|
var evaluated-list/eax: (addr cell) <- lookup *evaluated-list-ah
|
||||||
var function-ah/ecx: (addr handle cell) <- get evaluated-list, left
|
var function-ah/ecx: (addr handle cell) <- get evaluated-list, left
|
||||||
var args-ah/edx: (addr handle cell) <- get evaluated-list, right
|
var args-ah/edx: (addr handle cell) <- get evaluated-list, right
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "C", 4/fg, 0/bg
|
debug-print "C", 4/fg, 0/bg
|
||||||
apply function-ah, args-ah, out, globals, trace, screen-cell, keyboard-cell
|
apply function-ah, args-ah, out, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "Y", 4/fg, 0/bg
|
debug-print "Y", 4/fg, 0/bg
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
# trace "=> " out {{{
|
# trace "=> " out {{{
|
||||||
{
|
{
|
||||||
|
@ -265,8 +264,8 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
|
||||||
print-cell out, stream, 0/no-trace
|
print-cell out, stream, 0/no-trace
|
||||||
trace trace, "eval", stream
|
trace trace, "eval", stream
|
||||||
}
|
}
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "Z", 4/fg, 0/bg
|
|
||||||
# }}}
|
# }}}
|
||||||
|
debug-print "Z", 4/fg, 0/bg
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
|
fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
|
||||||
|
@ -313,9 +312,9 @@ fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr hand
|
||||||
rest <- lookup *rest-ah
|
rest <- lookup *rest-ah
|
||||||
var params-ah/ecx: (addr handle cell) <- get rest, left
|
var params-ah/ecx: (addr handle cell) <- get rest, left
|
||||||
var body-ah/eax: (addr handle cell) <- get rest, right
|
var body-ah/eax: (addr handle cell) <- get rest, right
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "t", 7/fg, 0/bg
|
debug-print "D", 7/fg, 0/bg
|
||||||
apply-function params-ah, args-ah, body-ah, out, *callee-env-ah, globals, trace, screen-cell, keyboard-cell
|
apply-function params-ah, args-ah, body-ah, out, *callee-env-ah, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "U", 7/fg, 0/bg
|
debug-print "Y", 7/fg, 0/bg
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -340,9 +339,9 @@ fn apply-function params-ah: (addr handle cell), args-ah: (addr handle cell), _b
|
||||||
# evaluate each expression, writing result to `out`
|
# evaluate each expression, writing result to `out`
|
||||||
{
|
{
|
||||||
var curr-ah/eax: (addr handle cell) <- get body, left
|
var curr-ah/eax: (addr handle cell) <- get body, left
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "before call|", 7/fg, 0/bg
|
debug-print "E", 7/fg, 0/bg
|
||||||
evaluate curr-ah, out, *new-env-ah, globals, trace, screen-cell, keyboard-cell
|
evaluate curr-ah, out, *new-env-ah, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "T", 7/fg, 0/bg
|
debug-print "X", 7/fg, 0/bg
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
body-ah <- get body, right
|
body-ah <- get body, right
|
||||||
|
@ -472,9 +471,9 @@ fn lookup-symbol sym: (addr cell), out: (addr handle cell), env-h: (handle cell)
|
||||||
var env-nil?/eax: boolean <- nil? env
|
var env-nil?/eax: boolean <- nil? env
|
||||||
compare env-nil?, 0/false
|
compare env-nil?, 0/false
|
||||||
break-if-=
|
break-if-=
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "b", 7/fg, 0/bg
|
debug-print "b", 7/fg, 0/bg
|
||||||
lookup-symbol-in-globals sym, out, globals, trace, screen-cell, keyboard-cell
|
lookup-symbol-in-globals sym, out, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "y", 7/fg, 0/bg
|
debug-print "x", 7/fg, 0/bg
|
||||||
trace-higher trace
|
trace-higher trace
|
||||||
# trace "=> " out " (global)" {{{
|
# trace "=> " out " (global)" {{{
|
||||||
{
|
{
|
||||||
|
@ -490,8 +489,8 @@ fn lookup-symbol sym: (addr cell), out: (addr handle cell), env-h: (handle cell)
|
||||||
write stream, " (global)"
|
write stream, " (global)"
|
||||||
trace trace, "eval", stream
|
trace trace, "eval", stream
|
||||||
}
|
}
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "(y)", 7/fg, 0/bg
|
|
||||||
# }}}
|
# }}}
|
||||||
|
debug-print "y", 7/fg, 0/bg
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
# check car
|
# check car
|
||||||
|
|
|
@ -558,7 +558,7 @@ fn edit-sandbox _self: (addr sandbox), key: byte, globals: (addr global-table),
|
||||||
clear-screen-cell screen-cell
|
clear-screen-cell screen-cell
|
||||||
var keyboard-cell/esi: (addr handle cell) <- get self, keyboard-var
|
var keyboard-cell/esi: (addr handle cell) <- get self, keyboard-var
|
||||||
rewind-keyboard-cell keyboard-cell # don't clear keys from before
|
rewind-keyboard-cell keyboard-cell # don't clear keys from before
|
||||||
set-cursor-position 0, 0, 0
|
set-cursor-position 0, 0, 0 # for any debug prints during evaluation
|
||||||
run data, value, globals, trace, screen-cell, keyboard-cell
|
run data, value, globals, trace, screen-cell, keyboard-cell
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -681,9 +681,9 @@ fn run in: (addr gap-buffer), out: (addr stream byte), globals: (addr global-tab
|
||||||
allocate-pair nil-ah
|
allocate-pair nil-ah
|
||||||
var eval-result-storage: (handle cell)
|
var eval-result-storage: (handle cell)
|
||||||
var eval-result/edi: (addr handle cell) <- address eval-result-storage
|
var eval-result/edi: (addr handle cell) <- address eval-result-storage
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "O", 4/fg, 0/bg
|
debug-print "^", 4/fg, 0/bg
|
||||||
evaluate read-result, eval-result, *nil-ah, globals, trace, screen-cell, keyboard-cell
|
evaluate read-result, eval-result, *nil-ah, globals, trace, screen-cell, keyboard-cell
|
||||||
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "P", 4/fg, 0/bg
|
debug-print "$", 4/fg, 0/bg
|
||||||
var error?/eax: boolean <- has-errors? trace
|
var error?/eax: boolean <- has-errors? trace
|
||||||
{
|
{
|
||||||
compare error?, 0/false
|
compare error?, 0/false
|
||||||
|
|
Loading…
Reference in New Issue