网页汇编接口
网一:三个不同目标
LLVM 原生、LLVM/WASI 线性内存、WasmGC 直接生成不能共用一个“原生指针 ABI”假设。WASI 继续使用逻辑 i128 值和豫言帧;WasmGC 使用引擎引用、类型数组、结构及 Wasm 调用栈。原生 .o 不能直接接入 WasmGC 模块。
网二:LLVM/WASI
目标为 wasm32-wasip1,使用支持 tail-call 的工具链;原生 C 编译参数增加 --target=wasm32-wasip1 -mtail-call。语言层逻辑槽仍为 16 字节,但低位地址是 32 位线性内存偏移。必须让 LLVM/clang 执行 i128 函数参数和返回值的 Wasm ABI 降级,不能在宿主直接假定两 i128 是四个 i64 的固定导出函数。
内存容量、栈、GC 和宿主能力受 WASI 构建限制。普通初始豫言栈 4 MiB,普通单堆上限 64 MiB;编译宿主模式允许更大限制。编译器对写新帧、尾调用参数、续延局部存储调用栈空间检查。线性内存的 C 栈与豫言显式栈不是同一块。
外调 豫言_登记垃圾回收根 改名为 豫言_网页汇编登记垃圾回收根,报错接口改名为 豫言_网页汇编报错并中止,以包装函数修正签名。宿主系统操作通过显式接口传递整数与字节;线性内存地址只表示 guest 偏移,宿主必须检查边界后复制,禁止当成本机裸指针。
进程桥操作码由 1 起依次为:启动、等待、结果信息、读输出、释放、核数、存上下文、多路等待、真实路径;标准流模式 0–3 依次为捕获、弃流、继承输出、继承全部标准流。此系统桥与 WasmGC 的引用桥不同;实现普通语言核心无需假装宿主支持全部操作。
网三:WasmGC 值型
所有普通表达式结果统一为 (ref null eq),允许以下实际值型:
| 值 | WasmGC 表示 |
|---|---|
| 单位/擦除类型 | ref.null eq |
| -2^30 至 2^30-1 整数 | ref.i31,按有符号 i31 解码 |
| 其余 i64 整数 | $big = struct(field i64) |
| 爻 | i31 的 0/1;非任意对象真值 |
| 小数 | $float = struct(field f64) |
| 元组/引用/闭包/数组 | $tuple = array(mut (ref null eq)) |
| 字符串/字节串 | $bytes = array(mut i8),长度为逻辑字节数,不附原生隐藏零 |
| 构造器实例 | $variant = struct(field i32, field (ref $tuple));首字段编号,次字段载荷 |
| 函数代码引用 | i31 的函数表索引 |
闭包首项仍是代码引用,随后为捕获值。普通源码函数沿用擦除后的逐参闭包链;下述多参数函数型对应内部 IR,不能直接由源箭头数量推定。取函数引用须 ref.cast (ref i31)、i31.get_u,然后以对应参数数目的函数类型 call_indirect。不能拿原生地址填 i31。
网四:调用、模块、异常
本基线生成 $t0…$t16,每种类型有相应数量的 (ref null eq) 参数及一个同型结果。闭包 self 算在运行时参数数目内;超过此上限不能声称已实现。尾调用用 return_call_indirect。正常分支合并点用带结果块及 br,不分配原生风格续延帧。
函数表按收集的闭包函数顺序分配索引;全局以 路径#定义名 作键分配可变 eq 引用全局;本基线该键未包含原生定义序号。生成器输出一个合并模块,不提供可像原生 .o 那样任意拼接的独立 WasmGC 模块 ABI。要换掉单个函数,必须保持表索引、类型和相应全局映射,或显式适配。
入口导出 _start。先从 data 段初始化字符串全局,再按收集顺序调用模块初始化函数并丢弃结果,随后执行启动文本。字节常量按 \hh 生成,不能先假定是有效文本而改变原始字节。
提前返回采用 $escape 异常标签,携带两个 eq 引用(标识与值);每次动态入口获得递增 i31 标识。计数到 1073741823 后不允许环绕,继续请求触发 trap。捕获时比较标识,不相等则重抛;离开动态范围的续延恢复不受支持。当前异常处理器由 $exception 可变全局保存。普通算术、索引越界、类型 cast 失败的 Wasm trap 不是自动可捕获的语言字符串异常。
网五:WasmGC 宿主引用桥
导入名称必须为模块 yuyan:gc-host/v1、字段 call,函数类型为 (eqref, eqref)→eqref。第一参是表示原语名的 bytes,第二参是按 C 参数次序排列的 tuple。未内联的系统原语走此接口。
模块向宿主暴露类型原型全局:yy_bytes、yy_tuple、yy_big、yy_float。宿主从这些实例获取引擎实际类型,构造返回引用;不能仅凭相同字段形状创建另一个无法通过 cast 的类型。原型和宿主使用的具体 Wasmtime API 属于同一目标配置,未经验证不能跨版本混用。
桥接可支持单位、i31/i64、f64、bytes、普通 tuple。转换 i31 到原生时得到整数编码;原生爻返回再映成 i31。桥接递归深度上限 512;不通传任意构造器实例、语言闭包或原生指针。转换使用每次调用独立的临时分配器,返回引用构造完成后释放全部临时原生块;不能保留其地址给下一次调用。逐次复制不保证保留任意循环/共享身份,因此引用读写和闭包等操作必须留在 guest 内部,不经通用复制桥执行。
已在 guest 内实现的核心外调包括:引用及数组新建/读写、当前异常处理器、不安全恒等转换、整数加减乘除/相等、串与字节拼接、串比较、字节长度及取字节、若干 UTF-8/JSON 字符串操作。它们必须遵循对应参数次序;不能把所有调用交给宿主后破坏可变对象身份。
网六:兼容声明
本篇根据 Wasm 后端源码说明目标契约。完整网页目标实现需独立通过数值边界、尾递归、异常动态范围、嵌零字节、宿主失败及引擎 GC 压力测试。原生通过不自动给网页目标盖章。