yfaming on Nostr: 看完了 Crafting Interpreters 第 15 章,A Virtual Machine。 ...
看完了 Crafting Interpreters 第 15 章,A Virtual Machine。
这一章实现了一个基于栈的虚拟机(stack-based virtual machine)。
基于栈的虚拟机,是虚拟机的两大主流架构之一,另一种是基于寄存器的虚拟机。CPython、JVM、WebAssembly 是基于栈的;而 Lua、Android 的 Dalvik、Linux 的 BPF 则是基于寄存器的。
基于栈的虚拟机,初看有些神秘,但其实非常简单。
顾名思义,它有一个栈保存运行时的状态。大部分指令默认从栈上取操作数(operand),并将计算结果保存到栈上。(这使得基于栈的虚拟机的字节码指令非常紧凑,因为不需要指定从哪里取数及存到哪里。)
具体到 clox 的虚拟机,VM struct,它有有一个栈,还有个 `ip` 指针,指向下一条指令。运行时,通过一个循环,不断从 ip 获取指令,然后通过一个 switch 语句进行指令分派,决定要执行的逻辑。
就这么简单。
这一章支持了 constant、return 及加减乘除指令,后续将不断扩展指令集,以及更重要的,将 Lox 代码编译为字节码指令。
接下来,开始 Crafting Interpreters 第二部分,用 C 实现的 Lox 字节码解释器 clox。
在第一部分,用 Java 实现的 tree-walk interpreter jlox 中,我们完整实现了 Lox 解释器,包括 scanner、parser、resolver、interpreter 等等。
但是,第一部分的解释器利用了 Java 语言的许多特性。
比如,Lox 的值,全部用 Java 的 Object 类型表示。
Lox 里的 return,用 Java 的异常来实现。
而 Java 自带 GC,所以 Lox 中对象的生命周期,我们也完全没考虑过。
在第二部分,我们将使用 C 语言实现解释器。C 比 Java 更加 low-level,它不支持 OOP,不支持异常和 GC。
因此,这几个问题,我们就需要在 C 里面手动处理了。
而且,第二部分我们实现的是字节码解释器。我们需要定义字节码,并在 parsing 将 ast 编译为字节码。
用不同语言实现同一门语言,但采用略有不同的技术,可以加深我们的理解,并学习 compiler/interpreter 领域的不同主题。
Published at
2026-08-16 12:26:59 UTCEvent JSON
{
"id": "242a982283f475d3ea7f13693eba3a0f9729f5e1c4208f27f50b9e0b46441f89",
"pubkey": "908fbc3babc322eea473a0ab1e6bf6b3adcf899288ac97b2fa79f34ad408d4e4",
"created_at": 1786883219,
"kind": 1,
"tags": [
[
"q",
"1aea59b1f714db6bebf6019f30c55e36795d9bbba666682c752163c90db1acff",
"wss://relay.damus.io/",
"908fbc3babc322eea473a0ab1e6bf6b3adcf899288ac97b2fa79f34ad408d4e4"
]
],
"content": "看完了 Crafting Interpreters 第 15 章,A Virtual Machine。\n\n这一章实现了一个基于栈的虚拟机(stack-based virtual machine)。\n基于栈的虚拟机,是虚拟机的两大主流架构之一,另一种是基于寄存器的虚拟机。CPython、JVM、WebAssembly 是基于栈的;而 Lua、Android 的 Dalvik、Linux 的 BPF 则是基于寄存器的。\n\n基于栈的虚拟机,初看有些神秘,但其实非常简单。\n\n顾名思义,它有一个栈保存运行时的状态。大部分指令默认从栈上取操作数(operand),并将计算结果保存到栈上。(这使得基于栈的虚拟机的字节码指令非常紧凑,因为不需要指定从哪里取数及存到哪里。)\n\n具体到 clox 的虚拟机,VM struct,它有有一个栈,还有个 `ip` 指针,指向下一条指令。运行时,通过一个循环,不断从 ip 获取指令,然后通过一个 switch 语句进行指令分派,决定要执行的逻辑。\n\n就这么简单。\n\n这一章支持了 constant、return 及加减乘除指令,后续将不断扩展指令集,以及更重要的,将 Lox 代码编译为字节码指令。\n\n\nnostr:nevent1qvzqqqqqqypzpyy0hsa6hseza6j88g9tre4ldvade7ye9z9vj7e0570nft2q348yqy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgewaehxw309akxzmn89eex2mrp09ejumrpdejz77ngqqsp46jek8m3fkmta0mqr8esc40rv72anwa6veng936jzc7fpkc6elcmzqjf3",
"sig": "7a5d22a2e208de4804f125ce2637afc866196a6a5e73cc616f42cb25a05aba771784cc7963edb1845f4804d6e0a66c4b50852f2588ebcc31c930057d7e7ede88"
}