Spider is a compiler that translates WebAssembly binaries into lua-no-ffi, lua-jit, luau, and json targets.
The current project story is simple:
lua-no-ffiis now a real working target, not a side experiment.- Spider is measured on full translated real-world fixtures, not toy snippets.
- The old LuaJIT limits around
upvalue,scope, and giant generated closures are no longer treated as "original language limits we must accept"; they are compiler problems that Spider now attacks directly. - The legacy
ffipath still exists, and Windows support for that route was also extended through a machine-instructions-based implementation path.
Full numbers live in docs/notes/lua-no-ffi-measurements.md. This is the reduced front-page table.
| Fixture | Workload | Wasmtime | lua-no-ffi |
lua-jit / host note |
Size signal |
|---|---|---|---|---|---|
real-world-binjgb |
canonical frame_limit = 16 |
486.18 ms |
4091.13 ms |
lua-jit: full details in measurements |
.wasm: 134,905 B, Lua: 1,576,674 B |
real-world-binjgb-host-all |
--all-frames 16 |
188.04 ms |
10707.79 ms |
host-only row, no lua-jit number |
host workflow row in full table |
real-world-plmpeg-host-all |
--all-frames 12 on canonical sample |
66.33 ms |
1800.14 ms |
compare against plmpeg-stream below |
host comparison lives in measurements |
real-world-plmpeg-stream-host-all |
--all-frames 12 streaming path |
40.38 ms |
1168.06 ms |
sequential stateful path | host comparison lives in measurements |
real-world-h264bsd-mp4 |
canonical MP4 probe set | 526.91 ms |
7544.49 ms |
control target in full table | .wasm: 165,414 B, Lua: 2,184,930 B |
real-world-libjpeg-turbo-mjpeg |
canonical MJPEG probe set / host-all | 102.57 ms |
3845.82 ms |
host-all 12: 92.18 ms vs 870.81 ms |
.wasm: 375,047 B, Lua: 3,678,957 B |
self-hosting-luanoffi-builder |
generated module snapshot | n/a | current generated lua-no-ffi loads past previous top-level blocker |
lua-jit still has a deep upvalue case |
.wasm: 165,494 B, generated lua-no-ffi: 2,176,834 B |
This is not the full matrix. The complete runtime and size tables, including more fixtures and the detailed comparisons against the old path, are in docs/notes/lua-no-ffi-measurements.md.
Spider now argues a stronger point than before: Wasm can be lowered into plain Lua-family code without centering the whole runtime story on ffi, and that claim is being tested on full translated workloads rather than toy examples.
lua-no-ffi is now the project's center of gravity because it is benchmarked directly against the older lua-jit route, it is where backend work is paying off, and it gives Spider a more portable path with less dependence on host ffi.
Read these first:
Spider is already being pushed on a broad translated workload set. Important examples:
- tests/manual/real-world-plmpeg
- tests/manual/real-world-plmpeg-stream
- tests/manual/real-world-h264bsd-mp4
- tests/manual/real-world-libjpeg-turbo
- tests/manual/real-world-libjpeg-turbo-mjpeg
- tests/manual/real-world-binjgb
- tests/manual/self-hosting-luanoffi-builder
- tests/manual/real-world-lodepng
- tests/manual/real-world-miniz
- tests/manual/real-world-tinyexpr
This is the point of the repository now: not "can it compile a tiny wasm," but "how far can the backend go on real translated systems?"
The old reading of Spider was "generate Lua, rely on ffi, and treat LuaJIT limits as fixed"; the current reading is "push lua-no-ffi as a first-class target, measure it on real fixtures, and reshape generated code when those limits become a compiler problem instead of an excuse."
If you want the current state quickly, read these in order:
- docs/notes/lua-no-ffi-overview.md
- docs/notes/lua-no-ffi-measurements.md
- tests/manual/self-hosting-luanoffi-builder/README.md
If you want current open edges instead of the success story:
The main target lowers Wasm into plain LuaJIT-compatible code without making host ffi the core dependency.
The legacy target keeps the classic ffi-based fast path as a compatibility and comparison baseline.
The Luau target emits Luau-oriented output for that runtime family.
The JSON target emits a structural representation useful for debugging and inspection.
Spider/
├── CLI/ # Command-line interface
├── Conformance/ # Conformance tests
├── IR/ # Intermediate Representation
├── Sources/ # Source lifters / frontends
├── Targets/ # Output targets
├── Tools/ # Helper tooling
├── docs/notes/ # Measurements, status notes, open problems
└── tests/manual/ # Real-world manual fixtures
cargo build --release./target/release/spider-cli.exe input.wasm -t lua-no-ffi
./target/release/spider-cli.exe input.wasm -t lua-jit
./target/release/spider-cli.exe input.wasm -t luau
./target/release/spider-cli.exe input.wasm -t jsoncargo test
cargo test -p conformance --test luajit
cargo test -p conformance --test luau