/src/php-src/Zend/zend_variables.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 | | | Dmitry Stogov <dmitry@php.net> | |
18 | | +----------------------------------------------------------------------+ |
19 | | */ |
20 | | |
21 | | #include <stdio.h> |
22 | | #include "zend.h" |
23 | | #include "zend_API.h" |
24 | | #include "zend_ast.h" |
25 | | #include "zend_globals.h" |
26 | | #include "zend_constants.h" |
27 | | #include "zend_list.h" |
28 | | |
29 | | #if ZEND_DEBUG |
30 | | static void ZEND_FASTCALL zend_string_destroy(zend_string *str); |
31 | | #else |
32 | | # define zend_string_destroy _efree |
33 | | #endif |
34 | | static void ZEND_FASTCALL zend_reference_destroy(zend_reference *ref); |
35 | | static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref); |
36 | | |
37 | | typedef void (ZEND_FASTCALL *zend_rc_dtor_func_t)(zend_refcounted *p); |
38 | | |
39 | | static const zend_rc_dtor_func_t zend_rc_dtor_func[] = { |
40 | | [IS_UNDEF] = (zend_rc_dtor_func_t)zend_empty_destroy, |
41 | | [IS_NULL] = (zend_rc_dtor_func_t)zend_empty_destroy, |
42 | | [IS_FALSE] = (zend_rc_dtor_func_t)zend_empty_destroy, |
43 | | [IS_TRUE] = (zend_rc_dtor_func_t)zend_empty_destroy, |
44 | | [IS_LONG] = (zend_rc_dtor_func_t)zend_empty_destroy, |
45 | | [IS_DOUBLE] = (zend_rc_dtor_func_t)zend_empty_destroy, |
46 | | [IS_STRING] = (zend_rc_dtor_func_t)zend_string_destroy, |
47 | | [IS_ARRAY] = (zend_rc_dtor_func_t)zend_array_destroy, |
48 | | [IS_OBJECT] = (zend_rc_dtor_func_t)zend_objects_store_del, |
49 | | [IS_RESOURCE] = (zend_rc_dtor_func_t)zend_list_free, |
50 | | [IS_REFERENCE] = (zend_rc_dtor_func_t)zend_reference_destroy, |
51 | | [IS_CONSTANT_AST] = (zend_rc_dtor_func_t)zend_ast_ref_destroy |
52 | | }; |
53 | | |
54 | | ZEND_API void ZEND_FASTCALL rc_dtor_func(zend_refcounted *p) |
55 | 22.4M | { |
56 | 22.4M | ZEND_ASSERT(GC_TYPE(p) <= IS_CONSTANT_AST); |
57 | 22.4M | zend_rc_dtor_func[GC_TYPE(p)](p); |
58 | 22.4M | } |
59 | | |
60 | | #if ZEND_DEBUG |
61 | | static void ZEND_FASTCALL zend_string_destroy(zend_string *str) |
62 | 9.77M | { |
63 | 9.77M | CHECK_ZVAL_STRING(str); |
64 | 9.77M | ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); |
65 | 9.77M | ZEND_ASSERT(GC_REFCOUNT(str) == 0); |
66 | 9.77M | ZEND_ASSERT(!(GC_FLAGS(str) & IS_STR_PERSISTENT)); |
67 | 9.77M | efree(str); |
68 | 9.77M | } |
69 | | #endif |
70 | | |
71 | | static void ZEND_FASTCALL zend_reference_destroy(zend_reference *ref) |
72 | 36.6k | { |
73 | 36.6k | ZEND_ASSERT(!ZEND_REF_HAS_TYPE_SOURCES(ref)); |
74 | 36.6k | i_zval_ptr_dtor(&ref->val); |
75 | 36.6k | efree_size(ref, sizeof(zend_reference)); |
76 | 36.6k | } |
77 | | |
78 | | static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref) |
79 | 44.9k | { |
80 | 44.9k | } |
81 | | |
82 | | ZEND_API void zval_ptr_dtor(zval *zval_ptr) /* {{{ */ |
83 | 11.1M | { |
84 | 11.1M | i_zval_ptr_dtor(zval_ptr); |
85 | 11.1M | } |
86 | | /* }}} */ |
87 | | |
88 | | ZEND_API void zval_ptr_safe_dtor(zval *zval_ptr) |
89 | 3.87M | { |
90 | 3.87M | if (Z_REFCOUNTED_P(zval_ptr)) { |
91 | 201 | zend_refcounted *ref = Z_COUNTED_P(zval_ptr); |
92 | | |
93 | 201 | if (GC_DELREF(ref) == 0) { |
94 | 179 | ZVAL_NULL(zval_ptr); |
95 | 179 | rc_dtor_func(ref); |
96 | 179 | } else { |
97 | 22 | gc_check_possible_root(ref); |
98 | 22 | } |
99 | 201 | } |
100 | 3.87M | } |
101 | | |
102 | | ZEND_API void zval_internal_ptr_dtor(zval *zval_ptr) /* {{{ */ |
103 | 0 | { |
104 | 0 | if (Z_REFCOUNTED_P(zval_ptr)) { |
105 | 0 | zend_refcounted *ref = Z_COUNTED_P(zval_ptr); |
106 | |
|
107 | 0 | if (GC_DELREF(ref) == 0) { |
108 | 0 | if (Z_TYPE_P(zval_ptr) == IS_STRING) { |
109 | 0 | zend_string *str = (zend_string*)ref; |
110 | |
|
111 | 0 | CHECK_ZVAL_STRING(str); |
112 | 0 | ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); |
113 | 0 | ZEND_ASSERT((GC_FLAGS(str) & IS_STR_PERSISTENT)); |
114 | 0 | free(str); |
115 | 0 | } else { |
116 | 0 | zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects, resources or reference"); |
117 | 0 | } |
118 | 0 | } |
119 | 0 | } |
120 | 0 | } |
121 | | /* }}} */ |
122 | | |
123 | | /* This function should only be used as a copy constructor, i.e. it |
124 | | * should only be called AFTER a zval has been copied to another |
125 | | * location using ZVAL_COPY_VALUE. Do not call it before copying, |
126 | | * otherwise a reference may be leaked. */ |
127 | | ZEND_API void zval_add_ref(zval *p) |
128 | 77.5k | { |
129 | 77.5k | if (Z_REFCOUNTED_P(p)) { |
130 | 63.6k | if (Z_ISREF_P(p) && Z_REFCOUNT_P(p) == 1) { |
131 | 80 | ZVAL_COPY(p, Z_REFVAL_P(p)); |
132 | 63.5k | } else { |
133 | 63.5k | Z_ADDREF_P(p); |
134 | 63.5k | } |
135 | 63.6k | } |
136 | 77.5k | } |
137 | | |
138 | | ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue) |
139 | 128 | { |
140 | 128 | if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) { |
141 | 0 | ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue))); |
142 | 128 | } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) { |
143 | 128 | ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue))); |
144 | 128 | CHECK_ZVAL_STRING(Z_STR_P(zvalue)); |
145 | 128 | ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0)); |
146 | 128 | } else { |
147 | 0 | ZEND_UNREACHABLE(); |
148 | 0 | } |
149 | 128 | } |