验收:120 个程序走同一条流水线
本节阅读量:第十一章继承第十章 92 个示例,并新增 28 个 coroutine 专项示例:
|
|
应看到 120。新增部分由 19 个正常示例、7 个静态 validation 错误和 2 个动态错误组成。全目录中有 112 个程序能够完成 compile 并分别生成 Linux/macOS 汇编;另外 8 个必须在 compile 阶段被拒绝:继承的 set_undefined_error.lang,以及本章 7 个 yield validation 错误。
19 个正常示例
| 示例 | 主要检查 | 结果 |
|---|---|---|
coroutine_lazy.lang |
创建不执行 body | 42 |
coroutine_no_yield.lang |
首次 resume 完成 | 42 |
coroutine_one_yield.lang |
一次暂停 | 42 |
coroutine_protocol.lang |
paused/done record | 42 |
coroutine_begin.lang |
多次 yield | 42 |
coroutine_if.lang |
condition/branch yield | 42 |
coroutine_if_unselected.lang |
未选分支不执行 | 42 |
coroutine_capture.lang |
外层捕获 | 42 |
coroutine_state.lang |
cell 跨暂停共享 | 42 |
coroutine_yield_order.lang |
yield 副作用顺序 | 42 |
coroutine_resume_operand_order.lang |
resume operand 顺序 | 42 |
coroutine_yield_record.lang |
yield 堆对象 | 42 |
coroutine_done_repeat.lang |
同一完成 record | 42 |
coroutine_done_no_restart.lang |
body 不重跑 | 42 |
coroutine_interleaved.lang |
交错推进 | 42 |
coroutine_nested.lang |
嵌套边界 | 42 |
coroutine_name_hygiene.lang |
内部名字卫生 | 42 |
coroutine_gc_capture_record.lang |
捕获 record 与完成态跨 GC | 42 |
coroutine_gc_saved_next.lang |
next closure 跨 GC | 42 |
可运行全部正常专项:
|
|
每行应打印 42。
检查 surface/core 边界
|
|
验收点:
ast保留Coroutine、Yield、Resume;core不再出现三个 surface 节点;core出现用户无法写出的$coro.*;ir只含第十章已有 op;ir能看到 statecell、store、continuationclosure、普通call和协议record。
|
|
源码故意使用 coroutine、resume、yield、state、next 和 done 作为普通变量名,仍应输出 42。
协议和顺序回归
|
|
都应输出 42。它们分别防止协议 tag 错误、yield value 顺序错误、resume operand 顺序错误、提前执行未选分支,以及每次完成都重新分配 record。coroutine_done_repeat.lang 连续 resume 四次并逐次检查身份,还能防止 dispatcher 清空 state 后丢失 done closure。
七个静态错误
|
|
每项打印 error: 并返回 1。换成 core、ir、alloc 或 compile 也必须由同一个 validation pass 拒绝;ast 只展示语法树,是唯一例外。
两个动态错误
|
|
两项都包含:
|
|
它们能生成汇编,链接本章的 gc_runtime.o 后进入已有语言错误出口。Linux、WSL 或 Intel Mac:
|
|
Apple Silicon Mac:
|
|
状态均为 70;coroutine_reentry_error.lang 同样验收。
GC 与分配验收
|
|
前两项输出 42。alloc 应显示 dispatcher、state、continuation 和 captured cell 都是 root,并拥有 %r15 相对槽;恢复后 (+ value 2) 的确定整数结果仍可进入寄存器。
两个示例累计分配超过一个半区。若 continuation 或 captured record 没有进入 root,搬移后恢复会读取旧地址。coroutine_gc_capture_record.lang 还会在完成后再次制造 GC 压力,再连续恢复两次并比较 record 身份;这会同时检查自引用 done closure 与 completed record 已被 collector 正确更新。
两种目标与旧能力回归
|
|
两份都应是完整 AT&T x86-64 汇编,不含 fallback。最终 Value 若是 record,main 按既有规则返回 0,所以编译验收程序应像本例一样最终取出整数。
全量双目标检查只对 112 个可编译程序生成汇编。不要为了凑数量绕过另外 8 个静态错误;它们在 mini compile 返回状态 1,正是验收成功。两个动态错误属于这 112 个可编译程序,生成的可执行文件运行后状态为 70。
再抽查继承能力:
|
|
前六项依次为 42、42、2、42、42、42;最后一项仍出现 ordinary spill。正式发布回归应覆盖全部 92 个继承示例。
最终必须同时满足:surface 语义正确、core 无泄漏、静态边界统一、动态错误一致、GC 保存 continuation、统一后端不回退。只看到一个 yield 示例输出 42,还不足以说明本章完成。