WebAssembly的基础使用方法

什么是WebAssembly(wasm)?

WebAssembly或wasm是一种新的,便携式的,大小和加载时间效率高的格式,适合编译到Web上。WebAssembly设计

  1. 一种二进位表示的新语言,但有另外的文字格式可以让你编辑与调试。

  2. 编译目标:顾名思义,只要透过特定的编译器,你就能将你自己惯用的语言编译成WebAssembly,然后执行在浏览器上!目前可以透过Emscripten(LLVM to JS compiler)来编译C / C ++的程式。

  3. 提供增强JavaScript程式的方法:你可以将性能关键的程式部分用WebAssembly撰写,或是用第2点提及的C / C ++编译成WebAssembly,然后像一般import js module一般,导入你的JavaScript Application。透过WebAssembly,你能够自由控制Memory的存取与释放。

  4. 当浏览器能够支持运行WebAssembly的时候,由于二进位格式以及事先编译与优化的关系,势必能够产生比JavaScript运行速度更快,档案大小更小的结果。

  5. 语言的安全性WebAssembly当然也很重视,在JavaScript VM中,WebAssembly运行在一个沙箱化的执行环境,迁入web端运行时会强制使用浏览器的同源和权限安全策略。此外,wasm的实作设计中更特别提及他是内存安全的。

  6. Non-Web Embeddings:虽然是为了Web设计,但也希望能在其他环境中运行,因此底层实作并没有要求Web API,让其拥有良好的可移植性,不管是Nodejs,IoT设备都可使用。

WebAssembly目前由W3C Community Group设计开发,成员包含所有主流浏览器的代表。

WebAssembly有许多高级目标,目前版本的主要为MVP(Minimum Viable Product),提供先前asm.js的多数功能,并以先C / C ++的编译为主。

WebAssembly 主要试图解决现有技术的一些问题:

JavaScript:性能不够理想,以及语言本身的一堆坑(这个大家都懂)

Flash:私有技术(而且漏洞一堆),并且是纯二进制格式

Silverlight:私有技术,并且是纯二进制格式


各种插件(Plug-in):安全性问题,平台兼容问题

JavaScript 的坑我想我不用讲了吧,这里随便拉个人出来都比我讲得好。重点解释一下 WebAssembly 设计过程中考虑到的其它几个方面:

一. 二进制格式

Web 的基础是超文本(Hypertext),即包含超链接(Hyperlink)的文本(字符串)。这个特性使人能读懂,机器也容易分析。因此,和这个理念相符的技术往往在 Web 方向上有着更大的可能性被广泛应用——不说别的,就说后端语言吧,现在烂大街的后端语言哪个处理字符串不方便?要是都像 C 这样 char* 满天飞,现在后端工程师的工资估计得乘个 10。

不过呢,早期这一设计的确限制了 Web 表现力的发展。那时候标准混乱,浏览器们各自为政,基于有特定功能的 tag 的 HTML 的用途极为有限,尤其是当时尚未出现或完善的动态内容(XHR),多媒体内容(canvas, audio, video)以及高性能运算(WebGL,asm.js 等)等场合。

于是那时的 Flash 横空出世。一个插件让 Web 的表现力提升了一大截:不仅自带矢量绘图,动态内容,多媒体内容甚至显卡 3D 加速也获得了支持。在那个 JavaScript 引擎的性能还很弱的年代,Flash 让无数开发者看到了希望。

然而随着 HTML 相关标准的不断完善和 JavaScript 引擎性能的突然提升,Flash 的优点没有那么突出了,而它的一大缺点却暴露了出来:二进制格式。长久以来 Flash 被滥用于提供(动态和静态)内容(我不信你们没看过整站用 Flash 做的网站;而 Flash 在设计的时候也没考虑过操作 DOM 的问题,毕竟人家自带一套用户界面),这样一来搜索引擎和通用的文本分析方案(例如浏览器的搜索功能)对它束手无策。而搜索引擎几乎已经成为 Web 内容提供的中心——它们提供到任何地方的超链接。于是,在 JavaScript 引擎的效率已经相当可观的今天,Flash 不灵了。

当然了,二进制格式有其好处:相对文本格式更轻量,在互联网上传输的成本更低,解释效率也更高(如果设计得当的话)。所以 WebAssembly 最终选择了一个妥协的方案:它要求一个程序段具有两种可互相转换的等价表达:二进制格式和文本格式。这二者可理解为类似机器码和汇编的关系:传输和运行的时候使用二进制格式,展现给人的时候用文本格式。这样就同时保留了二者的优点。当然了,为了安全性,要求以文本格式传输的程序不可被执行。

不过,由于代码混淆和压缩技术的广泛应用,WebAssembly 的这一设计意图最终不容易达到预想中的效果吧。

二. 私有技术和平台兼容性问题

Flash 的诸多漏洞(包括一堆 0day)让人们意识到:让一个公司的私有技术主导 Web 并不是什么好主意。新的硬件平台?对不起,不支持。有 bug?等人家更新吧,你什么也干不了。高发热?对不起,你别无选择。没有权限安装浏览器插件?抱歉,你就别用了。不仅仅是 Flash,Silverlight,ActiveX 插件等也是同样的境地。

如果轮子不好用,那么自己造一个。我们需要开源的标准。

三. 可执行代码的安全性问题

这是黑暗森林法则的一个推论:我们不能信任任何人。网站不应该相信用户的输入是无害的;同样,用户也不应该相信网站提供的内容是无害的,尤其在这些内容会被在本地执行的时候。长期以来,我们给了传统浏览器插件(Plug-in)太多的权力,而事实证明它们中的一部分正在有效地利用用户给他们的所有权力(说你呢,支付宝)。

用户应当有权利掌控他们的设备。

不过呢,WebAssembly 将面临新的挑战:一个全新的体系必将带来更多的安全问题。

四. 性能

WebAssembly 将是一个编译型语言。它的设计目标描述了一个美好的未来:

定义一个可移植,体积紧凑,加载迅捷的二进制格式为编译目标,而此二进制格式文件将可以在各种平台(包括移动设备和物联网设备)上被编译,然后发挥通用的硬件性能以原生应用的速度运行。

五. 远景

如果 WebAssembly 不出现,则 HTML,CSS,JavaScript 必将成为前端界的事实汇编语言:人们不断创造更多的(他们认为更好的)对这三者的高级(high-level)描述形式,并最后以这三者作为“编译目标”。WebAssembly 的出现则提供了一个更好的选择:接近原生的运算效率,开源、兼容性好、平台覆盖广的标准,以及可以借此机会抛弃 JavaScript 的历史遗留问题。何乐而不为呢?

等等,第一点就有问题了,你说他是二进位表示的语言,那该怎么写?!text format又是长什么样子?

问得好,这就是本篇的重点,WebAssembly的档案格式为wasm,举一个例子来看,一个用c ++撰写的加法函数:

add.c
 
      
1
2
3
4
 
      
#include 
int add int num1,int num2) {
return num1 + num2;
}

若编译为wasm会长这个样子(为节省空间我转成十六进制):

add.wasm
 
      
1
2
3
4
6
7
 
      
00 61 73 6d 01 00 00 00 01 87 80 80 80 00 01 60
02 7f 7f 01 7f 03 82 80 80 80 00 01 00 04 84 80
80 80 00 01 70 00 00 05 83 80 80 80 00 01 00 01
06 81 80 80 80 00 00 07 95 80 80 80 00 02 06 6d
65 6d 6f 72 79 02 00 08 5f 5a 33 61 64 64 69 69
00 00 0a 8d 80 80 80 00 01 87 80 80 80 00 00 20
01 20 00 6a 0b

当然我们很难去编辑这样的东西,所以有另一种text format叫做wast,上述的.wasm转成.wast后:

add.wast
 
      
1
2
3
4
5
6
7
8
9
10
11
12
 
      
 
      
(module
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "add" (func $add))
(func $add (param $0 i32) (param $1 i32) (result i32)
(i32.add
(get_local $1)
(get_local $0)
)
)
)

这样就好懂多了,我们一行一行来解释:

line 1的模块就是WebAssembly中一个可载入,可执行的最小单位程式,在运行时载入后可以产生实例来执行,而这个模块也朝着与ES6模块整合的方向,也就是说以后能透过

你可能感兴趣的:(V8)