163 lines
5.4 KiB
Markdown
163 lines
5.4 KiB
Markdown
# Syscall Policies
|
|
|
|
Domain: host ABI operational policy
|
|
Function: normative
|
|
|
|
This chapter defines the operational policies that sit on top of the host ABI.
|
|
|
|
It complements [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md), which defines the structural ABI itself.
|
|
|
|
Unless a domain chapter explicitly narrows behavior further, this chapter is the transversal policy for all syscalls in v1.
|
|
|
|
## 1 Error Model: Faults vs Status Returns
|
|
|
|
Syscalls use a status-first hybrid model.
|
|
|
|
### Fault conditions
|
|
|
|
The VM faults when contract rules are violated, for example:
|
|
|
|
- invalid syscall id;
|
|
- unresolved canonical identity;
|
|
- missing required capability;
|
|
- insufficient argument slots;
|
|
- invalid or dead heap handle.
|
|
|
|
These are not ordinary domain statuses.
|
|
|
|
Faults are split into two runtime classes:
|
|
|
|
- `Trap`: guest-visible structural violation (ABI misuse / invalid call shape).
|
|
- `Panic`: runtime invariant break (internal inconsistency).
|
|
|
|
`Unavailable` is not a canonical fault class in this policy model.
|
|
|
|
- operational unavailability should be represented as `status`;
|
|
- structural host/runtime collapse should be treated as `Panic`.
|
|
|
|
### Status returns
|
|
|
|
Normal operational success and operational failure conditions should be represented as values in return slots.
|
|
|
|
Examples:
|
|
|
|
- asset not yet loaded;
|
|
- audio voice unavailable;
|
|
- persistent storage full.
|
|
|
|
When a syscall returns `status`, that `status:int` occupies the first return slot.
|
|
Any additional payload is domain-defined and follows that leading status slot.
|
|
|
|
### Return shape policy (`void` vs `status`)
|
|
|
|
This policy is normative:
|
|
|
|
- if an operation has observable operational failure modes, it must return `status:int` explicitly;
|
|
- if an operation can be operationally rejected, ignored, deferred with failure, or conclude with guest-observable `no_effect`, it is not eligible to remain `void`;
|
|
- if an operation has no real operational error path, it may remain `void` (`ret_slots = 0`);
|
|
- `status` coding is domain-owned and may differ by operation, but must be deterministic and documented.
|
|
|
|
Practical rule:
|
|
|
|
- `void` is allowed only for operations whose non-fault path is effectively unconditional success;
|
|
- any operation with a meaningful operational non-success outcome must surface that outcome through `status`, not through absence of return values.
|
|
|
|
### No-op policy
|
|
|
|
Silent no-op is not allowed when an operation can fail operationally in a guest-observable way.
|
|
|
|
In those cases, the runtime must return explicit `status` instead of masking failure as implicit success.
|
|
|
|
Implicit fallback is also forbidden when it hides an operational error or state rejection that the guest could observe or reason about.
|
|
|
|
This means operational problems must not be reclassified as:
|
|
|
|
- silent success;
|
|
- silent ignore;
|
|
- `Trap`, when the failure is not structural;
|
|
- `Panic`, when the failure is not an internal invariant break.
|
|
|
|
## 2 Capability System
|
|
|
|
Each syscall requires a declared capability.
|
|
|
|
Example groups:
|
|
|
|
- `gfx`
|
|
- `audio`
|
|
- `asset`
|
|
- `fs` (includes game memcard module `mem` in v1)
|
|
|
|
Capability checks exist to constrain which host-managed surfaces a cartridge may use.
|
|
|
|
Input in v1 is VM-owned intrinsic surface and is not capability-gated through syscall policy.
|
|
|
|
Game memcard operations (`mem.*`) are status-first and use `fs` capability in v1.
|
|
`mem` remains layered on runtime `fs`; no parallel persistence channel is introduced.
|
|
Domain surface, status catalog and slot semantics are defined in [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md).
|
|
|
|
## 3 Interaction with the Garbage Collector
|
|
|
|
The VM heap and host-managed memory are separate.
|
|
|
|
### Heap vs host memory
|
|
|
|
| Memory | Managed by | GC scanned |
|
|
| --------------- | ---------- | ---------- |
|
|
| VM heap objects | VM GC | Yes |
|
|
| Asset banks | Host | No |
|
|
| Audio buffers | Host | No |
|
|
| Framebuffers | Host | No |
|
|
|
|
### Host root rule
|
|
|
|
If the host stores a VM heap handle beyond the duration of the syscall, that handle must be treated as a host root according to the runtime contract.
|
|
|
|
This rule applies to VM heap objects, not to host-owned asset identifiers or primitive values.
|
|
|
|
## 4 Determinism Rules
|
|
|
|
Syscalls must obey machine-level determinism.
|
|
|
|
Forbidden patterns:
|
|
|
|
- reading wall-clock time as gameplay state;
|
|
- non-deterministic OS access in the gameplay contract;
|
|
- blocking I/O in the execution slice.
|
|
|
|
Allowed patterns:
|
|
|
|
- frame-based timing;
|
|
- request + poll status models;
|
|
- deterministic event publication at frame boundaries.
|
|
|
|
## 5 Cost Model and Budgeting
|
|
|
|
Each syscall contributes to frame cost.
|
|
|
|
The system may account for:
|
|
|
|
- syscall count;
|
|
- cycles spent in syscalls;
|
|
- allocations triggered by syscalls.
|
|
|
|
This keeps host interaction visible in certification, telemetry, and profiling.
|
|
|
|
## 6 Blocking and Long Operations
|
|
|
|
Syscalls must not block the execution model.
|
|
|
|
Long operations should follow explicit staged patterns such as:
|
|
|
|
1. request;
|
|
2. status polling or completion observation.
|
|
|
|
This keeps the host ABI compatible with a deterministic frame machine.
|
|
|
|
## 7 Relationship to Other Specs
|
|
|
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md) defines the structural ABI.
|
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines VM heap ownership and handles.
|
|
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines visibility of cost and diagnostics.
|
|
- domain chapters (e.g. `04`, `05`, `15`) define per-operation status tables.
|