PHP Opcode内核实现 - [ PHP内核学习 ]
catalogue
. Opcode简介
. PHP中的Opcode
. opcode翻译执行(即时解释执行)
1. Opcode简介
opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定。 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。 这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等
通常opcode还有另一种称谓: 字节码(byte codes)。 例如Java虚拟机(JVM),.NET的通用中间语言(CIL: Common Intermeditate Language)等等
PHP中的opcode则属于前面介绍中的后着,PHP是构建在Zend虚拟机(Zend VM)之上的。PHP的opcode就是Zend虚拟机中的指令(基于Zend的中间代码)
Relevant Link:
http://www.luocong.com/learningopcode/doc/1._%E4%BB%80%E4%B9%88%E6%98%AFOpCode%EF%BC%9F.htm
2. PHP中的Opcode
0x1: 数据结构
在PHP实现内部,opcode由如下的结构体表示
\php-5.6.17\Zend\zend_compile.h
struct _zend_op
{
opcode_handler_t handler; // 执行该opcode时调用的处理函数
znode_op op1; // opcode所操作的操作数
znode_op op2; // opcode所操作的操作数
znode_op result;
ulong extended_value;
uint lineno;
zend_uchar opcode; // opcode代码
zend_uchar op1_type;
zend_uchar op2_type;
zend_uchar result_type;
};
和CPU的指令类似,有一个标示指令的opcode字段,以及这个opcode所操作的操作数,PHP不像汇编那么底层, 在脚本实际执行的时候可能还需要其他更多的信息,extended_value字段就保存了这类信息, 其中的result域则是保存该指令执行完成后的结果
例如如下代码是在编译器遇到print语句的时候进行编译的函数
\php-5.6.17\Zend\zend_compile.c
void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */
{
//新创建一条zend_op
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); //将新建的zend_op的返回值类型设置为临时变量(IS_TMP_VAR),因为print中的内存仅仅为了临时输出,并不需要保存
opline->result_type = IS_TMP_VAR;
//为临时变量申请空间
opline->result.var = get_temporary_variable(CG(active_op_array));
//指定opcode为ZEND_PRINT
opline->opcode = ZEND_PRINT;
//将传递进来的参数赋值给这条opcode的第一个操作数
SET_NODE(opline->op1, arg);
SET_UNUSED(opline->op2);
GET_NODE(result, opline->result);
}
aaarticlea/png;base64,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" alt="" />
0x2: opcode类型: zend_op->zend_uchar opcode
比对汇编语言的概念,每个opcode都对应于一个类型,表明该opcpde的"操作指令",opcode的类型为zend_uchar,zend_uchar实际上就是unsigned char,此字段保存的整形值即为op的编号,用来区分不同的op类型,opcode的可取值都被定义成了宏
/Zend/zend_vm_opcodes.h
#define ZEND_NOP 0
#define ZEND_ADD 1
#define ZEND_SUB 2
#define ZEND_MUL 3
#define ZEND_DIV 4
#define ZEND_MOD 5
#define ZEND_SL 6
#define ZEND_SR 7
#define ZEND_CONCAT 8
#define ZEND_BW_OR 9
#define ZEND_BW_AND 10
#define ZEND_BW_XOR 11
#define ZEND_BW_NOT 12
#define ZEND_BOOL_NOT 13
#define ZEND_BOOL_XOR 14
#define ZEND_IS_IDENTICAL 15
#define ZEND_IS_NOT_IDENTICAL 16
#define ZEND_IS_EQUAL 17
#define ZEND_IS_NOT_EQUAL 18
#define ZEND_IS_SMALLER 19
#define ZEND_IS_SMALLER_OR_EQUAL 20
#define ZEND_CAST 21
#define ZEND_QM_ASSIGN 22
#define ZEND_ASSIGN_ADD 23
#define ZEND_ASSIGN_SUB 24
#define ZEND_ASSIGN_MUL 25
#define ZEND_ASSIGN_DIV 26
#define ZEND_ASSIGN_MOD 27
#define ZEND_ASSIGN_SL 28
#define ZEND_ASSIGN_SR 29
#define ZEND_ASSIGN_CONCAT 30
#define ZEND_ASSIGN_BW_OR 31
#define ZEND_ASSIGN_BW_AND 32
#define ZEND_ASSIGN_BW_XOR 33
#define ZEND_PRE_INC 34
#define ZEND_PRE_DEC 35
#define ZEND_POST_INC 36
#define ZEND_POST_DEC 37
#define ZEND_ASSIGN 38
#define ZEND_ASSIGN_REF 39
#define ZEND_ECHO 40
#define ZEND_PRINT 41
#define ZEND_JMP 42
#define ZEND_JMPZ 43
#define ZEND_JMPNZ 44
#define ZEND_JMPZNZ 45
#define ZEND_JMPZ_EX 46
#define ZEND_JMPNZ_EX 47
#define ZEND_CASE 48
#define ZEND_SWITCH_FREE 49
#define ZEND_BRK 50
#define ZEND_CONT 51
#define ZEND_BOOL 52
#define ZEND_INIT_STRING 53
#define ZEND_ADD_CHAR 54
#define ZEND_ADD_STRING 55
#define ZEND_ADD_VAR 56
#define ZEND_BEGIN_SILENCE 57
#define ZEND_END_SILENCE 58
#define ZEND_INIT_FCALL_BY_NAME 59
#define ZEND_DO_FCALL 60
#define ZEND_DO_FCALL_BY_NAME 61
#define ZEND_RETURN 62
#define ZEND_RECV 63
#define ZEND_RECV_INIT 64
#define ZEND_SEND_VAL 65
#define ZEND_SEND_VAR 66
#define ZEND_SEND_REF 67
#define ZEND_NEW 68
#define ZEND_INIT_NS_FCALL_BY_NAME 69
#define ZEND_FREE 70
#define ZEND_INIT_ARRAY 71
#define ZEND_ADD_ARRAY_ELEMENT 72
#define ZEND_INCLUDE_OR_EVAL 73
#define ZEND_UNSET_VAR 74
#define ZEND_UNSET_DIM 75
#define ZEND_UNSET_OBJ 76
#define ZEND_FE_RESET 77
#define ZEND_FE_FETCH 78
#define ZEND_EXIT 79
#define ZEND_FETCH_R 80
#define ZEND_FETCH_DIM_R 81
#define ZEND_FETCH_OBJ_R 82
#define ZEND_FETCH_W 83
#define ZEND_FETCH_DIM_W 84
#define ZEND_FETCH_OBJ_W 85
#define ZEND_FETCH_RW 86
#define ZEND_FETCH_DIM_RW 87
#define ZEND_FETCH_OBJ_RW 88
#define ZEND_FETCH_IS 89
#define ZEND_FETCH_DIM_IS 90
#define ZEND_FETCH_OBJ_IS 91
#define ZEND_FETCH_FUNC_ARG 92
#define ZEND_FETCH_DIM_FUNC_ARG 93
#define ZEND_FETCH_OBJ_FUNC_ARG 94
#define ZEND_FETCH_UNSET 95
#define ZEND_FETCH_DIM_UNSET 96
#define ZEND_FETCH_OBJ_UNSET 97
#define ZEND_FETCH_DIM_TMP_VAR 98
#define ZEND_FETCH_CONSTANT 99
#define ZEND_GOTO 100
#define ZEND_EXT_STMT 101
#define ZEND_EXT_FCALL_BEGIN 102
#define ZEND_EXT_FCALL_END 103
#define ZEND_EXT_NOP 104
#define ZEND_TICKS 105
#define ZEND_SEND_VAR_NO_REF 106
#define ZEND_CATCH 107
#define ZEND_THROW 108
#define ZEND_FETCH_CLASS 109
#define ZEND_CLONE 110
#define ZEND_RETURN_BY_REF 111
#define ZEND_INIT_METHOD_CALL 112
#define ZEND_INIT_STATIC_METHOD_CALL 113
#define ZEND_ISSET_ISEMPTY_VAR 114
#define ZEND_ISSET_ISEMPTY_DIM_OBJ 115
#define ZEND_PRE_INC_OBJ 132
#define ZEND_PRE_DEC_OBJ 133
#define ZEND_POST_INC_OBJ 134
#define ZEND_POST_DEC_OBJ 135
#define ZEND_ASSIGN_OBJ 136
#define ZEND_INSTANCEOF 138
#define ZEND_DECLARE_CLASS 139
#define ZEND_DECLARE_INHERITED_CLASS 140
#define ZEND_DECLARE_FUNCTION 141
#define ZEND_RAISE_ABSTRACT_ERROR 142
#define ZEND_DECLARE_CONST 143
#define ZEND_ADD_INTERFACE 144
#define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145
#define ZEND_VERIFY_ABSTRACT_CLASS 146
#define ZEND_ASSIGN_DIM 147
#define ZEND_ISSET_ISEMPTY_PROP_OBJ 148
#define ZEND_HANDLE_EXCEPTION 149
#define ZEND_USER_OPCODE 150
#define ZEND_JMP_SET 152
#define ZEND_DECLARE_LAMBDA_FUNCTION 153
#define ZEND_ADD_TRAIT 154
#define ZEND_BIND_TRAITS 155
#define ZEND_SEPARATE 156
#define ZEND_QM_ASSIGN_VAR 157
#define ZEND_JMP_SET_VAR 158
#define ZEND_DISCARD_EXCEPTION 159
#define ZEND_YIELD 160
#define ZEND_GENERATOR_RETURN 161
#define ZEND_FAST_CALL 162
#define ZEND_FAST_RET 163
#define ZEND_RECV_VARIADIC 164
#define ZEND_SEND_UNPACK 165
#define ZEND_POW 166
#define ZEND_ASSIGN_POW 167
0x3: opcode执行句柄: zend_op->handler
op的执行句柄,其类型为opcode_handler_t
typedef int (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
这个函数指针为op定义了执行方式,每一种opcode字段都对应一个种类的handler,比如如果$a = 1;这样的代码生成的op,操作数为const和cv,最后就能确定handler为函数ZEND_ASSIGN_SPEC_CV_CONST_HANDLER
/Zend/zend_vm_execute.h
void zend_init_opcodes_handlers(void)
{
static const opcode_handler_t labels[] = {
..
ZEND_ASSIGN_SPEC_CV_CONST_HANDLER,
..
}
}
0x4: opcpde操作数znode
操作数字段是_zend_op类型中比较重要的部分了,其中op1,op2,result三个操作数定义为znode类型
\php-5.6.17\Zend\zend_compile.h
typedef struct _znode { /* used only during compilation */
/*
这个int类型的字段定义znode操作数的类型
#define IS_CONST (1<<0) //表示常量,例如$a = 123; $b = "hello";这些代码生成OP后,123和"hello"都是以常量类型操作数存在
#define IS_TMP_VAR (1<<1) //表示临时变量,临时变量一般在前面加~来表示,这是一些OP执行过程中需要用到的中间变量,例如初始化一个数组的时候,就需要一个临时变量来暂时存储数组zval,然后将数组赋值给变量
#define IS_VAR (1<<2) //一般意义上的变量,以$开发表示
#define IS_UNUSED (1<<3) // Unused variable
#define IS_CV (1<<4) // Compiled variable,这种类型的操作数比较重要,此类型是在PHP后来的版本中(大概5.1)中才出现,CV的意思是compiled variable,即编译后的变量,变量都是保存在一个符号表中,这个符号表是一个哈希表,如果每次读写变量的时候都需要到哈希表中去检索,会对效率有一定的影响,因此在执行上下文环境中,会将一些编译期间生成的变量缓存起来。此类型操作数一般以!开头表示,比如变量$a=123;$b="hello"这段代码,$a和$b对应的操作数可能就是!0和!1, 0和1相当于一个索引号,通过索引号从缓存中取得相应的值
*/
int op_type; /*
此字段为一个联合体,根据op_type的不同,u取不同的值
1. op_type=IS_CONST的时候,u中的constant保存的就是操作数对应的zval结构
2. 例如$a=123时,123这个操作数中,u中的constant是一个IS_LONG类型的zval,其值lval为123
*/
union {
znode_op op;
zval constant; /* replaced by literal/zv */
zend_op_array *op_array;
zend_ast *ast;
} u;
zend_uint EA; /* extended attributes */
} znode;
0x5: opcode编译后数组op_array
在zend_do_print函数中的第一行,我们注意到下面这行代码
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
PHP脚本代码被编译后产生的opcode保存在op_array中,其内部存储的结构如下
\php-5.6.17\Zend\zend_compile.h
struct _zend_op_array
{
/* Common elements */
zend_uchar type;
const char *function_name; // 如果是用户定义的函数则,这里将保存函数的名字
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
zend_uint num_args;
zend_uint required_num_args;
zend_arg_info *arg_info;
/* END of common elements */ zend_uint *refcount; zend_op *opcodes; // opcode数组
zend_uint last; zend_compiled_variable *vars;
int last_var; zend_uint T; zend_uint nested_calls;
zend_uint used_stack; zend_brk_cont_element *brk_cont_array;
int last_brk_cont; zend_try_catch_element *try_catch_array;
int last_try_catch;
zend_bool has_finally_block; /* static variables support */
HashTable *static_variables; zend_uint this_var; const char *filename;
zend_uint line_start;
zend_uint line_end;
const char *doc_comment;
zend_uint doc_comment_len;
zend_uint early_binding; /* the linked list of delayed declarations */ zend_literal *literals;
int last_literal; void **run_time_cache;
int last_cache_slot; void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};
整个PHP脚本代码被编译后的opcodes保存在这里,这里需要明白的是,并非全部的PHP用户态代码都能在编译compile时期被翻译过来,因为本质上PHP是一种即时编译执行的脚本语言,有很多代码是在运行时run-time时期被动态地进行翻译并产生对应的opcode,例如lambda-function、var变量函数。所以本质上来说,PHP的opcode翻译可能是一个递归的过程
在执行的时候由下面的execute函数执行
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
// ... 循环执行op_array中的opcode或者执行其他op_array中的opcode
}
每条opcode都有一个opcode_handler_t的函数指针字段,用于执行该opcode,PHP有三种方式来进行opcode的处理
. CALL: PHP默认使用CALL的方式,也就是函数调用的方式
. SWITCH: 由于opcode执行是每个PHP程序频繁需要进行的操作,可以使用SWITCH或者GOTO的方式来分发
. GOTO: 通常GOTO的效率相对会高一些,不过效率是否提高依赖于不同的CPU
实际上我们会发现,在/zend/zend_language_parser.c中就是Zend的opcode翻译解释执行过程,其中包含了call、switch、goto三种opcode执行方式
这就是PHP为什么称之为解释型语言的内核原理,PHP在完成Lex词法解析后,在语法解析即生成产生式的时候,直接通过call、switch、goto的方式调用zend api进行即使解释执行
Relevant Link:
http://www.nowamagic.net/librarys/veda/detail/1325
http://php.net/manual/zh/internals2.opcodes.list.php
http://www.nowamagic.net/librarys/veda/detail/1543
http://www.nowamagic.net/librarys/veda/detail/1324
http://www.nowamagic.net/librarys/veda/detail/1543
http://www.laruence.com/2008/06/18/221.html
http://www.php-internals.com/book/?p=chapt02/02-03-02-opcode
3. opcode翻译执行(即时解释执行)
Relevant Link:
http://www.php-internals.com/book/?p=chapt02/02-03-03-from-opcode-to-handler
Copyright (c) 2016 Little5ann All rights reserved
PHP Opcode内核实现 - [ PHP内核学习 ]的更多相关文章
- linux内核设计与实现学习笔记-模块
模块 1.概念: 如果让LINUX Kernel单独运行在一个保护区域,那么LINUX Kernel就成为了“单内核”. LINUX Kernel是组件模式的,所谓组件模式是指:LINUX K ...
- LINUX内核分析第一周学习总结——计算机是如何工作的
LINUX内核分析第一周学习总结——计算机是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/ ...
- LINUX内核分析第二周学习总结——操作系统是如何工作的
LINUX内核分析第二周学习总结——操作系统是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...
- LINUX内核分析第四周学习总结——扒开系统调用的“三层皮”
LINUX内核分析第四周学习总结--扒开系统调用的"三层皮" 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC ...
- linux内核分析第四周学习笔记
linux内核分析第四周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux内核分析第二周学习笔记
linux内核分析第二周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- linux内核分析第一周学习笔记
linux内核分析第一周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux内核的ioctl函数学习
Linux内核的ioctl函数学习 来源:Linux公社 作者:Linux 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围.为什 ...
- Linux内核分析第一周学习博客 --- 通过反汇编方式学习计算机工作过程
Linux内核分析第一周学习博客 通过反汇编方式学习计算机工作过程 总结: 通过这次对一个简单C程序的反汇编学习,我了解到计算机在实际工作工程中要涉及大量的跳转指针操作.计算机通常是顺序执行一条一条的 ...
- Linux内核分析第二周学习博客——完成一个简单的时间片轮转多道程序内核代码
Linux内核分析第二周学习博客 本周,通过实现一个简单的操作系统内核,我大致了解了操作系统运行的过程. 实验主要步骤如下: 代码分析: void my_process(void) { int i = ...
随机推荐
- WebApp:如何让安卓的webview缓存webapp的html、js和图片等资源
一.开发环境 客户端:安卓+webview(vuejs) 服务器端:tomcat 8.0 二.问题 使用安卓原生+web(基于webpack+vuejs)的方式开发了一个安卓应 ...
- 数据挖掘系列(9)——BP神经网络算法与实践
神经网络曾经很火,有过一段低迷期,现在因为深度学习的原因继续火起来了.神经网络有很多种:前向传输网络.反向传输网络.递归神经网络.卷积神经网络等.本文介绍基本的反向传输神经网络(Backpropaga ...
- 如何用 fiddler 调试线上代码
有时代码上线了,突然就碰到了坑爹的错误.或者有时看别人家线上的代码,对于一个文件想 fork 下来试试效果又不想把全部文件拉到本地,都可以使用 fiddler 的线上调试功能. 比方说我们打开携程的首 ...
- <实训|第九天>掌握linux中普通的权限控制和三种特殊的权限(sst),做合格的运维工程师
linux中,权限的学习是必不可少的,不论是作为一名运维工程师或者是单一的管理者,学习好linux中的权限控制,你就可以保护好自己的隐私同时规划好你所管理的一切. 权限的学习是很多的,不要认为自己已经 ...
- JAVA对象和XML文档、原来他们之间还有这一出
最近项目开发中遇到一个问题,访问接口不再通过url地址请求的方式,而是 通过socket发送xml格式的报文到指定服务器来进行信息的统一认证.. 因此组装xml格式的报文字符串以及解析服务器返回的xm ...
- java并发:线程同步机制之Volatile关键字&原子操作Atomic
volatile关键字 volatile是一个特殊的修饰符,只有成员变量才能使用它,与Synchronized及ReentrantLock等提供的互斥相比,Synchronized保证了Synchro ...
- Bootstrap系列 -- 1. 如何使用Bootstrap
一. Bootstrap 简介 Bootstrap 是一个前端框架,使用Bootstrap可以做出很多漂亮的页面,中文官网:http://www.bootcss.com/ 二. Bootstrap核心 ...
- Bootstrap系列 -- 2. 标题
一. Bootstrap标题 在Bootstrap中使用标题和Html本身没有太大的区别使用h1-h6, 而Bootstrap只是默认修改了H1-h6的样式,网上找到如下资料参考 二. Bootstr ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- ios UITableview 刷新某一个cell 或 section
//一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:]; [tableview reloadSections:ind ...