视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
opcode 操作数 5 种不同的类型
2020-11-03 23:12:02 责编:小采
文档

zend_op_array.opcodes 指向指令列表,具体每条指令的结构如下:

struct _zend_op { // *opline *opcodes
 const void *handler; //指令执行handler
 znode_op op1; //操作数1
 znode_op op2; //操作数类型实际就是个32位整形,它主要用于存储一些变量的索引位置、数值记录等等
 znode_op result; //返回值
 uint32_t extended_value;
 uint32_t lineno;
 zend_uchar opcode; //opcode指令
 zend_uchar op1_type; //操作数1类型
 zend_uchar op2_type;
 zend_uchar result_type; //返回值类型
};

//操作数结构
//比如赋值语句:"$a = 45;",两个操作数分别记录"$a"、"45"的存储位置,执行时根据op2取到值"45",
//然后赋值给"$a",而"$a"的位置通过op1获取到
//当然操作数并不是全部这么用的,上面只是赋值时候的情况,其它操作会有不同的用法
//如函数调用时的传参,op1记录的就是传递的参数是第几个,op2记录的是参数的存储位置,
//result记录的是函数接收参数的存储位置。
typedef union _znode_op { //操作数类型实际就是个32位整形,它主要用于存储一些变量的索引位置、数值记录等等
 uint32_t constant; //操作数记录着当前指令的关键信息, 可以用于变量的存储、访问
 uint32_t var;
 uint32_t num;
 uint32_t opline_num; /* Needs to be signed */
#if ZEND_USE_ABS_JMP_ADDR
 zend_op *jmp_addr;
#else
 uint32_t jmp_offset;
#endif
#if ZEND_USE_ABS_CONST_ADDR
 zval *zv;
#endif
} znode_op;
//操作数有5种不同的类型;
#define IS_CONST (1<<0) //字面量,编译时就可确定且不会改变的值,比如:$a = "hello~",其中字符串"hello~"就是常量
#define IS_TMP_VAR (1<<1) //临时变量 $a = "hello~" . time(),其中"hello~" . time()的值类型就是IS_TMP_VAR
 //"123" + $b的结果类型也是IS_TMP_VAR,从这两个例子可以猜测,临时变量多是执行期间其它
 //类型组合现生成的一个中间值,由于它是现生成的,所以把IS_TMP_VAR赋值给IS_CV变量时不会增加其引用计数
#define IS_VAR (1<<2)//PHP变量
 //这个很容易认为是PHP脚本里的变量,其实不是,这里PHP变量的含义可以这样理解:PHP变量是没有显
 //式的在PHP脚本中定义的,不是直接在代码通过$var_name定义的
 //。这个类型最常见的例子是PHP函数的返回值,再如$a[0]数组这种,它取出的值也是IS_VAR,再比如$$a这种
#define IS_UNUSED (1<<3) /* Unused variable */ //表示操作数没有用
#define IS_CV (1<<4) /* Compiled variable */
 //PHP脚本变量,即脚本里通过$var_name定义的变量,这些变量是编译阶段确定的,所以是compile variable

 //result_type除了上面几种类型外还有一种类型EXT_TYPE_UNUSED (1<<5),返回值没有使用时会用到,
 //这个跟IS_UNUSED的区别是:IS_UNUSED表示本操作返回值没有意义(也可简单的认为没有返回值),
 //而EXT_TYPE_UNUSED的含义是有返回值,但是没有用到,比如函数返回值没有接收

更多PHP相关知识,请访问PHP中文网!

下载本文
显示全文
专题