写点什么

WebAssembly 的未来:潜在新特性一览

  • 2018-08-05
  • 本文字数:4119 字

    阅读完需:约 14 分钟

WebAssembly 简介

WebAssembly 开发团队的描述:

WebAssembly(或 wasm)是一种适用于 Web 的可移植编译格式,提供更小的文件尺寸和更快的加载速度。

实际上,WebAssembly 旨在成为高级语言的编译目标。目前可以使用 C、C++、Rust、Go、Java、C#编译器(还有更多)来创建 wasm 模块。

WebAssembly 模块以二进制的格式发送到浏览器,并在专有虚拟机上执行。这个虚拟机与 JavaScript 虚拟机共享资源,如内存和线程。WebAssembly 模块总是与 JavaScript 代码一起使用,在必要的时候可以执行一些有用的操作。

目前正在进行中的很多提案旨在让 WebAssembly 成为更好的编译目标,并减少 JavaScript“胶水”代码。

WebAssembly 提案

WebAssembly 提案的流程是分阶段的,从阶段 1(不成熟)到阶段 5(完成标准化)。以下是目前所有提案的清单(前 4 个阶段),每个提案都将在后面详细介绍。

第 1 阶段(功能提案)包括以文本格式自定义注解、主机绑定、尾调用、批量内存操作、ECMA 模块集成、垃圾回收、异常处理、固定宽度 SIMD、线程。第 2 阶段(规范提议)包括 BigInt 转换。第 2 阶段(实现)包括引用类型和返回多个值。第 4 阶段(标准化)包括导出和导入可变全局变量和有符号扩展操作。

引用类型

目前的 WebAssembly 类型系统还很小,只有四种数字类型。目前,如果要使用复杂类型(例如字符串、对象、数组、结构体),需要将它们序列化为线性内存,并提供它们所在位置的引用。这个提案对类型系统进行了扩展,添加了一个新的 anyref 类型,模块可以持有对主机环境对象的引用,也就是说,你可以将 JS 对象传给 wasm 模块。

通过 anyref 引用的对象对于 wasm 模块来说意义不是很大,关键在于模块可以持有在 JS 堆上分配的对象的引用,这意味着在 wasm 执行期间需要对这些引用进行跟踪。该提案被视为垃圾回收提案的垫脚石。

返回多个值

WebAssembly 的虚拟机是基于栈的,操作对象在函数被调用之前是放在栈上的,函数会使用这些对象并替换为返回值。在目前的规范中,函数只能返回单个值。新的提案允许指令、函数和块返回多个值(例如,整数除法可以返回除数和余数)。

下面是一个简单的“swap”函数,它可以返回多个值(result i32 i32)。

复制代码
(func $swap (param i32 i32) (result i32 i32)
(get_local 1) (get_local 0)
)

导出和导入可变全局变量

目前,wasm 支持全局变量和局部变量。全局变量可以被导入和导出,并与 JS 宿主共享,不过必须将它们定义为不可变的。

新的提案将 WebAssembly.Global 构造函数添加到 JS API 中,允许导出和导入可变的全局变量。该特性对于跨多个 wasm 模块共享状态来说非常有用。

有符号扩展操作

符号扩展是一种在保留符号的同时增加二进制数位数的方法。这个提案添加了少量符号扩展指令,例如 i32.extend8_s——将有符号的 8 位整数扩展为 32 位整数。

FireFox 已经实现了这个特性,并计划在 9 月发布。

BigInt 转换

JavaScript 只有一个数字类型,即 IEEE 754 浮点数——这种表示法存在一定的局限性。现在有一个新兴的标准,即增加对“大整数”的支持,目前处于 TC39 流程的第 3 阶段。最终确定后,将为开发人员提供任意精度的整数。

WebAssembly 的四种数字类型之一是 64 位整数。新提案将提供完全的互操作,让 JS 的 BigInt 和 wasm 的 64 位整数实现双向转换。

顺便提一下,现在已经有一个用于在 JavaScript 中执行 64 位运算的库,叫作 long.js。最近,他们移除了基于 JavaScript 的实现,改用更简单的 WebAssembly!

线程

JavaScript 已经通过 WebWorker 实现了多线程,但是在 worker 之间只能使用 postMessage 进行较慢的消息传递。共享内存提案已经在 TC39 中定稿,并在 2017 年 2 月成为 ECMAScript 的一部分。共享数组缓冲区和原子性让线程之间共享数据变得更加容易。

WebAssembly 的这个提案也是允许共享访问线性内存,并提供原子操作。但值得注意的是,提案并没有引入创建线程的机制(引起了很多争议),而是由宿主提供此功能,也就是我们熟悉的 WebWorker。

我相信会有一些人对这个提案感到失望。不过,WebAssembly 之所以能够快速发展到 MVP 版本,跟团队专注于简单性不无关系。利用成熟的宿主功能(WebWorker)是非常有意义的。

将来可能会添加原生线程,但会作为单独的提案,不过这可能还需要几年的时间!

固定宽度 SIMD

单指令多数据流(SIMD)是一组支持矢量风格处理的指令,例如,将一个向量添加到另一个向量种。所有现代 CPU 都支持这些指令。有一个 SIMD.js TC39 提案,增加了很多 128 位类型,例如 float32 x 4,以及相应的操作(如 add、multiply),但最近删除了这部分内容,因为 WebAssembly 中已经添加了类似的功能。这样做是有道理的,因为这些是低级指令,而 WebAssembly 恰好是低级运行时。

WebAssembly 的 SIMD 提案非常简单,为 wasm 添加一个新的 128 位类型,可以表示四个数字的向量,以及用于创建和操作这些新类型的简单指令集。这将为某些算法类别的性能带来改进。

异常处理

程序会在出现异常时中断控制流,异常会顺着调用栈向上传播,直到遇到合适的“catch”块。异常处理是大多数现代编程语言的共同特征,尽管 Swift 在早期版本中并不支持它们。

WebAssembly MVP 在当前控制流指令中没有任何类似于异常处理的东西。因此不得不使用 Emscripten 这样的工具来模拟这个功能,但这是以牺牲性能为代价——目前,默认情况下捕获 C++ 异常是关闭的,其他语言也面临类似的问题。

异常处理提案概述了构建一个与宿主环境“良好配合”的概念所涉及的大量复杂性。有趣的是,这是第二次尝试创建这个提案,可见他们目前面临的挑战有多严峻!

该提案不仅要向 WebAssembly 添加异常处理,更是要引入一种更通用的事件概念,看起来很像中断。当事件发生时,执行被暂停,在 events 处安插一个恰当的处理程序。

除了事件,可能还会添加标准的 try/catch 指令:

复制代码
try block_type
instruction*
catch
instruction*
end

这将减少 WebAssembly 编译器的一些复杂性。

垃圾回收

大多数现代编程语言(不包括系统级语言)使用垃圾回收器进行内存管理。简而言之,垃圾回收器(GC)让开发人员无需过多考虑内存管理,他们可以创建对象、传递对象、在函数 / 变量之间共享对象,并且在不再使用这些对象时依靠 GC 来清理它们。

WebAssembly 没有垃圾回收器。事实上,它没有任何可用于内存管理的工具,它只是为你提供了一块“内存”。不使用 GC 的编程语言仍然需要某种机制来管理内存分配,例如 Rust 使用了一个小型的 WebAssembly 优化分配器。

目前,需要垃圾回收器的编程语言没有其他选择,只能将 GC 编译为 wasm,并将其作为二进制文件的一部分,例如 AssemblyScript 就在二进制文件中包含了一个“makeshift GC”。但这样会增加二进制文件的大小,同时 GC 算法的效率也会受到影响。缺少 GC 是 Scala 和 Elm 等语言还不支持编译成 WebAssembly 的原因。

这个提案将 GC 功能带到 WebAssembly 中。有趣的是,它不会有自己的 GC,而是与宿主环境的 GC 集成。还有其它各种其他提案(宿主绑定、引用类型)旨在改进与宿主的互操作性,从而更容易共享状态和调用 API。使用单个 GC 来管理内存会让这些变得更容易。

这个提案是一个重大变更,wasm 的类型系统因此添加了很多新的东西,包括简单的元组、结构体和数组。还有一些讨论是关于添加字符串类型的。

在 WebAssembly 中使用 GC 是可选的,这样 Rust/C++ 就可以使用内存分配器和线性内存。新类型将在新的 WebAssembly 堆上进行分配,尽管提案中未明确说明。我猜宿主堆也可以使用,但可能会带来很大的开销。

这个提案增加了很多新的指令,这是结构体的一个例子:

复制代码
;; structures with fields
(type $point (struct (field $x f64) (field $y f64) (field $z f64)))
 
;; allocated with new
(call $g (new $point (i32.const 1) (i32.const 2) (i32.const 3)))
 
;; field accessors - type checked when validated
(load_field $point $x (get_local $p)

ECMA 模块集成

ECMAScript 模块(ESM)是一个相对较新的规范,所有主流浏览器现在都已支持。

目前,wasm 模块是通过 HTTP 进行加载的,然后使用 JS API 进行实例化:

复制代码
const req = fetch("./myModule.wasm");
 
const instance = await WebAssembly.instantiateStreaming(req)
instance.exports.foo()

这个提案引入了一种机制,可以通过 ESM 导入的方式来加载 wasm 模块:

复制代码
import {foo} from "./myModule.wasm";
foo()

这让实例化 wasm 模块变得更简单,而更大的好处是它们成为 JS 模块图的一部分,也可以进行摇树优化(tree shaking)、捆绑、代码分割和 ESM 支持的其他优化。

批量内存操作

该提案增加了复制 / 填充线性内存区域的新操作。它们将为某些场景带来更好的性能。

尾调用

递归函数调用可能会导致很深的调用栈,会带来各种问题(性能、内存消耗、堆栈溢出的可能性)。通过尾调用优化,递归函数调用将被替换为迭代。这种技术对于函数式语言来说非常重要。为此,该提案引入了新的 return_call 指令。

宿主绑定

基于多种因素(wasm 类型系统太过简单、缺少引用类型等等),WebAssembly 与 JavaScript 宿主之间的当前接口非常有限。如果你想要编写一个操作 DOM 或使用其他浏览器 API 的 wasm 模块,必须编写大量“胶水”代码。

这个提案允许 WebAssembly 模块创建、传递、调用和操作 JavaScript/DOM 对象。它添加了一部分与宿主绑定相关的内容,其中包括用于描述绑定机制或接口的注解。

Rust 已经有了一个工具,叫作 wasm-bindgen,它的作用与该提案很相似。使用 wasm-bindgen,你就可以轻松地跨越 wasm 和 JS 传递字符串等对象。该工具将绑定元数据添加到 wasm 模块中,并生成所需的 JS 胶水代码。

以文本格式自定义注解

wasm 二进制格式支持将元数据添加到模块中。这个提案为文本格式也添加了类似的功能,这对宿主绑定来说非常有用。举个例子:

复制代码
(module
(func (export "f") (param i32 (@js unsigned)) ...)
)

@js unsigned 注解添加了用于生成宿主绑定的其他元数据。

结论

希望这些能让你对 WebAssembly 未来的发展方向有所了解。这些提案中的一些小改进可能很快就能完成,但大的改进可能需要几年时间才能完全实现。

查看英文原文: https://blog.scottlogic.com/2018/07/20/wasm-future.html

感谢覃云对本文的审校。

2018-08-05 09:502296
用户头像

发布了 731 篇内容, 共 451.8 次阅读, 收获喜欢 2002 次。

关注

评论

发布
暂无评论
发现更多内容

企业数智化首选!众多行业领先企业选择用友BIP,实现业务敏捷

用友BIP

圣雄能源电石厂:“一机一码”,助力巡检新格局

草料二维码

设备巡检管理系统 草料二维码 设备巡检二维码 设备巡检系统 设备管理软件

Things3 for Mac(日程和任务管理工具) v3.20.8中文免激活版

Rose

CorelDRAW Mac破解版,CorelDRAW序列号最新,cdr平面设计

Rose

寻找适合编写静态分析规则的语言

华为云开发者联盟

软件开发 华为云 静态分析 华为云开发者联盟 企业号2024年7月PK榜

远超美国!中国AI专利数量全球第一!商汤推出面向C端用户大模型“Vimi”,可生成分钟级视频!|AI日报

可信AI进展

人工智能

Path Finder:Mac平台上的一款功能强大的文件管理工具

Rose

PPSSPPSDL for mac(PSP游戏模拟器)附PSP游戏安装包 v1.17.1激活版

Rose

实用的防休眠工具 Caffeinated for Mac v2.0.6激活版

Rose

Syncaila for Mac(多机位自动对视频音频同步工具) v2.1.4激活版

Rose

GreatSQL中 Insert 慢是什么情况?

GreatSQL

财会监督 |合同风险管理:企业风险控制的精准锚点

用友BIP

三年级课堂上演投影仪“消失术“,英特尔与希沃有话说

E科讯

nuke破解版下载 mac影视后期特效合成软件

Rose

数据工程(二):数据需求管理,解锁信息宝藏的“指南针”

数造万象

工具 需求管理 数据工程

Royal TSX常见问题:解决远程桌面(RDP)连接错误

Rose

3CX的具体介绍

cts喜友科技

通信 通讯 云通讯

下课10分钟,AI都做了什么?

E科讯

AI+采购丨精益每一步,敏捷每一刻,数智采购的进化之路

用友BIP

「多模态大模型」解读 | 突破单一文本模态局限

Baihai IDP

程序员 AI LLMs 企业号 7 月 PK 榜 多模态大模型

最强GTD时间管理工具 OmniFocus Pro 3 for Mac 附注册码

Rose

让AI成为教师的“好帮手”,英特尔联合希沃打造更懂教师的教学神器

E科讯

场景应用|AR远程协作之——远程验收

AR玩家

AR Rokid Vision pro 炬目AR AR远程协作

企业数智化首选!上半年,众多头部民营企业选择用友!

用友BIP

Live Home 3D Pro(3D家庭室内设计工具)支持3D渲染和虚拟漫游功能

Rose

AI+,企业最期待的是什么?

用友BIP

“内卷”的电商江湖:拼服务才有出路

Alter

WebAssembly的未来:潜在新特性一览_JavaScript_Colin Eberhardt_InfoQ精选文章