VMs follow a strict state machine: IDLE (can be CALLed) -> RUNNING (executing) ->
WAITING_FOR_REPLY (blocked at CALL) or HALTED (terminal) or FAULTED (can be
RESUMEd). Only IDLE VMs can be CALLed — this prevents reentrancy by construction.
Call graphs are acyclic at all times.
CALL suspends the caller (RUNNING -> WAITING_FOR_REPLY), transfers gas to the
callee, and starts the callee (IDLE -> RUNNING). REPLY pops the call frame, returns
unused gas, and resumes the caller (WAITING_FOR_REPLY -> RUNNING).
RESUME restarts a FAULTED VM (FAULTED -> RUNNING), transferring fresh gas. Registers
and PC are preserved — the faulting instruction is retried. This enables demand
paging: the parent maps the missing page via indirection, then RESUMEs the child.