关于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 ?>" ...
随机推荐
- POP的Stroke动画
POP的Stroke动画 效果 源码 https://github.com/YouXianMing/Animations // // PopStrokeController.m // Animatio ...
- 关于JAVA多线程并发synchronized的测试与合理使用
在项目开发中, 或许会碰到JAVA的多线程处理, 为保证业务数据的正常, 必须加上锁机制, 常用的处理方法一般是加上synchronized关键字, 目前JDK版本对synchronized已经做了 ...
- Android图片加载框架最全解析(五),Glide强大的图片变换功能
大家好,又到了学习Glide的时间了.前段时间由于项目开发紧张,再加上后来又生病了,所以停更了一个月,不过现在终于又可以恢复正常更新了.今天是这个系列的第五篇文章,在前面四篇文章的当中,我们已经学习了 ...
- MySQL中limit的用法
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.L ...
- [12] 扇形体(Fan)图形的生成算法
顶点数据的生成 bool YfBuildFunVertices ( Yreal radius, Yreal degree, Yreal height, Yuint slices, YeOriginPo ...
- 点云数据(point cloud) 【转】
转自caimagic的专栏 一:什么是点云数据 点云数据是指在一个三维坐标系统中的一组向量的集合.这些向量通常以X,Y,Z三维坐标的形式表示,而且一般主要用来代表一个物体的外表面形状.不经如此,除(X ...
- C#中的集合(HashTable与Array类)
一.Array类 1.Array类的属性 序号 属性 & 描述 1 IsFixedSize 获取一个值,该值指示数组是否带有固定大小. 2 IsReadOnly 获取一个值,该值指示数组是否只 ...
- iOS开发-沙盒(sandbox)机制
苹果前天发的财报,貌似现在用ios系统的比以前又多了一些,但是大家的iPhone购买的渠道也是五花八门,有的从非正规渠道购买的iPhone里的操作系统已经被越狱过,越狱这个事情和Android的roo ...
- 独特的deadlock(仅update语句也能造成死锁)
最近遇到了一个看上去很奇怪,分析起来很有意思的死锁问题.这个死锁看上去难以理解.而分析过程中,又使用了很多分析SQL Server死锁的典型方法.记录下来整个分析过程还是很有意义的. 问题重现步骤: ...
- 2.Dynamic Programming on Stolen Values【dp】
Problem: There are n houses built in a line, each of which contains some value in it. A thief is go ...