Skip to main content

Module foreign_marshal

Module foreign_marshal 

Source
Expand description

Shape-value <-> MessagePack marshaling for foreign function calls.

ADR-006 §2.7.29 W17-foreign-ffi 2026-05-23

ADR-006 §2.7.4 / §2.7.5 / §2.7.6: this module is the Rust-side carrier shape for foreign function (extern C / Python / TypeScript) call args and results, sitting between the byte-level msgpack wire and the runtime-tier KindedSlot carrier.

Per §2.7.5 the extension contract via *mut c_void stays on raw u64 (the RawCallableInvoker.invoke signature in module_exports.rs is the stable-ABI surface); the conversion to/from KindedSlot happens inside shape-vm at this boundary, not at the extension call frame.

W17-foreign-ffi rebuild (v0.3 Round 8, 2026-05-23 — supervisor (iv) ruling fail-safe FFI version-mismatch refused at extension load time via crates/shape-runtime/src/plugins/loader.rs’s shape_abi_version check; this module’s marshal layer trusts the load gate and treats kind metadata as a §2.7.5 producer-side proof).

Producer-side proof discipline (§2.7.5):

  • marshal_args reads each input KindedSlot::kind as the single source of truth for the per-arg dispatch arm; the producer stamped the kind at compile time + opcode emission, the deleted tag_bits dispatch is absent from this boundary.
  • unmarshal_result is the inverse: the declared return_type string + schema_id (registered at compile time) are the kind oracles. The msgpack wire bytes are NOT free to re-discriminate; the caller’s return-type proof selects the per-NativeKind constructor on the KindedSlot::from_* API surface (ADR-006 §2.7.6 / Q8 carrier-bound).

Forbidden patterns refused on sight (CLAUDE.md §Renames-to-refuse- on-sight + broader-family regex):

  • Reframing this marshal layer as a deleted-tag_bits dispatch reintroduction with any of the §Renames-to-refuse-on-sight descriptors — REFUSED. NativeKind is the discriminator from end to end; the deleted is_tagged() probe + the deleted ValueWord synthesizer do not appear here.
  • Re-introducing ValueWord “for the wire” — REFUSED. Wire is rmpv::Value (an external msgpack model, NOT a deleted internal carrier).
  • Silent FFI version-mismatch degradation — REFUSED per supervisor (iv) ruling. Fail-safe REFUSE LOAD with structured error sits at the extension load gate (shape-runtime/src/plugins/loader.rs).

Functions§

marshal_args
Serialize a slice of KindedSlot args to msgpack bytes (as an array).
unmarshal_result
Deserialize msgpack bytes to a KindedSlot using declared type information.