WebAssembly 的实时编译(JIT)接口可能是相当低级的,公开的是通用原语而不是高级功能。尽管如此,仍然需要更高级别的功能,以及比 WebAssembly 规范所能提供的更大的灵活性。还需要进行实验,特别是在希望动态生成新代码的应用程序领域,以确定哪些功能和接口是最合适的。JIT 和优化库将在 WebAssembly 中运行,并提供支持和更高级别的功能,它们将非常适合这一需求。
这样的库不会是 WebAssembly 规范本身的一部分,但这个概念与这里的讨论相关,因为我们可以期望在库中解决的功能是我们可能不需要添加到规范中的功能。此策略有助于保持规范本身的简单性,并减少每个规范实现所需的功能的表面积。
而且,库将促进我们最终可能想要添加到 WebAssembly 本身的新功能的轻量级实验。在库层中,我们可以在向规范本身添加功能并冻结所有细节之前,快速迭代、试验并获得真实世界的洞察力。随着新功能的标准化,库将成为多边形填充,这将有助于这些功能获得采用。
这就提出了一个问题:我们应该如何决定哪些特性属于规范,哪些特性属于库。将功能放在库中而不是放在规范和实现本身中的一些基本优势包括:
-
库可以自由选择提供更大程度的未定义行为、实现定义的行为、未指定的行为等等。这意味着它可以执行更积极的优化,包括许多在优化编译器中非常常见的优化,否则可能会在 WebAssembly 规范本身中缺失:
- 、
cos
、exp
、log
、pow
和atan2
等sin
数学函数的常量折叠、强度缩减和代码移动。 - 执行依赖于假设整数运算不会溢出的激进表达式简化。
- 执行带有冗余负载消除的 GVN,以及其他基于别名规则的优化,如果违反这些规则,则会导致未定义的行为。
- 通过功能测试利用浮点重新关联和底层平台感知的矢量化。
- 、
-
库可以支持更高级别的功能,以及为某些应用程序定制的功能,而 WebAssembly 规范本身仅限于通用原语。可能的例子是:
- 更丰富的类型系统,可以包括复杂的、有理的、任意位宽的整数、非 2 的幂的 SIMD 类型、区间算术等。
- 更高级别的类型系统,可以包括各种类型的基本多态性(具有真正的动态性或单态)。
- 更丰富的控制流构造。
- 更广泛的操作符集合,如字符串处理操作符、数据类型序列化、测试工具和线性代数操作符,所有这些都可以从语言级别的集成中受益。 由于规范本身所需的每个功能都需要由所有实现来实现,因此特定于领域的功能可能会让人们“为他们不使用的东西付费”。有了功能库,人们只需为他们选择使用的功能付费。
-
库可以随着时间的推移而发展,以满足高级语言不断变化的需求。在实践中,编译器 IR(如 LLVM IR)不断发展,以添加新功能、更改现有功能,有时还会删除功能,而这些类型的更改在规范中要困难得多。
由于底层 WebAssembly 平台的确定性,库方法还意味着使用特定版本的库的应用程序可以获得一致的行为和性能。
可能的方法范围很广:
-
“自定义 WebAssembly ”。这可能涉及一个库,其输入格式在概念上是 WebAssembly,但具有一些附加功能。该库可以优化并降低这些功能,将标准 WebAssembly 呈现给底层实现。
-
“带上你自己的编译器”没有什么能阻止你将成熟的 AOT 风格的编译器捆绑到 WebAssembly 中,这些编译器将独立的源语言或 IR 编译到 WebAssembly 中。显然,这将涉及下载大小和启动时间方面的权衡,但它将允许独特的灵活性。
-
以及介于两者之间的许多事情。