# Intrinsics and Builtin Types Specification

Status: Draft v1 (Temporary)
Applies to: builtin type declarations, builtin constants, intrinsic member surfaces, builtin layout metadata, lowering direction, and artifact-facing intrinsic contracts

## 1. Purpose

This document defines the PBS-facing contract for:

- VM-owned builtin types,
- VM-owned intrinsic operations,
- and source-level shells that expose those features to PBS programs.

Its purpose is to let the frontend expose builtin semantic types such as
`Vec2`, `Color`, and `Pixel` as first-class language types while preserving
three invariants:

- semantic ownership remains with the VM,
- builtin values have canonical stack layout,
- and builtin domain behavior does not drift into host bindings or frontend helper code.

## 2. Scope

This document defines:

- the source-level shell model for `declare builtin type`,
- the canonical metadata carried by builtin type declarations,
- builtin constants declared through reserved metadata,
- builtin field layout and projection rules,
- admissible field types for builtin layouts,
- intrinsic member metadata and owner inheritance,
- lowering categories for builtin declarations and members,
- the runtime-facing artifact direction for intrinsic operations,
- and canonical intrinsic registry ownership at ISA/profile boundary.

This document does not define:

- the full final parser grammar integration into `3. Core Syntax Specification.md`,
- the final PBX section numbering for intrinsic declarations,
- the full VM intrinsic registry binary format,
- user-extensible builtin types,
- or heap-backed builtin layouts.

## 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. `1. Language Charter.md`
4. `3. Core Syntax Specification.md`
5. `4. Static Semantics Specification.md`
6. `5. Manifest, Stdlib, and SDK Resolution Specification.md`
7. `6.2. Host ABI Binding and Loader Resolution Specification.md`
8. `6. VM-owned vs Host-backed.md`
9. This document

If a rule here conflicts with higher-precedence authority, the higher-precedence
authority wins.

## 4. Normative Inputs

This document depends on, at minimum:

- `1. Language Charter.md`
- `3. Core Syntax Specification.md`
- `4. Static Semantics Specification.md`
- `5. Manifest, Stdlib, and SDK Resolution Specification.md`
- `6.2. Host ABI Binding and Loader Resolution Specification.md`
- `6. VM-owned vs Host-backed.md`
- `13. Lowering IRBackend Specification.md`
- `15. Bytecode and PBX Mapping Specification.md`

## 5. Core Model

### 5.1 Builtin type

A builtin type is a VM-owned semantic type whose language-visible identity is
not authored by ordinary user code.

Properties:

- the type is first-class in the PBS type system,
- the type has canonical layout metadata,
- the type may expose field-like projection surfaces,
- the type may expose intrinsic member-call surfaces,
- and the type's semantic meaning is owned by the VM rather than by `stdlib`, SDK packaging, or the host.

### 5.2 Builtin declaration shell

`declare builtin type` is a reserved shell declaration.

Properties:

- it exists for binding, checking, lowering, and artifact emission,
- it has no user-authored executable body,
- and it does not transfer semantic ownership away from the VM registry.

### 5.3 Builtin constant

A builtin constant is a VM-owned named value exposed to source through a
reserved top-level `declare const` shell carrying builtin metadata.

### 5.4 Intrinsic operation

An intrinsic operation is a VM-owned callable behavior with canonical
definition in the VM contract.

### 5.5 Canonical intrinsic registry artifact

Final intrinsic ids are owned by one canonical ISA-scoped registry artifact.

Rules:

- compiler and runtime consumers must derive final intrinsic ids from that same artifact,
- dual-authoring of compiler-local and runtime-local intrinsic-id maps is forbidden,
- strict CI mode must fail on parity mismatch between consumer snapshots and canonical artifact.

## 6. Reserved Surface Forms

This document temporarily defines the intended source-level shell shape.
Final parser integration belongs to `3. Core Syntax Specification.md`.

### 6.1 Builtin type shell

Illustrative form:

```pbs
[BuiltinType(name="vec2", version=1)]
declare builtin type Vec2(
    pub x: float,
    pub y: float,
) {
    [IntrinsicCall(name="dot")]
    fn dot(other: Vec2) -> float;

    [IntrinsicCall(name="length")]
    fn length() -> float;
}
```

### 6.2 Builtin constant shell

Illustrative form:

```pbs
[BuiltinConst(target="vec2", name="zero", version=1)]
declare const ZERO: Vec2;
```

## 7. `BuiltinType` Metadata

`BuiltinType` declares the canonical VM-facing identity of a builtin type.

Required fields:

- `name`
- `version`

Rules:

- the declaration name after `declare builtin type` is the PBS-visible type name,
- `BuiltinType.name` is the canonical VM identity name,
- `BuiltinType.version` is the canonical semantic version of that builtin contract,
- the VM identity name need not equal the PBS-visible type name,
- and the pair `(name, version)` is the canonical builtin type identity in v1.

Example:

- source-visible name: `Vec2`
- canonical builtin identity: `("vec2", 1)`

## 8. Declaration Form and Structural Rules

`declare builtin type` uses a field-list surface similar to nominal aggregate
declarations.

Rules:

- `declare builtin type` is reserved to SDK/toolchain-controlled modules,
- ordinary user-authored modules must reject it,
- the declaration introduces a type name in the type namespace,
- the parenthesized member list declares builtin field projections,
- the body may contain signatures only,
- the body must not contain executable PBS statements,
- builtin members must not declare PBS bodies,
- and builtin declarations must not be used to encode ordinary user-defined structs.

This surface is intentionally shell-like.
The declaration is not the implementation authority for builtin behavior.

## 9. Builtin Fields Are Projections, Not Ordinary Storage Fields

The field-like entries in a builtin declaration describe named projections over a
canonical VM layout.

Rules:

- they are not ordinary user-defined struct fields,
- their names are visible for projection syntax such as `value.x`,
- they describe a canonical flattened layout order,
- and their meaning is projection over VM-owned builtin value representation.

Consequences:

- a builtin field declaration does not imply ordinary mutability semantics,
- a builtin field declaration does not imply that builtin values are structs,
- and a builtin field declaration does not allow user code to provide storage-level implementation bodies.

## 10. Builtin Slot Inference

Builtin field slot offsets are inferred by the compiler, not authored in source.

Rules:

- slot offsets are zero-based and deterministic,
- offsets are computed from declaration order plus flattened widths of field types,
- nested builtin fields contribute their full flattened width to subsequent offsets,
- and source-level `Slot(...)` metadata is forbidden in v1.

## 11. Builtin Layout Admissibility

Builtin field types are restricted.

A type is builtin-layout-admissible when it has:

- fixed width in slots,
- finite flattened layout,
- stack-only representation in this feature set,
- and canonical VM-owned layout metadata.

In v1 temporary scope, builtin-layout-admissible types are:

- predeclared builtin scalar types whose runtime contract defines fixed slot width,
- and declared builtin types whose own layout is fixed, finite, and stack-only.

The following are not builtin-layout-admissible unless a future spec explicitly
changes the rule:

- user-declared structs,
- services,
- contracts,
- callbacks,
- `optional`,
- `result`,
- and any type with runtime-variable or heap-defined width.

## 12. Nested Builtin Layout and Flattening

Builtin fields may refer to other builtin-layout-admissible types.

Rules:

- nested builtin field types flatten recursively into the enclosing layout,
- the enclosing builtin layout is the concatenation of its fields' flattened layouts in slot order,
- a nested field retains its nominal field identity for projection purposes,
- and verifier-facing slot widths are computed from the fully flattened layout.

Example:

```pbs
[BuiltinType(name="color", version=1)]
declare builtin type Color(
    pub raw: int,
);

[BuiltinType(name="pixel", version=1)]
declare builtin type Pixel(
    pub x: int,
    pub y: int,
    pub color: Color,
);
```

Canonical semantic layout:

```text
Pixel -> [int, int, Color]
```

Canonical flattened slot layout:

```text
Pixel -> [int, int, int]
```

## 13. Member Categories

Builtin members belong to one of the following semantic categories:

1. projection surface,
2. builtin constant surface,
3. layout-only constructor or factory surface,
4. intrinsic call surface.

This document normatively defines projection, builtin constants, and intrinsic
call surfaces.
Layout-only constructors may be introduced by future syntax or by existing
constructor lowering rules, but their implementation remains VM-facing rather
than host-backed.

## 14. `IntrinsicCall` Metadata

`IntrinsicCall` identifies a VM-owned callable member over builtin semantics.

Required fields:

- `name`

Optional fields:

- `version`

Rules:

- `IntrinsicCall` is valid only on method signatures declared inside a `declare builtin type` body,
- the enclosing `BuiltinType` provides the default intrinsic owner identity,
- `IntrinsicCall.name` is the canonical intrinsic operation name within that owner,
- if `IntrinsicCall.version` is omitted, it inherits the enclosing builtin type version,
- if `IntrinsicCall.version` is present, it overrides only the operation version,
- and `IntrinsicCall` must not be interpreted as host-binding metadata.

Canonical intrinsic identity in v1 is:

```text
(owner, name, version)
```

where:

- `owner` is inherited from `BuiltinType.name`,
- `name` is taken from `IntrinsicCall.name`,
- and `version` is inherited or overridden as above.

Example:

```pbs
[BuiltinType(name="vec2", version=1)]
declare builtin type Vec2(
    pub x: float,
    pub y: float,
) {
    [IntrinsicCall(name="dot")]
    fn dot(other: Vec2) -> float;
}
```

declares canonical intrinsic identity:

```text
("vec2", "dot", 1)
```

## 15. `BuiltinConst` Metadata

`BuiltinConst` identifies a VM-owned named constant surface.

Required fields:

- `target`
- `name`
- `version`

Rules:

- `BuiltinConst` is valid only on reserved top-level `declare const` shells,
- `target` identifies the canonical builtin owner name,
- `name` identifies the canonical constant name within that builtin owner,
- `version` identifies the constant contract version,
- the declared PBS constant name is source-visible and may differ from the canonical constant name,
- and builtin constants are VM-owned declarations, not host bindings.

Example:

```pbs
[BuiltinConst(target="vec2", name="zero", version=1)]
declare const ZERO: Vec2;
```

declares a source-visible constant `ZERO` whose canonical builtin constant
identity is:

```text
("vec2", "zero", 1)
```

## 16. Static Semantics

The following static rules apply.

### 16.1 Namespace rules

Rules:

- `declare builtin type` introduces a nominal type name in the type namespace,
- builtin type names participate in visibility and import rules like other reserved type declarations,
- ordinary user-authored type declarations must not redeclare visible builtin type names in the same scope,
- and builtin constants declared through `declare const` introduce names in the value namespace.

### 16.2 Member lookup rules

Rules:

- `expr.field` is valid when `expr` has a builtin type declaring a projection field named `field`,
- the projected type is the field's declared type,
- `expr.method()` is valid when the builtin type declares a matching intrinsic member surface,
- and missing builtin fields or members are compile-time errors.

### 16.3 Body restrictions

Rules:

- builtin declarations have no executable member bodies,
- builtin methods are signature-only shells,
- builtin constants are declaration-only shells,
- and ordinary user code must not implement builtin semantics in PBS bodies.

## 17. Lowering Model

Builtin shells guide lowering; they do not supply executable implementation.

### 17.1 Projection lowering

Projection over builtin fields lowers to canonical projection over flattened
layout.

Rules:

- field projection does not imply host interaction,
- field projection does not emit `SYSC`,
- field projection may lower to direct stack projection, reshaping operations, or another VM-owned form,
- and the projected semantics are determined by builtin layout metadata.

### 17.2 Builtin constant lowering

Builtin constants lower to VM-owned constant materialization.

Rules:

- builtin constants must not lower through host binding resolution,
- builtin constants may lower to direct value materialization, VM-owned constant pool lookup, or intrinsic-like constant fetch,
- and the canonical constant identity determines which VM-owned value is materialized.

### 17.3 Intrinsic method lowering

Intrinsic methods lower to VM-owned intrinsic call behavior.

Rules:

- intrinsic methods must not lower through `SYSC`,
- intrinsic methods must not emit `HOSTCALL`,
- intrinsic method identities lower from `(owner, name, version)` metadata,
- and the runtime-facing call form is VM-facing rather than host-facing.

## 18. Artifact Direction

This feature requires a distinct intrinsic artifact path.

Illustrative final executable form:

```text
INTRINSIC <id>
```

Illustrative optional pre-resolution form:

```text
INTRCALL <decl_index>
```

with declaration metadata carrying:

```text
(owner, name, version)
```

Rules:

- implementations may emit final `INTRINSIC <id>` directly when intrinsic ids are stable for the targeted VM contract,
- implementations may emit declaration-based intrinsic callsites when a preload resolution step is desired,
- any such intrinsic declaration path remains VM-facing and must not reuse host-binding metadata,
- and intrinsic artifacts are distinct from `SYSC`, `HOSTCALL`, and `SYSCALL`.

## 19. Verifier Obligations

The verifier must treat intrinsics and builtin layouts as first-class structural
facts.

Rules:

- each builtin type has a known flattened slot width,
- each intrinsic has known argument and result layouts,
- verifier stack effects are computed from flattened layouts rather than only from source spellings,
- and verifier reasoning must preserve nominal builtin type identity even when two builtin layouts occupy the same slot width.

Example:

```text
Vec2.dot(Vec2, Vec2) -> float
```

If `Vec2` flattens to two float-width slots, the verifier-facing stack effect is:

```text
pop 4, push 1
```

## 20. Determinism and Ownership Rules

Builtin and intrinsic semantics are VM-owned.

Rules:

- builtin operations must not rely on host registry resolution,
- builtin operations must not require runtime capability grants,
- builtin operations must not be specified merely as frontend helper code,
- and builtin operations must remain within the VM-owned category defined by `6. VM-owned vs Host-backed.md`.

## 21. Relationship to `stdlib` and SDK Packaging

`stdlib` and SDK packaging may expose builtin declarations as compile-time
surfaces.

Rules:

- packaging location does not make builtin semantics host-backed,
- source modules may import builtin shells from reserved stdlib surfaces,
- the shell remains descriptive rather than semantically authoritative,
- and the VM contract remains the owner of builtin identities, layouts, constants, and intrinsic behavior.

## 22. Deterministic Static Errors

At minimum, a conforming implementation must reject:

1. `declare builtin type` in an ordinary user-authored module,
2. missing required `BuiltinType` metadata on a builtin declaration,
3. duplicate builtin field names within one declaration,
4. source-level `Slot(...)` usage in builtin declarations,
5. builtin field types that are not builtin-layout-admissible,
6. `IntrinsicCall` used outside a builtin declaration body,
7. `BuiltinConst` used outside a reserved top-level `declare const` shell,
8. duplicate canonical builtin type identities in the same compilation environment,
9. duplicate intrinsic canonical identities within the same builtin owner and version line,
10. cyclic or unresolved flattened builtin layout composition,
11. executable member bodies inside builtin declarations,
12. any lowering that routes VM-owned builtin operations through the host-binding pipeline.

## 23. Current Decision Summary

The current temporary contract is:

1. Builtin types are VM-owned semantic types exposed through reserved shell declarations.
2. `BuiltinType(name, version)` maps source-visible type names to canonical VM builtin identities.
3. Builtin fields describe projection surfaces over canonical flattened layout.
4. Builtin field types must be builtin-layout-admissible and stack-only in this feature set.
5. Builtin types may contain other builtin-layout-admissible types, including nested builtin composition such as `Pixel` containing `Color`.
6. `IntrinsicCall(name, version?)` identifies VM-owned intrinsic member behavior and inherits owner identity from the enclosing builtin type.
7. `BuiltinConst(target, name, version)` exposes VM-owned builtin constants through reserved top-level `declare const` shells.
8. Builtin projections, constants, and intrinsic calls must not lower through `SYSC`, `HOSTCALL`, or `SYSCALL`.
9. Runtime-facing intrinsic artifacts are distinct from host-binding artifacts.
