把现有程序带进网页
开发者希望保留已经写好的C、C++程序,又让访问者用浏览器运行。插件需要安装,且不能覆盖所有平台。Alon Zakai的Emscripten采取另一条路线:先利用LLVM编译基础设施处理源程序,再把中间表示转换成JavaScript。
这并非简单替换语法。低层表示中的分支需要重组为浏览器擅长处理的循环和条件结构;整数溢出等行为也要保留。Zakai的技术论文把这些问题与性能放在一起讨论。
参考:[1]
早期定义与一个加一函数
现存早期技术定义署2013年1月18日,由Dave Herman、Luke Wagner、Alon Zakai合写。它把asm.js规定为JavaScript的子集,以静态检查识别适合优化的程序,执行含义仍由JavaScript决定。
文中的add1函数先用x=x|0把参数限制为32位整数,返回前又对加一结果作整数转换。这样,检查器可以确定运算类型,编译器便能使用机器整数。
参考:[2]
从规范到试验构建
2013年3月21日,Wagner宣布OdinMonkey已进入Firefox Nightly。它是浏览器JavaScript引擎中的asm.js优化模块;当时桌面Windows、Mac和Linux已有x86、x64支持,ARM移动版仍在推进。
开发者已经可以用Emscripten生成所需代码,也可按草案手写。代码用“use asm”表明优化意图。公告以Bullet物理引擎模拟大量落箱的演示说明用途。验证不合格时,浏览器给出警告而非改变程序的JavaScript语义。Wagner同时提醒,频繁跨越普通代码与asm.js的边界会损失性能。
参考:[3]
正式版发行与移植实践
6月25日,Mozilla的Martin Best确认Firefox 22已经发行并包含asm.js优化。他说明,Mozilla与游戏业伙伴合作开发这条路线,目标是让高性能C++游戏进入网页。Unreal Engine 3的移植证明,既有大型程序可以通过Emscripten进入这一执行路径。
另一种用法只迁移计算繁重的库。网页游戏可以把物理计算交给Bullet或Box2D,其余部分仍手写JavaScript。Best还提到视频解码和图像处理的移植尝试。程序无需另装专用插件;不过,兼容的浏览器能够执行代码,与具备专门优化后达到的速度,是两件事。
参考:[4]
后续规范及其边界
规范继续变化。2014年8月18日的工作草案记录,7月7日加入了32位浮点类型及Math.fround;这些属于后续扩充,不宜回填为最早定义的内容。
2017年的WebAssembly论文进一步解释了这条路线的限制:asm.js依附JavaScript语义,增加64位整数之类的能力,需要先扩展JavaScript。论文将WebAssembly作为采用紧凑二进制表示的新方案讨论。它说明了后续设计要解决什么问题,也保留了asm.js曾以现有网页语言承载低层程序的技术位置。