summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/commands.nim3
-rw-r--r--compiler/options.nim4
-rw-r--r--compiler/vm.nim7
-rw-r--r--compiler/vmdef.nim6
4 files changed, 11 insertions, 9 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 04c918672..f90d79d5b 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -678,6 +678,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
       setTarget(conf.target, conf.target.targetOS, cpu)
   of "run", "r":
     processOnOffSwitchG(conf, {optRun}, arg, pass, info)
+  of "maxloopiterationsvm":
+    expectArg(conf, switch, arg, pass, info)
+    conf.maxLoopIterationsVM = parseInt(arg)
   of "errormax":
     expectArg(conf, switch, arg, pass, info)
     # Note: `nim check` (etc) can overwrite this.
diff --git a/compiler/options.nim b/compiler/options.nim
index 3866f4b7f..2d56974c5 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -235,6 +235,7 @@ type
     hintCounter*: int
     warnCounter*: int
     errorMax*: int
+    maxLoopIterationsVM*: int ## VM: max iterations of all loops
     configVars*: StringTableRef
     symbols*: StringTableRef ## We need to use a StringTableRef here as defined
                              ## symbols are always guaranteed to be style
@@ -380,7 +381,8 @@ proc newConfigRef*(): ConfigRef =
     ccompilerpath: "",
     toCompile: @[],
     arguments: "",
-    suggestMaxResults: 10_000
+    suggestMaxResults: 10_000,
+    maxLoopIterationsVM: 10_000_000,
   )
   setTargetFromSystem(result.target)
   # enable colors by default on terminals
diff --git a/compiler/vm.nim b/compiler/vm.nim
index d190c4645..8a08de36d 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -486,11 +486,11 @@ proc compile(c: PCtx, s: PSym): int =
 template handleJmpBack() {.dirty.} =
   if c.loopIterations <= 0:
     if allowInfiniteLoops in c.features:
-      c.loopIterations = MaxLoopIterations
+      c.loopIterations = c.config.maxLoopIterationsVM
     else:
       msgWriteln(c.config, "stack trace: (most recent call last)")
       stackTraceAux(c, tos, pc)
-      globalError(c.config, c.debug[pc], errTooManyIterations)
+      globalError(c.config, c.debug[pc], errTooManyIterations % $c.config.maxLoopIterationsVM)
   dec(c.loopIterations)
 
 proc recSetFlagIsRef(arg: PNode) =
@@ -513,8 +513,7 @@ const
   errConstantDivisionByZero = "division by zero"
   errIllegalConvFromXtoY = "illegal conversion from '$1' to '$2'"
   errTooManyIterations = "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"
+    "if you are sure this is not a bug in your code, compile with `--maxLoopIterationsVM:number` (current value: $1)"
   errFieldXNotFound = "node lacks field: "
 
 proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 6c359c9b1..a9ff7f2d0 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -23,8 +23,6 @@ const
 
   byteExcess* = 128 # we use excess-K for immediates
 
-  MaxLoopIterations* = 10_000_000 # max iterations of all loops
-
 # Calculate register shifts, masks and ranges
 
 const
@@ -259,14 +257,14 @@ type
 proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph): PCtx =
   PCtx(code: @[], debug: @[],
     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: "",
     cache: cache, config: g.config, graph: g)
 
 proc refresh*(c: PCtx, module: PSym) =
   c.module = module
   c.prc = PProc(blocks: @[])
-  c.loopIterations = MaxLoopIterations
+  c.loopIterations = c.config.maxLoopIterationsVM
 
 proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
   result = c.callbacks.len