Coverage Report

Created: 2026-06-02 06:37

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 © Zend Technologies Ltd., a subsidiary company of          |
6
   |     Perforce Software, Inc., and Contributors.                       |
7
   +----------------------------------------------------------------------+
8
   | This source file is subject to the Modified BSD License that is      |
9
   | bundled with this package in the file LICENSE, and is available      |
10
   | through the World Wide Web at <https://www.php.net/license/>.        |
11
   |                                                                      |
12
   | SPDX-License-Identifier: BSD-3-Clause                                |
13
   +----------------------------------------------------------------------+
14
   | Authors: Andi Gutmans <andi@php.net>                                 |
15
   |          Zeev Suraski <zeev@php.net>                                 |
16
   +----------------------------------------------------------------------+
17
*/
18
19
#include "zend.h"
20
#include "zend_stack.h"
21
22
0
#define ZEND_STACK_ELEMENT(stack, n) ((void *)((char *) (stack)->elements + (stack)->size * (n)))
23
24
ZEND_API void zend_stack_init(zend_stack *stack, int size)
25
350k
{
26
350k
  stack->size = size;
27
350k
  stack->top = 0;
28
350k
  stack->max = 0;
29
350k
  stack->elements = NULL;
30
350k
}
31
32
ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
33
0
{
34
  /* We need to allocate more memory */
35
0
  if (stack->top >= stack->max) {
36
0
    stack->max += STACK_BLOCK_SIZE;
37
0
    stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0);
38
0
  }
39
0
  memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size);
40
0
  return stack->top++;
41
0
}
42
43
44
ZEND_API void *zend_stack_top(const zend_stack *stack)
45
0
{
46
0
  if (stack->top > 0) {
47
0
    return ZEND_STACK_ELEMENT(stack, stack->top - 1);
48
0
  } else {
49
0
    return NULL;
50
0
  }
51
0
}
52
53
54
ZEND_API void zend_stack_del_top(zend_stack *stack)
55
0
{
56
0
  --stack->top;
57
0
}
58
59
60
ZEND_API int zend_stack_int_top(const zend_stack *stack)
61
0
{
62
0
  int *e = zend_stack_top(stack);
63
0
  if (e) {
64
0
    return *e;
65
0
  } else {
66
0
    return FAILURE;
67
0
  }
68
0
}
69
70
71
ZEND_API bool zend_stack_is_empty(const zend_stack *stack)
72
0
{
73
0
  return stack->top == 0;
74
0
}
75
76
77
ZEND_API void zend_stack_destroy(zend_stack *stack)
78
350k
{
79
350k
  if (stack->elements) {
80
0
    efree(stack->elements);
81
0
    stack->elements = NULL;
82
0
  }
83
350k
}
84
85
86
ZEND_API void *zend_stack_base(const zend_stack *stack)
87
0
{
88
0
  return stack->elements;
89
0
}
90
91
92
ZEND_API int zend_stack_count(const zend_stack *stack)
93
0
{
94
0
  return stack->top;
95
0
}
96
97
98
ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element))
99
0
{
100
0
  int i;
101
102
0
  switch (type) {
103
0
    case ZEND_STACK_APPLY_TOPDOWN:
104
0
      for (i=stack->top-1; i>=0; i--) {
105
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
106
0
          break;
107
0
        }
108
0
      }
109
0
      break;
110
0
    case ZEND_STACK_APPLY_BOTTOMUP:
111
0
      for (i=0; i<stack->top; i++) {
112
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
113
0
          break;
114
0
        }
115
0
      }
116
0
      break;
117
0
  }
118
0
}
119
120
121
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)
122
0
{
123
0
  int i;
124
125
0
  switch (type) {
126
0
    case ZEND_STACK_APPLY_TOPDOWN:
127
0
      for (i=stack->top-1; i>=0; i--) {
128
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
129
0
          break;
130
0
        }
131
0
      }
132
0
      break;
133
0
    case ZEND_STACK_APPLY_BOTTOMUP:
134
0
      for (i=0; i<stack->top; i++) {
135
0
        if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
136
0
          break;
137
0
        }
138
0
      }
139
0
      break;
140
0
  }
141
0
}
142
143
ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), bool free_elements)
144
116k
{
145
116k
  int i;
146
147
116k
  if (func) {
148
77.7k
    for (i = 0; i < stack->top; i++) {
149
0
      func(ZEND_STACK_ELEMENT(stack, i));
150
0
    }
151
77.7k
  }
152
116k
  if (free_elements) {
153
116k
    if (stack->elements) {
154
0
      efree(stack->elements);
155
      stack->elements = NULL;
156
0
    }
157
116k
    stack->top = stack->max = 0;
158
116k
  }
159
116k
}