Linux 之父出席、干货分享、圆桌讨论,精彩尽在 OpenCloudOS 社区开放日,报名戳 了解详情
写点什么

WebAssembly 到底处于编译阶段的哪个环节?

  • 2019 年 8 月 09 日
  • 本文字数:2444 字

    阅读完需:约 8 分钟

WebAssembly到底处于编译阶段的哪个环节?

相信不少人听说过 WebAssembly,它是由 Google、Microsoft、Mozilla、Apple 等几家大公司合作发起的一个关于面向 Web 的通用二进制和文本格式的项目。现在就让我们一步步揭开 WebAssembly 的神秘面纱,并亲自动手将 WebAssembly 应用在实际业务中。


引言

众所周知,无论是 Chrome、Firefox、Safari、Edge 还是其他浏览器,能够运行的语言就是 Javascript。为了能够让其他语言的代码在浏览器中运行,WebAssembly 被创造出来,详见《WebAssembly是什么》。我们并不需要亲自编写 WebAssembly 的代码,唯一要做的就是把其他高级语言编译成 WebAssembly 即可,这样便能复用大量其他语言现有的代码。而且 WebAssembly 还拥有比 JavaScript 更好的性能,能够更快的加载和执行。



那为啥 WebAssembly 的性能就一定会比 JavaScript 好很多呢?具体原因还得看下它们到底是处于编译阶段哪个环节了。


编译步骤

作为程序员的我们,每天都在用各种高级语言写源代码。但要让机器能读懂这些字符串代码,就得靠编译系统一步步把它们编译成目标代码。



预编译

预编译首先会处理源代码中那些以 #开头(如 #include、#define 等)的预编译指令,在编译开始前就先对原始的代码文件进行调整。经过了预编译之后,你写的代码其实已经有了很大的变化。


词法分析

词法分析是计算机科学中将字符序列转换为单词(Token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(lexical analyzer,简称 lexer),也叫扫描器(Scanner),供语法分析器调用。


词法分析阶段是编译过程的第一个阶段,任务是从左到右以字符流的方式逐行扫描源代码,然后根据构词规则一一识别关键词、标志符、字面量、运算符等,并分割成一个个按顺序排列的标记 Token。


语法分析

语法分析是根据某种给定的形式文法对由单词序列(如英语单词序列)构成的输入文本进行分析并确定其语法结构的一种过程。进行语法分析的程序或者函数叫作语法分析器(parser),供语义分析调用。


语法分析阶段是编译过程的一个逻辑阶段,任务是在词法分析分割出来的标记 Token 的基础上,将 Token 序列组合成各类语法短语如“程序”、“语句”、“表达式”等。


语义分析

语义分析是编译过程的一个最实质性的阶段,任务是对结构上正确的源代码进行上下文有关性质的审查,进行类型审查。


其实经过语法分析之后就能初步得到了抽象语法树,树上的每个节点都是一个表达式,但此时还不确定是否有意义。于是需要通过语义分析,遍历整个抽象语法树,把每个节点的表达式都标识类型,并且验证是否合法。


抽象语法树

抽象语法树(Abstract Syntax Tree,AST),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构,如下图所示:



从语法分析开始,就已经生成了初步的抽象语法树。经过了语义分析之后,抽象语法树又变得更加完善,自此最终版的抽象语法树 AST 已经建立完成。


中间码

经过前面几个阶段之后,我们已经有了最终版的 AST。但是该 AST 并不能完美运行在各个硬件平台上,因为不同平台的汇编处理都是不一样的。


于是便在 AST 和多个平台的汇编代码中间,抽象出了一个中间码(Intermediate Representation),在中间码的设计里抹平了硬件平台造成的差异。中间码的强大之处在于跨平台,与语言无关。


目标代码

计算机是通过汇编指令来执行操作的,如移动到内存某个地址、位移多少个字节等。因此需要通过目标平台的汇编器,由 AST 转成的中间码生成目标平台的汇编代码,这些才是机器能读懂的目标代码。



编译前端与后端

前面介绍了这么多编译步骤,其实我们可以把中间码当成一个分界线,中间码以前的环节叫做编译前端,中间码以后的环节叫做编译后端。


编译前端

编译前端包括预编译、词法分析、语法分析、语义分析、抽象语法树等,专门用来处理语言专属特性。虽然不同语言的词法关键字、语法规则、语义分析的函数类型校验可能都不一样,甚至某些语言都没有预编译这个环节,但每个语言都可以开发一套编译前端,按照标准生成的统一中间码就可以无缝对接给任意编译后端,这就是语言无关。


编译后端

编译后端这里只包含了目标代码生成部分,其实还应该包括将目标代码链接成为可执行文件的环节。编译后端专门负责处理各个平台的差异,根据不同语言生成的标准中间码,生成对应的目标代码,这就是平台无关。



编译工具

GCC

GCC(GNU Compiler Collection,GNU 编译器套装),包含了编译前端与编译后端所有模块。其中,编译前端部分支持 C、C++、Fortran、Pascal、Objective-C、Java 等语言,编译后端支持 x86、mips、Alpha、ARM、AVR、IA-64、SPARC、PowerPC 等 30 多种平台。


GCC 虽然被广泛的使用,但目前也面临了危机。后起之秀的 Clang / LLVM,大有全面赶超 GCC 的势头。


Clang / LLVM

Clang 是一个 C++编写、基于 LLVM、发布于 LLVM BSD 许可证下的 C / C++ / Objective-C / Objective-C++ 的编译器。那为啥已经有了 GCC 后还要开发 Clang 呢?Clang 相比于 GCC 有什么优势呢?因为 Clang 是一个高度模块化开发的轻量级编译器,它的编译速度快、占用内存小、非常方便进行二次开发。


而有了 Clang 这个编译器前端还不够,于是就跟 LLVM 这个编译器后端组合成一个完整的编译器套件,如下图所示:



WebAssembly 在编译环节的位置

前面说了这么多,但还是不知道 WebAssembly 处于编译阶段哪个环节啊?心急吃不了热豆腐,凡事都要对基础知识有一定了解之后,才能茅塞顿开。


通过下图你便可以一目了然 WebAssembly 所处的位置,它能做到像 Java 字节码一样,一次编译到处运行,具有跨平台特性。以此同时,作为中间码的 WebAssembly 直接省略编译前端的步骤,而 JavaScript 需要实时编译,相比之下性能优势显著。



参考资料


2019 年 8 月 09 日 08:131623

评论

发布
暂无评论
发现更多内容

为什么哈希表可以管理亿级数据?

八两

php redis hash rehash

工作那么久,才知道的 SOLID 设计原则

闻人

架构师 极客大学架构师训练营

查找算法系列文(一)一文入门二叉树

淡蓝色

Java 数据结构 算法 二叉树

第四周 学习总结

冯凯

辟谣:程序员不配谈恋爱?你错的可以!真相来了

码农神说

程序员 漫画 相亲

centos7 操作

InfoQ_1c4a1f813eb1

【极客大学】【架构师训练营】【第二周】依赖倒置原则和接口隔离原则

NieXY

极客大学架构师训练营

【在云端 002】云时代,何以安放我的个人数据

Bora.Don

云计算 云存储

线性表(数组、链表、队列、栈)详细总结

淡蓝色

Java 数据结构 算法 链表 线性表

每日一题-翻转字符串里的单词

程序员老王

LeetCode

别兜售你自己不会购买的东西

Neco.W

创业 销售管理 销售

RabbitMQ跨机房迁移数据零丢失

心平气和

RabbitMQ 消息队列

游戏夜读 | 《老残游记》很有趣

game1night

Redis系列(三):缓存过期该如何剔除?RDB和AOF又是什么?

z小赵

Java redis 高并发 高并发系统设计

多个maven项目启动顺序

terrytian

maven

循序渐进的中台研发

理帆

中台 业务中台

好奇心, 优秀软件工程师的内核品质

亚伦碎语

读书感悟 随笔杂谈

设计原则与设计模式

dapaul

极客大学架构师训练营

李艺:建立订阅者意识,当好一名知识服务生,做好知识课程

李艺

知识付费

基于业务表 Binlog 的事件驱动设计

理帆

MySQL 事件驱动 Binlog

设计模式之单例模式和组合模式

dapaul

极客大学架构师训练营

食堂就餐卡系统设计

John

极客大学架构师训练营

十五年后苹果再次变心

池建强

apple 苹果 芯片 wwdc

【极客大学】【架构师训练营】【第二周】总结:设计原则

NieXY

极客大学架构师训练营

就餐卡系统架构设计文档

牛珈羽

极客大学架构师训练营

SpringBean的生命周期

编号94530

Java spring Spring Boot 生命周期

iOS & Android 去马赛克处理

liu_liu

ios android 去马赛克

区块链目前实际的应用场景汇总

CECBC

区块链技术 去中心化 应用场景

架构师训练营 - 第三周学习总结

清风徐徐

ARTS Week5

丽子

wee1作业总结

牛珈羽

极客大学架构师训练营

GPU容器虚拟化:用户态和内核态的技术和实践详解

GPU容器虚拟化:用户态和内核态的技术和实践详解

WebAssembly到底处于编译阶段的哪个环节?_语言 & 开发_Paul_InfoQ精选文章