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:
Timothee Cour
2021-06-24 02:55:31 -07:00
committed by GitHub
parent 0c8d3ae985
commit 565e07a993
6 changed files with 53 additions and 2 deletions

View File

@@ -387,6 +387,8 @@
- 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 `--nilseqs` which is now a noop.

View File

@@ -330,6 +330,7 @@ type
warnCounter*: int
errorMax*: int
maxLoopIterationsVM*: int ## VM: max iterations of all loops
isVmTrace*: bool
configVars*: StringTableRef
symbols*: StringTableRef ## We need to use a StringTableRef here as defined
## symbols are always guaranteed to be style

View File

@@ -548,9 +548,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
"pc", $pc, "opcode", alignLeft($c.code[pc].opcode, 15),
"ra", regDescr("ra", ra), "rb", regDescr("rb", instr.regB),
"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)
case instr.opcode
of opcEof: return regs[ra]
of opcRet:

View File

@@ -249,6 +249,9 @@ proc registerAdditionalOps*(c: PCtx) =
"isExported() requires a symbol. '" & $n & "' is of kind '" & $n.kind & "'", n.info)
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) =
var res = hashes.hash(a.getString(0), a.getInt(1).int, a.getInt(2).int)
if c.config.backend == backendJs:

11
lib/std/vmutils.nim Normal file
View 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
View 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()