章节摘要:集装箱里装的是指令。本章钻到执行层:栈式虚拟机为什么是唯一合理解、结构化控制流凭什么取代任意跳转、加载存储指令如何与内存申报咬合、实例化与链接如何把静态字节点亮成运行态。读完本章,你看到的将不再是"调用了一个函数",而是引擎逐条推演指令的完整过程——调试、优化、排错都建立在这套画面上。 一条主线:一条指令的完整旅程 第二章把箱子拆到了节,本章跟着最细的颗粒走:一条指令从被验证、被实例化到被执行的全旅程。 旅程的起点是一个刚通过验证的模块。宿主发起实例化,引擎按导入节逐项接通外部依赖,按内存节与数据节铺好初始字节,按元素节装订函数表,然后(若有起始节)执行启动函数。到这一步,静态的字节获得了可以呼吸的运行态。
章节摘要:集装箱里装的是指令。本章钻到执行层:栈式虚拟机为什么是唯一合理解、结构化控制流凭什么取代任意跳转、加载存储指令如何与内存申报咬合、实例化与链接如何把静态字节点亮成运行态。读完本章,你看到的将不再是"调用了一个函数",而是引擎逐条推演指令的完整过程——调试、优化、排错都建立在这套画面上。
第二章把箱子拆到了节,本章跟着最细的颗粒走:一条指令从被验证、被实例化到被执行的全旅程。
旅程的起点是一个刚通过验证的模块。宿主发起实例化,引擎按导入节逐项接通外部依赖,按内存节与数据节铺好初始字节,按元素节装订函数表,然后(若有起始节)执行启动函数。到这一步,静态的字节获得了可以呼吸的运行态。之后宿主每调用一次导出函数,引擎就推演一段指令序列:操作数进栈出栈、控制流在结构化框架内跳转、加载存储指令触碰内存平原、越界或除零时引擎拉响陷阱警报。本章四个小节正对着这段旅程的四段:栈机是推演的语法,控制流是推演的路线图,内存访问是推演伸出去的手,实例化与链接是推演开始前的通电仪式。
3.1 栈虚拟机模型回答"为什么是栈"。指令不命名寄存器,只隐式操作栈顶——格式最省、验证最简、移植最易。本节用逐条指令的栈快照推演一段完整计算,并讲清陷阱语义:除零、越界、不可达,全是当场熄火而非带病运行。
3.2 控制流指令讲"为什么不能随便跳"。Wasm 的分支只能进出明确标注的结构块,引擎因此拿到两条重要保证:验证阶段就能确定每个合并点的栈形,编译阶段能把结构块映射到原生分支。本节用阶乘与斐波那契两个经典函数演示 block、loop、br_if 的配合,并把数值运算指令的家族谱系一并归拢——整数加减乘除、比较、位运算、浮点转换,各自的使用纪律。
3.3 加载存储与内存访问把手伸向内存平原。对齐提示、静态偏移、边界检查三件事决定了内存指令的写法与性能表现。本节给出结构体布局的手工管理示例——编译器平时替你做的事,这里摊开给你看。
3.4 实例化与链接模型处理"通电仪式"。模块如何声明需要什么(导入),宿主如何接通什么(注入),双方签名如何对账,多模块如何互相拼装。依赖注入在 Wasm 世界是字面意义的运行时机制,不是设计模式的隐喻。
本章的认知转折在于重新理解"错误"的位置。传统运行时把大量错误留给运行中捕获——空指针、越界、除零,往往在深夜的生产环境里才现形;Wasm 把能静态检查的全部拦在验证阶段,剩下运行期的错误统一收敛为陷阱语义:明确、即时、无未定义行为。工程上的收益是双重的:编译期多一层免费体检,运行期的故障模式屈指可数、日志可判读。
第二个结论关于性能直觉。栈机是规范层的虚构——真实引擎会把它编译成寄存器机器码,操作数栈在寄存器分配后基本消失。但规范层的写法仍然影响性能:指令序列影响引擎的模式识别,内存访问的对齐与局部性影响缓存命中。理解栈机不是要你在它上面优化,而是要你知道引擎看到的"原材料"长什么样。
内核的执行故事讲完,第四章回到岸上:把高级语言装进集装箱的工具链、把集装箱跑起来的运行时引擎,以及验货与计量用的调试器与性能分析器。格式与指令的知识将在那里第一次变成生产力。