mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
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()
|
||||
Reference in New Issue
Block a user