VM: allow overriding MaxLoopIterations without rebuilding nim (#13233)
This commit is contained in:
parent
f12bea16ad
commit
b462baed65
6 changed files with 13 additions and 10 deletions
|
|
@ -678,6 +678,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
setTarget(conf.target, conf.target.targetOS, cpu)
|
setTarget(conf.target, conf.target.targetOS, cpu)
|
||||||
of "run", "r":
|
of "run", "r":
|
||||||
processOnOffSwitchG(conf, {optRun}, arg, pass, info)
|
processOnOffSwitchG(conf, {optRun}, arg, pass, info)
|
||||||
|
of "maxloopiterationsvm":
|
||||||
|
expectArg(conf, switch, arg, pass, info)
|
||||||
|
conf.maxLoopIterationsVM = parseInt(arg)
|
||||||
of "errormax":
|
of "errormax":
|
||||||
expectArg(conf, switch, arg, pass, info)
|
expectArg(conf, switch, arg, pass, info)
|
||||||
# Note: `nim check` (etc) can overwrite this.
|
# Note: `nim check` (etc) can overwrite this.
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ type
|
||||||
hintCounter*: int
|
hintCounter*: int
|
||||||
warnCounter*: int
|
warnCounter*: int
|
||||||
errorMax*: int
|
errorMax*: int
|
||||||
|
maxLoopIterationsVM*: int ## VM: max iterations of all loops
|
||||||
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
|
||||||
|
|
@ -380,7 +381,8 @@ proc newConfigRef*(): ConfigRef =
|
||||||
ccompilerpath: "",
|
ccompilerpath: "",
|
||||||
toCompile: @[],
|
toCompile: @[],
|
||||||
arguments: "",
|
arguments: "",
|
||||||
suggestMaxResults: 10_000
|
suggestMaxResults: 10_000,
|
||||||
|
maxLoopIterationsVM: 10_000_000,
|
||||||
)
|
)
|
||||||
setTargetFromSystem(result.target)
|
setTargetFromSystem(result.target)
|
||||||
# enable colors by default on terminals
|
# enable colors by default on terminals
|
||||||
|
|
|
||||||
|
|
@ -486,11 +486,11 @@ proc compile(c: PCtx, s: PSym): int =
|
||||||
template handleJmpBack() {.dirty.} =
|
template handleJmpBack() {.dirty.} =
|
||||||
if c.loopIterations <= 0:
|
if c.loopIterations <= 0:
|
||||||
if allowInfiniteLoops in c.features:
|
if allowInfiniteLoops in c.features:
|
||||||
c.loopIterations = MaxLoopIterations
|
c.loopIterations = c.config.maxLoopIterationsVM
|
||||||
else:
|
else:
|
||||||
msgWriteln(c.config, "stack trace: (most recent call last)")
|
msgWriteln(c.config, "stack trace: (most recent call last)")
|
||||||
stackTraceAux(c, tos, pc)
|
stackTraceAux(c, tos, pc)
|
||||||
globalError(c.config, c.debug[pc], errTooManyIterations)
|
globalError(c.config, c.debug[pc], errTooManyIterations % $c.config.maxLoopIterationsVM)
|
||||||
dec(c.loopIterations)
|
dec(c.loopIterations)
|
||||||
|
|
||||||
proc recSetFlagIsRef(arg: PNode) =
|
proc recSetFlagIsRef(arg: PNode) =
|
||||||
|
|
@ -513,8 +513,7 @@ const
|
||||||
errConstantDivisionByZero = "division by zero"
|
errConstantDivisionByZero = "division by zero"
|
||||||
errIllegalConvFromXtoY = "illegal conversion from '$1' to '$2'"
|
errIllegalConvFromXtoY = "illegal conversion from '$1' to '$2'"
|
||||||
errTooManyIterations = "interpretation requires too many iterations; " &
|
errTooManyIterations = "interpretation requires too many iterations; " &
|
||||||
"if you are sure this is not a bug in your code edit " &
|
"if you are sure this is not a bug in your code, compile with `--maxLoopIterationsVM:number` (current value: $1)"
|
||||||
"compiler/vmdef.MaxLoopIterations and rebuild the compiler"
|
|
||||||
errFieldXNotFound = "node lacks field: "
|
errFieldXNotFound = "node lacks field: "
|
||||||
|
|
||||||
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ const
|
||||||
|
|
||||||
byteExcess* = 128 # we use excess-K for immediates
|
byteExcess* = 128 # we use excess-K for immediates
|
||||||
|
|
||||||
MaxLoopIterations* = 10_000_000 # max iterations of all loops
|
|
||||||
|
|
||||||
# Calculate register shifts, masks and ranges
|
# Calculate register shifts, masks and ranges
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -259,14 +257,14 @@ type
|
||||||
proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph): PCtx =
|
proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph): PCtx =
|
||||||
PCtx(code: @[], debug: @[],
|
PCtx(code: @[], debug: @[],
|
||||||
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
||||||
prc: PProc(blocks: @[]), module: module, loopIterations: MaxLoopIterations,
|
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
|
||||||
comesFromHeuristic: unknownLineInfo, callbacks: @[], errorFlag: "",
|
comesFromHeuristic: unknownLineInfo, callbacks: @[], errorFlag: "",
|
||||||
cache: cache, config: g.config, graph: g)
|
cache: cache, config: g.config, graph: g)
|
||||||
|
|
||||||
proc refresh*(c: PCtx, module: PSym) =
|
proc refresh*(c: PCtx, module: PSym) =
|
||||||
c.module = module
|
c.module = module
|
||||||
c.prc = PProc(blocks: @[])
|
c.prc = PProc(blocks: @[])
|
||||||
c.loopIterations = MaxLoopIterations
|
c.loopIterations = c.config.maxLoopIterationsVM
|
||||||
|
|
||||||
proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
|
proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
|
||||||
result = c.callbacks.len
|
result = c.callbacks.len
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ Advanced options:
|
||||||
--incremental:on|off only recompile the changed modules (experimental!)
|
--incremental:on|off only recompile the changed modules (experimental!)
|
||||||
--verbosity:0|1|2|3 set Nim's verbosity level (1 is default)
|
--verbosity:0|1|2|3 set Nim's verbosity level (1 is default)
|
||||||
--errorMax:N stop compilation after N errors; 0 means unlimited
|
--errorMax:N stop compilation after N errors; 0 means unlimited
|
||||||
|
--maxLoopIterationsVM:N set max iterations for all VM loops
|
||||||
--experimental:$1
|
--experimental:$1
|
||||||
enable experimental language feature
|
enable experimental language feature
|
||||||
--legacy:$2
|
--legacy:$2
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "interpretation requires too many iterations; if you are sure this is not a bug in your code edit compiler/vmdef.MaxLoopIterations and rebuild the compiler"
|
errormsg: "interpretation requires too many iterations; if you are sure this is not a bug in your code"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# issue #9829
|
# issue #9829
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue