
从 turso、smolvm 和 wasm3 出发,分别练习把一个 SQL 数据库、一台可分支的微虚拟机和只有 10 KB 内存的 WASM 沙箱放进自己的进程,并给出今晚能跑通的最小路径。
rdi、rsi、rdx、rcx、xmm0)。docs/Interpreter.md 里贴了对应的汇编,一条按位或操作编译出来只有五条指令,最后一句 jmpq *%rax 直接跳到下一个操作。文档承认这种写法在 70 年代叫 threaded code,作者是先把实现写出来才找到先例的。10throw 把异常挂在运行时上再返回一个私有标记。10platforms/ 下按目标各放一份适配,覆盖 Android、iOS、ESP32、Arduino、OpenWrt、树莓派这些环境;test/ 按 fuzz、lang、wasi、snapshot 分开。wasm3 还能编译成 WebAssembly 运行,并执行自己。1wasm3-linux-x64.elf,其余架构打包在 wasm3-linux-other.tar.gz 里;macOS 一条 brew install wasm3;源码编译只要 CMake 加一个 C 编译器。11 门槛落在「跑什么」这一侧:手上得有一个 .wasm 文件,官方文档给了 Rust、AssemblyScript、TinyGo 三条生成路径。12# 取一个静态二进制并赋可执行权限
curl -L -o wasm3 https://github.com/wasm3/wasm3/releases/latest/download/wasm3-linux-x64.elf
chmod +x wasm3
# 看用法:默认入口是 _start 函数
./wasm3 --help
# 用 Rust 编一个 WASI 程序,再交给 wasm3 运行
cargo new --bin hello && cd hello
rustup target add wasm32-wasip1
cargo build --release --target wasm32-wasip1
../wasm3 ./target/wasm32-wasip1/release/hello.wasm# 看一次计算花掉多少 gas
wasm3 --gas-meter --func fib test/lang/fib32.wasm 24
# 给一个预算,看它在哪一步被挡住
wasm3 --gas-limit 100 --func fib test/lang/fib32.wasm 24Gas used: 8935.3961,第二条以 [trap] out of gas 结束;官方文档还提醒,打开 gas 计量大约要付 10% 的吞吐代价。12 接着用 --snapshot count.dmp --func run count.wasm 起一个长循环,按 Ctrl+C 把执行状态存进文件,再用 --resume 接着算,这一步能看到执行状态在解释器里是怎么被完整暂停和恢复的。13 最后一件事是打开 docs/Interpreter.md 对着汇编读一遍操作链。100.8.0-pre。214cli/main 打开数据库拿到 Connection,Connection 把 SQL 交给 Parser,它用的是 lemon-rs,也就是 SQLite 解析器移植到 Rust 之后的分支,直接放在仓库里维护,解析出的 AST 交给 translate 生成 VDBE 程序,Statement::step() 再驱动这台虚拟机执行。15 有一条现成的观察手段:在 shell 里敲 EXPLAIN SELECT 'hello, world';,能看到一个六条指令的程序——Init 跳到 Transaction,Goto 跳到 String8 把常量写进寄存器 r[1],ResultRow 取它作为结果,Halt 结束。15 这套字节码足够通用,有人拿它跑起了 Doom。16JOIN 子句先被改写成等价的 WHERE 子句,WHERE 映射成字节码循环,ORDER BY 让程序把结果行先送进排序器,GROUP BY 让程序把结果行先送进聚合函数。15 这四句话就是「一条查询怎么变成循环」最直接的说明。BEGIN CONCURRENT 就建立在这套机制上,也是它在写并发上比 SQLite 走得更远的地方。2Completion 跟踪,函数返回 IOResult:要么 Done,要么带回一批还没完成的 Completion。判断一个函数做不做 I/O,看签名就够了,几个 Completion 可以用 CompletionGroup 合成一个。文档把这种写法叫应用层的 function coloring:异步性写在类型里,再由调用方一处处传递下去。Linux 上这套 I/O 走的是 io_uring。215tursodb,不用起服务端,也不用配端口。想按语言用,官方给了 Rust、JavaScript、Python、Go、Java、.NET 六套绑定,另有 WebAssembly 版本。2 门槛在认知这一侧:项目还没到 1.0,官方自己建议仍然保留独立备份。2# 安装 CLI(脚本来自 README,装的是最新正式版)
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/tursodatabase/turso/releases/latest/download/turso_cli-installer.sh | sh
# 进交互式 shell,默认是内存数据库
tursodb
# 建表、插数据、查回来
CREATE TABLE users (id INT, username TEXT);
INSERT INTO users VALUES (1, 'alice');
SELECT * FROM users;
# 把这句查询编译出的字节码打出来
EXPLAIN SELECT 'hello, world';.open demo.db 换成一个持久化文件,把上面几步重跑一遍,再 ls -l 看看落出了哪些文件;然后建一个索引,把同一条 EXPLAIN 前后各打一次,比较字节码多了哪几条指令;最后打开手册附录 A,对着 sql/、translate/、vdbe/、core/ 四个目录找一遍解析器、翻译器、虚拟机和存储的位置。15--branchable 启动后,smolvm machine branch --from source --name child 会给它做一次检查点,再从同一个点起一台独立子机,子机带着源机器正在跑的进程、内存和磁盘继续跑。要一次分叉很多台就加上 --freeze-source,源机器停住,后续分支复用同一份检查点,磁盘叠层不会一层层堆上去。18 检查点抓的是 RAM、CPU 状态和磁盘,可以存成文件之后在别的机器上恢复,也可以用 --at '~N' 回退到更早的代数。318smolvm-branch-ready 标记分叉点,并声明每个子机该执行的程序;子机启动时,环境里已经带好 SMOLVM_BRANCH_NAME、SMOLVM_BRANCH_INDEX、SMOLVM_BRANCH_BATCH_ID、SMOLVM_BRANCH_BATCH_SIZE。18 并行实验这类需求因此可以只把准备步骤跑一次,后面每个子机都从同一个热状态开始。Machine API。3 机器还能打包成一个 .smolmachine 文件,推到任意 OCI registry,或者做成自包含的可执行文件。官方给的例子是把 python:3.12-alpine 打成一个可执行文件,./python312 run -- python3 --version 直接就能跑。3--allow-host 或 --allow-host-pattern 限定到具体主机和通配子域;凭据替换让客户机里的代码只拿到一个占位符,真实密钥留在宿主机一侧。官方同时写明:客户机里的 root 按不可信处理,--volume 挂进去的目录和转发的 SSH agent 都属于显式授予的权限。319curl -sSL https://smolmachines.com/install.sh | bash,macOS 和 Linux 都支持。3 门槛落在硬件这一侧:Linux 上要有 /dev/kvm,Windows 上要打开 Windows Hypervisor Platform,云主机和嵌套虚拟化的环境里这个条件经常不成立。3 另有一条容易踩的坑:macOS 上的二进制必须带着 hypervisor 权限签名,自己重新签名或从源码编译会丢掉这个权限,每次启动都失败。20curl -sSL https://smolmachines.com/install.sh | bash
# 一条命令起一台一次性机器,跑完即删
smolvm machine run --net --image alpine -- uname -a
# 交互式进去看一眼
smolvm machine run --net -it --image alpine -- /bin/sh
# 常驻一台,在里面装东西
smolvm machine create --net --name dev && smolvm machine start --name dev
smolvm machine exec --name dev -- apk add git
# 从活着的机器分叉出一台子机
smolvm machine start --name source --branchable
smolvm machine branch --from source --name childsmolvm machine run --net --image alpine -- uname -a,把输出的内核版本和宿主机对比,确认这是另一台机器的内核;然后进交互式 shell,用 wget 从一个网址取点东西来验证网络通不通,这里要提前知道默认的网络后端不模拟网卡,客户机里没有 eth0,ping 会直接报 Network unreachable。20 最后起一台带 --branchable 的机器,在里面改一个文件,再分叉一台子机,确认子机看到的是改动之后的状态,而源机器还能继续被分叉第二次。machine branch、machine checkpoint 和 GPU 加速,pack create 还需要额外准备 ext4 模板文件;挂载只支持目录,不支持单个文件;GPU 加速要求宿主机的 libkrun 带 GPU=1 编译,并装好 virglrenderer 和 Vulkan 驱动。20 发布包提供 SHA-256 校验和,安装脚本在拿到校验和文件时会校验,发布物目前还没有签名或来源证明。19| 你想练的主线 | 仓库与本期信号 | 最小条件 | 第一条可观察路径 | 主要限制 |
|---|---|---|---|---|
| 字节码解释器与栈机器 | wasm3 · v0.9.0 8 月 25 日凌晨发布,v0.9.1-beta.1 9 月 11 日凌晨发布 | 一个静态二进制,或 CMake 加 C 编译器 | wasm3 hello.wasm 跑出 Hello, world | 需要自备 .wasm 文件;解释执行比编译代码慢 4 到 15 倍。(README) |
| 数据库内部:字节码虚拟机与 MVCC | turso · v0.8.0-pre.14 昨天下午发布,正式版仍是 v0.7.1 | 一条 curl 安装脚本 | 在 tursodb 里敲 EXPLAIN SELECT 'hello, world'; | 还没到 1.0,没有触发器、视图、保存点和多进程访问。(README) |
| 虚拟化边界:microVM 与快照分叉 | smolvm · v1.20.0 今天早上 08:04 发布 | /dev/kvm,或 macOS、Hyper-V 上的虚拟化平台 | smolvm machine run --net --image alpine -- uname -a | Windows 上暂无分支与检查点;发布物未签名。(README) |
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.