Repository navigation
0.2a0
Pre-release
Pre-release
pwasm can now run real programs compiled from C. This release bundles WebAssembly builds of MicroPython, QuickJS and Micro QuickJS, so you can run untrusted Python or JavaScript in a sandbox with memory, CPU and time limits, using nothing but Python. #12
from pwasm.guests import MicroPython, QuickJS
mp = MicroPython(timeout=2.0)
print(mp.exec("print([x * x for x in range(5)])")) # [0, 1, 4, 9, 16]
js = QuickJS(max_memory=32 * 1024 * 1024)
print(js.eval("[1, 2, 3].map(x => x * 2)")) # [2, 4, 6]Running untrusted code
- New
pwasm.guestsmodule withMicroPython,QuickJSandMQuickJSclasses. Guests can call Python functions you register, return results decoded from JSON, and raisePythonErrororJSErrorfor guest exceptions. - New
pwasm.sandbox.Sandboxclass for running your own modules. It handles import resolution, WASI and resource limits, and providesalloc(),free()andcall()helpers for moving data in and out. - Resource limits: pass
limits=Limits(fuel=..., max_memory=...)toinstantiate()and calllimits.set_deadline()for wall-clock timeouts. Two new exceptions,OutOfFuelandTimeout, are both subclasses ofTrapError. Instances without limits pay no overhead for these checks. pwasm.wasi.WasiLiteis a small WASI preview1 implementation. It covers captured stdout/stderr, stdin, clocks, randomness, arguments and environment variables. It has no filesystem or network access.pwasm.emscripten.EmscriptenSjLjimplements theinvoke_*trampolines needed by C code compiled with emscripten-style setjmp/longjmp.
WebAssembly support
- pwasm now implements the full WebAssembly 2.0 core instruction set except SIMD. That includes i64, f32 and f64 arithmetic, conversions, sign extension, saturating truncation, multi-value, bulk memory, tables,
call_indirectand reference types. - The non-SIMD WebAssembly 2.0 core spec test suite is now vendored and runs in CI.
- Modules can import Python functions, memories, globals and tables, including ones exported by other instances. Function references can be called from Python.
decode_module()now acceptsbytearrayandmemoryviewas well asbytes.
Performance
- New compile-to-Python tier: hot functions are translated into Python source code, which typically runs 8 to 14 times faster than the interpreter.
instantiate()has a newmode=argument that takes"auto"(the default),"compile"or"interpret". - Compiled code is cached on disk in
~/.cache/pwasm, so later processes start much faster. For example, QuickJS start-up drops from about 1.3s to 0.1s. SetPWASM_CACHE_DIRto change the location, or set it to an empty string to disable the cache. - The interpreter now compiles each function to flat code with branches resolved ahead of time. This builds on the parallel-array and super-instruction optimizations from #11.
Other changes
- pwasm now runs on PyPy. CI tests PyPy 3.11 as well as CPython 3.10 through 3.14.
- The executor has been rewritten. Internal helpers such as
pwasm.executor.execute_function()andto_i32()have been removed.MemoryInstanceandGlobalInstancenow live inpwasm.runtime. - The wheel is now about 650KB because it includes the three guest
.wasmfiles.
Release notes by Claude Opus 5.5