Why Pliro limits a running program
A program can accidentally do far more work than you intended. Runtime limits help stop runaway work and report what went wrong.
What is being counted?
An instruction budget limits the small execution steps Pliro performs; it is not simply a count of source lines. One line can require several steps. An execution slice is the work between cooperative checkpoints. A positive wait or completed input request allows another turn and starts a fresh instruction slice. Cooperative cancellation means the runtime checks for a Stop request at its checkpoints.
Call depth counts functions still waiting for other function calls to finish. If A calls B and B calls C, those calls are nested. This is different from calling one function many times in a loop after each previous call has finished.
The event-work budget counts event delivery and scheduled handler runs across the entire session. Dispatch means delivering an event; an invocation is one run of a handler. Waiting does not refill this budget. A one-shot timer becomes ready once, and arming it means starting its wait. Bounded history means the host keeps only a limited amount of past event information.
Runtimes enforce:
- a configurable instruction budget per cooperative execution slice;
- cooperative cancellation;
- a bounded user-function call-depth limit, configurable in session runtimes
and fixed at 256 in the current generated native runtime; - a session-wide event-work budget, 10,000 units by default, that charges every
broadcast dispatch, matching key/pointer-press/pointer-release/completed-click dispatch, and
queued handler
invocation; a one-shot timer receives that single handler charge when armed,
not a second charge when it wakes; - bounded input size and event history in hosts that retain events.
A tight loop such as while true: without a positive wait or input request
eventually fails with the instruction-budget diagnostic instead of freezing the
IDE or browser.
The event-work budget is independent of instruction-budget slices and positive
waits never replenish it. Exceeding it fails with E4018.
Starting a persistent keyboard/pointer-event program without every required
host capability fails with E4019 instead of silently finishing or waiting
forever. Calling pointerX() or pointerY() outside a pointer-event task
fails with E4020. Native targets that cannot provide the required host are
rejected earlier with E6001.
