# PBS IRBackend to IRVM Lowering Specification

Status: Draft v1 (Backend Baseline)  
Applies to: executable-backend lowering from `IRBackend` handoff into `IRVM`

## 1. Purpose

This document defines the normative lowering contract from executable `IRBackend` to `IRVM`.

Its purpose is to make backend lowering deterministic, reviewable, and compatible with runtime ISA/verification authority.

## 2. Scope

This document defines:

- required backend preconditions before `IRBackend -> IRVM` starts,
- `IRVM` structural obligations needed before optimization/emission,
- deterministic function-id assignment and control-flow lowering obligations,
- callsite lowering obligations across function, host-backed, and VM-owned intrinsic paths,
- mandatory compiler-side structural pre-verification before bytecode emission,
- and deterministic rejection obligations for backend-originated failures.

This document does not define:

- binary PBX layout details,
- loader patching internals,
- runtime execution internals,
- or one mandatory optimizer implementation.

## 3. Authority and Precedence

Normative precedence:

1. Runtime authority (`docs/specs/hardware/topics/chapter-2.md`, `chapter-3.md`, `chapter-9.md`, `chapter-12.md`, `chapter-16.md`)
2. Bytecode authority (`docs/specs/bytecode/ISA_CORE.md`)
3. `docs/specs/compiler-languages/pbs/13. Lowering IRBackend Specification.md`
4. This document

If a rule here conflicts with higher-precedence authorities, it is invalid.

## 4. Normative Inputs

This document depends on:

- `docs/specs/compiler-languages/pbs/13. Lowering IRBackend Specification.md`
- `docs/specs/compiler-languages/pbs/6.1. Intrinsics and Builtin Types Specification.md`
- `docs/specs/compiler-languages/pbs/6.2. Host ABI Binding and Loader Resolution Specification.md`
- `15. Bytecode and PBX Mapping Specification.md`
- `21. IRVM Optimization Pipeline Specification.md`

## 5. Backend Entry Preconditions

Lowering from `IRBackend` to `IRVM` may start only when:

1. frontend admission to `IRBackend` is complete for the active slice,
2. required callsite categories (`CALL_FUNC`/`CALL_HOST`/`CALL_INTRINSIC`) are available,
3. required canonical host/intrinsic metadata is available for admitted callsites,
4. dependency-scoped fail-fast exclusions have already been applied at the `IRBackend` boundary,
5. compiler-selected published-wrapper entrypoint identity is present and unambiguous,
6. and target `vm_profile` is selected deterministically.

## 6. IRVM Model Obligations

`IRVM` v1 is a quasi-ISA backend form:

1. it may contain Core ISA ops and internal extension ops (`IRVM_EXT`),
2. each `IRVM_EXT` must declare structural metadata equivalent to opcode-spec needs:
   - `pops`,
   - `pushes`,
   - `is_branch`,
   - `is_terminator`,
3. and `IRVM_EXT` must be eliminable before bytecode emission.

`IRVM` must preserve, per function:

1. `param_slots`,
2. `local_slots`,
3. `return_slots`,
4. `max_stack_slots`,
5. function entry mapping and deterministic identity.

## 7. Control-Flow Lowering Obligations

Control-flow lowering must satisfy:

1. symbolic labels are allowed internally in lowering,
2. final jump immediates must be resolved to `u32` offsets relative to function start before emission,
3. jump targets must be instruction-boundary-valid within function ranges,
4. and reachable fallthrough beyond function end without terminator is rejected.

## 8. Deterministic Function-ID Assignment

Function indexing must be deterministic:

1. the compiler-selected published wrapper is the physical entrypoint,
2. the published wrapper function id is `0`,
3. remaining functions are ordered by `(moduleId -> modulePool canonical key, callable_name, source_start)`,
4. manifest-owned or name-only entrypoint fallback is forbidden,
5. and identical admitted input graphs must produce identical function-id assignments.

For PBS executable lowering:

- the userland callable marked with `[Frame]` remains the logical frame root,
- the wrapper path must contain final `FRAME_RET`,
- and lowering must preserve that distinction through `IRVM`.

## 9. Callsite Lowering Obligations

### 9.1 Function calls

`CALL_FUNC` lowers to `CALL <func_id>` with valid index and arity-consistent signature contracts.

### 9.2 Host-backed calls

`CALL_HOST` lowers to pre-load `HOSTCALL <sysc_index>`, not raw `SYSCALL`.

When a host-backed callsite carries backend-owned symbolic asset lowering metadata:

1. the backend must validate the symbolic asset operand against the backend-owned admitted surface,
2. the backend must resolve the symbolic identity to canonical runtime-facing `asset_id`,
3. and the final host-backed lowering path must consume the resolved `asset_id`, not the original symbolic address.

### 9.3 VM-owned intrinsic calls

`CALL_INTRINSIC` lowers to VM-owned intrinsic path and must remain distinct from host-binding paths.

Final intrinsic id resolution rules:

1. compiler must resolve final intrinsic ids from the canonical ISA-scoped intrinsic registry artifact,
2. compiler-local hardcoded maps or runtime-source parsing must not be authoritative identity sources,
3. runtime and compiler consumers must validate parity against the same canonical artifact in strict CI mode.

### 9.4 Closure and coroutine constraints (v1)

1. closure calls with unknown static callee are rejected in v1,
2. `SPAWN` and `YIELD` are outside the executable `core-v1` claim scope and MUST be rejected as unsupported forms in v1 backend admission,
3. `SPAWN` argument-count and `YIELD` stack-shape invariants remain reserved for a future profile that explicitly admits these opcodes,
4. and any profile that admits `SPAWN`/`YIELD` MUST publish dedicated conformance evidence before claiming support.

## 10. Mandatory Compiler-Side Pre-Verification

Before bytecode emission, backend must run structural pre-verification on lowered `IRVM` (after resolving to Core-ISA-compatible form), covering at minimum:

1. jump target validity,
2. stack-depth join consistency,
3. underflow/overflow against declared limits,
4. return-shape consistency,
5. function-id validity,
6. callsite arity consistency,
7. and structural validity of host/intrinsic call forms.
8. and structural validity of backend-owned symbolic-to-operational rewrites such as `Addressable -> asset_id`.

For PBS host-backed asset calls in v1, this validation includes the rewrite selected by preserved host metadata such as `[AssetLowering(param = N)]`.

This pre-verification does not replace runtime verifier authority.

## 11. Deterministic Rejection Policy

When backend lowering fails at this boundary:

1. rejection must be deterministic,
2. diagnostics identity and phase must remain stable,
3. and source attribution must be preserved whenever the failure remains source-attributable and user-actionable.

## 12. Explicit Deferrals

The following are intentionally deferred:

- optimizer pass catalog and tuning policy,
- richer internal IR analysis models beyond v1 obligations,
- advanced closure/lifetime optimizations beyond v1 constraints,
- and executable support for `SPAWN`/`YIELD` in `core-v1`.

## 13. Non-Goals

- Defining one in-memory IR implementation graph.
- Redefining runtime verifier/loader internals.
- Defining PBX binary chunk policy in this document.

## 14. Exit Criteria

This document is healthy when:

1. `IRBackend -> IRVM` obligations are explicit and testable,
2. deterministic function/call/control-flow lowering rules are explicit,
3. mandatory pre-verification boundary is explicit,
4. and scope boundaries with optimization/emission specs are explicit.
