php源码学习d12 AST的遍历1

1.php代码先转化成抽象语法树,要执行还需要将抽象语法书转化操作指令集。

2.指令结构_zend_op

struct _zend_op {
	const void *handler; //操作方式
	znode_op op1; // 操作数1
	znode_op op2; // 操作数2
	znode_op result; //结果
	uint32_t extended_value; // 额外存储
	uint32_t lineno; // 行号
	zend_uchar opcode; // 唯一对应一个handler
	zend_uchar op1_type; // 类型
	zend_uchar op2_type;
	zend_uchar result_type;
};
// znode_op是个联合体
typedef union _znode_op {
	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;

typedef struct _znode { /* used only during compilation */
	zend_uchar op_type;
	zend_uchar flag;
	union {
		znode_op op;
		zval constant; /* replaced by literal/zv */
	} u;
} znode;

3.inline 内联函数

函数不解析,不压栈,直接嵌入代码。

4.宏替换中的do{}while(0) 

限定了宏内容的作用域,是为了保证宏替换的完整性,防止宏替换不全。

5.zend_copy 只拷贝value和u1,没有拷贝u2

#define ZVAL_COPY(z, v)									\
	do {												\
		zval *_z1 = (z);								\
		const zval *_z2 = (v);							\
		zend_refcounted *_gc = Z_COUNTED_P(_z2);		\
		uint32_t _t = Z_TYPE_INFO_P(_z2);				\
		ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);			\
		if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \
			GC_REFCOUNT(_gc)++;							\
		}												\
	} while (0)

zend_string_copy 只是对refcount++

static zend_always_inline zend_string *zend_string_copy(zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		GC_REFCOUNT(s)++;
	}
	return s;
}

6.笔记地址

http://replay.xesv5.com/ll/2480/8e1b791bb452497dab0e2c39e4791038.flv.mp4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值