xref: /PHP-7.1/Zend/zend_variables.c (revision ccd4716e)
1 /*
2    +----------------------------------------------------------------------+
3    | Zend Engine                                                          |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1998-2018 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@zend.com>                                |
16    |          Zeev Suraski <zeev@zend.com>                                |
17    |          Dmitry Stogov <dmitry@zend.com>                             |
18    +----------------------------------------------------------------------+
19 */
20 
21 /* $Id$ */
22 
23 #include <stdio.h>
24 #include "zend.h"
25 #include "zend_API.h"
26 #include "zend_ast.h"
27 #include "zend_globals.h"
28 #include "zend_constants.h"
29 #include "zend_list.h"
30 
_zval_dtor_func(zend_refcounted * p ZEND_FILE_LINE_DC)31 ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
32 {
33 	switch (GC_TYPE(p)) {
34 		case IS_STRING:
35 		case IS_CONSTANT: {
36 				zend_string *str = (zend_string*)p;
37 				CHECK_ZVAL_STRING_REL(str);
38 				zend_string_free(str);
39 				break;
40 			}
41 		case IS_ARRAY: {
42 				zend_array *arr = (zend_array*)p;
43 				zend_array_destroy(arr);
44 				break;
45 			}
46 		case IS_CONSTANT_AST: {
47 				zend_ast_ref *ast = (zend_ast_ref*)p;
48 
49 				zend_ast_destroy_and_free(ast->ast);
50 				efree_size(ast, sizeof(zend_ast_ref));
51 				break;
52 			}
53 		case IS_OBJECT: {
54 				zend_object *obj = (zend_object*)p;
55 
56 				zend_objects_store_del(obj);
57 				break;
58 			}
59 		case IS_RESOURCE: {
60 				zend_resource *res = (zend_resource*)p;
61 
62 				/* destroy resource */
63 				zend_list_free(res);
64 				break;
65 			}
66 		case IS_REFERENCE: {
67 				zend_reference *ref = (zend_reference*)p;
68 
69 				i_zval_ptr_dtor(&ref->val ZEND_FILE_LINE_RELAY_CC);
70 				efree_size(ref, sizeof(zend_reference));
71 				break;
72 			}
73 		default:
74 			break;
75 	}
76 }
77 
_zval_internal_dtor(zval * zvalue ZEND_FILE_LINE_DC)78 ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
79 {
80 	switch (Z_TYPE_P(zvalue)) {
81 		case IS_STRING:
82 		case IS_CONSTANT:
83 			CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
84 			zend_string_release(Z_STR_P(zvalue));
85 			break;
86 		case IS_ARRAY:
87 		case IS_CONSTANT_AST:
88 		case IS_OBJECT:
89 		case IS_RESOURCE:
90 			zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
91 			break;
92 		case IS_REFERENCE: {
93 				zend_reference *ref = (zend_reference*)Z_REF_P(zvalue);
94 
95 				zval_internal_ptr_dtor(&ref->val);
96 				free(ref);
97 				break;
98 			}
99 		case IS_LONG:
100 		case IS_DOUBLE:
101 		case IS_FALSE:
102 		case IS_TRUE:
103 		case IS_NULL:
104 		default:
105 			break;
106 	}
107 }
108 
_zval_internal_dtor_for_ptr(zval * zvalue ZEND_FILE_LINE_DC)109 ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC)
110 {
111 	switch (Z_TYPE_P(zvalue)) {
112 		case IS_STRING:
113 		case IS_CONSTANT:
114 			CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
115 			zend_string_free(Z_STR_P(zvalue));
116 			break;
117 		case IS_ARRAY:
118 		case IS_CONSTANT_AST:
119 		case IS_OBJECT:
120 		case IS_RESOURCE:
121 			zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
122 			break;
123 		case IS_REFERENCE: {
124 				zend_reference *ref = (zend_reference*)Z_REF_P(zvalue);
125 
126 				zval_internal_ptr_dtor(&ref->val);
127 				free(ref);
128 				break;
129 			}
130 		case IS_LONG:
131 		case IS_DOUBLE:
132 		case IS_FALSE:
133 		case IS_TRUE:
134 		case IS_NULL:
135 		default:
136 			break;
137 	}
138 }
139 
140 /* This function should only be used as a copy constructor, i.e. it
141  * should only be called AFTER a zval has been copied to another
142  * location using ZVAL_COPY_VALUE. Do not call it before copying,
143  * otherwise a reference may be leaked. */
zval_add_ref(zval * p)144 ZEND_API void zval_add_ref(zval *p)
145 {
146 	if (Z_REFCOUNTED_P(p)) {
147 		if (Z_ISREF_P(p) && Z_REFCOUNT_P(p) == 1) {
148 			ZVAL_COPY(p, Z_REFVAL_P(p));
149 		} else {
150 			Z_ADDREF_P(p);
151 		}
152 	}
153 }
154 
zval_add_ref_unref(zval * p)155 ZEND_API void zval_add_ref_unref(zval *p)
156 {
157 	if (Z_REFCOUNTED_P(p)) {
158 		if (Z_ISREF_P(p)) {
159 			ZVAL_COPY(p, Z_REFVAL_P(p));
160 		} else {
161 			Z_ADDREF_P(p);
162 		}
163 	}
164 }
165 
_zval_copy_ctor_func(zval * zvalue ZEND_FILE_LINE_DC)166 ZEND_API void ZEND_FASTCALL _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
167 {
168 	if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) {
169 		ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue)));
170 	} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) {
171 		CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
172 		ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
173 	} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT)) {
174 		CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
175 		Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0);
176 	} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT_AST)) {
177 		zend_ast *copy = zend_ast_copy(Z_ASTVAL_P(zvalue));
178 		ZVAL_NEW_AST(zvalue, copy);
179 	}
180 }
181 
182 
zend_print_variable(zval * var)183 ZEND_API size_t zend_print_variable(zval *var)
184 {
185 	return zend_print_zval(var, 0);
186 }
187 
188 
_zval_dtor_wrapper(zval * zvalue)189 ZEND_API void _zval_dtor_wrapper(zval *zvalue)
190 {
191 	zval_dtor(zvalue);
192 }
193 
194 
195 #if ZEND_DEBUG
_zval_internal_dtor_wrapper(zval * zvalue)196 ZEND_API void _zval_internal_dtor_wrapper(zval *zvalue)
197 {
198 	zval_internal_dtor(zvalue);
199 }
200 
201 
_zval_ptr_dtor_wrapper(zval * zval_ptr)202 ZEND_API void _zval_ptr_dtor_wrapper(zval *zval_ptr)
203 {
204 
205 	i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_CC);
206 }
207 
208 
_zval_internal_ptr_dtor_wrapper(zval * zval_ptr)209 ZEND_API void _zval_internal_ptr_dtor_wrapper(zval *zval_ptr)
210 {
211 	zval_internal_ptr_dtor(zval_ptr);
212 }
213 #endif
214 
215 /*
216  * Local variables:
217  * tab-width: 4
218  * c-basic-offset: 4
219  * indent-tabs-mode: t
220  * End:
221  */
222