0%

VM Value, Call, and Runtime Contracts

Goal

Choose a safe, efficient VM-internal value/call model and extract only the genuinely backend-neutral runtime contracts. Keep native ABI adaptation at the native boundary.

  • Nine of the eleven contracts this section names have zero definitions in the tree: VmCallSig, RuntimeCallSpec, VmLayoutPlan, CompiledLayoutPlan, ReprEvidence, EnumReprEvidence, VmEnumLayout, CompiledEnumLayout, TargetSpec. Only ori_llvm::codegen::abi::FunctionAbi (abi/mod.rs:107) and ori_repr::executable::ExecutableProgram (executable/mod.rs:189) resolve.
  • This is a coinage section whose vocabulary is owned upstream, not a refactor of existing contracts. Its first act is to CONSUME the sibling name freeze, never to author a competing spelling.
  • The measured deliverable is the value/call model and the runtime-contract read-view. The safety and dependency-direction clauses (unsafe_code = "deny", no ori_llvm/oric dependency) are already true and are preserve-invariants, not budget.

Ownership Boundaries — what this section may not author

  • Name freeze: VmLayoutPlan / CompiledLayoutPlan(TargetSpec) carry 28 plan references across bytecode-vm, repr-opt#13, enum-layout-ssot, clang-arc-lessons, ffi-boundary-safety, and iterator-element-ownership, and zero code definitions. bytecode-vm#s-429b48fe holds the freeze and states every remaining item is blocked on it. Coining a competing spelling here is LEAK:scattered-knowledge across eight plans.
  • Built-in callable identity: RuntimeCall::from_symbol (runtime.rs:258) matches raw string spellings and collapses "ori_panic" | "ori_panic_cstr" into one Panic identity, though arc.md §Protocol Builtins gives them opposite ownership contracts (ori_panic consumes msg as an RL-2 transfer; ori_panic_cstr borrows). That cure is bytecode-vm#s-374b9321 (DESIGN-30, hr-3f982596bd15b2c4). This section consumes the corrected identity; it never extends the string table.
  • Enum layout: EnumTag::payload_gep_index() (enum_repr.rs:126) is an LLVM-aggregate-index accessor already living in the shared ori_repr crate — D4’s prohibition has a live counterexample. It is owned by the IN-PROGRESS enum-layout-ssot#s-0f9158ab over the same VmLayoutPlan/ExecutableProgram/EnumLayoutInfo surface. Coordinate; do not edit.
  • Compiled ABI: FunctionAbi, compute_function_abi_with_ownership, select_call_conv, and compute_closure_param_passing are owned by the IN-PROGRESS BUG-05-007#05 plus native-backend#s-35021a4c / repr-opt#12 / #13. They are the section’s constrained symbols; select_call_conv and compute_closure_param_passing are exactly the target calling-convention and byval/indirect selection D2 bans from VmCallSig.
  • Fourth-computer hazard: BUG-05-009 already names three parallel store-size/layout computers (ori_arc::pool_type_store_size, ori_llvm::type_store_size, ori_repr::compute_field_layout) and prescribes one shared repr-owned kernel. A VmLayoutPlan authored here either discharges that thesis or becomes its fourth instance.

The Incumbent This Section Must Argue Against

  • ori_vm::execute::value::VmValue (value.rs:32) is { tag: ValueTag, payload: u64 } with a static 16-byte assertion, over a 21-variant #[repr(u8)] ValueTag (11 of them IteratorStep* mirrors of the other 10 — a product encoded as a sum). That is a dynamic tag on every slot: the exact opposite of D1’s rule that the opcode supplies the static type.
  • The shape is byte-for-byte Lua 5.4 (lobject.h:49/:67, 16 B) while the plan’s memory north star is pinned LuaJIT -joff, whose TValue (lj_obj.h:174) is an 8-byte NaN-boxed union. The 2x per-slot disadvantage is baked in before the section starts, and mission gate 6 makes memory unconditional.
  • PhysicalFunctionPlan / PhysicalLane / PhysicalPcPlan / OperandSpan (physical/layout.rs:10-165) already ARE an unnamed VmLayoutPlan, exported as PhysicalVmPlan. The VmLayoutPlan deliverable is largely rename-and-freeze, not greenfield.
  • runtime_argument_ownership (ori_vm/src/execute/runtime.rs:47) already threads ori_arc::ArgOwnership per call-site operand. D5’s per-argument-ownership gap is on the DESCRIPTOR, not the call site.

Implementation Sketch

  • Prototype at least two safe representations against representative opcodes and calls: typed register banks/lanes, and fixed-size aligned slots with side metadata. The opcode supplies the static type; a dynamic tag is introduced only at a genuine dynamic boundary.
  • Define “genuine dynamic boundary” operationally rather than by intuition: a CFG merge whose predecessors disagree on the AIMS ownership obligation for a slot. Prove or refute that KnownFacts::intersect_with (ori_vm/src/physical/facts.rs:81) keeps a lane-keyed ownership map precise across such merges. Where it cannot, the fallback is a hybrid — untagged lanes for merge-invariant obligations, a narrow tagged lane only at the merges that fail the test, never universally.
  • Prior art constrains the option set rather than supplying it: WasmKit ships untyped uniform slots with types recovered statically from the instruction stream, and its frame decomposition (header / locals / constant pool / dynamic stack) is a frame vocabulary that names no sret, no calling convention, and no target stack rules. wasm3’s op-chaining mechanism is the indirect-table shape this plan already measured at 1.676x slower than a match loop on stable Rust and rejected. NaN-boxing and pointer-tagging literature answers a dynamic-typing constraint Ori does not share. No fetched source removed the tag while preserving a per-slot ownership obligation; that remainder is this section’s actual design work.
  • Derive a logical VmCallSig from canonical types, backend-neutral ReprEvidence, and typed AIMS carriers. It describes VM arguments, results, references, and ownership effects; it does not import compiled calling conventions, sret, Fast/CCC, target stack rules, or LLVM attributes.
  • Keep VmCallSig separate from compiled FunctionAbi. Per repr-opt#13 and native-backend#s-35021a4c, one backend-neutral compiled ABI classifier is consumed by LLVM and ori_backend; the VM does not become a third consumer of platform ABI frames. The crate graph already forecloses the import (ori_vm depends only on ori_arc, ori_ir, ori_registry, ori_repr), so the live risk is shape mimicry — VmCallSig re-deriving indirect/byval/sret reasoning inside ori_vm — which is reviewer-time semantic, not a dependency lint. Express the split as two sibling descriptors over one logical source, mirroring lua’s CallInfo versus luajit’s separate CCallInfo; never as one type with a mode flag, and never as an overlay stacked on the platform ABI.
  • Keep VmCallSig to one type. abi::CallConv ~ abi::CallConvSite is the highest-similarity duplication pair in the scoped set (0.954); a VM “calling convention” enum plus a VM “call site” enum reproduces that twin inside ori_vm.
  • Per plans/enum-layout-ssot, derive VmEnumLayout from shared enum evidence and VM policy. VM tag/payload locations, safe handles, and trace/drop schemas never reuse CompiledEnumLayout byte offsets or LLVM aggregate indices. The genuinely neutral evidence is min_tag_width / VariantRepr / is_pointer; payload_gep_index is not, and is constrained.
  • Extract a backend-neutral RuntimeCallSpec containing identity, semantic signature, per-argument ownership, result independence/aliasing, unwind contract, and capability requirements. RuntimeCall today carries exactly one semantic fact (arity()); five of D5’s six facets are absent. LLVM declarations and ori_backend runtime calls translate the spec through the shared compiled layout/ABI plan; VM calls translate it to safe runtime wrappers.
  • Extract RuntimeCallSpec as a DERIVED READ-VIEW over ExecutableProgram’s existing parameter_facts, return_facts, effect_facts, drop_plan, and param_disjointness families, not as new ExecutableProgramParts fields. The 19 highest-churn symbols in ori_vm are hand-built ExecutableProgram test fixtures (the first production symbol ranks 20th at a 13x lower score); every new field on the shared contract is paid for 19 times in fixture construction before a production line changes. Those *_facts accessors also already form a 0.82-0.88 similarity mesh, so a fifth member multiplies the duplication signal as well as the fixture tax.
  • Preserve the layer’s uniform shape: every scoped identity type in ori_repr::executable derives Copy + Hash + structural Eq with zero #[allow], zero suppression, zero cfg. A RuntimeCallSpec carrying a Vec<ArgOwnership> breaks Copy and departs from that convention — use a fixed-arity array or an interned index. Do not spray (ownership, aliasing, unwind, capabilities) as four parallel side tables keyed by RuntimeCall.
  • Never derive the ownership facet from a collapsed identity: an ownership field computed for the merged ori_panic | ori_panic_cstr identity is provably wrong for one of the two.
  • Keep source semantics separate from backend storage optimization. A call declared to borrow and return independent storage may not mutate or return an unretained alias merely because dynamic RC is one: RC uniqueness does not prove that the source value is dead. A future consume-and-COW fast path must be an explicit proved ownership-transfer variant selected from shared AIMS/liveness facts, with a reference borrowed variant and evaluator/VM/LLVM parity pins.
  • Make the safety clause structural rather than merely forbidden: the ownership authority for a slot is the frozen AIMS fact at that program point, carried in a side map keyed by (lane, pc-range), never a dynamic RC observation read out of the slot. QuickJS’s JS_DupValue/JS_FreeValue gate ownership work on the tag; removing the tag removes that gate, so ownership actions must resolve statically from the opcode plus the frozen plan.
  • Keep the first VM crate unsafe_code = "deny". Workspace Cargo.toml:107 already denies it, ori_vm inherits via [lints] workspace = true, and ori_vm/src contains zero unsafe. Raw native-bit-compatible storage requires a measured win, an explicit safety design, and project approval; mixed-tier frames and OSR remain out of scope.

Spec & Rules

  • ReprEvidence supplies neutral extent/range/niche/field facts; VmLayoutPlan chooses VM storage, while CompiledLayoutPlan chooses the one target layout/ABI shared by LLVM and ori_backend. None is currently a deterministic Salsa key or serialized chunk format, and none currently exists as a definition — the names are consumed from bytecode-vm#s-429b48fe’s freeze.
  • Enum evidence follows the same split: EnumReprEvidence is shared, VmEnumLayout is interpreter-private, and CompiledEnumLayout is the single target-specific input to both compiled backends.
  • Runtime call descriptors are semantic contracts. LLVM values/attributes remain in ori_llvm; BIR/MIR/emission objects remain in ori_backend.
  • Runtime implementation choices must satisfy the descriptor’s aliasing and ownership contract in every profile. Dynamic uniqueness can select a representation strategy only inside the authority granted by that contract.
  • VM execution preserves the exact post-AIMS logical ownership-event, cleanup, transfer, COW/reuse, and unwind identities. Its validated VmLayoutPlan may realize them with counters, tracing, regions, copying, recycling, or an individually proved no-op; it never imports the compiled projection’s Rc* instruction spelling or reclassifies policy.
  • Calculus-first per arc.md §CP-1: if the lane-keyed ownership map requires a new AIMS ownership-transfer variant, the governing theorem is proven in the compiled Lean corpus BEFORE any Rust is written, with scratch Lean (§CP-4) used to test the CFG-merge case first. arc.md PV-2 clauses (2)/(3) — running count >= 1 at every READ and >= 1 + live siblings at every MUTATE — are the obligations a conservative merge must not silently trade for a keep-alive leak or a reintroduced dynamic check.
  • Ground the ownership facet in the burden-sole survivor stream before designing it: run ori build <file>.ori --emit-rc-remarks / compiler_repo/diagnostics/rc-stats.sh --rc-remarks and read the cause.lattice_dim histogram, which names the boundaries where an under-specified VM descriptor produces a leak or a double-free. A DEFAULT-path RC count is FALSE-GREEN and is never a verdict (arc.md §STOP); codegen-audit.sh and arc-dump.sh supply the compiled-ABI and post-AIMS carrier views, and bisect-passes.sh --rc-only carries no VM verdict at all.

Layer Coverage

LayerDisposition
L1N/A: no grammar changes.
L2N/A: no typechecking semantics change.
L3N/A: no canonicalization semantics change.
L4Covered by the neutral representation/AIMS ownership contract criterion; a new ownership-transfer variant additionally requires its compiled-Lean theorem per arc.md §CP-1.
L5N/A: the representations are contract/prototype inputs; production execution begins in the skeleton. This N/A is CONDITIONAL — it holds only while the section ships zero production-path execution change; the first such change converts L5 to covered.
L6Covered by the LLVM-debug runtime-descriptor regression criterion.
L7Covered by the LLVM-release runtime-descriptor regression criterion.
L8Covered by the AOT runtime-descriptor regression criterion.
L9Covered by the section cross-executor criterion. The comparator is currently red on BUG-04-283 (critical), BUG-04-234, BUG-04-188, and BUG-04-272 — shapes these contracts must cover. A green reading obtained from a corpus that dodges them is INVERTED-TDD:goal-drift; BUG-04-188 (owned list temporary passed to a borrowing builtin not dropped under --backend=llvm) is the compiled-side instance of D5’s own per-argument-ownership defect class.
L10Covered by the section leak-freedom criterion.
L11Covered by the ABI/runtime contract-fixture criterion. No graph-visible spec anchor reaches these files (spec-diagnostics: substrate-dark); source the clauses directly from compiler_repo/docs/ori_lang/v2026/spec/.
L12N/A: this internal contract has no independent user entry point.
  • Coverage claims are established by a real run, never from the intel graph’s test topology: test-posture reports direct_tests: 0 for ori_llvm::codegen::abi::tests, a test module that exists on disk. The facet is inverted, not merely stale.
  • history-coupling (co-change) and surprise-coupling are DARK for this file set, so the “what will this contract change drag in” surface is unavailable from the graph. Blast-radius claims are confirmed at source; callers compute_function_abi is itself partial with three unresolved occurrences.

Work Items

  • Prototype and select a safe typed VM slot model plus logical VmCallSig from shared AIMS and representation facts, explicitly arguing against the incumbent ori_vm::execute::value::VmValue (21-variant ValueTag + u64 payload, 16 bytes/slot) toward the pinned LuaJIT -joff TValue (8 bytes) as the measured target for mission gate 6; consume the VmLayoutPlan / CompiledLayoutPlan(TargetSpec) name freeze from bytecode-vm#s-429b48fe rather than coining an independent name. Define D1’s ‘genuine dynamic boundary’ operationally as a CFG merge whose predecessors disagree on the AIMS ownership obligation for a slot, and prove or refute that KnownFacts::intersect_with (ori_vm/src/physical/facts.rs:81) keeps a lane-keyed ownership map precise across such merges; where it cannot, use a narrow tagged lane only at the merges that fail this test (not universally) as the hybrid fallback. Keep the shared compiled FunctionAbi out of VM frames, and document the deferred raw-layout/OSR decision. If the prototype requires a new AIMS ownership-transfer variant, prove the governing rule in the compiled Lean corpus (arc.md §CP-1) before implementing it, using scratch Lean (§CP-4) to test the merge case first.
  • Record VmEnumLayout’s boundary against the shared ori_repr::enum_repr evidence (EnumRepr, min_tag_width, VariantRepr) and explicitly exclude payload_gep_index (an LLVM-aggregate-index accessor that has escaped into the shared crate, doc-commented as GEP index for the payload in the LLVM struct) from any VM-side derivation. Coordinate directly with the in-progress enum-layout-ssot#s-0f9158ab plan, which owns EnumLayoutInfo over the same VmLayoutPlan/ExecutableProgram surface; do not author VmEnumLayout independently while that plan is in-progress — land the coordination decision (adopt its coinage, or explicitly defer VmEnumLayout authoring past its completion) instead of an independent enum-layout contract.
  • Extract backend-neutral RuntimeCallSpec as a derived read-view over ExecutableProgram’s existing parameter_facts, return_facts, effect_facts, drop_plan, and param_disjointness families — not as new ExecutableProgramParts fields — covering identity, semantic signature, per-argument ownership, result independence/aliasing, unwind contract, and capability requirements, while preserving Copy + Hash + Eq shape (a fixed-arity array or interned index for the ownership facet, never a Vec). Do not fix the ori_panic/ori_panic_cstr from_symbol identity collapse or extend the string-literal identity table — that cure belongs to bytecode-vm#s-374b9321 (DESIGN-30, hr-3f982596bd15b2c4); this section consumes its corrected identity once landed. Do not touch payload_gep_index (owned by in-progress enum-layout-ssot#s-0f9158ab), FunctionAbi/compute_function_abi_with_ownership (owned by in-progress BUG-05-007#05/native-backend#s-35021a4c/repr-opt#12/#13), or select_call_conv/compute_closure_param_passing (target calling-convention selection D2 forbids in VmCallSig). Build safe VM wrappers over the extracted spec while ori_llvm-specific declarations and ori_backend BIR/emitter details stay in their owning crates; prove evaluator/VM/LLVM debug/release/AOT behavior unchanged.

Intel dossier — pointer and tier disposition

Dossier: value-abi-runtime-alignment--s-f9b40534.intel.md (this section’s content/intel/ sidecar)

Read that dossier from line 1 through EOF before acting on this section. This block is a pointer and an audit record, never a substitute: not the BLUF, not a summary, not selected tiers.

Dossier tierTitleLinesDispositionWhere / why
00. Bottom line up front25integrated## Goal; ## Ownership Boundaries — what this section may not author; ## The Incumbent This Section Must Argue Against
11. The target, verbatim30integrated## Goal (target sentence preserved verbatim); ## Implementation Sketch (D1-D6 restated against live-tree status); ## Layer Coverage (L5 N/A made explicitly CONDITIONAL on shipping zero production-path execution change)
22. Terrain — what actually exists75integrated## The Incumbent This Section Must Argue Against (VmValue/ValueTag 16B, PhysicalFunctionPlan as unnamed VmLayoutPlan, runtime_argument_ownership); ## Ownership Boundaries (RuntimeCall::from_symbol collapse, payload_gep_index, compiled-ABI classifier); ## Implementation Sketch (RuntimeCall carries only arity(); neutral enum evidence is min_tag_width/VariantRepr/is_pointer)
33. Code-graph recon132integrated## Implementation Sketch (crate graph forecloses the ori_llvm import so the live D3 risk is shape mimicry; RuntimeCallSpec as a derived read-view against the 19-fixture churn tax; Copy + Hash + structural Eq shape constraint from the uniform attribute posture); ## Layer Coverage (trailing bullets: test-topology facet inverted so coverage needs a real run; co-change and surprise-coupling dark; callers compute_function_abi partial)
3D3D. Diagnostic / observability surface23integrated## Spec & Rules (final bullet: ground the ownership facet in the burden-sole —emit-rc-remarks / rc-stats.sh cause.lattice_dim histogram before designing it; DEFAULT-path RC counts are FALSE-GREEN per arc.md §STOP; codegen-audit.sh / arc-dump.sh roles; bisect-passes.sh carries no VM verdict)
3H3H. Hygiene constraints the recommended design must satisfy25integrated## Ownership Boundaries (coining a competing spelling is LEAK:scattered-knowledge; BUG-05-009 fourth-computer hazard); ## Implementation Sketch (never derive the ownership facet from the collapsed ori_panic/ori_panic_cstr identity; no non-Copy spec and no four parallel side tables); ## Spec & Rules (arc.md §CP-1 calculus-first before any new ownership-transfer variant); ## Layer Coverage L9 (INVERTED-TDD:goal-drift on a corpus that dodges the red shapes)
44. The cluster — related bugs25integrated## Ownership Boundaries — the fourth-computer-hazard bullet naming BUG-05-009 as the root-cause sibling this deliverable either discharges or joins; ## Layer Coverage L9 — the comparator recorded red on BUG-04-283, BUG-04-234, BUG-04-188 and BUG-04-272, with BUG-04-188 named as the compiled-side instance of D5’s own per-argument-ownership defect class
55. Conformance audit — parallel-drift / MISSING_ABSTRACTION29integrated## Implementation Sketch (keep VmCallSig to one type — the CallConv ~ CallConvSite 0.954 twin must not be reproduced inside ori_vm; the ExecutableProgram *_facts accessors already form a 0.82-0.88 similarity mesh, so RuntimeCallSpec is a derived read-view rather than a fifth member)
66. Plan ownership — who owns this vocabulary34integrated## Goal (coinage section whose vocabulary is owned upstream; first act is to consume a freeze); ## Ownership Boundaries (name freeze at bytecode-vm#s-429b48fe with the 28-reference/0-definition ratio; identity cure at s-374b9321; enum layout at in-progress enum-layout-ssot#s-0f9158ab; compiled ABI at in-progress BUG-05-007#05 / native-backend#s-35021a4c / repr-opt#12/#13)
77. Prior art — in-graph38integrated## The Incumbent This Section Must Argue Against (Ori’s VmValue is byte-for-byte the Lua 5.4 16-byte shape against a LuaJIT lj_obj.h:174 8-byte TValue north star; the 21-variant tag is a product encoded as a sum); ## Implementation Sketch (express the VmCallSig / FunctionAbi split as two sibling descriptors mirroring lua CallInfo vs luajit CCallInfo, never one type with a mode flag; removing the tag removes QuickJS’s tag-gated ownership hook, so ownership must resolve statically from the opcode plus the frozen plan)
7W7W. External prior art (web) — open-hard target75integrated## Implementation Sketch (the operational definition of ‘genuine dynamic boundary’ as a CFG merge whose predecessors disagree on the AIMS obligation, plus the KnownFacts::intersect_with probe and the narrow-hybrid fallback; the prior-art bullet: WasmKit untagged static-typed slots and its header/locals/constant-pool/dynamic-stack frame vocabulary, wasm3’s op-chaining already measured at 1.676x and rejected, NaN-boxing answering a dynamic-typing constraint Ori does not share, and the unmapped ownership remainder as the section’s real design work; the (lane, pc-range)-keyed side map making the safety clause structural rather than merely forbidden)
88. Sentiment — unavailable, declared13not_applicableThe tier’s own finding is that the sentiment surface is absent, not weak: lua/luajit/quickjs/mruby/wasm3 are code-indexed but issue-dark, so pain/controversy percentiles cannot be computed and the tier explicitly neither raises nor lowers the test bar. Its declared substitutes are already carried elsewhere — the measured external tradeoffs by tier 7W and the plan’s own recorded probes by the Implementation Sketch. It imposes no constraint of its own on what this section must say; the absence itself is recorded by tier 9’s declared-gap list.
99. Declared coverage gaps31integrated## Layer Coverage (trailing bullets: the inverted test-topology facet means coverage claims come from a real run, and the dark co-change / surprise-coupling surfaces plus the partial ABI caller inventory force source confirmation for blast radius) and L11 (spec-diagnostics substrate-dark, so clauses are sourced directly from compiler_repo/docs/ori_lang/v2026/spec/); ## Ownership Boundaries (the constrained-symbols set payload_gep_index / FunctionAbi / compute_function_abi_with_ownership / select_call_conv / compute_closure_param_passing recorded as external hazards, not deliverables)
1010. Recommended recon entry points25not_applicableThis tier is a navigation reading list for whoever executes the section, not a constraint on what the section’s own headings must say. Every entry on it lands in the body through the tier that supplies its substance — s-429b48fe and s-374b9321 via tier 6, value.rs / physical/layout.rs / runtime.rs / enum_repr.rs / executable/mod.rs via tier 2, facts.rs:81 via tier 7W, BUG-05-009 via tier 4, and arc.md §Protocol Builtins / §CP-1 via tiers 3H and 7W. It changed no heading beyond what those tiers already changed, and recording it as integrated would double-count them.