[转]PHP7源码分析 - 语言执行原理

小玄儿
• 阅读 2172

高级语言根据运行方式的不同,大体分为两种:编译型和解释型。

编译是指在应用源程序执行之前,就将程序源代码“翻译”成汇编语言,然后进一步根据软硬件环境编译成目标文件。一般称完成编译工作的工具为编译器。而解释型语言,在程序运行时才被“翻译”为机器语言。但是执行一次“翻译”一次,所以执行效率较低。解释器的工作就是解释型语言中,负责“翻译”源代码的程序。

编译型

  #include(stdio.h)>
  int main() {
      printf("hello word");
    return 1;
  }

[转]PHP7源码分析 - 语言执行原理

编译和执行过程如图所示。

  • 第1步:C语言代码预处理(比如依赖处理、宏替换等)。如以上代码示例,#inlcude<stdio.h>就会在预处理阶段被替换。
  • 第2步:编译。编译器会把C语言翻译成汇编语言程序,一条C语言通常编译为多条汇编代码。同时编译器会对程序进行优化,生成目标汇编程序。
  • 第3步:编译得到的汇编语言通过汇编器再汇编成目标程序hello.o。
  • 第4步:链接。程序中往往包含一些共享目标文件,如示例程序中的printf()函数,位于静态库,需要经过链接器(如Uinx连接器ld)进行链接。

编译型语言,代码发生更新都要经过以上步骤。

对编译型语言与解释型语言的区别的理解,立足于源代码被编译成目标平台CPU指令的时机。对于编译型语言,编译结果已经是针对当前CPU体系的指令;而解释型语言,需要先编译成中间代码,再经由该解释型语言的特定虚拟机,翻译成特定CPU体系的指令被执行。解释型语言是在运行过程中,翻译为目标平台的指令。常说解释型语言“慢”,主要也是慢在这里。

PHP7

在PHP 7中,源代码首先进行词法分析,将源代码切割为多个字符串单元,分割后的字符串称为Token。而一个一个独立的Token是无法表达完整语义的,需经过语法分析阶段,将Token转换为抽象语法树(简称AST)。之后,抽象语法树被转换为机器指令执行。在PHP中,这些指令称为opcode。

到AST的生成这一步,编译型语言与解释型语言所需经历的过程相似。从抽象语法树之后开始产生差异。

PHP7执行过程

[转]PHP7源码分析 - 语言执行原理

  • 第1步:词法分析将PHP代码转换为有意义的标识Token。该步骤的词法分析器使用Re2c实现。
  • 第2步:语法分析将Token和符合文法规则的代码生成抽象语法树。语法分析器基于Bison实现。语法分析使用了BNF(Backus-Naur Form,巴科斯范式)来表达文法规则,Bison借助状态机、状态转移表和压栈、出栈等一系列操作,生成抽象语法树。
  • 第3步:上步的抽象语法树生成对应的opcode,并被虚拟机执行。opcode是PHP 7定义的一组指令标识,指令对应着相应的handler(处理函数)。当虚拟机调用opcode,会找到opcode背后的处理函数,执行真正的处理。

Token

Token是PHP代码被切割成的有意义的标识。就是一个个的“词块”,但是单独存在的词块不能表达完整的语义,还需要借助规则进行组织串联。语法分析器就是这个组织者。它会检查语法,匹配Token,对Token进行关联。

PHP 7中,组织串联的产物就是AST(Abstract Syntax Tree,抽象语法树)。

AST

AST是PHP 7版本新特性。在这之前的版本中,PHP代码的执行过程中是没有生成AST这一步的。PHP 7对抽象语法树的支持,实现了PHP编译器和解释器解耦,有效提升了可维护性。
顾名思义,抽象语法树具有树状结构。AST的节点分为多种类型,对应着PHP语法。
可以认为节点类型是对语法规则的抽象,例如赋值语句,生成的抽象语法树节点为ZEND_AST_ASSIGN。而赋值语句的左右操作数又将作为ZEND_AST_ASSIGN类型节点的孩子。通过这样的节点关系,构建出抽象语法树。

opcodes

AST扮演了源码到中间代码的临时存储介质的角色,还需要将其转换为opcode,才能被引擎直接执行。opcode只是单条指令,opcodes是opcode的集合形式,是PHP执行过程中的中间代码,类似Java中的字节码。opcode生成之后由虚拟机执行。
PHP性能优化措施中有一个比较常见的“开启opcache”,指的就是这里的opcodes的缓存(opcodes cache)。通过省去从源码到opcode的阶段,引擎可以直接执行缓存的opcode,以此提升性能。
点赞
收藏
评论区
推荐文章
小万哥 小万哥
1年前
掌握 C++ 编译过程:面试中常见问题解析
C编译过程C是一种高级编程语言,但是计算机并不能直接理解它。因此,需要将C代码翻译成计算机可以理解的机器语言。这个过程就是编译过程,是C程序从源代码到可执行文件的转换过程,包括预处理、编译、汇编和链接四个阶段。1.预处理在编译器开始编译之前
半臻 半臻
4年前
Python基础1——变量、判断、循环、字符串、列表
1认识python1.1认识python计算机识别机器语言,机器语言由二进制0和1组成计算机要执行高级语言,转换方式1.编译:C语言、C、java。一次性编译成可执行文件2.解释:一行一行地解释python是解释型语言python解释器、pycharm编辑器举个例子:要给工地煮饭编译:把饭菜都做好,做成盒饭(.exe,.class
Karen110 Karen110
4年前
计算机系统漫游:贯穿计算机系统所有方面的重要概念
作者:RandalE.Bryant,DavidR.O'Hallaron来源:华章计算机(hzbook\jsj)计算机系统是由硬件和系统软件组成的,它们共同协作以运行应用程序。计算机内部的信息被表示为一组组的位,它们依据上下文有不同的解释方式。程序被其他程序翻译成不同的形式,开始时是ASCII文本,然后被编译器和链接器翻译成二进制可执行文件。处
Wesley13 Wesley13
3年前
GCC相关资料收集
GCC相关资料收集一、什么是GccLinux系统下的Gcc(GNUCCompiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。Gcc编译器能将C、C语言源程序、汇程式化序和目标程序编译、连接成可
Wesley13 Wesley13
3年前
Java程序运行机制及开发环境
Java既是编译型语言,又是解释型语言java源文件首先需要通过javac编译生成后缀名为.class的字节码文件(与平台无关,只面向JVM),然后使用Java虚拟机将字节码解释成特定平台上的机器码运行。Java虚拟机JVM不同平台上的JVM不同,但是都提供了相同的接口。开发Java准备1.下
Wesley13 Wesley13
3年前
Java字节码详解
也许你写了无数行的代码,也许你能非常溜的使用高级语言,但是你未必了解那些高级语言的执行过程。例如大行其道的Java。Java号称是一门“一次编译到处运行”的语言,但是我们对这句话的理解深度又有多少呢?从我们写的java文件到通过编译器编译成java字节码文件(也就是.class文件),这个过程是java编译过程;而我们的java虚拟机执行的就是字节码文件
Stella981 Stella981
3年前
JSP运行原理和九大隐式对象
一、JSP的原理:JSP文件会在服务器端的JSP引擎作用下转化为一个Servlet类的Java源代码文件。紧接着,这个Servlet类会在Java编译器的作用下被编译成一个class文件,并装载到jvm解释执行。剩下的就等同于Servlet的处理过程了。由于JSP第一次访问时会翻译成servle
Wesley13 Wesley13
3年前
JS篇(004)
答案:1.脚本语言。JavaScript是一种解释型的脚本语言,C、C等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。2.基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。3.简单。JavaScript语言中采用的是弱类型的变量
Stella981 Stella981
3年前
Python程序的执行过程原理(解释型语言和编译型语言)
Python是一门解释型语言?我初学Python时,听到的关于Python的第一句话就是Python是一门解释型语言,我就这样一直相信下去,直到发现.pyc文件的存在,如果真是解释型语言,那么生成的.pyc文件的是什么呢?c应该是compiled的缩写才对啊!为了防止其他学习Python的人也被这句话误解,那么我们就在文中来澄清一下这个问题,并且
Wesley13 Wesley13
3年前
20165305 苏振龙《信息安全系统设计基础》第一周学习总结
第一章:计算机系统漫游一、信息二进制(位串)上下文二、C语言代码转汇编代码命令:gccShello.iohello.s三、源程序翻译过程:源程序文本→预处理器(预处理)→编译器(编译)→汇编器(汇编)→链接器(链接)→可执行目标程序(二进制)四、了解编译系统工作原理的益处:1、优化程序性能2
Stella981 Stella981
3年前
Django环境搭建(一)
搭建Django环境之前先搭建python运行环境需要了解:  解释器(编译器):    计算机不能直接理解任何除机器语言外的其他语言,所以程序员必须要把自己写的语言翻译成机器语言,而将其他语言翻译成机器语言的工具,就叫做编译器    编译器翻译的方式有两种,一个是编译,