从ASM.JS到WebAssembly
tl;dr 我先用上下文和补充材料铺垫,所以不耐烦或已经知情的读者应该跳过视频部分直接看今天的大新闻。或者现在就阅读Luke Wagner的博客文章。
我在2015年4月21日Fluent大会上的"ECMAScript Harmony: Rise of the Compilers"演讲:
Jeremy Ashkenas两天后在布鲁克林接过这个话题并深入探讨:
我在5月15日ModernWeb.tw会议上的演讲幻灯片:
也许除了"JS满20岁"之外,你还能察觉到一个主题。关于编译器的崛起、Java字节码和asm.js、共享内存线程和SIMD。在Hacker News上经常出现的典型反驳是这样的:
在我的ModernWeb.tw幻灯片引发的HN子话题中,我同意Patrick Walton关于浏览器与Unix内核、JS与C的类比。人们还不能用任何语言编写内核代码,至少现在还不能。在那个子话题的其他地方,JS被比作特定架构的汇编代码,其中CPU架构由物理现实固定,而软件则用编译成机器码的虚拟语言编写,或通过解释器运行。
无论如何,无论是类比为C还是汇编,JS都牢牢掌握着客户端的"内核"。相比之下,Web"用户态代码"可以用许多语言编写。添加第二种(字节码)语法看起来像是"现在你有两个问题"的损失,相对于单一语法的替代方案。直到现在。
今天的大新闻
如今,JS已成为Web的汇编语言,这已是陈词滥调。更准确地说,JS是一种可移植且安全的机器语言的语法。今天,我很高兴地宣布,跨浏览器工作已经开始于WebAssembly,这是一种用于Web上安全代码的新中间表示。
是什么:WebAssembly,简称"wasm",文件后缀为.wasm,一种用于低级安全代码的新二进制语法,最初与asm.js表达力相同,但长期来看能够与JS语义分道扬镳,以便最好地充当多种源级编程语言的通用对象级格式。
至关重要的是,wasm和asm在相当长的时间内保持等价,以支持通过JS对wasm支持进行polyfill。即使JS和asm.js演进出共享内存线程和SIMD支持,这一点仍然至关重要。可能的长期分歧示例:零成本异常、动态链接、call/cc。是的,我们的目标是开发Web的多编程语言对象文件格式。
为什么:asm.js很棒,但一旦引擎对其进行优化,解析器就成为热点——在移动设备上非常热。传输压缩是必需的并且节省带宽,但解析前的解压缩会带来损害。次要考虑:即使在其asm.js子集中,JS也有一些尴尬的角落。最后,一旦浏览器原生支持WebAssembly语法,JS和wasm可以分道扬镳,而不会将不安全或不适当的特性引入JS,仅由编译少数完全不同编程语言的编译器使用。
如何:如果你使用Emscripten,那么通过命令行标志的wasm支持最初将包括并以原型polyfill为目标。但随着原生wasm解码器出现在顶级引擎中(参见V8原生原型解码器),Emscripten将自动配置以获得最佳结果。另一个原型:JS AST压缩器(编码器)。
这些原型将随着WebAssembly的成熟并逐渐接受更多开发人员测试而演进并跟踪草案规范更改。除了Emscripten之外的其他编译器,以及除了LLVM之外的其他编译器框架将加入其中。我预计所有引擎都将支持快速原生解码器。所有这些部分都是实现通用WebAssembly标准目标的手段。
谁:一个W3C社区小组,WebAssembly CG,向所有人开放。正如你可以从github日志中看到的,WebAssembly迄今为止一直是Google、Microsoft、Mozilla和其他一些人的共同努力。我很抱歉这项工作最初是通过私人github帐户完成的,但这是一个临时措施,旨在帮助几家大公司达成共识并投入到必须进行的长期合作游戏中。
在这里,你可以看到Google的PNaCl团队的JF Bastien几乎无法保守秘密。幸好我用漫画书引用作为合理掩护回复了。好险!
拥有Google的PNaCl团队和V8团队,以及Microsoft的关键人物,还有Mozilla的asm.js和Emscripten专家,一旦大家都明白了,就紧密合作,这令人振奋。我想特别高度赞扬Google的JF Bastien、K. Gadd和Ben Titzer;Mozilla的Dan Gohman;Microsoft的Abhijith Chatra和Michael Holman;以asm.js和Emscripten闻名的Alon Zakai;JavaScriptCore/WebKit的Filip Pizlo;尤其是asm.js/OdinMonkey的主脑Luke Wagner。
大局观
在计算历史上,通用、语言中立中间形式的梦想可以追溯到Melvin Conway的UNCOL(1958年,LISP诞生的同一年)之前。我记得80年代的ANDF,以及70年代的U-something。没有人想要"N x M"语言源与机器目标的问题。
有时我们必须在Fortuna之轮上转一两圈才能成功。神经元似乎进化了不止一次。相信我,我发现卑微的JS(我并没有提前计划这么远!)已经铺平了通往WebAssembly的进化道路,这很有趣。然而,我们就在这里。
尽管它不是用于生成wasm的唯一编译器框架,但LLVM对这个项目来说是一个福音,对wasm的Emscripten和PNaCl前辈也是如此。向Chris Lattner和团队致敬。
我认识的PNaCl朋友们性情很好,但我想有些人对我多年来在HN上扮演卡珊德拉反对他们的特洛伊感到不满。所以我想大大赞扬他们从LLVM中消除了许多未定义行为(UB)——实际上是从所有抽象级别,从C/C++规范到硬件。那种吃力不讨好的工作对WebAssembly来说是一个巨大的帮助,WebAssembly必须是大部分确定和定义良好的,以便互操作和安全。
(敏锐的读者到此时会想起Gary Bernhardt的《JavaScript的诞生与死亡》。我活着就是为了调侃Gary。
底线:随着JS和wasm的共同进化,我相信几年内所有顶级浏览器都将拥有真正多语言虚拟机的JS引擎。我预测在同一时间跨度内,JS将持续存在并进化以吸收更多API和基于硬件的功能——但不是全部,其中wasm承担重任。
我们再次看到Web如何偏爱一系列"小爆炸":
- 通过测试每个跳跃与开发人员和实现者的适应性,以及
- 支持对旧部署浏览器的可用polyfill,
来保持进化路径上的社区共识。
我通常以一个笑话结束:“总是赌JS”。我期待将"和wasm"融入那句话——不是玩笑。
/be