vihaco_module/loader.rs
1// SPDX-FileCopyrightText: 2026 The vihaco Authors
2// SPDX-License-Identifier: MIT
3
4//! Program-construction capabilities and legacy section-loading hooks.
5//!
6//! With `program-image-execution`, callers construct images explicitly and the
7//! section-loading hooks are unavailable. Lowering capabilities remain available
8//! in both feature configurations.
9
10#[cfg(not(feature = "program-image-execution"))]
11use vihaco_bytecode::{BytecodeSectionView, SstSectionView};
12
13pub use crate::lowering::{FunctionScope, MetadataLoweringContext};
14
15/// Allow a machine to load the bytecode data owned directly by its section.
16///
17/// When used with the [`vihaco_runtime_derive::composite`] macro, this hook runs before
18/// generated child-section forwarding. Implement this for each composite to
19/// make its own section behavior explicit, even when that behavior is a no-op.
20/// Return program data to an outer owner rather than storing it inside Dispatch.
21/// Existing loaders that only mutate their receiver use `type Output = ();`.
22#[cfg(not(feature = "program-image-execution"))]
23pub trait LoadOwnBytecodeSection<C> {
24 /// The artifact produced for this section, or `()` for a loader that stores it.
25 type Output;
26
27 fn load_own_bytecode_section<'bc>(
28 &mut self,
29 section: BytecodeSectionView<'bc, C>,
30 ) -> eyre::Result<Self::Output>;
31}
32
33/// Allow a machine to load the SST data owned directly by its section.
34///
35/// When used with the [`vihaco_runtime_derive::composite`] macro, this hook runs before
36/// generated child-section forwarding. Implement this for each composite to
37/// make its own section behavior explicit, even when that behavior is a no-op.
38/// Return program data to an outer owner rather than storing it inside Dispatch.
39/// Existing loaders that only mutate their receiver use `type Output = ();`.
40#[cfg(not(feature = "program-image-execution"))]
41pub trait LoadOwnSstSection<C> {
42 /// The artifact produced for this section, or `()` for a loader that stores it.
43 type Output;
44
45 fn load_own_sst_section<'bc>(
46 &mut self,
47 section: SstSectionView<'bc, C>,
48 ) -> eyre::Result<Self::Output>;
49
50 /// Lower a section's parsed instructions after preparing loader capabilities.
51 ///
52 /// Call this from `load_own_sst_section` before storing executable code.
53 /// For a generated composite syntax aggregate, the single `Lower<Self>`
54 /// bound requires every included instruction's loader capabilities. An
55 /// error returns no partial instruction vector.
56 fn lower_instructions<I>(
57 &mut self,
58 instructions: impl IntoIterator<Item = I>,
59 ) -> eyre::Result<Vec<I::Runtime>>
60 where
61 I: vihaco_abi::Lower<Self>,
62 {
63 instructions
64 .into_iter()
65 .map(|instruction| instruction.lower(self))
66 .collect()
67 }
68}
69
70/// Allow a machine to load a bytecode section completely.
71///
72/// For composites generated by [`vihaco_runtime_derive::composite`], this loads the
73/// composite's own section through [`LoadOwnBytecodeSection`] and then forwards
74/// direct child sections to `#[loadable]` devices. The generated implementation
75/// returns the own-section output after all child loads succeed. Loadable children
76/// use `Output = ()`: an authored owner stores each child artifact internally.
77///
78/// Loading is not transactional. On error, no output is returned, but earlier
79/// mutations to this loader or already-loaded children are retained.
80#[cfg(not(feature = "program-image-execution"))]
81pub trait LoadBytecodeSection<C> {
82 /// The artifact produced for this section, or `()` for a loader that stores it.
83 type Output;
84
85 fn load_bytecode_section<'bc>(
86 &mut self,
87 section: BytecodeSectionView<'bc, C>,
88 ) -> eyre::Result<Self::Output>;
89}
90
91/// Allow a machine to load an SST section completely.
92///
93/// For composites generated by [`vihaco_runtime_derive::composite`], this loads the
94/// composite's own section through [`LoadOwnSstSection`] and then forwards
95/// direct child sections to `#[loadable]` devices. The generated implementation
96/// returns the own-section output after all child loads succeed. Loadable children
97/// use `Output = ()`: an authored owner stores each child artifact internally.
98///
99/// Loading is not transactional. On error, no output is returned, but earlier
100/// mutations to this loader or already-loaded children are retained.
101#[cfg(not(feature = "program-image-execution"))]
102pub trait LoadSstSection<C> {
103 /// The artifact produced for this section, or `()` for a loader that stores it.
104 type Output;
105
106 fn load_sst_section<'bc>(
107 &mut self,
108 section: SstSectionView<'bc, C>,
109 ) -> eyre::Result<Self::Output>;
110}