关于PHP中的opcode
简介
1、当Zend engine解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode),opcode是一个四元组,(opcode, op1, op2, result),它们分别代表操作码,第一操作数,第二操作数,结果
2、因为PHP是构建在Zend虚拟机(Zend VM)之上的,所以PHP的opcode就是Zend虚拟机中的指令
opcode结构
struct _zend_op {
opcode_handler_t handler;
znode_op op1;
znode_op op2;
znode_op result;
ulong extended_value;
uint lineno;
zend_uchar opcode;
zend_uchar op1_type;
zend_uchar op2_type;
zend_uchar result_type;
};
1、 opcode_handler_t opcode的函数指针 参考地址 opcode handler
2、result
我们看一下两个输出函数 ,echo 和 print
void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->result_type = IS_TMP_VAR;
opline->result.var = get_temporary_variable(CG(active_op_array));
opline->opcode = ZEND_PRINT;
SET_NODE(opline->op1, arg);
SET_UNUSED(opline->op2);
GET_NODE(result, opline->result);
}
/* }}} */
void zend_do_echo(const znode *arg TSRMLS_DC) /* {{{ */
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_ECHO;
SET_NODE(opline->op1, arg);
SET_UNUSED(opline->op2);
}
/* }}} */
我们可以看到print有result的设置 op2均为使用,从这里我们也能看出print和echo的区别来,print有返回值,而echo没有,这里的没有和返回null是不同的, 如果尝试将echo的值赋值给某个变量或者传递给函数都会出现语法错误
3、op1,op2 记录参数
4、lineno 对应的行号
5、opcode 对应相应的操作
6、extended_value 和CPU的指令类似,有一个标示指令的opcode字段,以及这个opcode所操作的操作数,PHP不像汇编那么底层, 在脚本实际执行的时候可能还需要其他更多的信息,extended_value字段就保存了这类信息
关于result op1 op2的结构znode
typedef union _znode_op {
zend_uint constant;
zend_uint var;
zend_uint num;
zend_ulong hash;
zend_uint opline_num; /* Needs to be signed */
zend_op *jmp_addr;
zval *zv;
zend_literal *literal;
void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
} znode_op;
typedef struct _znode { /* used only during compilation */
int op_type;
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;
op_type
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
#define IS_VAR (1<<2)
#define IS_UNUSED (1<<3) /* Unused variable */
#define IS_CV (1<<4) /* Compiled variable */
IS_CONST:表示常量,例如$a = 1; $b = "hello";这些代码生成OP后,1和"hello"都是以常量类型操作数存在。
IS_TMP_VAR:表示临时变量,临时变量一般在前面加~来表示,这是一些OP执行过程中需要用到的中间变量,例如初始化一个数组的时候,就需要一个临时变量来暂时存储数组zval,然后将数组赋值给变量。
IS_VAR: 一般意义上的变量,以$开发表示
IS_UNUSED : 暂时不介绍,从名字来看应该是标识为不使用
IS_CV:这种类型的操作数比较重要,此类型是在PHP后来的版本中(大概5.1)中才出现,CV的意思是compiled variable,即编译后的变量,变量都是保存在一个符号表中,这个符号表是一个哈希表,试想如果每次读写变量的时候都需要到哈希表中去检索,势必会对效率有一定的影响,因此在执行上下文环境中,会将一些编译期间生成的变量缓存起来,此过程以后再详细介绍。此类型操作数一般以!开头表示,比如变量$a=123;$b="hello"这段代码,$a和$b对应的操作数可能就是!0和!1, 0和1相当于一个索引号,通过索引号从缓存中取得相应的值。
u
此字段为一个联合体,根据op_type的不同,u取不同的值。比如op_type=IS_CONST的时候,u中的constant保存的就是操作数对 应的zval结构。例如$a=123时,123这个操作数中,u中的constant是一个IS_LONG类型的zval,其值lval为123
关于PHP中的opcode的更多相关文章
- 【转】中间代码opcode的执行
原文链接:http://www.orlion.ga/941/ 原文:http://www.nowamagic.net/librarys/veda/detail/1543 假如我们现在使用的是CLI模式 ...
- PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看
catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...
- PHP Opcode内核实现 - [ PHP内核学习 ]
catalogue . Opcode简介 . PHP中的Opcode . opcode翻译执行(即时解释执行) 1. Opcode简介 opcode是计算机指令中的一部分,用于指定要执行的操作, 指令 ...
- Opcode是啥以及如何使用好Opcache
转载 https://www.zybuluo.com/phper/note/1016714 啥是Opcode? 我们在日常的PHP开发过程中,应该经常会听见Opcache这个词,那么啥是Opcode ...
- nordic-mesh中应用的代码实现
nordic-mesh中应用的代码实现 Nordic-Mesh遵循SIG-Mesh-Profile中的mesh定义,实现了element.model等概念. 一个应用中包含一个或多个element,e ...
- 置换python2.7.13的opcode遇到的一些坑
主要有两个坑 1.XXXSLICE相关的opcode #define SLICE #define SLICE_1 #define SLICE_2 #define SLICE_3 #define STO ...
- php opcode
opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定. 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数. 这些操作数可能是寄存 ...
- OPCode 详解
OpCode 操作码(Operation Code, OPCode):描述机器语言指令中,指令要执行某种操作的机器码 OPCode在不同的场合中通常具有不同的含义,例如PHP虚拟机(Zend VM). ...
- i春秋——“百度杯”CTF比赛 十月场——Vld(Vulcan Logic Dumper 、php opcode、sql 报错注入)
打开题目看到提示 "do you know Vulcan Logic Dumper?" ,再查看源码看到"<!-- index.php.txt ?>" ...
随机推荐
- opencv学习_5 (IplImage的结构)
IplImage结构体为: typedef struct _IplImage { int nSize; /* IplImage大小 */ int ID; /* 版本 (=0)*/ int nChann ...
- QT笔记:数据库总结(三)之SQL模型类-QSqlTableModel模型
QSqlTableModel类继承至QSqlQueryModel类,该类提供了一个可读写单张SQL表的可编辑数据模型,功能:修改,插入,删除,查询,和排序 常用函数 QVariant headerDa ...
- Binary Tree Inorder Traversal leetcode java
题目: Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binar ...
- 总结div里面水平垂直居中的实现方法
最近经常碰到要垂直居中的问题,所以想着总结一下:关于如何设置小盒子在大盒子里面水平垂直方向同时居中的实现方法有很多种,下面仅列举了常用的几种. 首先看一下要实现的效果图及对应的html代码: < ...
- Android -- 跳转应用市场评分
Code Uri uri = Uri.parse("market://details?id="+getPackageName()); Intent intent = new Int ...
- CKEditor && CKFinder 配置
准备 ...
- 【HTML5】实现QQ聊天气泡效果
今天自己用 HTML/CSS 做了个类似QQ的聊天气泡,以下是效果图: 以下说下关键地方的样式设置.然后贴出html和css代码(不多). 步骤1:布局 消息採用div+float布局,每条消息用一个 ...
- 【C#】C#委托学习
虽然做.NET这行也快2年了,但基础不太好啊,今天看了下委托方面的知识,记录下. 1.委托 总的来说,委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋 ...
- WPF代码模板-布局部分
Grid 两行和三列 <Grid ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition ...
- SpringMVC上传文件的三种方式(转载)
直接上代码吧,大伙一看便知 这时:commonsmultipartresolver 的源码,可以研究一下 http://www.verysource.com/code/2337329_1/common ...