在2015.06.17, JavaScript之父Brendan Eich宣布了一个新项目:将新的底层功能(low level primitives)带入web中[1], 这将使在浏览器或其他JavaScript环境中采用类似于C & C++等语言编写的项目的编译更加容易。如果是第一次听到这个想法,可参见阅读"What is WebAssembly”的基本描述[3]。
WebAssembly团队包括来自Google, Microsoft, Mozilla, Apple, 以及W3C WebAssembly Community Group(社区团体)的成员。
这份声明使web开发界猜测WebAssembly可能会如何影响到JavaScript的未来, Eric Elliott(下面简称EE)采访了Brendan Eich(下面简称BE).
EE: 最近,你在博客中宣布将开始WebAssembly新项目,基本上就是一个web汇编语言,一个底层编译目标。 能否讲下它是做什么的,背后的动机是什么。
BE: 这在某种程度上是从ASM.js就开始的一个持续过程。ASM.js是JavaScript的一个子集,没有对象, 没有垃圾回收, 没有JIT编译器中断(just in time compiler pauses)。它的目标是C/C++—JavaScript的一个静态类型子集。这已经由Mozilla以及大型游戏厂商, Epic Games公司的Unreal引擎以及Unity公司的Unity引擎和IDE演示过了。
这样,大量的游戏就可以用自己的引擎来发布,市场上有Unreal引擎3和Unreal引擎4, 而基于Unity 5建立的游戏是用另外一种指令集作为JavaScript的目标。
这些游戏过去可能瞄向PS4、XBox和PC。现在他们也可以利用WebGL、ASM.js、web音频与其他重要的APIs、平板游戏APIs、全屏APIs等瞄向web。
当我在Mozilla公司的时候,ASM.js就取得了非凡的成功,现在已经转向了微软。我记得几年前与Anders Hejlsberg和Steve Lucco谈论过,Anders是做C#和.NET,Steve带领Chakra团队。他们都非常感兴趣,Edge开始支持ASM.js,通过在线优化达到好的性能,就像Mozilla对模块优化所做的那样。
其实,我认为这是对Native Client的最后一击,或者说,是对真正可移植的原生Client(Portable Native Client:PNaCl)的最后一击。PNaCl是Google唯一可以将浏览器中的C & C++编译为安全原生Client的版本,但从来没有在Chrome中完全发挥出作用。对一些Google属性来说它放在白名单中,我认为Google+有一个图形编辑器。
随着时间发展,完全原生client不会扩展到其他浏览器上,如果打算做的话将有很长的道路要走。尽管ASM.js起初没有线程,没有锁,没有原生代码中需要的大量功能:没有SIMD (single instruction, multiple data: 单指令多数据),没有现代CPUs中包含的向量单元(vector unit)的短向量内联函数(short vector intrinsics for vector units)。
的确,JavaScript之前没有这些功能,但现在情况正在变化。SIMD已经在Firefox支持,V8将支持,Intel已经在他们的V8版本中有一个实现,Crosswalk支持,而且Microsoft宣布将在Chakra中支持SIMD。
(译者注:Chakra JavaScript引擎支持微软Edge浏览器以及Windows 10中使用HTML/CSS/JS编写的应用。)
假设web停滞,虽然这个假定不好,我认为之前的PNaCl和Dart等项目是个错误。它们都假定JavaScript能力不够,不能改善,因此他们必须要做一些事情,因此有了第二套系统,或第三套系统增加到了浏览器中,然而没有完全融入到Chrome中。
这里我并非沾沾自喜,实际情况是我们需要渐进式发展。所有的浏览器必须小步前进。这真的是Firefox与Chrome在浏览器竞争中的一个功能-Firefox领先。当然情况也会发生变化,2000年之前IE达到95%的市场份额,Microsoft没有再投资web,而是投向了.NET和Windows Presentation Foundation(译者注:Windows Presentation Foundation (WPF) 的首要目标在于协助开发人员建立吸引人又有效率的用户界面)。
无论如何不能总是看历史,ASM.js的持续发展是wasm,这非常重要,理由是一旦ASM.js跨入其他浏览器,情况就越来越清晰,它会跨入所有的浏览器。
然而,JavaScript,甚至JavaScript的子集ASM.js都没有SIMD、线程、共享内存和其他基础功能(primitives)。对于ASM.js仍然需要解析JavaScript,但它只是一个子集。你可以对该子集运行一个专门的解析器,这又是一项维护琐事,因为现在有了两个解析器,一个解析器用于完整的JavaScript语言,另一个解析器用于JS子集ASM.js。
这样将面临代价很高的解析问题,但可以用一个更加高效的,压缩的抽象语法树(abstract syntax tree:AST),这就是WebAssembly的目的。
当人们被问到web上的字节码(bytecode),就认为是Java字节码。我认为微软和其他地方的研究人员已经表明那不是他们想要的,在许多地方都很令人难受,AST编码就好的多。
首先,WebAssembly开始就像ASM.js一样,但是用一个压缩的语法,一个二进制语法。但是一旦所有的浏览器支持了wasm和ASM.js,然后在一些浏览器版本更新后,就可以开始增加更多的无需添加到JavaScript的语义(semantics)到wasm中。
实际上可以在JavaScript和wasm都添加,因为是同一个引擎(1vm),但有一些不想放入JavaScript的功能就可以放入wasm,这样可以利用C++或Haskell等语言的优点。有大量的语言都可以编译为wasm。
EE: 可以举一些例子吗?
BE: 好,这都在GitHub中有写到, 就是将共享内存数组buffers要让多线程游戏交叉编译,这是对JavaScript施加的一个压力,因为这花费了最多的时间,我们不想要JavaScript中的竞争条件 — 它总是在一个BUG很多的脆弱进程中。这是一个我们想要放到WebAssembly中的一个例子,如果我们可以选择的话。
沿着这个思路,还有很多类似的功能,例如零花费异常(zero cost exception)在JavaScript中可能没有意义,这些功能需要一些编译器和runtime聪明一些,但他们对于C++和Swift是有意义的。
另一个例子是call/cc (call-with-current-continuation)。Call/cc是非常强大的一个工具,它对JavaScript引擎的实现和安全风险都提出了挑战。
还有一些非本地函数的gotos,可以调用一个continuation进入到另外一个栈。所以这些是不同于ES6 generators中本地、受限的continuations。它们是更深的continuation。所以call/cc可以放入wasm,放入同时能够处理wasm与JavaScript的引擎。这是可以想象到的。它不必进入JavaScript语言但可以成为WebAssembly语法,同时不影响之前的JavaScript语言。
EE: 说到这里,那wasm是否存在安全风险需要仔细考虑呢?
BE: 因为它开始与ASM.js共存,因此不会增加任何新的安全风险,但可能在1-2年后开始新的分支,那时就需要查看所有扩展的安全属性。这是一项新的挑战,这也是Google做native client成员思考最多的,他们在这个领域的知识将非常有帮助。
我们正在努力消除PNaCl和Emscripten在使用C++和LLVM编译器中那些不确定的行为。从硬件向上查到C++规范,存在大量不确定行为,这不利于安全。
JavaScript已经远远超过规范中那些内容,将努力比其他语言更安全。对于WebAssembly,需要做的比JavaScript还要多。
EE: 在register中有一条有意思的头条新闻:你是否正试图杀死JavaScript? 事实的真相是什么呢?
BE: [笑] 不, 我是实用主义者。我不是有经验的C/C++ hacker,这是一个大系统,大家都在努力, 但也面临着web上的兼容性约束。
你不能违反web,不能了却往事从头开始。任何想要尝试这样做的人都将失败。
甚至当你看移动设备上的原生应用时,用户界面与图片都有相当成熟的原生语言和工具包,但还是有大量的web,存在大量的hybrid apps。
Facebook仍然在使用web views。所有的大型应用,Amazon, Pinterest等等都在使用web views。有大量的web应用是很愚蠢地使用native表示层而不是HTML编写,这纯粹是重复发明轮子。所以web仍然是非常非常重要的,它也是盈利最多的平台。
智能手机已经到处都是。在几年之内,地球上几乎每个成年人都将人手一部智能手机,这是非常巨大的一个量级,但这并不真正意味着智能手机就是一台PC, 它更多的仍然是一个消费级设备。不像你现在正在坐着,输入信息,从事研究,更深入地购物。
所以杀死JavaScript是不可行的,我正在做的是对真正的ASM.js的工程问题做出响应。从Epic公司的Unity引擎加载一个大的游戏会花20-30秒,这太长了。利用压缩的抽象语法树编码将快20倍,仅需要几秒钟。所以对wasm是有真正的需求,这是个有效需求。
Wasm帮助JS赢得胜利,它不仅仅是原生代码编译的胜利。最终所有的浏览器和webviews都将支持wasm语法来服务于编译目标主人,并释放JavaScript以便它可以服务于JavaScript主人。
JavaScript曾经有过分房子阶段,但长期来说是不可行的。就像我说的,即使共享数组buffer延伸,那也只是对JavaScript做的一点点延伸,如果可以让wasm做C++想要做的一些外部工作,而不需要想各种办法将这些不安全的事情放入JavaScript,将可以极大缓解JavaScript的压力。
所以,提升解析性能而不是服务于两个masters,才是做wasm的真正原因。我们并非是杀死JavaScript,我认为不可能杀死JavaScript。
“天没有塌下来.”
EE: 这对于担心JavaScript被杀死的许多人是个好消息。实际上,这是我在互联网上看到的对wasm声明最多的反应,人们害怕天正在塌下来。我想我们可以说天没有塌下来, JavaScript仍然会坚守一段时间。
BE: 我认为即使JavaScript有特权地位,wasm真正能够开始作为类似于C++等静态语言的目标,我们在未来将垃圾回收、JIT编译等扩展功能放入wasm中还需要一段时间,动态语言执行良好所需要的一些特性也还需要一段时间。
与此同时,Google里的成员正在做Dart编译器,他们就是在坚守JavaScript,因为当你不是在checked模式下编译时,Dart代码就是真正的动态代码-它需要JavaScript的JITs (Just In Time即时编译),它需要多种形式的内联缓存以及其他优化。
理论上, 我们会将Dart中的大整数/大数放入JavaScript,这是在未来的ECMAScript的日程中。我认为JavaScript将长期存在。真的很难说在哪一个点上我们会在浏览器中放弃内嵌的JavaScript,而只使用内嵌高级语言。
EE: 回到上世纪90年代,我自己写了大量的C/C++代码。我是在demoscene环境中长大的,我不知道你是否熟悉,但我们基本上是在构建艺术型应用,类似于依靠实际代码运行而不是事先录制好视频的电影。我们不再使用汇编语言来做视频处理,或处理大量数据等工作。你是将wasm视为人们构建这些应用的有效工具吗?
(译者注:Demoscene 是一种计算机亚文化,高手们通过编程展现出炫丽的实时动画音乐场景。主要技术是实时计算机图形学。)
BE: 是的。应当指出JavaScript将有SIMD。回到10年前Mozilla公司的Vladimir Vukićević 最早开始做的WebGL,然后进入到Khronos Group行业协会,WebGL作为基础的一部分可以支持大型游戏公司Epic, Unity等等的业务,这真的是太棒了。
但那只是基于OpenGL ES, OpenGL的移动profile。在WebGL 2中那只是从OpenGL ES2提升到3,所以你看看桌面GPUs, 它们可以做更多的事情。Wasm将会用OpenGL 4,最新的,最棒的桌面,有很炫的额外阴影,瞄向所有令人疯狂的Nvidia GPUs。
这些GPUs未来可能会慢慢进入移动设备,但这会花很长时间。不论WebGL发生什么,接下来几年我们对于wasm有一个选择, 就是要能够更快的编程,包括那些高级GPUs.
EE: 谁在做这件事? 我知道你已经在你的博客中提到有来自Microsoft和Google的员工在工作,都有谁在做,我们能够看到的支持来自哪里?
BE: 对我来说这很难,因为我是发布了声明,但我不属于其他公司,你可能已经注意到,公司不能将其名称租借出去,但这通常是由于协议延迟。这没什么困难,主角就是从事WebKit, JavaScriptCore的人们, Filip Pizlo这个名字在GitHub库中非常活跃(WebAssembly GitHub账号)。
Filip为Apple工作。其他公司还有Microsoft, Mozilla, 和Google。
Mozilla利用ASM.js走在前列,Google的成员们利用PNaCl,都在解决大量的相同问题和不确定行为,思考ASM.js当前还不支持的更高级特性,例如在做共享数组buffer之前需要实现动态链接和线程。
我认为在某个时间点上可以解决这些问题。我认为在Hacker News上许多人认为我是个超级极客(big jerk), 因为不知怎么回事,从我在Mozilla的骷髅王冠开始, 我就极力从思想上控制业界的每个人阻止PNaCl进入其他浏览器,或者说如果我只是将它放在Mozilla (以非常大的代价) 那么其他人就会跟随,因为如果Mozilla和Google做某件事,那么其他人也必须做这件事。 不是这样的,可看看WebM。
(译者注:WebM项目是一个使用BSD许可证的开源项目。它采用了On2 Technologies开发的VP8及其后续版本VP9视频编解码器和Xiph.Org基金会开发的Vorbis音频编解码器,使用的封装格式则以Matroska格式为基础。WebM项目是在2010年的Google I/O会议上发布的,之后宣布将会支持WebM的厂商有Mozilla、Opera和Google等。但WebM与H.264之间存在激烈的竞争。)
所以我认为那些不面对现实的人们有许多抱怨。事实是PNaCl不会跨浏览器,但许多工作是基于LLVM的。在我们做ASM.js之前PNaCl就已经开始了,所以这是相当完美的联姻。最初还认为是多灾多难,但实际上它已经让之前从事ASM.js和PNaCl的人们转向从事WebAssembly工作。
EE: 假定大家都支持这件事, 那么什么时候我们可以看到浏览器内嵌支持wasm呢?
BE: 我不清楚。他们必须建立一个原型或者可以继续发展的某项工作,因为我们从JavaScript和HTML学习到的一件事就是,不要做大量的硬版本(hard version)。你可以通过对象检测,特性检测等工作来检验自己的想法,或使用一些自动化配置测试工具,编写防御性的代码使得退回去更优雅一些。
所以在几年之后,当wasm 2018内部包含了call/cc, 可能一些其他语言就运气不佳,但如果它也有诸如零花费异常等高级特性,那你就可能想要在浏览器中利用不带零花费异常功能的wasm 2017运行,尽管可能你会遭受到异常调用的严重影响。但这也许可以。
从JavaScript编程来讲有一些非常重要,在8年前使用ES4时我们已经将mimetype versioning戏称为1JS. 在RFC 4329中,Bjoern Hoehrmann将JavaScript写为`<script type=”application/ecmascript”>` 。他说有一个version参数,但没有说version有哪些值, (但不能忽略这个参数),于是人们总是得到错误的versions,错误的mimetypes或没有任何mimetype的script标签。
version locking的整个思路是失败的, 而且我认为在其他runtime系统中使用它通常就是个问题。在接下来几个月里,我期望他们可以对抽象语法树编码性能感到满意,权衡编码与解码效率,这里解码是最重要的。他们对如何扩展语法会有好的想法。
接下来,他们可以开始每天晚上运行。我期望某个时间点 — 我想是到明年 — 但这完全是个猜测,我没有可透视未来的魔幻水晶球。但我们将会开始看到,支持wasm的浏览器至少每天晚上都会运行,也可能会在这个秋季实现。
社团人们将很快开始考虑语法的标准化。有一件事使得这件很紧迫的工作显得不那么紧迫,那就是已经有一个polyfill — 实际上就是一个库— 一个JavaScript版本的解码器,这个解码器可以将二进制代码变回到ASM.js, 可作为抽象语法树的原型。
即使现在JavaScript已经有软件实现的wasm,但不必提交成为正式的语法。在现代HTML5时代,web标准的关键是不断迭代,不要去做一些宏大的10年的规范,希望事情马上就尘埃落定,就像ES4曾经做过大的重构, ES6也是有大量变化,唯一拯救它的就是在真正的引擎中做增量式原型。
HTML5就是一个庞大、多年的version,最终打了一个巨大的版本戳5,但实际上在任何人声称已经完成之前又过去了很多年。
EE: 你刚才提到了一个原型, 那现在是否可以下载,试用?
BE: 可以的。如果通过GitHub账号登录,访问WebAssembly,可以在polyfill-prototype-1下看到一个解码器。我还没有时间,但如果你看看Emscripten,Emscripten将通过一个可选的模式来使用这个polyfill,即JavaScript解码器的库。我想现在可以试验下。
EE: 所有这些都会融入到wasm,那么会像在你的谈话"Taking the High Road and the Low Road"中所说的那样,JavaScript中还会增加一些底层特性吗?
BE: 是的,就像我说的那样,wasm会沿着支持道路走下去,不再需要polyfill,那么就会比ASM.js有更多的表达力,它会有更强大的语义,但这还需要一段时间。
同时许多人还会深入学习JavaScript,因为人们需要它,即使它不能被编译,人们希望可以手工编码。同时,SIMD,以及libm中的一些功能,例如`Math`对象、内联函数都被提升到高层语言中。如果你曾经编写过C或C++代码,你会看到有许多功能已经增加到ES6中,还有更多的功能已经在排在日程上。
我认为我们将仍然是既要走底层道路,同时也要走高层道路,但我认为这可能是按5年时间来算,现在还不需要太担心,如果有一些底层功能只用于编译器,并且可以确信JavaScript手工编程人员不需要,那么就不会增加该功能到JavaScript中,即不需要服务于两个主人。
EE: 你认为这会导致大量语言被碎片化,或者说差异化(diversity),区别是什么? 这是件好事还是坏事? 许多人好像很困惑。
BE: 我认为JavaScript已经成为浏览器中唯一的动态语言,但wasm可以支持许多编译语言,也就是静态语言—尤其是使用LLVM的语言。微软有自己的编译器,所以他们会通过另一个编译器框架支持wasm,但这非常棒。越多越好。
当然,GCC或类似的编译器都可以生成wasm,但我认为动态语言,例如Dart, Ruby, Python, 甚至JavaScript — 都会需要我前面提到的一些扩展, 例如垃圾回收钩子、JIT支持等等,否则它们将没有竞争力。
有好的先例,JVM经过多年的成长,感谢John Rose加入了类似于`invokedynamic` 以及其他钩子用于JIT编译优化,,例如多种形式的内联缓存, 所以JVM实际上是一个可信赖的动态语言平台。
所有这些运行时(runtime)都已经变成了通晓多种语言的虚拟机—JavaScript VMs. Java还没有死,就是因为JVM现在支持Clojure, Scala以及其他语言。我们几乎是在编程语言的第二个黄金年代,你知道,现在有Rust, Haskell, Idris, 以及其他语言。
我想说的是越多越好. 那不会成为巴别塔(the tower of Babel),因为我认为不论是现在和未来,JavaScript都将成为浏览器的通用语言(the lingua franca of the browser)。如果你正在编写前端代码,或者当你描绘轮廓时在非关键路径上做的其他事情。
但如果你真的想把这些映射为3d游戏, 或者一些超级复杂的计算机视觉内核算法, 那么你可能要用C++或其他语言编译成wasm, 也许5年后, 如果人们对可编译为wasm的语言充满热情, 那么这门语言地位就会上升, 我认为这不是个问题, 这只是大都市生活的一部分.
EE: 也就是说你最终想要看到的是JavaScript语言消失, 如果有更好的语言出现的话?
BE: 再重复一遍,我没有预测它会如何被杀死,因为web上所有的内容都必须在浏览器内运行,wasm中实现一个能够像V8那样快速运行的JavaScript runtime将是对工程师的一个真正挑战。但沿着这条路走下去,如果过了很多年某个人做到了,那么就可以让JavaScript成为n个wasm实现语言的一种。
但JavaScript语言在web中仍然有神奇的立足点。而且它还在不断发展,因为我们仍然在努力使JavaScript成为手工编码人员更好的语言,所以它不会停滞不前。人们对ES6的评价是:这不是之前的JavaScript了,现在非常棒。
再次,没有可透视未来的魔幻水晶球,我只是认为很难让JavaScript语言消失。我不会去杀死JavaScript语言。当人们不再需要JavaScript时,其寿命自然会终止,如果人们发现其他语言更好,如果继续沿着这条路走, 经过许多次的更新迭代, 人们不担心嵌入到浏览器中的是JavaScript语言, 那么我会说“que sera sera.”(法语: 该来的总会来)
我认为, 那些想让JavaScript语言消失的人是因为他们对它由于某些原因而抱有敌意, 他们将会失望而归,JavaScript语言不会消失。
这对于JavaScript和其他语言来说实际上是件好事。不要假设时间会停滞,我认为wasm将会包含越来越多其他语言的特性,也包括JavaScript语言的特性。
这是各方都能够赢的实例,这确实满足了web业界每一家的利益, 无论是Apple, Google, Microsoft, 还是Mozilla。
现在要做的是聚焦增量式提升,而不是偏离现实太远。类似于ES4, PNaCl, Dart, XHTML的工作都将回退到以往的日子。所有那些试图以自己公司宏大计划模式来重建web的大碰撞将不会再起作用。
所以现在我们这些人一起合作,解决这些小的碰撞,我们应当会看到一系列的小碰撞将会产生非常大的累积效果。
译者注:最后附上一页Brendan Eich在Modern Web 2015会议上的主旨演讲-JavaScript at 20 Years视频中的最后一页,Alaways bet on JS(永远赌JS赢):
后记:[6]中Brendan Eich于2013就已经指出Web就是游戏平台(The Web is the Game Platform),许多技术用于加速Web端的游戏开发,包括asm.js, 一个JavaScript优化技术,纯JS子集目标语言for编译器;Emscripten, 一个C++到JavaScript的编译器;OdinMonkey, SpiderMonkey JavaScript引擎编译器forasm.js源码。与Epic游戏公司创始人和CEO Tim Sweeney对许多事有相同的观点,例如通过C++通过asm.js,JS可下沉作为一种安全的类似汇编的target语言。
这些都表明,游戏产业在拉动和推动Web端JavaScript技术的快速发展。
参考资料:
[1] WebAssembly系列1-从 ASM.JS 到 WebAssembly, http://my.oschina.net/1pei/blog/487683
[2] Why we Need WebAssembly, An Interview with Brendan Eich, Eric Elliott, June 17th, 2015, https://medium.com/javascript-scene/why-we-need-webassembly-an-interview-with-brendan-eich-7fb2a60b0723
[3] What is WebAssembly? The Dawn of a New Era, Eric Elliott, June 18th, 2015, https://medium.com/javascript-scene/what-is-webassembly-the-dawn-of-a-new-era-61256ec5a8f6
[4] Modern Web 2015, May 15th-16th, 2015, http://modernweb.tw/program.html
[5] WebGL 2 Specification, Editor's Draft 24 July 2015, https://www.khronos.org/registry/webgl/specs/latest/2.0/
[6] The Web is the Game Platform, 29 March, 2013, https://brendaneich.com/2013/03/the-web-is-the-game-platform/