Coverage Report

Created: 2026-01-18 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/zend_stack.c
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine                                                          |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.00 of the Zend license,     |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.zend.com/license/2_00.txt.                                |
11
   | If you did not receive a copy of the Zend license and are unable to  |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@zend.com so we can mail you a copy immediately.              |
14
   +----------------------------------------------------------------------+
15
   | Authors: Andi Gutmans <andi@php.net>                                 |
16
   |          Zeev Suraski <zeev@php.net>                                 |
17
   +----------------------------------------------------------------------+
18
*/
19
20
#include "zend.h"
21
#include "zend_stack.h"
22
23
23.5k
#define ZEND_STACK_ELEMENT(stack, n) ((void *)((char *) (stack)->elements + (stack)->size * (n)))
24
25
ZEND_API void zend_stack_init(zend_stack *stack, int size)
26
709
{
27
709
  stack->size = size;
28
709
  stack->top = 0;
29
709
  stack->max = 0;
30
709
  stack->elements = NULL;
31
709
}
32
33
ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
34
2.53k
{
35
  /* We need to allocate more memory */
36
2.53k
  if (stack->top >= stack->max) {
37
191
    stack->max += STACK_BLOCK_SIZE;
38
191
    stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0);
39
191
  }
40
2.53k
  memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size);
41
2.53k
  return stack->top++;
42
2.53k
}
43
44
45
ZEND_API void *zend_stack_top(const zend_stack *stack)
46
21.0k
{
47
21.0k
  if (stack->top > 0) {
48
21.0k
    return ZEND_STACK_ELEMENT(stack, stack->top - 1);
49
21.0k
  } else {
50
8
    return NULL;
51
8
  }
52
21.0k
}
53
54
55
ZEND_API void zend_stack_del_top(zend_stack *stack)
56
1.92k
{
57
1.92k
  --stack->top;
58
1.92k
}
59
60
61
ZEND_API int zend_stack_int_top(const zend_stack *stack)
62
0
{
63
0
  int *e = zend_stack_top(stack);
64
0
  if (e) {
65
0
    return *e;
66
0
  } else {
67
0
    return FAILURE;
68
0
  }
69
0
}
70
71
72
ZEND_API bool zend_stack_is_empty(const zend_stack *stack)
73
1.16k
{
74
1.16k
  return stack->top == 0;
75
1.16k
}
76
77
78
ZEND_API void zend_stack_destroy(zend_stack *stack)
79
709
{
80
709
  if (stack->elements) {
81
191
    efree(stack->elements);
82
191
    stack->elements = NULL;
83
191
  }
84
709
}
85
86
87
ZEND_API void *zend_stack_base(const zend_stack *stack)
88
940
{
89
940
  return stack->elements;
90
940
}
91
92
93
ZEND_API int zend_stack_count(const zend_stack *stack)
94
35.5k
{
95
35.5k
  return stack->top;
96
35.5k
}
97
98
99
ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element))
100
0
{
101
0
  int i;
102
103
0
  switch (type) {
104
0
    case ZEND_STACK_APPLY_TOPDOWN:
105
0
      for (i=stack->top-1; i>=0; i--) {
106
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
107
0
          break;
108
0
        }
109
0
      }
110
0
      break;
111
0
    case ZEND_STACK_APPLY_BOTTOMUP:
112
0
      for (i=0; i<stack->top; i++) {
113
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
114
0
          break;
115
0
        }
116
0
      }
117
0
      break;
118
0
  }
119
0
}
120
121
122
ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, zend_stack_apply_direction type, int (*apply_function)(void *element, void *arg), void *arg)
123
0
{
124
0
  int i;
125
126
0
  switch (type) {
127
0
    case ZEND_STACK_APPLY_TOPDOWN:
128
0
      for (i=stack->top-1; i>=0; i--) {
129
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
130
0
          break;
131
0
        }
132
0
      }
133
0
      break;
134
0
    case ZEND_STACK_APPLY_BOTTOMUP:
135
0
      for (i=0; i<stack->top; i++) {
136
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
137
0
          break;
138
0
        }
139
0
      }
140
0
      break;
141
0
  }
142
0
}
143
144
ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), bool free_elements)
145
183
{
146
183
  int i;
147
148
183
  if (func) {
149
122
    for (i = 0; i < stack->top; i++) {
150
0
      func(ZEND_STACK_ELEMENT(stack, i));
151
0
    }
152
122
  }
153
183
  if (free_elements) {
154
183
    if (stack->elements) {
155
0
      efree(stack->elements);
156
      stack->elements = NULL;
157
0
    }
158
183
    stack->top = stack->max = 0;
159
183
  }
160
183
}