Coverage Report

Created: 2025-12-31 07:28

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