Coverage Report

Created: 2025-11-16 06:23

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
30.3M
#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
2.96M
{
27
2.96M
  stack->size = size;
28
2.96M
  stack->top = 0;
29
2.96M
  stack->max = 0;
30
2.96M
  stack->elements = NULL;
31
2.96M
}
32
33
ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
34
21.2M
{
35
  /* We need to allocate more memory */
36
21.2M
  if (stack->top >= stack->max) {
37
1.25M
    stack->max += STACK_BLOCK_SIZE;
38
1.25M
    stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0);
39
1.25M
  }
40
21.2M
  memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size);
41
21.2M
  return stack->top++;
42
21.2M
}
43
44
45
ZEND_API void *zend_stack_top(const zend_stack *stack)
46
9.11M
{
47
9.11M
  if (stack->top > 0) {
48
9.11M
    return ZEND_STACK_ELEMENT(stack, stack->top - 1);
49
9.11M
  } else {
50
3.95k
    return NULL;
51
3.95k
  }
52
9.11M
}
53
54
55
ZEND_API void zend_stack_del_top(zend_stack *stack)
56
8.66M
{
57
8.66M
  --stack->top;
58
8.66M
}
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
2.10M
{
74
2.10M
  return stack->top == 0;
75
2.10M
}
76
77
78
ZEND_API void zend_stack_destroy(zend_stack *stack)
79
2.95M
{
80
2.95M
  if (stack->elements) {
81
657k
    efree(stack->elements);
82
657k
    stack->elements = NULL;
83
657k
  }
84
2.95M
}
85
86
87
ZEND_API void *zend_stack_base(const zend_stack *stack)
88
531k
{
89
531k
  return stack->elements;
90
531k
}
91
92
93
ZEND_API int zend_stack_count(const zend_stack *stack)
94
77.3M
{
95
77.3M
  return stack->top;
96
77.3M
}
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
743k
{
146
743k
  int i;
147
148
743k
  if (func) {
149
495k
    for (i = 0; i < stack->top; i++) {
150
146
      func(ZEND_STACK_ELEMENT(stack, i));
151
146
    }
152
495k
  }
153
743k
  if (free_elements) {
154
743k
    if (stack->elements) {
155
87
      efree(stack->elements);
156
      stack->elements = NULL;
157
87
    }
158
743k
    stack->top = stack->max = 0;
159
743k
  }
160
743k
}