php zend引擎解析原理,PHP内核分析-Zend引擎-栈结构及操作

Zend引擎对栈常量的定义:

#define ZEND_STACK_APPLY_TOPDOWN 1//由顶部向底部对栈进行遍历操作

#define ZEND_STACK_APPLY_BOTTOMUP 2//由底部向顶部对栈进行遍历操作

#define STACK_BLOCK_SIZE 64 //每次扩容的元素个数

看一下Zend引擎栈的数据结构定义:

typedef struct _zend_stack {

int top;//栈顶,用数字表示(从底到顶分别为0,1,2...)

int max;//栈当前最大元素个数,当栈满后会将max+STACK_BLOCK_SZE来进行扩容

void **elements;//栈元素指针数组

} zend_stack;

栈的常用操作如下:

//初始化栈,不包含zend_stack结构的内存分配。仅初始化top, max的值和elements的值。

ZEND_API int zend_stack_init(zend_stack *stack)

{

stack->top = 0;

stack->max = 0;

stack->elements = NULL;

return SUCCESS;

}

//以memcpy的方式将element元素复制入栈。size表示元素的大小。

ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size)

{

if (stack->top >= stack->max) { /* we need to allocate more memory */

stack->elements = (void **) erealloc(stack->elements,

(sizeof(void **) * (stack->max += STACK_BLOCK_SIZE)));

//当栈满后会将max+STACK_BLOCK_SZE来进行扩容

if (!stack->elements) {

return FAILURE;

}

}

stack->elements[stack->top] = (void *) emalloc(size);

memcpy(stack->elements[stack->top], element, size);

return stack->top++;

}

//获取栈顶部元素的指针,并赋值给**element

ZEND_API int zend_stack_top(const zend_stack *stack, void **element)

{

if (stack->top > 0) {

*element = stack->elements[stack->top - 1];

return SUCCESS;

} else {

*element = NULL;

return FAILURE;

}

}

//删除栈顶。

ZEND_API int zend_stack_del_top(zend_stack *stack)

{

if (stack->top > 0) {

efree(stack->elements[--stack->top]);

}

return SUCCESS;

}

//返回栈顶元素的指针的值

ZEND_API int zend_stack_int_top(const zend_stack *stack)

{

int *e;

if (zend_stack_top(stack, (void **) &e) == FAILURE) {

return FAILURE; /* this must be a negative number, since negative numbers can't be address numbers */

} else {

return *e;

}

}

//根据stack->top的值来判断栈是否为空.stack->top用数字来表示的好处。

ZEND_API int zend_stack_is_empty(const zend_stack *stack)

{

if (stack->top == 0) {

return 1;

} else {

return 0;

}

}

//销毁栈。其实也可以while(stack->top--){zend_stack_del_top(stack)};stack->elements = NULL;

ZEND_API int zend_stack_destroy(zend_stack *stack)

{

int i;

if (stack->elements) {

for (i = 0; i < stack->top; i++) {

efree(stack->elements[i]);

}

efree(stack->elements);

stack->elements = NULL;

}

return SUCCESS;

}

//直接返回栈数据元素指针

ZEND_API void **zend_stack_base(const zend_stack *stack)

{

return stack->elements;

}

//返回栈元素个数。这就是用数字来表示栈顶而不直接用指针来表示的好处。

ZEND_API int zend_stack_count(const zend_stack *stack)

{

return stack->top;

}

//遍历栈并执行函数。注意,传入的函数返回值为int型。为0时表示函数执行成功,为1时表示函数执行失败。

ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element))

{

int i;

switch (type) {

//自顶向下执行

case ZEND_STACK_APPLY_TOPDOWN:

for (i=stack->top-1; i>=0; i--) {

if (apply_function(stack->elements[i])) {

break;

}

}

break;

//自底向上执行

case ZEND_STACK_APPLY_BOTTOMUP:

for (i=0; itop; i++) {

if (apply_function(stack->elements[i])) {

break;

}

}

break;

}

}

//与zend_stack_apply函数一样,都是遍历栈并执行函数。但此函数支持调用函数传递参数。

ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg)

{

int i;

switch (type) {

case ZEND_STACK_APPLY_TOPDOWN:

for (i=stack->top-1; i>=0; i--) {

if (apply_function(stack->elements[i], arg)) {

break;

}

}

break;

case ZEND_STACK_APPLY_BOTTOMUP:

for (i=0; itop; i++) {

if (apply_function(stack->elements[i], arg)) {

break;

}

}

break;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值