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