shape_vm/executor/control_flow/native_abi.rs
1//! Native C ABI linking and invocation for `extern C` foreign functions.
2//!
3//! ADR-006 §2.7.4 / §2.7.5 SURFACE: this module is a forbidden-pattern
4//! carrier — every input / output path consumed the deleted `ValueWord`
5//! / `tag_bits` / `as_heap_ref` / `vmarray_from_vec` / `as_native_*` /
6//! `value_to_*` surfaces. The C ABI extension contract (libffi-driven
7//! call) stays raw bits per §2.7.5 cross-crate ABI policy, but the
8//! marshalling between the VM stack (kinded) and the FFI argument
9//! buffer (raw) is the consumer-side migration target. Per the
10//! B11-control-flow-heap dispatch the body is stubbed pending phase-2c
11//! rebuild.
12//!
13//! The pre-rebuild surface (now deleted):
14//!
15//! - `link_native_function(spec, layouts, cache)` — parsed the textual
16//! C signature, validated layout references, opened the dynamic
17//! library, resolved the symbol, built a libffi `Cif`. The signature
18//! parsing + layout resolution path is independent of `ValueWord`
19//! and could be preserved verbatim — but `NativeLinkedFunction`
20//! itself is the public type used by `executor/mod.rs:222` for the
21//! `ForeignFunctionHandle::Native(Arc<NativeLinkedFunction>)`
22//! variant; its fields stay unchanged.
23//!
24//! - `invoke_linked_function(linked, args: &[ValueWord], raw_invoker,
25//! vm_stack: &mut [ValueWord])` — encoded VM args into FFI buffers
26//! per `CType` arm, called libffi, then decoded the return value
27//! back into `ValueWord` via `from_native_*` / `from_string` /
28//! `from_array(vmarray_from_vec(...))`. The mutable-slice writeback
29//! path also wrote back via `vmarray_from_vec`. All of the above
30//! are deleted ValueWord-shape constructors; rebuild needs `&[KindedSlot]`
31//! in / `KindedSlot` out, with `&mut [u64]` + parallel `&mut
32//! [NativeKind]` for the writeback path on the §2.7.7 stack ABI.
33//!
34//! Rebuild plan: keep the `CType` parser, `CSignature`,
35//! `NativeTypeLayout` resolution, libffi `Cif` construction, and all
36//! the type-classification helpers (none of those touch ValueWord).
37//! Migrate `invoke_linked_function` to the kinded API; the
38//! `RawCallableInvoker` extension contract on the §2.7.5 FFI side
39//! stays `(*mut c_void, &u64, &[u64]) -> Result<u64, String>` per
40//! `module_exports.rs:21`.
41
42use crate::bytecode::{NativeAbiSpec, NativeStructLayoutEntry};
43use shape_runtime::module_exports::RawCallableInvoker;
44use shape_value::KindedSlot;
45use std::collections::HashMap;
46use std::sync::Arc;
47
48/// Phase-2c rebuild placeholder. The pre-rebuild type carried libffi
49/// `Cif` + `CodePtr` + parsed `CSignature` + a layout map + an
50/// `Arc<Library>` keep-alive — that internal layout is reconstructed
51/// in phase-2c on top of the kinded marshalling path. The placeholder
52/// keeps the public type name + `Arc`-wrap visible to
53/// `executor/mod.rs:222`'s `ForeignFunctionHandle::Native(Arc<...>)`
54/// variant.
55pub struct NativeLinkedFunction {
56 /// SURFACE: the field bag is kept zero-sized so attempted
57 /// instantiation surfaces a NotImplemented at the link site rather
58 /// than papering over with a dead body that compiles into wrong
59 /// runtime behavior.
60 _phase_2c_placeholder: (),
61}
62
63/// Phase-2c surface stub. The pre-rebuild body parsed the textual C
64/// signature (`fn(<params>) -> <ret>`), validated `cview<...>` /
65/// `cmut<...>` / `cslice<...>` layout references against the
66/// program-supplied `NativeStructLayoutEntry` table, opened the dynamic
67/// library via `libloading`, resolved the symbol, and built a libffi
68/// `Cif`. The signature parser and layout resolver themselves do not
69/// touch `ValueWord` — they're preserved as a starting point for the
70/// phase-2c rebuild. The library opening / symbol resolution path is
71/// also kind-independent.
72pub fn link_native_function(
73 _spec: &NativeAbiSpec,
74 _native_layouts: &[NativeStructLayoutEntry],
75 _library_cache: &mut HashMap<String, Arc<libloading::Library>>,
76) -> Result<NativeLinkedFunction, String> {
77 Err(format!(
78 "native_abi::link_native_function: phase-2c — extern C FFI rebuild (ADR-006 §2.7.4 / §2.7.5)"
79 ))
80}
81
82/// Phase-2c surface stub. Pre-rebuild body marshalled `&[ValueWord]`
83/// args into libffi argument buffers per `CType` arm, called libffi
84/// via `Cif::call::<T>`, and decoded the return value into a
85/// `ValueWord` via the deleted `from_native_*` / `from_string` /
86/// `from_array(vmarray_from_vec(...))` constructors. Rebuild target
87/// signature: `&[KindedSlot] -> Result<KindedSlot, String>` with
88/// per-`NativeKind` arg dispatch at the body site (§2.7.6) and a
89/// kinded result whose `NativeKind` is sourced from the FFI return
90/// `CType` (post-proof per §2.7.5.1). The `vm_stack` writeback path
91/// for `cmut_slice<T>` argument writebacks rebuilds against the
92/// §2.7.7 parallel `(stack: &mut [u64], kinds: &mut [NativeKind])`
93/// pair.
94pub fn invoke_linked_function(
95 _linked: &NativeLinkedFunction,
96 _args: &[KindedSlot],
97 _raw_invoker: Option<RawCallableInvoker>,
98 _vm_stack_data: Option<&mut [u64]>,
99 _vm_stack_kinds: Option<&mut [shape_value::NativeKind]>,
100) -> Result<KindedSlot, String> {
101 Err(format!(
102 "native_abi::invoke_linked_function: phase-2c — extern C FFI rebuild (ADR-006 §2.7.4 / §2.7.5)"
103 ))
104}