1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2016 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 +----------------------------------------------------------------------+
18 */
19
20 /* $Id$ */
21
22 #include <stdio.h>
23 #include "zend.h"
24 #include "zend_API.h"
25 #include "zend_ast.h"
26 #include "zend_globals.h"
27 #include "zend_constants.h"
28 #include "zend_list.h"
29
30
_zval_dtor_func(zval * zvalue ZEND_FILE_LINE_DC)31 ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
32 {
33 switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
34 case IS_STRING:
35 case IS_CONSTANT:
36 CHECK_ZVAL_STRING_REL(zvalue);
37 str_efree_rel(zvalue->value.str.val);
38 break;
39 case IS_ARRAY: {
40 TSRMLS_FETCH();
41
42 if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
43 /* break possible cycles */
44 Z_TYPE_P(zvalue) = IS_NULL;
45 zend_hash_destroy(zvalue->value.ht);
46 FREE_HASHTABLE(zvalue->value.ht);
47 }
48 }
49 break;
50 case IS_CONSTANT_AST:
51 zend_ast_destroy(Z_AST_P(zvalue));
52 break;
53 case IS_OBJECT:
54 {
55 TSRMLS_FETCH();
56
57 Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
58 }
59 break;
60 case IS_RESOURCE:
61 {
62 TSRMLS_FETCH();
63
64 /* destroy resource */
65 zend_list_delete(zvalue->value.lval);
66 }
67 break;
68 case IS_LONG:
69 case IS_DOUBLE:
70 case IS_BOOL:
71 case IS_NULL:
72 default:
73 return;
74 break;
75 }
76 }
77
78
_zval_internal_dtor(zval * zvalue ZEND_FILE_LINE_DC)79 ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
80 {
81 switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
82 case IS_STRING:
83 case IS_CONSTANT:
84 CHECK_ZVAL_STRING_REL(zvalue);
85 str_free(zvalue->value.str.val);
86 break;
87 case IS_ARRAY:
88 case IS_CONSTANT_AST:
89 case IS_OBJECT:
90 case IS_RESOURCE:
91 zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
92 break;
93 case IS_LONG:
94 case IS_DOUBLE:
95 case IS_BOOL:
96 case IS_NULL:
97 default:
98 break;
99 }
100 }
101
102
zval_add_ref(zval ** p)103 ZEND_API void zval_add_ref(zval **p)
104 {
105 Z_ADDREF_PP(p);
106 }
107
108
_zval_copy_ctor_func(zval * zvalue ZEND_FILE_LINE_DC)109 ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
110 {
111 switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
112 case IS_RESOURCE: {
113 TSRMLS_FETCH();
114
115 zend_list_addref(zvalue->value.lval);
116 }
117 break;
118 case IS_BOOL:
119 case IS_LONG:
120 case IS_NULL:
121 break;
122 case IS_CONSTANT:
123 case IS_STRING:
124 CHECK_ZVAL_STRING_REL(zvalue);
125 if (!IS_INTERNED(zvalue->value.str.val)) {
126 zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
127 }
128 break;
129 case IS_ARRAY: {
130 zval *tmp;
131 HashTable *original_ht = zvalue->value.ht;
132 HashTable *tmp_ht = NULL;
133 TSRMLS_FETCH();
134
135 if (zvalue->value.ht == &EG(symbol_table)) {
136 return; /* do nothing */
137 }
138 ALLOC_HASHTABLE_REL(tmp_ht);
139 zend_hash_init(tmp_ht, zend_hash_num_elements(original_ht), NULL, ZVAL_PTR_DTOR, 0);
140 zvalue->value.ht = tmp_ht;
141 zend_hash_copy(tmp_ht, original_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
142 tmp_ht->nNextFreeElement = original_ht->nNextFreeElement;
143 }
144 break;
145 case IS_CONSTANT_AST:
146 Z_AST_P(zvalue) = zend_ast_copy(Z_AST_P(zvalue));
147 break;
148 case IS_OBJECT:
149 {
150 TSRMLS_FETCH();
151 Z_OBJ_HT_P(zvalue)->add_ref(zvalue TSRMLS_CC);
152 }
153 break;
154 }
155 }
156
157
zend_print_variable(zval * var)158 ZEND_API int zend_print_variable(zval *var)
159 {
160 return zend_print_zval(var, 0);
161 }
162
163
_zval_dtor_wrapper(zval * zvalue)164 ZEND_API void _zval_dtor_wrapper(zval *zvalue)
165 {
166 TSRMLS_FETCH();
167
168 GC_REMOVE_ZVAL_FROM_BUFFER(zvalue);
169 zval_dtor(zvalue);
170 }
171
172
173 #if ZEND_DEBUG
_zval_copy_ctor_wrapper(zval * zvalue)174 ZEND_API void _zval_copy_ctor_wrapper(zval *zvalue)
175 {
176 zval_copy_ctor(zvalue);
177 }
178
179
_zval_internal_dtor_wrapper(zval * zvalue)180 ZEND_API void _zval_internal_dtor_wrapper(zval *zvalue)
181 {
182 zval_internal_dtor(zvalue);
183 }
184
185
_zval_ptr_dtor_wrapper(zval ** zval_ptr)186 ZEND_API void _zval_ptr_dtor_wrapper(zval **zval_ptr)
187 {
188 zval_ptr_dtor(zval_ptr);
189 }
190
191
_zval_internal_ptr_dtor_wrapper(zval ** zval_ptr)192 ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zval_ptr)
193 {
194 zval_internal_ptr_dtor(zval_ptr);
195 }
196 #endif
197
zval_copy_static_var(zval ** p TSRMLS_DC,int num_args,va_list args,zend_hash_key * key)198 ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
199 {
200 HashTable *target = va_arg(args, HashTable*);
201 zend_bool is_ref;
202 zval *tmp;
203
204 if (Z_TYPE_PP(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) {
205 is_ref = Z_TYPE_PP(p) & IS_LEXICAL_REF;
206
207 if (!EG(active_symbol_table)) {
208 zend_rebuild_symbol_table(TSRMLS_C);
209 }
210 if (zend_hash_quick_find(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, (void **) &p) == FAILURE) {
211 if (is_ref) {
212 ALLOC_INIT_ZVAL(tmp);
213 Z_SET_ISREF_P(tmp);
214 zend_hash_quick_add(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), (void**)&p);
215 } else {
216 tmp = EG(uninitialized_zval_ptr);
217 zend_error(E_NOTICE,"Undefined variable: %s", key->arKey);
218 }
219 } else {
220 if (is_ref) {
221 SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
222 tmp = *p;
223 } else if (Z_ISREF_PP(p)) {
224 ALLOC_INIT_ZVAL(tmp);
225 ZVAL_COPY_VALUE(tmp, *p);
226 zval_copy_ctor(tmp);
227 Z_SET_REFCOUNT_P(tmp, 0);
228 Z_UNSET_ISREF_P(tmp);
229 } else {
230 tmp = *p;
231 }
232 }
233 } else {
234 tmp = *p;
235 }
236 if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), NULL) == SUCCESS) {
237 Z_ADDREF_P(tmp);
238 }
239 return ZEND_HASH_APPLY_KEEP;
240 }
241 /* }}} */
242
243 /*
244 * Local variables:
245 * tab-width: 4
246 * c-basic-offset: 4
247 * indent-tabs-mode: t
248 * End:
249 */
250