Coverage Report

Created: 2025-06-13 06:43

/src/php-src/Zend/zend_stack.c
Line
Count
Source (jump to first uncovered line)
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
22.0M
#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
3.44M
{
27
3.44M
  stack->size = size;
28
3.44M
  stack->top = 0;
29
3.44M
  stack->max = 0;
30
3.44M
  stack->elements = NULL;
31
3.44M
}
32
33
ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
34
14.2M
{
35
  /* We need to allocate more memory */
36
14.2M
  if (stack->top >= stack->max) {
37
1.00M
    stack->max += STACK_BLOCK_SIZE;
38
1.00M
    stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0);
39
1.00M
  }
40
14.2M
  memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size);
41
14.2M
  return stack->top++;
42
14.2M
}
43
44
45
ZEND_API void *zend_stack_top(const zend_stack *stack)
46
7.86M
{
47
7.86M
  if (stack->top > 0) {
48
7.85M
    return ZEND_STACK_ELEMENT(stack, stack->top - 1);
49
7.85M
  } else {
50
4.42k
    return NULL;
51
4.42k
  }
52
7.86M
}
53
54
55
ZEND_API void zend_stack_del_top(zend_stack *stack)
56
6.16M
{
57
6.16M
  --stack->top;
58
6.16M
}
59
60
61
ZEND_API int zend_stack_int_top(const zend_stack *stack)
62
30
{
63
30
  int *e = zend_stack_top(stack);
64
30
  if (e) {
65
30
    return *e;
66
30
  } else {
67
0
    return FAILURE;
68
0
  }
69
30
}
70
71
72
ZEND_API bool zend_stack_is_empty(const zend_stack *stack)
73
2.40M
{
74
2.40M
  return stack->top == 0;
75
2.40M
}
76
77
78
ZEND_API void zend_stack_destroy(zend_stack *stack)
79
3.43M
{
80
3.43M
  if (stack->elements) {
81
659k
    efree(stack->elements);
82
659k
    stack->elements = NULL;
83
659k
  }
84
3.43M
}
85
86
87
ZEND_API void *zend_stack_base(const zend_stack *stack)
88
656k
{
89
656k
  return stack->elements;
90
656k
}
91
92
93
ZEND_API int zend_stack_count(const zend_stack *stack)
94
13.8M
{
95
13.8M
  return stack->top;
96
13.8M
}
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
900k
{
146
900k
  int i;
147
148
900k
  if (func) {
149
602k
    for (i = 0; i < stack->top; i++) {
150
1.63k
      func(ZEND_STACK_ELEMENT(stack, i));
151
1.63k
    }
152
600k
  }
153
900k
  if (free_elements) {
154
900k
    if (stack->elements) {
155
2.31k
      efree(stack->elements);
156
2.31k
      stack->elements = NULL;
157
2.31k
    }
158
900k
    stack->top = stack->max = 0;
159
900k
  }
160
900k
}