1. 介绍
本文基于 WebAssembly 规范 [WEBASSEMBLY] 以及 WebAssembly JavaScript 嵌入规范 [WASMJS]。 它描述了 WebAssembly 如何集成进更广泛的 Web 平台,例如用户代理实现但超出 JavaScript [ECMASCRIPT] 自身范围的额外 API。2. 流式模块编译与实例化
[Exposed =(Window ,Worker )]partial namespace WebAssembly {Promise <Module >compileStreaming (Promise <Response >,source optional WebAssemblyCompileOptions = {});options Promise <WebAssemblyInstantiatedSource >instantiateStreaming (Promise <Response >,source optional object ,importObject optional WebAssemblyCompileOptions = {}); };options
compileStreaming(source, options)
方法时,返回用 source 和 options 编译潜在 WebAssembly 响应 的结果。
instantiateStreaming(source, importObject, options)
方法时,执行如下步骤:
-
令 promiseOfModule 为用 source 和 options 编译潜在 WebAssembly 响应 的结果。
-
返回用导入 importObject 对 promiseOfModule 实例化 promise Module 的结果。
Response
的 promise source 和 WebAssemblyCompileOptions
options 编译潜在 WebAssembly 响应,请遵循如下步骤:
注: 此算法接收 Response
对象或其 promise,并编译和实例化响应得到的字节。此过程可后台异步流式实现。如果 Response
不是
CORS 同源、非 ok 状态 或未匹配
`application/wasm` MIME 类型,
则返回的 promise 会以 TypeError
拒绝;
如果编译或实例化失败,promise 将以 CompileError
或相关错误类型拒绝,视失败原因而定。
-
令 returnValue 为 新的 promise。
-
监听 source 状态:
-
如果 source 正常完成并返回 unwrappedSource:
-
令 response 为 unwrappedSource 的 response。
-
令 mimeType 为从 response 的 header list 获取
`Content-Type`的结果。 -
如 mimeType 为 null,则使用
TypeError拒绝 returnValue 并中止本分支。 -
去除 mimeType 首尾的所有 HTTP 制表或空格字节。
-
如 mimeType 不是 字节忽略大小写 匹配
`application/wasm`, 则使用TypeError拒绝 returnValue 并中止。注: 格式不允许附加参数,包括空的
`application/wasm;`。 -
如 response 的 status 非 ok 状态,则用
TypeError拒绝 returnValue 并中止。 -
消费 response 的 body 为
ArrayBuffer, 并赋结果给 bodyPromise。注: 这里描述响应消耗完毕才编译只是为了规格表述简单;实现中一般会流式处理,两者对外不可区分,因而采用了易于理解的模型。
-
监听 bodyPromise:
-
如 bodyPromise 正常完成返回 bodyArrayBuffer:
-
令 stableBytes 为对缓冲区 bodyArrayBuffer 拷贝的字节。
-
异步编译 WebAssembly 模块 stableBytes, 使用 网络任务源 和 options, 并用结果 resolve returnValue。
-
-
如 bodyPromise 被拒绝且原因 reason:
-
Reject returnValue,原因为 reason。
-
-
-
-
如果 source 被拒绝,原因为 reason:
-
Reject returnValue,原因为 reason。
-
-
-
返回 returnValue。
3. 序列化
Web 用户代理必须为 Module
接口添加
[Serializable]
扩展属性。
当给定 value,serialized 和 forStorage 时,序列化步骤为:
-
若 forStorage 为 true,抛出 "DataCloneError"
DOMException。 -
设置 serialized.[[Bytes]] 为 value.[[Bytes]] 的 子串序列化。
-
设置 serialized.[[AgentCluster]] 为 当前 Realm 对应的 agent cluster。
给定 serialized,value 和 targetRealm,反序列化步骤为:
-
令 bytes 为 serialized.[[Bytes]] 的 子串反序列化。
-
设置 value.[[Bytes]] = bytes。
-
如果 targetRealm 对应的 agent cluster 不等于 serialized.[[AgentCluster]],则抛出 "DataCloneError"
DOMException。 -
编译 WebAssembly 模块 使用 bytes,并设置 value.[[Module]] 为其结果。
引擎在执行结构化序列化时应尝试共享/复用内部编译代码,尽管某些极端情况下如 CPU 或浏览器升级可能无法做到,则需重新编译。
注: 结构化序列化的语义等价于将用来编译
Module
的二进制源程序序列化、反序列化,再在目标 realm 重新编译。鉴于上述引擎优化,结构化序列化为开发者提供了对已编译代码缓存和窗口/worker间代码共享的显式控制力。
4. 面对开发者的显示约定
本节为非规范性内容。
浏览器、JavaScript 引擎和离线工具在引用 JS 结构和语法单元时有通用方式。例如 JavaScript 源码位置常用于堆栈追踪或错误信息,并以文本文件中的十进制行列表示。函数名变量名直接取自源码。即使不同实现的堆栈追踪字符串格式未必一致,源码位置仍跨浏览器易于理解。
为实现 WebAssembly 构造体通用表达,本规范采纳如下约定:
WebAssembly 位置指代二进制中特定指令,可在浏览器或引擎中与 JS 源代码位置类似场景显示。格式为:
${url}:wasm-function[${funcIndex}]:${pcOffset}
其中
-
${url}是模块关联的 URL(如可用,见备注)。 -
${funcIndex}是 函数索引,相对于模块。 -
${pcOffset}是指令在模块二进制中的偏移(十六进制小写数字,前缀0x)。
备注:
-
URL 字段依据上下文解析。在浏览器用基于响应的 API 实例化时使用相关 URL;用基于
ArrayBuffer的 API 实例化时,应显示 API 调用位置。这类似于 JS 的eval执行;如果浏览器已用如foo.js line 10 > eval或eval at bar (foo.js:10:3)表示 eval,也可类似用于WebAssembly.instantiate。离线工具可用文件名代替。 -
用十六进制表示模块偏移量与原生工具如
objdump相符,也方便区分 JS 行号。其余数用十进制。
虽然 导出函数实例的 "name" 属性由 JS API 规范定义,合成函数名也用于调试器调用栈和堆栈追踪字符串等场景。 若模块含 name section, 合成函数名用法如下:
-
如有函数名子区段,显示名为
${module_name}.${function_name}或${function_name}(视有无模块名)。 -
否则,输出可根据上下文:
-
函数名与位置一起显示如在堆栈追踪时,仅需模块名或空字符串(因 function index 在位置中已体现)。
-
否则用
${module_name}.wasm-function[${funcIndex}]或wasm-function[${funcIndex}]来指明函数索引。
-
请注意本文档不定义堆栈帧字符串等格式,这样可使引擎保留原 JS 格式(以兼容已有代码),且 WebAssembly 帧输出风格仍与 JS 一致。
5. 媒体类型注册
application/wasm 媒体类型已在 IANA 媒体类型数据库注册 [IANA-MEDIA-TYPES],
注册模板如下 registration template:
application/wasm
- 类型名(Type Name):
- application
- 子类型名(Subtype Name):
- wasm
- 所需参数(Required Parameters):
- 无
- 可选参数(Optional Parameters):
- 无
- 编码注意事项(Encoding Considerations):
- binary(二进制)
- 安全注意事项(Security Considerations):
-
WebAssembly 是一种标准、安全、可移植、低级代码格式。与执行 WebAssembly 代码相关的安全注意事项详见 https://www.w3.org/TR/wasm-core/#security-considerations。
WebAssembly 格式不包含完整性或隐私保护。如需此类保护,必须外部实现,如通过 HTTPS。
- 互操作性注意事项(Interoperability Considerations):
- 详见 WebAssembly Core 一致性
https://www.w3.org/TR/wasm-core/#conformance - 已发布规范(Published specification):
- https://www.w3.org/TR/wasm-core-1/ https://www.w3.org/TR/wasm-js-api-1/ https://www.w3.org/TR/wasm-web-api-1/
- 应用用途(Application Usage):
- application/wasm 媒体类型用于描述通过 HTTP 发送、被浏览器执行的 WebAssembly 文件,这是一种常见场景。此外,该类型也被多种 WebAssembly 运行时采用,兼具安全性、可移植性、高效执行及紧凑表达。
- 片段标识符注意事项(Fragment Identifier Considerations):
- 无
- 使用限制(Restrictions on usage):
- 无
- 临时注册(Provisional Registrations):
- N/A
- 附加信息(Additional information):
-
- 此类型已废弃别名(Deprecated alias names for this type):
- 无
- 魔数(Magic number(s)):
- 0x00 0x61 0x73 0x6D
- 文件扩展名(File extension(s)):
- .wasm
- Macintosh 文件类型码(Macintosh file type code(s)):
- 无
- 对象标识符或 OID(Object Identifier(s) or OID(s)):
- 无
- 预期用途(Intended usage):
- 通用(Common)
- 其他信息与评论(Other Information & Comments):
- 通用(Common)
- 联系人(Contact Person):
-
- 联系人姓名(Contact Name):
- Eric Prud’hommeaux
- 联系邮件(Contact Email Address):
- eric@w3.org
- 作者/变更控制方(Author/Change Controller):
- W3C
6. 安全与隐私注意事项
本节为非规范性内容。
WebAssembly 除了通过 JS API 规范中描述的 JavaScript API 外,不会访问周围环境。 因此,WebAssembly 无法收集或暴露任何信息(无论是个人的、敏感的还是其他)给网站或任何第三方,超出 JavaScript 能收集、暴露或处理的信息。 WebAssembly 内存的生命周期与周围 JavaScript 环境中的对象一致,且不会被持久化或序列化(除非通过拷贝给 JavaScript 并用现有序列化 API)。 不会提供对底层平台或硬件、其他设备,或用户代理原生界面的访问权限。WebAssembly 是一种额外的程序执行机制,可以在 JavaScript 可执行的任何地方被执行。 因此,其威胁模型本质上与 JavaScript 代码相同,也有类似的传输安全(如 WebAssembly 代码在传输过程中应受到主动和被动网络攻击者的保护) 和策略考量(如某些加载机制或执行通过同源策略或内容安全策略等机制受到限制)。
7. 变更历史
本节为非规范性内容。
自 WebAssembly 规范初始 1.0 发布以来,已有很多扩展提案被集成。 下列各节概述了都有哪些变更。
7.1. 2.0 版本
媒体类型注册已完成
application/wasm 媒体类型的注册已成功完成。