PHP源代码分析:Opcode列表及功能简介
Opcode的全称是operation code。是Zend Engine产生的中间代码,有点类似于汇编语言。opcode是一个四元组,(opcode, op1, op2, result),它们分别代表opcode,第一操作数,第二操作数,结果。在Zend Engine的实现中,opcode使用下面的结构来实现的。
struct _zend_op {
opcode_handler_t handler;
/* OPCODE处理函数 */
znode result;
/* 本OPCODE操作结果,根据不同的opcode有不同的含义 */
znode op1;
/* 第一操作数 */
znode op2;
/* 第二操作数 */
ulong extended_value;
/* 与OPCODE有关的扩展值,例如: CAST中保存的就是目标类型 */
uint lineno;
/* OPCODE对应的代码的行号 */
zend_uchar opcode;
/* OPCODE代码 */
};
在这个结构中, handler是一个函数指针,指向本opcode对应的虚拟机中的处理函数。result是一个znode类型的变量,用于保存操作结果。op1, op2分别是该opcode对应的两个操作数。op1, op2, result在不同的opcode中有不同的含义,不是每个opcode都有这三个变量。extended_value保存的是与opcode有关的扩展值。lineno是该opcode对应的源代码的行号,这个调试错误定位时非常有用;最后一个zend_uchar表示就是这个opcode的代码。因为同一个opcode,由于操作数的类型不同,可能会对应不同的处理函数,因此Zend Engine在实现时在每个_zend_op结构中都保留了handler指针,这样可以提高虚拟机的处理效率。
Zend Engine 2.0/2.1 (对应PHP 5.x)大概实现了130多个opcode。下面对每个opcode的大概作用作一个简单的介绍:
|
Opcode代码 |
值 |
ver |
含义 |
|
ZEND_NOP |
0 |
|
空操作 |
|
ZEND_ADD |
1 |
|
加 |
|
ZEND_SUB |
2 |
|
减 |
|
ZEND_MUL |
3 |
|
乘 |
|
ZEND_DIV |
4 |
|
除 |
|
ZEND_MOD |
5 |
|
求模 |
|
ZEND_SL |
6 |
|
左移位 Shift Left |
|
ZEND_SR |
7 |
|
右移位 Shift Right |
|
ZEND_CONCAT |
8 |
|
字符串连接 |
|
ZEND_BW_OR |
9 |
|
按位或 |
|
ZEND_BW_AND |
10 |
|
按位与 |
|
ZEND_BW_XOR |
11 |
|
按位异或 |
|
ZEND_BW_NOT |
12 |
|
按位非 |
|
ZEND_BOOL_NOT |
13 |
|
逻辑非! |
|
ZEND_BOOL_XOR |
14 |
|
逻辑异或 XOR |
|
ZEND_IS_IDENTICAL |
15 |
|
=== |
|
ZEND_IS_NOT_IDENTICAL |
16 |
|
!== |
|
ZEND_IS_EQUAL |
17 |
|
== |
|
ZEND_IS_NOT_EQUAL |
18 |
|
<>,!= |
|
ZEND_IS_SMALLER |
19 |
|
< |
|
ZEND_IS_SMALLER_OR_EQUAL |
20 |
|
<= |
|
ZEND_CAST |
21 |
|
类型强制转换,目标类型extend_value |
|
ZEND_QM_ASSIGN |
22 |
|
?: 操作赋值 |
|
ZEND_ASSIGN_ADD |
23 |
|
+= |
|
ZEND_ASSIGN_SUB |
24 |
|
-= |
|
ZEND_ASSIGN_MUL |
25 |
|
*= |
|
ZEND_ASSIGN_DIV |
26 |
|
/= |
|
ZEND_ASSIGN_MOD |
27 |
|
%= |
作者: chnzbq 发布时间: 2009-01-04
28
<<=
ZEND_ASSIGN_SR
29
>>=
ZEND_ASSIGN_CONCAT
30
.=
ZEND_ASSIGN_BW_OR
31
|=
ZEND_ASSIGN_BW_AND
32
&=
ZEND_ASSIGN_BW_XOR
33
^=
ZEND_PRE_INC
34
++前自增 ++$a
ZEND_PRE_DEC
35
–前自减 –$a
ZEND_POST_INC
36
后自增++ $a ++
ZEND_POST_DEC
37
后自减– $a–
ZEND_ASSIGN
38
赋值=
ZEND_ASSIGN_REF
39
引用赋值 =&
ZEND_ECHO
40
ECHO
ZEND_PRINT
41
ZEND_JMP
42
无条件跳转指令
ZEND_JMPZ
43
条件跳转
ZEND_JMPNZ
44
ZEND_JMPZNZ
45
ZEND_JMPZ_EX
46
ZEND_JMPNZ_EX
47
ZEND_CASE
48
CASE操作符
ZEND_SWITCH_FREE
49
SWITCH
ZEND_BRK
50
BREAK
ZEND_CONT
51
CONTINUE
ZEND_BOOL
52
BOOL转换
ZEND_INIT_STRING
53
初始化字符串
ZEND_ADD_CHAR
54
将字符加到字符串
ZEND_ADD_STRING
55
将字符串加到字符串
ZEND_ADD_VAR
56
将变量加到字符串
ZEND_BEGIN_SILENCE
57
错误屏蔽开始
ZEND_END_SILENCE
58
错误屏蔽结束
ZEND_INIT_FCALL_BY_NAME
59
初始化通过名称调用函数
ZEND_DO_FCALL
60
函数调用
ZEND_DO_FCALL_BY_NAME
61
通过名称调用函数
ZEND_RETURN
62
函数返回
ZEND_RECV
63
函数声明时传递参数
ZEND_RECV_INIT
64
函数声明时传递参数,用默认值初始化
ZEND_SEND_VAL
65
函数调用时传递值作为参数
ZEND_SEND_VAR
66
函数调用时传递变量作为参数
ZEND_SEND_REF
67
函数调用时传递引用作为参数
ZEND_NEW
68
new 操作
ZEND_INIT_NS_FCALL_BY_NAME
69
5.3
命名空间函数调用
ZEND_FREE
70
free操作
ZEND_INIT_ARRAY
71
数组初始化
ZEND_ADD_ARRAY_ELEMENT
72
添加数组元素
ZEND_INCLUDE_OR_EVAL
73
include/require/eval操作
ZEND_UNSET_VAR
74
5.1
UNSET操作
ZEND_UNSET_DIM
75
5.1
ZEND_UNSET_OBJ
76
5.1
ZEND_FE_RESET
77
5.1
FOREACH操作
ZEND_FE_FETCH
78
FOREACH操作
ZEND_EXIT
79
EXIT
ZEND_FETCH_R
80
这一系列OPCODE用于获取各种类型的变量地址,分别用于不同的操作。R:只读,W:只写,RW:读写。
DIM – 数组
OBJ – 对象
ZEND_FETCH_DIM_R
81
ZEND_FETCH_OBJ_R
82
ZEND_FETCH_W
83
ZEND_FETCH_DIM_W
84
ZEND_FETCH_OBJ_W
85
ZEND_FETCH_RW
86
ZEND_FETCH_DIM_RW
87
ZEND_FETCH_OBJ_RW
88
ZEND_FETCH_IS
89
取出变量地址,用于IS*测试。IS*测试指的是对变量进行ISSET 或ISEMPTY测试。
ZEND_FETCH_DIM_IS
90
ZEND_FETCH_OBJ_IS
91
ZEND_FETCH_FUNC_ARG
92
获取函数参数地址
ZEND_FETCH_DIM_FUNC_ARG
93
ZEND_FETCH_OBJ_FUNC_ARG
94
ZEND_FETCH_UNSET
95
获取变量地址,用于UNSET
ZEND_FETCH_DIM_UNSET
96
ZEND_FETCH_OBJ_UNSET
97
ZEND_FETCH_DIM_TMP_VAR
98
ZEND_FETCH_CONSTANT
99
5.0
取得常量地址
ZEND_GOTO
100
5.3
GOTO 操作
ZEND_EXT_STMT
101
extension statement
ZEND_EXT_FCALL_BEGIN
102
extension function call begin
ZEND_EXT_FCALL_END
103
extension function call end
ZEND_EXT_NOP
104
extension noop
ZEND_TICKS
105
TICKS函数,5.3中过时,6.0取消
ZEND_SEND_VAR_NO_REF
106
ZEND_CATCH
107
5.0
异常处理捕获异常
ZEND_THROW
108
异常处理抛出异常
ZEND_FETCH_CLASS
109
使用对象名称获取对象指针
ZEND_CLONE
110
对象克隆
ZEND_INIT_METHOD_CALL
112
对象方法调用初始化
ZEND_INIT_STATIC_METHOD_CALL
113
对象静态方法调用初始化
ZEND_ISSET_ISEMPTY_VAR
114
标量类型变量IS*测试
ZEND_ISSET_ISEMPTY_DIM_OBJ
115
数组或对象类型变量IS*测试
ZEND_PRE_INC_OBJ
132
对象属性前自增 ++$obj->prop
ZEND_PRE_DEC_OBJ
133
对象属性前自减 –$obj->prop
ZEND_POST_INC_OBJ
134
对象属性后自增 $obj->prop++
ZEND_POST_DEC_OBJ
135
对象属性后自减 $obj->prop–
ZEND_ASSIGN_OBJ
136
对象赋值
ZEND_INSTANCEOF
138
instanceof操作符
ZEND_DECLARE_CLASS
139
类声明
ZEND_DECLARE_INHERITED_CLASS
140
继承类声明
ZEND_DECLARE_FUNCTION
141
函数声明
ZEND_RAISE_ABSTRACT_ERROR
142
实例化抽象类错误
ZEND_DECLARE_CONST
143
5.3
常数声明
ZEND_ADD_INTERFACE
144
类声明时添加接口
ZEND_DECLARE_INHERITED_CLASS_DELAYED
145
延迟
ZEND_VERIFY_ABSTRACT_CLASS
146
抽象类验证
ZEND_ASSIGN_DIM
147
数组元素赋值
ZEND_ISSET_ISEMPTY_PROP_OBJ
148
对象属性IS*测试
ZEND_HANDLE_EXCEPTION
149
异常处理
ZEND_USER_OPCODE
150
5.1
用户opcode
ZEND_U_NORMALIZE
151
6.0
ZEND_JMP_SET
152
5.3
作者: chnzbq 发布时间: 2009-01-04
作者: fyland 发布时间: 2009-01-04
作者: xiaojie515 发布时间: 2009-01-05
不是写明转贴吗???
作者: chnzbq 发布时间: 2009-01-06
作者: abcnic 发布时间: 2009-01-07