enable VM tracing in user code via {.define(nimVmTrace).} (#18244)
* enable VM tracing in user code via `{.define(nimVmTrace).}`
* add vmutils.vmTrace
* add vmTrace
This commit is contained in:
parent
0c8d3ae985
commit
565e07a993
6 changed files with 53 additions and 2 deletions
|
|
@ -387,6 +387,8 @@
|
||||||
|
|
||||||
- Added `--declaredlocs` to show symbol declaration location in messages.
|
- Added `--declaredlocs` to show symbol declaration location in messages.
|
||||||
|
|
||||||
|
- You can now enable/disable VM tracing in user code via `vmutils.vmTrace`.
|
||||||
|
|
||||||
- Deprecated `TaintedString` and `--taintmode`.
|
- Deprecated `TaintedString` and `--taintmode`.
|
||||||
|
|
||||||
- Deprecated `--nilseqs` which is now a noop.
|
- Deprecated `--nilseqs` which is now a noop.
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,7 @@ type
|
||||||
warnCounter*: int
|
warnCounter*: int
|
||||||
errorMax*: int
|
errorMax*: int
|
||||||
maxLoopIterationsVM*: int ## VM: max iterations of all loops
|
maxLoopIterationsVM*: int ## VM: max iterations of all loops
|
||||||
|
isVmTrace*: bool
|
||||||
configVars*: StringTableRef
|
configVars*: StringTableRef
|
||||||
symbols*: StringTableRef ## We need to use a StringTableRef here as defined
|
symbols*: StringTableRef ## We need to use a StringTableRef here as defined
|
||||||
## symbols are always guaranteed to be style
|
## symbols are always guaranteed to be style
|
||||||
|
|
|
||||||
|
|
@ -548,9 +548,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
"pc", $pc, "opcode", alignLeft($c.code[pc].opcode, 15),
|
"pc", $pc, "opcode", alignLeft($c.code[pc].opcode, 15),
|
||||||
"ra", regDescr("ra", ra), "rb", regDescr("rb", instr.regB),
|
"ra", regDescr("ra", ra), "rb", regDescr("rb", instr.regB),
|
||||||
"rc", regDescr("rc", instr.regC)]
|
"rc", regDescr("rc", instr.regC)]
|
||||||
|
if c.config.isVmTrace:
|
||||||
|
# unlike nimVMDebug, this doesn't require re-compiling nim and is controlled by user code
|
||||||
|
let info = c.debug[pc]
|
||||||
|
# other useful variables: c.loopIterations
|
||||||
|
echo "$# [$#] $#" % [c.config$info, $instr.opcode, c.config.sourceLine(info)]
|
||||||
c.profiler.enter(c, tos)
|
c.profiler.enter(c, tos)
|
||||||
|
|
||||||
case instr.opcode
|
case instr.opcode
|
||||||
of opcEof: return regs[ra]
|
of opcEof: return regs[ra]
|
||||||
of opcRet:
|
of opcRet:
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,9 @@ proc registerAdditionalOps*(c: PCtx) =
|
||||||
"isExported() requires a symbol. '" & $n & "' is of kind '" & $n.kind & "'", n.info)
|
"isExported() requires a symbol. '" & $n & "' is of kind '" & $n.kind & "'", n.info)
|
||||||
setResult(a, sfExported in n.sym.flags)
|
setResult(a, sfExported in n.sym.flags)
|
||||||
|
|
||||||
|
registerCallback c, "stdlib.vmutils.vmTrace", proc (a: VmArgs) =
|
||||||
|
c.config.isVmTrace = getBool(a, 0)
|
||||||
|
|
||||||
proc hashVmImpl(a: VmArgs) =
|
proc hashVmImpl(a: VmArgs) =
|
||||||
var res = hashes.hash(a.getString(0), a.getInt(1).int, a.getInt(2).int)
|
var res = hashes.hash(a.getString(0), a.getInt(1).int, a.getInt(2).int)
|
||||||
if c.config.backend == backendJs:
|
if c.config.backend == backendJs:
|
||||||
|
|
|
||||||
11
lib/std/vmutils.nim
Normal file
11
lib/std/vmutils.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
##[
|
||||||
|
Experimental API, subject to change.
|
||||||
|
]##
|
||||||
|
|
||||||
|
proc vmTrace*(on: bool) {.compileTime.} =
|
||||||
|
runnableExamples:
|
||||||
|
static: vmTrace(true)
|
||||||
|
proc fn =
|
||||||
|
var a = 1
|
||||||
|
vmTrace(false)
|
||||||
|
static: fn()
|
||||||
31
tests/stdlib/tvmutils.nim
Normal file
31
tests/stdlib/tvmutils.nim
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
discard """
|
||||||
|
joinable: false
|
||||||
|
nimout: '''
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
tvmutils.nim(28, 13) [opcLdImmInt] if i == 4:
|
||||||
|
tvmutils.nim(28, 10) [opcEqInt] if i == 4:
|
||||||
|
tvmutils.nim(28, 10) [opcFJmp] if i == 4:
|
||||||
|
tvmutils.nim(28, 13) [opcLdImmInt] if i == 4:
|
||||||
|
tvmutils.nim(28, 10) [opcEqInt] if i == 4:
|
||||||
|
tvmutils.nim(28, 10) [opcFJmp] if i == 4:
|
||||||
|
tvmutils.nim(29, 7) [opcLdConst] vmTrace(false)
|
||||||
|
tvmutils.nim(29, 15) [opcLdImmInt] vmTrace(false)
|
||||||
|
tvmutils.nim(29, 14) [opcIndCall] vmTrace(false)
|
||||||
|
5
|
||||||
|
6
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
# line 20 (only showing a subset of nimout to avoid making the test rigid)
|
||||||
|
import std/vmutils
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
for i in 0..<7:
|
||||||
|
echo i
|
||||||
|
if i == 2:
|
||||||
|
vmTrace(true)
|
||||||
|
if i == 4:
|
||||||
|
vmTrace(false)
|
||||||
|
|
||||||
|
static: main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue