WebAssembly 可移植 体积小 加载快并且兼容 Web 的全新格式

发布于 2020-02-24 18:15:44 字数 4025 浏览 1714 评论 0

WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,WebAssembly 是由主流浏览器厂商组成的 W3C 社区团体 制定的一个新的规范,多个浏览器已经达成对初始 WebAssembly 版本的一致意见。

特点

高效

WebAssembly 有一套完整的语义,实际上 wasm 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件能力以达到原生执行效率

安全

WebAssembly 运行在一个沙箱化的执行环境中,甚至可以在现有的 JavaScript 虚拟机中实现。在web环境中,WebAssembly将会严格遵守同源策略以及浏览器安全策略。

开放

WebAssembly 设计了一个非常规整的文本格式用来、调试、测试、实验、优化、学习、教学或者编写程序。可以以这种文本格式在web页面上查看wasm模块的源码

标准

WebAssembly 在 web 中被设计成无版本、特性可测试、向后兼容的。WebAssembly 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。

概述

WebAssembly是一种小体积,高加载速度的二进制编码格式

从名字就能知道,这是一门底层汇编级的语言。有了 WebAssembly,我们的虚拟机层就将会同时加载和运行两种类型的代码—— JavaScript 和 WebAssembly。

这两种代码可以通过 WebAssembly 所提供的 JS API 实现互相调用。事实上,WebAssembly 代码的基本单元被称作一个模块,并且这个模块在很多方面都和 ES2015 的模块是等价的。所以我们可以认

WebAssembly 模块是一个 高性能的JS函数

WebAssembly 不是用来取代JavaScript的。它被设计为和JavaScript一起协同工作,从而使得网络开发者能够利用两种语言的优势。

WebAssembly 设计的目的不是为了手写汇编级别代码,而是为诸如C、C++等低级源语言提供一个高效的编译目标,使得以各种语言编写的代码都可以以接近原生的速度在web中运行。这一点具有重大的意义,这意味着所有由传统语言编写的客户端 app 都可以在 web 上高效运行,也就是说在未来客户端全面web化,未来可能不再需要客户端app。

同时 WebAssembly 也是一个 W3C 标准,制定过程中得到了各大浏览器厂商积极参与。各大厂商都参与到标准制定里并不常见,像js引擎,css标准,每个浏览器实际都有一套自己的标准。而获得各个厂商支持的 WebAssembly 在我看来,是未来的标准风向,会被广泛采用。

几个常见概念

Module

一个 代码单元。包含编译好的二进制代码。可以高效的缓存、共享未来可以像一个 ES2015 模块一样导入/导出。

Memory

连续的,可变大小的字节数组缓冲区。可以理解为一个

Table

连续的,可变大小的类型数组缓冲区,现在 table 只支持函数引用类型,可以类比为一个

Instance

在 Module 基础上,包含所有运行时所需状态的实例,如果把 Module 类比为一个 cpp 文件,那么 Instance 就是链接了 dll 的 exe 文件。

构建方法

直接汇编文本编写

WebAssembly 使用S-表达式作为文本格式

S 表达式用于表示一棵树。树上的每个一个节点都有一对小括号包围。括号内的第一个标签告诉你该节点的类型,其后跟随的是由空格分隔的属性或孩子节点列表劣势显而易见,编码逻辑不容易理解。

移植一个C/C++程序

这张图是官网上的构建流程图,构建过程中使用了Emscripten——一个基于llvm的编译器,目的是把 c/c++ 编译为 asm.js(js的一个真子集)

我们知道,C 和 JS 语法十分相似。所以在 C 到 JS 的编译过程中,要解决的最重要的问题主要是两点:

  • C/C++是静态类型,js是动态类型
  • C/C++需要程序员手动管理内存,js则有自己的一套垃圾回收机制

因此,就出现了asm.js。asm.js只有两种静态类型(i32, f64),并取消js的垃圾回收(手动管理内存)。浏览器加载到asmjs时,不进行语法分析,直接翻译为机器码执行
实际上,asm.js就是WebAssembly的一种文本格式,但不同于之前提到的s表达式。这一点类比于c,汇编语言,机器码之间的关系
由于WebAssembly当前不能直接调用Web API(如存取DOM),它只能调用JavaScript,因此需要一段js胶水代码使WebAssembly能够调用到Web API
移植代码缺点在于需要较复杂的依赖,相比之下,汇编编写依赖都由程序员自己定义

使用方法

WebAssembly的模块在很大程度上和ES2015模块类似。在使用上也是分为两步:加载和调用

加载

  • 获取.wasm二进制模块文件
  • 编译为Module
  • 实例化为Instance,由于获取,编译和实例化都是异步的,所以实际使用中为了方便,可以直接构建一个异步的 loader 对 wasm 进行加载

调用

从 Instance 中获取函数接口

相关链接

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

新人笑

文章 0 评论 0

mb_vYjKhcd3

文章 0 评论 0

小高

文章 0 评论 0

来日方长

文章 0 评论 0

哄哄

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文