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;

}

}

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

  1. java fixflow流程设计_Fixflow引擎解析(一)(介绍) - Fixflow开源流程引擎介绍

    简介 Fixflow是一款开源的基于BPMN2.0标准的工作流引擎,由Fixflow开源联盟组织(Fixflow OpenSource Union) 进行社区化管理,引擎底层直接支持BPMN2.0国际 ...

  2. jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + div.aaron input[type="checkb ...

  3. linux操作系统原理_Linux内核分析-操作系统是如何工作的(二)

    linux操作系统的主要构架如图1所示,我们知道,操作系统是通过管理CPU进程.存储器.文件系统.设备驱动.以及网络接口等相关部分来工作的,我们这里主要是通过分析关于CPU的操作即进程的管理执行来分析 ...

  4. Java模板引擎解析原理_关于前后端分离与模板引擎

    随着不同终端(Pad/Mobile/PC)的兴起,对开发人员的要求越来越高,纯浏览器端的响应式已经不能满足用户体验的高要求,往往需要针对不同的终端开发定制的版本,为了提升开发效率,前后端分离的需要越来 ...

  5. ClickHouse内核分析-MergeTree的存储结构和查询加速

    注:以下分析基于开源 v19.15.2.2-stable 版本进行 引言 ClickHouse是最近比较火的一款开源列式存储分析型数据库,它最核心的特点就是极致存储压缩率和查询性能,本人最近正在学习C ...

  6. Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  7. 花式模拟【栈结构】做“日志分析”(洛谷P1165题题解,Java语言描述)

    题目要求 P1165题目链接 分析 标准的栈结构,但使用数组来模拟会更简单. 因为对于这个问题,其实数组不需要存储真实数值,只考虑当前最大值就行了. 毕竟,出栈也不需要返回当前真实值. 另外,我们只使 ...

  8. JavaScript引擎工作原理解析

    JavaScript引擎是什么 想知道JavaScript引擎是什么,首先要知道JavaScript(简称js)是什么,相信对于屏幕前的你来说,js是干什么的已经不用再多说,但还是有必要介绍下Java ...

  9. 庖丁解牛Linux内核分析01:操作系统工作原理基础

    目录 1 存储程序计算机工作模型 2 IA-32汇编基础 2.1 寄存器概述 2.1.1 通用寄存器 2.1.2 段寄存器 2.1.3 标志寄存器 2.2 数据格式 2.3 寻址方式 2.3.1 立即 ...

  10. 《Linux内核分析》(二)——从一个简单Linux内核分析进程切换原理

    转载:https://blog.csdn.net/FIELDOFFIER/article/details/44280717 <Linux内核分析>MOOC课程http://mooc.stu ...

最新文章

  1. [Gitlab]使用Webhook实现前端项目自动发布
  2. java代码程序_Java程序代码
  3. python可变参数_Python 的四种共享传参详解
  4. gis里创建要素面板怎么打开_gis、mike学习
  5. 前端学习(807):简单数据类型传参
  6. 4、Kafka常见问题
  7. Spring Boot 快速集成第三方登录功能
  8. SAP 查询分析器的实现的3种方法
  9. 交直流配电网潮流计算matlab,干货丨交直流混合配电网潮流计算(含分布式电源)...
  10. 聊聊 Xcode 编译 ToolChain
  11. Java第七周心得体会
  12. 区块链通证经济的核心不在技术,而在于商业逻辑的重构
  13. java获取法定节假日_java 获取n个工作日后的日期(包含法定节假日、双休日、节后补班)...
  14. 防止刷新或后退页面重复提交表单
  15. 购买新款macbook pro,现在买还是等双十一?
  16. DDR4时序标准规范(二)
  17. android ftdi,从 Android FTDI串行通信开始_ftdi_开发99编程知识库
  18. syntax error, unexpected ‘array‘ (T_ARRAY)
  19. 基于Python的基金数据汇总分析
  20. 汇编指令: JO、JNO、JB...

热门文章

  1. CSS 文本超过部分显示省略号,解决数字或英文不换行问题
  2. html内容太大超过盒子范围,HTML内容超过div宽度不能自动换行解决方法
  3. 麻烦大家给点C#的小程序的练习题做做,小女子谢谢了.......
  4. 数据库设计之概念结构设计
  5. 联想服务器CPU系列,联想推出采用第三代英特尔至强处理器的ThinkSystem SR860 V2服务器...
  6. 计算机组成原理:中央处理器(2)
  7. 以太坊之dapp例子
  8. Android实现录音功能及播放语音功能
  9. 50道C/C++编程练习题 复习必备(1-10)
  10. 在大学学什么? 学思维方法!什么是知识结构化?