Operating Envelope
A Lambda C script runs inside a clearly defined boundary. Two switches — FFI (host functions registered for the script) and sandbox mode (pointer-access restriction) — determine the size and shape of that boundary. This page makes the boundary explicit.
The Two Axes
| sandbox OFF | sandbox ON | |
|---|---|---|
| FFI: none | computation + raw memory poke | pure computation |
| FFI: present | full integration + escape hatch | integrated (recommended) |
Each quadrant has a distinct character.
Quadrant 1: Pure Computation
sandbox ON, no FFI
The minimal Lambda C. The script can perform any in-memory computation but cannot touch the outside world.
Available:
- The full C subset:
int,double,struct,union,enum,typedef, function pointers, full control flow (if,while,for,switch,goto). - Math intrinsics:
sin,cos,tan,asin,acos,atan,atan2,sinh,cosh,tanh,exp,log,log10,pow,sqrt,ceil,floor,fabs,fmod. - String / memory:
strcmp,strncmp,strcpy,strcat,strncat,strlen,memcpy,memset,atoi,sprintf,sscanf. - Heap (arena):
malloc,free,heap_mark,heap_release. - Search / sort:
qsort,rx_search,amatch,bf_search,bm_search. - Output:
printfand friends — but only if the host has wired up a stdout sink. On bare metal without a sink, they become silent no-ops.
Not available:
- Hardware access of any kind (GPIO, ADC, PWM, SPI, I2C, sensors, actuators).
- Real-world time (
clock,millis,timeare intrinsics but require host wiring to actually return wall-clock values). - File system, network, serial.
- Raw pointer access to addresses outside the VM-managed regions — blocked by sandbox.
In practice: the script can sqrt(2) and get the right answer in a local variable, but it has no way to communicate that answer to the outside world. Useful for algorithm validation in isolation; not useful for an embedded product on its own.
Quadrant 2: + Raw Memory Access
sandbox OFF, no FFI
Same as Quadrant 1, plus the script may dereference arbitrary pointer values:
int *gpio = (int *)0x40020000;
*gpio = 1;
In principle this allows the script to drive MMIO registers directly without any FFI binding. In practice this is rarely useful: the script must know exact memory addresses, has no type-safe marshalling, no validation of state, no error reporting back to the host, and breaks the moment the hardware mapping changes. This quadrant exists, but production code does not live here.
Quadrant 3: Integrated — Recommended Production Mode
sandbox ON, FFI present
The script can call host-registered FFI functions (typed, validated, dispatched in ~100 ns via integer ID) and is prevented from escaping the VM-managed memory regions through raw pointers.
This is the layer where real products live. Whatever the host exposes via FFI is reachable: GPIO, sensors, actuators, real-time clocks, communication buses, RTOS primitives, custom domain calls. Bugs in the script can corrupt VM data but cannot stray into OS memory, MMIO, or other tasks. The host's FFI implementations remain the safety boundary, validating each call against current physical state.
For most embedded deployments, this is the configuration you ship.
Quadrant 4: Full Authority
sandbox OFF, FFI present
Maximum expressive power. The script has FFI and raw pointer access. Useful when:
- The bytecode is fully trusted (your own production build).
- A small, performance-critical inner loop needs to touch memory the FFI surface does not expose.
- You are building developer tooling, simulators, or debug builds that need bare-metal escape hatches.
The trade-off is that a script-side bug can now corrupt arbitrary memory. Reserve this mode for trusted bytecode whose source you control.
Why This Matters
Reading the four quadrants top-to-bottom, the pattern is clear:
Lambda C alone is a sandboxed computer. The product comes alive only after a host-side FFI layer is built for the target hardware.
That FFI layer — the GPIO bindings, the sensor drivers, the timer hooks, the safety interlocks — is exactly where joint development and customization engagements happen. Lambda C is the bytecode VM, the compiler, and the contract. The remaining work is integration, and it is project-specific by design.
If your product can live entirely inside Quadrant 1 (pure compute), Lambda C alone may be enough — though in that case Lua, mruby, or an embedded interpreter of your choice would serve equally well. The reason to choose Lambda C is Quadrant 3, and the reason Quadrant 3 is hard to reach alone is the same reason we exist as a partner.
See Licensing & Engagement for how to start a conversation.