Skip to content
bizzehdee edited this page Jun 23, 2026 · 2 revisions

Resource Limits

DScript can enforce two independent limits on script execution to prevent runaway scripts from hanging the host process.

Wall-clock timeout

engine.SetTimeout(TimeSpan.FromMilliseconds(500));

Execution is cancelled if the script runs for longer than the specified wall-clock duration. The check is made every 1024 VM instructions to minimise overhead.

Instruction limit

engine.SetInstructionLimit(10_000_000);

Execution is cancelled after the VM dispatches the given number of bytecode instructions. This is deterministic — the same script always trips the limit at the same point regardless of CPU speed.

Combining both limits

engine.SetTimeout(TimeSpan.FromSeconds(2));
engine.SetInstructionLimit(50_000_000);

Both limits are active simultaneously. Execution stops at whichever is reached first.

ScriptTimeoutException

Both limits throw ScriptTimeoutException, which is a plain .NET exception not derived from JITException or ScriptException. This means script-level try/catch blocks cannot intercept it — it always propagates to the C# host.

try
{
    engine.SetTimeout(TimeSpan.FromMilliseconds(100));
    engine.Run(ScriptEngine.Compile("while(true) {}"));
}
catch (ScriptTimeoutException ex)
{
    Console.Error.WriteLine($"Timed out: {ex.Message}");
}

Resetting limits

Call the setters again to update the limits, or pass TimeSpan.Zero / 0 to disable them:

engine.SetTimeout(TimeSpan.Zero);        // disable wall-clock limit
engine.SetInstructionLimit(0);           // disable instruction limit

Implementation notes

  • _instrCount is reset to zero at the start of each Run() call.
  • The instruction limit check happens on every instruction outside the script's try/catch dispatcher.
  • The wall-clock check samples DateTime.UtcNow only every 1024 instructions to avoid the cost of a system call on every dispatch.

Clone this wiki locally