docs: cross-link Slang and the Typed Jerboa→Rust backend
ober
bb7d640744663f9418f7ebef5d2bbe2a91c98a3a
--- a/docs/jerboa-to-rust.md +++ b/docs/jerboa-to-rust.md @@ -13,6 +13,12 @@ The Rust backend should compile typed Jerboa modules into Rust crates, compile those crates into native artifacts, and generate Jerboa wrappers so dynamic Jerboa code can call typed compiled code safely. +This backend secures code by *translation* (lean on `rustc` and the borrow checker). +[slang.md](slang.md) is the parallel *restriction* path (gate a subset, harden the Chez +binary at the OS/CPU boundary). They are complementary, not competing, and could share a +subset validator and hardening tail — see +[slang.md → Relationship to the Rust Backend](slang.md#relationship-to-the-rust-backend). + ## Goals - Compile typed Jerboa modules to safe Rust where possible. --- a/docs/rust-target.md +++ b/docs/rust-target.md @@ -8,6 +8,12 @@ The source of truth should become `(typed-library ...)` modules as described in [typed-jerboa.md](typed-jerboa.md). Generated Rust should be disposable build output, checked by tests and rebuilt from Typed Jerboa source. +This is the *translation* path to a secure native binary. Its sibling, [slang.md](slang.md), +reaches a hardened binary by *restriction* instead — the same source runs on Chez, sandboxed +at the OS/CPU boundary. The two are complementary; see +[slang.md → Relationship to the Rust Backend](slang.md#relationship-to-the-rust-backend) for +how their front ends and hardening tail could be shared. + Jerboa can currently generate Rust for a deliberately small safe subset: - typed, pure functions --- a/docs/slang.md +++ b/docs/slang.md @@ -485,6 +485,62 @@ What each target gets automatically from a Slang binary: --- +## Relationship to the Rust Backend + +Slang is one of two "secure subset of Jerboa" paths in the tree. The other is the +Typed Jerboa → Rust backend ([rust-target.md](rust-target.md) for the shipped MVP, +[jerboa-to-rust.md](jerboa-to-rust.md) for the full plan). They look alike — each +gates a restricted subset and emits a hardened native binary — but they secure code +at opposite ends: + +| | Slang | Rust backend | +|------------------|-----------------------------------------|---------------------------------------| +| Mechanism | restriction + OS/CPU hardening | translation + Rust type/borrow checker| +| Backend | Chez nanopass → native | `rustc` → native | +| Safety boundary | the binary (seccomp/landlock, CET, signed) | the source (no `unsafe`, no UB emitted) | +| Subset | broad (full `match`, `cond`, `case`, caps) | narrow (typed pure fns; growing) | +| Same code runs? | yes — every Slang program is valid Jerboa | no — source is translated to Rust | + +They are complementary, not redundant. Rust's memory safety and Slang's +self-sandboxing binary defend against different attacks — a logic bug that corrupts +memory vs. a compromised process reaching the network or filesystem. In principle they +**stack**: a Rust-generated binary can still take Slang's preamble injection, musl +static link, and ed25519 signing. + +### A shared front end + +Both pipelines already share shape — *validate a subset, hand off to a backend, then +harden and package*. Only the middle differs, which suggests one front end with +pluggable policy and codegen: + +``` +source (.ss) + --> subset validator (declarative "allowed forms" policy) + | Slang policy: broad Rust policy: narrow + typed + --> normalized core + --> backend codegen + | Chez compile-whole-program OR Typed Jerboa -> Rust crate -> rustc + --> shared hardening tail + | preamble inject, musl static link, RELRO/PIE/CET, ed25519 sign + --> single static binary +``` + +What can be shared today: + +- **Validation pass infrastructure** — `lib/std/secure/compiler.ss` already rejects + unsafe forms by walking the AST. Make the allowed-forms set *data*, not code, so each + backend declares its own policy against one validator. +- **The hardening/packaging tail** — `lib/std/secure/preamble.ss` and `link.ss` are + backend-agnostic. Anything that produces an object/binary can reuse them, including the + output of `lib/jerboa/rust/codegen.ss` → `rustc`. + +What stays distinct on purpose: the two subsets disagree (Slang trades language surface +for a sandbox; Rust trades surface for compile-time memory proofs), and the codegen middles +are unrelated. So "share a front end" means a common validator + policy vocabulary and a +common hardening tail — not a single merged subset. + +--- + ## What This Is Not **Not a new compiler backend.** Chez's nanopass pipeline and machine backends are