PHP源代码分析:Opcode列表及功能简介

[Deprecated by http://www.phpinternals.com/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

ZEND_ASSIGN_SL
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
  
PRINT

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