This source file includes following definitions.
- zend_pzval_unlock_func
- zend_pzval_unlock_free_func
- zend_get_compiled_variable_value
- _get_zval_ptr_tmp
- _get_zval_ptr_var
- _get_zval_cv_lookup
- _get_zval_cv_lookup_BP_VAR_R
- _get_zval_cv_lookup_BP_VAR_UNSET
- _get_zval_cv_lookup_BP_VAR_IS
- _get_zval_cv_lookup_BP_VAR_RW
- _get_zval_cv_lookup_BP_VAR_W
- _get_zval_ptr_cv
- _get_zval_ptr_cv_BP_VAR_R
- _get_zval_ptr_cv_BP_VAR_UNSET
- _get_zval_ptr_cv_BP_VAR_IS
- _get_zval_ptr_cv_BP_VAR_RW
- _get_zval_ptr_cv_BP_VAR_W
- _get_zval_ptr
- _get_zval_ptr_ptr_var
- _get_zval_ptr_ptr_var_fast
- _get_zval_ptr_ptr_cv
- _get_zval_ptr_ptr_cv_BP_VAR_R
- _get_zval_ptr_ptr_cv_BP_VAR_UNSET
- _get_zval_ptr_ptr_cv_BP_VAR_IS
- _get_zval_ptr_ptr_cv_BP_VAR_RW
- _get_zval_ptr_ptr_cv_BP_VAR_W
- _get_zval_ptr_ptr
- _get_obj_zval_ptr_unused
- _get_obj_zval_ptr_ptr
- _get_obj_zval_ptr_ptr_unused
- _get_obj_zval_ptr
- zend_assign_to_variable_reference
- make_real_object
- zend_verify_arg_class_kind
- zend_verify_arg_error
- is_null_constant
- zend_verify_arg_type
- zend_assign_to_object
- zend_assign_to_string_offset
- zend_assign_tmp_to_variable
- zend_assign_const_to_variable
- zend_assign_to_variable
- zval_deep_copy
- zend_extension_statement_handler
- zend_extension_fcall_begin_handler
- zend_extension_fcall_end_handler
- zend_get_target_symbol_table
- zend_fetch_dimension_address_inner
- zend_fetch_dimension_address
- zend_fetch_dimension_address_read
- zend_fetch_dimension_by_zval
- zend_fetch_property_address
- zend_check_symbol
- execute_internal
- zend_clean_and_cache_symbol_table
- i_free_compiled_variables
- zend_free_compiled_variables
- i_create_execute_data_from_op_array
- zend_create_execute_data_from_op_array
- zend_is_by_ref_func_arg_fetch
- zend_vm_stack_push_args_with_copy
- zend_vm_stack_push_args
- zend_set_user_opcode_handler
- zend_get_user_opcode_handler
- zend_get_zval_ptr
- zend_get_zval_ptr_ptr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #define ZEND_INTENSIVE_DEBUGGING 0
23
24 #include <stdio.h>
25 #include <signal.h>
26
27 #include "zend.h"
28 #include "zend_compile.h"
29 #include "zend_execute.h"
30 #include "zend_API.h"
31 #include "zend_ptr_stack.h"
32 #include "zend_constants.h"
33 #include "zend_extensions.h"
34 #include "zend_ini.h"
35 #include "zend_exceptions.h"
36 #include "zend_interfaces.h"
37 #include "zend_closures.h"
38 #include "zend_generators.h"
39 #include "zend_vm.h"
40 #include "zend_dtrace.h"
41
42
43 #include "zend_virtual_cwd.h"
44
45 #define _CONST_CODE 0
46 #define _TMP_CODE 1
47 #define _VAR_CODE 2
48 #define _UNUSED_CODE 3
49 #define _CV_CODE 4
50
51 typedef int (*incdec_t)(zval *);
52
53 #define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
54 #define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
55 #define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
56 #define get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
57
58
59 static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
60 static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
61 static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
62
63 #define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
64
65 #define EX_T(offset) (*EX_TMP_VAR(execute_data, offset))
66 #define EX_CV(var) (*EX_CV_NUM(execute_data, var))
67
68 #define TEMP_VAR_STACK_LIMIT 2000
69
70 static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free, int unref TSRMLS_DC)
71 {
72 if (!Z_DELREF_P(z)) {
73 Z_SET_REFCOUNT_P(z, 1);
74 Z_UNSET_ISREF_P(z);
75 should_free->var = z;
76
77 } else {
78 should_free->var = 0;
79 if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) {
80 Z_UNSET_ISREF_P(z);
81 }
82 }
83 }
84
85 static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
86 {
87 if (!Z_DELREF_P(z)) {
88 ZEND_ASSERT(z != &EG(uninitialized_zval));
89 GC_REMOVE_ZVAL_FROM_BUFFER(z);
90 zval_dtor(z);
91 efree(z);
92 }
93 }
94
95 #undef zval_ptr_dtor
96 #define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC)
97 #define zval_ptr_dtor_nogc(pzv) i_zval_ptr_dtor_nogc(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC)
98
99 #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC)
100 #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)
101 #define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC)
102 #define PZVAL_LOCK(z) Z_ADDREF_P((z))
103 #define SELECTIVE_PZVAL_LOCK(pzv, opline) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
104
105 #define EXTRACT_ZVAL_PTR(t) do { \
106 temp_variable *__t = (t); \
107 __t->var.ptr = *__t->var.ptr_ptr; \
108 __t->var.ptr_ptr = &__t->var.ptr; \
109 if (!PZVAL_IS_REF(__t->var.ptr) && \
110 Z_REFCOUNT_P(__t->var.ptr) > 2) { \
111 SEPARATE_ZVAL(__t->var.ptr_ptr); \
112 } \
113 } while (0)
114
115 #define AI_SET_PTR(t, val) do { \
116 temp_variable *__t = (t); \
117 __t->var.ptr = (val); \
118 __t->var.ptr_ptr = &__t->var.ptr; \
119 } while (0)
120
121 #define FREE_OP(should_free) \
122 if (should_free.var) { \
123 if ((zend_uintptr_t)should_free.var & 1L) { \
124 zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \
125 } else { \
126 zval_ptr_dtor_nogc(&should_free.var); \
127 } \
128 }
129
130 #define FREE_OP_IF_VAR(should_free) \
131 if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \
132 zval_ptr_dtor_nogc(&should_free.var); \
133 }
134
135 #define FREE_OP_VAR_PTR(should_free) \
136 if (should_free.var) { \
137 zval_ptr_dtor_nogc(&should_free.var); \
138 }
139
140 #define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L)
141
142 #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)
143
144 #define MAKE_REAL_ZVAL_PTR(val) \
145 do { \
146 zval *_tmp; \
147 ALLOC_ZVAL(_tmp); \
148 INIT_PZVAL_COPY(_tmp, (val)); \
149 (val) = _tmp; \
150 } while (0)
151
152
153
154 #define CV_DEF_OF(i) (EG(active_op_array)->vars[i])
155
156 #define CTOR_CALL_BIT 0x1
157 #define CTOR_USED_BIT 0x2
158
159 #define IS_CTOR_CALL(ce) (((zend_uintptr_t)(ce)) & CTOR_CALL_BIT)
160 #define IS_CTOR_USED(ce) (((zend_uintptr_t)(ce)) & CTOR_USED_BIT)
161
162 #define ENCODE_CTOR(ce, used) \
163 ((zend_class_entry*)(((zend_uintptr_t)(ce)) | CTOR_CALL_BIT | ((used) ? CTOR_USED_BIT : 0)))
164 #define DECODE_CTOR(ce) \
165 ((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT)))
166
167 #undef EX
168 #define EX(element) execute_data->element
169
170 ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data, zend_uint var)
171 {
172 return EX_CV(var);
173 }
174
175 static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
176 {
177 return should_free->var = &EX_T(var).tmp_var;
178 }
179
180 static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
181 {
182 zval *ptr = EX_T(var).var.ptr;
183
184 return should_free->var = ptr;
185 }
186
187 static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)
188 {
189 zend_compiled_variable *cv = &CV_DEF_OF(var);
190
191 if (!EG(active_symbol_table) ||
192 zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
193 switch (type) {
194 case BP_VAR_R:
195 case BP_VAR_UNSET:
196 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
197
198 case BP_VAR_IS:
199 return &EG(uninitialized_zval_ptr);
200 break;
201 case BP_VAR_RW:
202 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
203
204 case BP_VAR_W:
205 Z_ADDREF(EG(uninitialized_zval));
206 if (!EG(active_symbol_table)) {
207 *ptr = (zval**)EX_CV_NUM(EG(current_execute_data), EG(active_op_array)->last_var + var);
208 **ptr = &EG(uninitialized_zval);
209 } else {
210 zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
211 }
212 break;
213 }
214 }
215 return *ptr;
216 }
217
218 static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_R(zval ***ptr, zend_uint var TSRMLS_DC)
219 {
220 zend_compiled_variable *cv = &CV_DEF_OF(var);
221
222 if (!EG(active_symbol_table) ||
223 zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
224 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
225 return &EG(uninitialized_zval_ptr);
226 }
227 return *ptr;
228 }
229
230 static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_UNSET(zval ***ptr, zend_uint var TSRMLS_DC)
231 {
232 zend_compiled_variable *cv = &CV_DEF_OF(var);
233
234 if (!EG(active_symbol_table) ||
235 zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
236 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
237 return &EG(uninitialized_zval_ptr);
238 }
239 return *ptr;
240 }
241
242 static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_IS(zval ***ptr, zend_uint var TSRMLS_DC)
243 {
244 zend_compiled_variable *cv = &CV_DEF_OF(var);
245
246 if (!EG(active_symbol_table) ||
247 zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
248 return &EG(uninitialized_zval_ptr);
249 }
250 return *ptr;
251 }
252
253 static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_RW(zval ***ptr, zend_uint var TSRMLS_DC)
254 {
255 zend_compiled_variable *cv = &CV_DEF_OF(var);
256
257 if (!EG(active_symbol_table)) {
258 Z_ADDREF(EG(uninitialized_zval));
259 *ptr = (zval**)EX_CV_NUM(EG(current_execute_data), EG(active_op_array)->last_var + var);
260 **ptr = &EG(uninitialized_zval);
261 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
262 } else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
263 Z_ADDREF(EG(uninitialized_zval));
264 zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
265 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
266 }
267 return *ptr;
268 }
269
270 static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_W(zval ***ptr, zend_uint var TSRMLS_DC)
271 {
272 zend_compiled_variable *cv = &CV_DEF_OF(var);
273
274 if (!EG(active_symbol_table)) {
275 Z_ADDREF(EG(uninitialized_zval));
276 *ptr = (zval**)EX_CV_NUM(EG(current_execute_data), EG(active_op_array)->last_var + var);
277 **ptr = &EG(uninitialized_zval);
278 } else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
279 Z_ADDREF(EG(uninitialized_zval));
280 zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
281 }
282 return *ptr;
283 }
284
285 static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC)
286 {
287 zval ***ptr = EX_CV_NUM(EG(current_execute_data), var);
288
289 if (UNEXPECTED(*ptr == NULL)) {
290 return *_get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
291 }
292 return **ptr;
293 }
294
295 static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
296 {
297 zval ***ptr = EX_CV_NUM(execute_data, var);
298
299 if (UNEXPECTED(*ptr == NULL)) {
300 return *_get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
301 }
302 return **ptr;
303 }
304
305 static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
306 {
307 zval ***ptr = EX_CV_NUM(execute_data, var);
308
309 if (UNEXPECTED(*ptr == NULL)) {
310 return *_get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
311 }
312 return **ptr;
313 }
314
315 static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
316 {
317 zval ***ptr = EX_CV_NUM(execute_data, var);
318
319 if (UNEXPECTED(*ptr == NULL)) {
320 return *_get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
321 }
322 return **ptr;
323 }
324
325 static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
326 {
327 zval ***ptr = EX_CV_NUM(execute_data, var);
328
329 if (UNEXPECTED(*ptr == NULL)) {
330 return *_get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
331 }
332 return **ptr;
333 }
334
335 static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
336 {
337 zval ***ptr = EX_CV_NUM(execute_data, var);
338
339 if (UNEXPECTED(*ptr == NULL)) {
340 return *_get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
341 }
342 return **ptr;
343 }
344
345 static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
346 {
347
348 switch (op_type) {
349 case IS_CONST:
350 should_free->var = 0;
351 return node->zv;
352 break;
353 case IS_TMP_VAR:
354 should_free->var = TMP_FREE(&EX_T(node->var).tmp_var);
355 return &EX_T(node->var).tmp_var;
356 break;
357 case IS_VAR:
358 return _get_zval_ptr_var(node->var, execute_data, should_free TSRMLS_CC);
359 break;
360 case IS_UNUSED:
361 should_free->var = 0;
362 return NULL;
363 break;
364 case IS_CV:
365 should_free->var = 0;
366 return _get_zval_ptr_cv(node->var, type TSRMLS_CC);
367 break;
368 EMPTY_SWITCH_DEFAULT_CASE()
369 }
370 return NULL;
371 }
372
373 static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
374 {
375 zval** ptr_ptr = EX_T(var).var.ptr_ptr;
376
377 if (EXPECTED(ptr_ptr != NULL)) {
378 PZVAL_UNLOCK(*ptr_ptr, should_free);
379 } else {
380
381 PZVAL_UNLOCK(EX_T(var).str_offset.str, should_free);
382 }
383 return ptr_ptr;
384 }
385
386 static zend_always_inline zval **_get_zval_ptr_ptr_var_fast(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
387 {
388 zval** ptr_ptr = EX_T(var).var.ptr_ptr;
389
390 if (EXPECTED(ptr_ptr != NULL)) {
391 should_free->var = *ptr_ptr;
392 } else {
393
394 should_free->var = EX_T(var).str_offset.str;
395 }
396 return ptr_ptr;
397 }
398
399 static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC)
400 {
401 zval ***ptr = EX_CV_NUM(EG(current_execute_data), var);
402
403 if (UNEXPECTED(*ptr == NULL)) {
404 return _get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
405 }
406 return *ptr;
407 }
408
409 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
410 {
411 zval ***ptr = EX_CV_NUM(execute_data, var);
412
413 if (UNEXPECTED(*ptr == NULL)) {
414 return _get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
415 }
416 return *ptr;
417 }
418
419 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
420 {
421 zval ***ptr = EX_CV_NUM(execute_data, var);
422
423 if (UNEXPECTED(*ptr == NULL)) {
424 return _get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
425 }
426 return *ptr;
427 }
428
429 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
430 {
431 zval ***ptr = EX_CV_NUM(execute_data, var);
432
433 if (UNEXPECTED(*ptr == NULL)) {
434 return _get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
435 }
436 return *ptr;
437 }
438
439 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
440 {
441 zval ***ptr = EX_CV_NUM(execute_data, var);
442
443 if (UNEXPECTED(*ptr == NULL)) {
444 return _get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
445 }
446 return *ptr;
447 }
448
449 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
450 {
451 zval ***ptr = EX_CV_NUM(execute_data, var);
452
453 if (UNEXPECTED(*ptr == NULL)) {
454 return _get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
455 }
456 return *ptr;
457 }
458
459 static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
460 {
461 if (op_type == IS_CV) {
462 should_free->var = 0;
463 return _get_zval_ptr_ptr_cv(node->var, type TSRMLS_CC);
464 } else if (op_type == IS_VAR) {
465 return _get_zval_ptr_ptr_var(node->var, execute_data, should_free TSRMLS_CC);
466 } else {
467 should_free->var = 0;
468 return NULL;
469 }
470 }
471
472 static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D)
473 {
474 if (EXPECTED(EG(This) != NULL)) {
475 return EG(This);
476 } else {
477 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
478 return NULL;
479 }
480 }
481
482 static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
483 {
484 if (op_type == IS_UNUSED) {
485 if (EXPECTED(EG(This) != NULL)) {
486
487
488 should_free->var = 0;
489 return &EG(This);
490 } else {
491 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
492 }
493 }
494 return get_zval_ptr_ptr(op_type, op, execute_data, should_free, type);
495 }
496
497 static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
498 {
499 if (EXPECTED(EG(This) != NULL)) {
500 return &EG(This);
501 } else {
502 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
503 return NULL;
504 }
505 }
506
507 static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
508 {
509 if (op_type == IS_UNUSED) {
510 if (EXPECTED(EG(This) != NULL)) {
511 should_free->var = 0;
512 return EG(This);
513 } else {
514 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
515 }
516 }
517 return get_zval_ptr(op_type, op, execute_data, should_free, type);
518 }
519
520 static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)
521 {
522 zval *variable_ptr = *variable_ptr_ptr;
523 zval *value_ptr = *value_ptr_ptr;
524
525 if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) {
526 variable_ptr_ptr = &EG(uninitialized_zval_ptr);
527 } else if (variable_ptr != value_ptr) {
528 if (!PZVAL_IS_REF(value_ptr)) {
529
530 Z_DELREF_P(value_ptr);
531 if (Z_REFCOUNT_P(value_ptr)>0) {
532 ALLOC_ZVAL(*value_ptr_ptr);
533 ZVAL_COPY_VALUE(*value_ptr_ptr, value_ptr);
534 value_ptr = *value_ptr_ptr;
535 zendi_zval_copy_ctor(*value_ptr);
536 }
537 Z_SET_REFCOUNT_P(value_ptr, 1);
538 Z_SET_ISREF_P(value_ptr);
539 }
540
541 *variable_ptr_ptr = value_ptr;
542 Z_ADDREF_P(value_ptr);
543
544 zval_ptr_dtor(&variable_ptr);
545 } else if (!Z_ISREF_P(variable_ptr)) {
546 if (variable_ptr_ptr == value_ptr_ptr) {
547 SEPARATE_ZVAL(variable_ptr_ptr);
548 } else if (variable_ptr==&EG(uninitialized_zval)
549 || Z_REFCOUNT_P(variable_ptr)>2) {
550
551 Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2);
552 ALLOC_ZVAL(*variable_ptr_ptr);
553 ZVAL_COPY_VALUE(*variable_ptr_ptr, variable_ptr);
554 zval_copy_ctor(*variable_ptr_ptr);
555 *value_ptr_ptr = *variable_ptr_ptr;
556 Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2);
557 }
558 Z_SET_ISREF_PP(variable_ptr_ptr);
559 }
560 }
561
562
563 static inline void make_real_object(zval **object_ptr TSRMLS_DC)
564 {
565 if (Z_TYPE_PP(object_ptr) == IS_NULL
566 || (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0)
567 || (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0)
568 ) {
569 SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
570 zval_dtor(*object_ptr);
571 object_init(*object_ptr);
572 zend_error(E_WARNING, "Creating default object from empty value");
573 }
574 }
575
576 ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)
577 {
578 *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
579
580 *class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
581 if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
582 return "implement interface ";
583 } else {
584 return "be an instance of ";
585 }
586 }
587
588 ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC)
589 {
590 zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
591 const char *fname = zf->common.function_name;
592 char *fsep;
593 const char *fclass;
594
595 if (zf->common.scope) {
596 fsep = "::";
597 fclass = zf->common.scope->name;
598 } else {
599 fsep = "";
600 fclass = "";
601 }
602
603 if (ptr && ptr->op_array) {
604 zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, ptr->opline->lineno);
605 } else {
606 zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
607 }
608 return 0;
609 }
610
611 static int is_null_constant(zval *default_value TSRMLS_DC)
612 {
613 if (IS_CONSTANT_TYPE(Z_TYPE_P(default_value))) {
614 zval constant = *default_value;
615 zval *constant_ptr = &constant;
616
617 zval_update_constant(&constant_ptr, 0 TSRMLS_CC);
618 if (Z_TYPE(constant) == IS_NULL) {
619 return 1;
620 }
621 zval_dtor(&constant);
622 }
623 return 0;
624 }
625
626 static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type, zval *default_value TSRMLS_DC)
627 {
628 zend_arg_info *cur_arg_info;
629 char *need_msg;
630 zend_class_entry *ce;
631
632 if (!zf->common.arg_info) {
633 return 1;
634 }
635
636 if (arg_num <= zf->common.num_args) {
637 cur_arg_info = &zf->common.arg_info[arg_num-1];
638 } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
639 cur_arg_info = &zf->common.arg_info[zf->common.num_args-1];
640 } else {
641 return 1;
642 }
643
644 if (cur_arg_info->class_name) {
645 const char *class_name;
646
647 if (!arg) {
648 need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
649 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "" TSRMLS_CC);
650 }
651 if (Z_TYPE_P(arg) == IS_OBJECT) {
652 need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
653 if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
654 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
655 }
656 } else if (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value TSRMLS_CC)))) {
657 need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
658 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
659 }
660 } else if (cur_arg_info->type_hint) {
661 switch(cur_arg_info->type_hint) {
662 case IS_ARRAY:
663 if (!arg) {
664 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC);
665 }
666
667 if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value TSRMLS_CC))))) {
668 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
669 }
670 break;
671
672 case IS_CALLABLE:
673 if (!arg) {
674 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "" TSRMLS_CC);
675 }
676 if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value TSRMLS_CC))))) {
677 return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "" TSRMLS_CC);
678 }
679 break;
680
681 default:
682 zend_error(E_ERROR, "Unknown typehint");
683 }
684 }
685 return 1;
686 }
687
688 static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const zend_execute_data *execute_data, int opcode, const zend_literal *key TSRMLS_DC)
689 {
690 zval *object = *object_ptr;
691 zend_free_op free_value;
692 zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R);
693
694 if (Z_TYPE_P(object) != IS_OBJECT) {
695 if (object == &EG(error_zval)) {
696 if (retval) {
697 *retval = &EG(uninitialized_zval);
698 PZVAL_LOCK(*retval);
699 }
700 FREE_OP(free_value);
701 return;
702 }
703 if (Z_TYPE_P(object) == IS_NULL ||
704 (Z_TYPE_P(object) == IS_BOOL && Z_LVAL_P(object) == 0) ||
705 (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
706 SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
707 object = *object_ptr;
708 Z_ADDREF_P(object);
709 zend_error(E_WARNING, "Creating default object from empty value");
710 if (Z_REFCOUNT_P(object) == 1) {
711
712 zval_ptr_dtor(&object);
713 if (retval) {
714 *retval = &EG(uninitialized_zval);
715 PZVAL_LOCK(*retval);
716 }
717 FREE_OP(free_value);
718 return;
719 }
720 Z_DELREF_P(object);
721 zval_dtor(object);
722 object_init(object);
723 } else {
724 zend_error(E_WARNING, "Attempt to assign property of non-object");
725 if (retval) {
726 *retval = &EG(uninitialized_zval);
727 PZVAL_LOCK(*retval);
728 }
729 FREE_OP(free_value);
730 return;
731 }
732 }
733
734
735 if (value_type == IS_TMP_VAR) {
736 zval *orig_value = value;
737
738 ALLOC_ZVAL(value);
739 ZVAL_COPY_VALUE(value, orig_value);
740 Z_UNSET_ISREF_P(value);
741 Z_SET_REFCOUNT_P(value, 0);
742 } else if (value_type == IS_CONST) {
743 zval *orig_value = value;
744
745 ALLOC_ZVAL(value);
746 ZVAL_COPY_VALUE(value, orig_value);
747 Z_UNSET_ISREF_P(value);
748 Z_SET_REFCOUNT_P(value, 0);
749 zval_copy_ctor(value);
750 }
751
752
753 Z_ADDREF_P(value);
754 if (opcode == ZEND_ASSIGN_OBJ) {
755 if (!Z_OBJ_HT_P(object)->write_property) {
756 zend_error(E_WARNING, "Attempt to assign property of non-object");
757 if (retval) {
758 *retval = &EG(uninitialized_zval);
759 PZVAL_LOCK(&EG(uninitialized_zval));
760 }
761 if (value_type == IS_TMP_VAR) {
762 FREE_ZVAL(value);
763 } else if (value_type == IS_CONST) {
764 zval_ptr_dtor(&value);
765 }
766 FREE_OP(free_value);
767 return;
768 }
769 Z_OBJ_HT_P(object)->write_property(object, property_name, value, key TSRMLS_CC);
770 } else {
771
772 if (!Z_OBJ_HT_P(object)->write_dimension) {
773 zend_error_noreturn(E_ERROR, "Cannot use object as array");
774 }
775 Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
776 }
777
778 if (retval && !EG(exception)) {
779 *retval = value;
780 PZVAL_LOCK(value);
781 }
782 zval_ptr_dtor(&value);
783 FREE_OP_IF_VAR(free_value);
784 }
785
786 static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC)
787 {
788 zval *str = T->str_offset.str;
789 zend_uint offset = T->str_offset.offset;
790 if (Z_TYPE_P(str) == IS_STRING) {
791 if ((int)offset < 0) {
792 zend_error(E_WARNING, "Illegal string offset: %d", offset);
793 return 0;
794 }
795
796 if (offset >= Z_STRLEN_P(str)) {
797 Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), offset+1+1);
798 memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), ' ', offset - Z_STRLEN_P(str));
799 Z_STRVAL_P(str)[offset+1] = 0;
800 Z_STRLEN_P(str) = offset+1;
801 } else if (IS_INTERNED(Z_STRVAL_P(str))) {
802 Z_STRVAL_P(str) = estrndup(Z_STRVAL_P(str), Z_STRLEN_P(str));
803 }
804
805 if (Z_TYPE_P(value) != IS_STRING) {
806 zval tmp;
807
808 ZVAL_COPY_VALUE(&tmp, value);
809 if (value_type != IS_TMP_VAR) {
810 zval_copy_ctor(&tmp);
811 }
812 convert_to_string(&tmp);
813 Z_STRVAL_P(str)[offset] = Z_STRVAL(tmp)[0];
814 str_efree(Z_STRVAL(tmp));
815 } else {
816 Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
817 if (value_type == IS_TMP_VAR) {
818
819
820
821 str_efree(Z_STRVAL_P(value));
822 }
823 }
824
825
826
827
828 }
829 return 1;
830 }
831
832
833 static inline zval* zend_assign_tmp_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
834 {
835 zval *variable_ptr = *variable_ptr_ptr;
836 zval garbage;
837
838 if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
839 UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
840 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
841 return variable_ptr;
842 }
843
844 if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) &&
845 EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
846
847 Z_DELREF_P(variable_ptr);
848 GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
849 ALLOC_ZVAL(variable_ptr);
850 INIT_PZVAL_COPY(variable_ptr, value);
851 *variable_ptr_ptr = variable_ptr;
852 return variable_ptr;
853 } else {
854 if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
855
856 ZVAL_COPY_VALUE(variable_ptr, value);
857 } else {
858 ZVAL_COPY_VALUE(&garbage, variable_ptr);
859 ZVAL_COPY_VALUE(variable_ptr, value);
860 _zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
861 }
862 return variable_ptr;
863 }
864 }
865
866 static inline zval* zend_assign_const_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
867 {
868 zval *variable_ptr = *variable_ptr_ptr;
869 zval garbage;
870
871 if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
872 UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
873 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
874 return variable_ptr;
875 }
876
877 if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) &&
878 EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
879
880 Z_DELREF_P(variable_ptr);
881 GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
882 ALLOC_ZVAL(variable_ptr);
883 INIT_PZVAL_COPY(variable_ptr, value);
884 zval_copy_ctor(variable_ptr);
885 *variable_ptr_ptr = variable_ptr;
886 return variable_ptr;
887 } else {
888 if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
889
890 ZVAL_COPY_VALUE(variable_ptr, value);
891 zendi_zval_copy_ctor(*variable_ptr);
892 } else {
893 ZVAL_COPY_VALUE(&garbage, variable_ptr);
894 ZVAL_COPY_VALUE(variable_ptr, value);
895 zendi_zval_copy_ctor(*variable_ptr);
896 _zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
897 }
898 return variable_ptr;
899 }
900 }
901
902 static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
903 {
904 zval *variable_ptr = *variable_ptr_ptr;
905 zval garbage;
906
907 if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
908 UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
909 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
910 return variable_ptr;
911 }
912
913 if (EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
914 if (Z_REFCOUNT_P(variable_ptr)==1) {
915 if (UNEXPECTED(variable_ptr == value)) {
916 return variable_ptr;
917 } else if (EXPECTED(!PZVAL_IS_REF(value))) {
918 Z_ADDREF_P(value);
919 *variable_ptr_ptr = value;
920 ZEND_ASSERT(variable_ptr != &EG(uninitialized_zval));
921 GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
922 zval_dtor(variable_ptr);
923 efree(variable_ptr);
924 return value;
925 } else {
926 goto copy_value;
927 }
928 } else {
929 Z_DELREF_P(variable_ptr);
930 GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
931 if (PZVAL_IS_REF(value)) {
932 ALLOC_ZVAL(variable_ptr);
933 *variable_ptr_ptr = variable_ptr;
934 INIT_PZVAL_COPY(variable_ptr, value);
935 zval_copy_ctor(variable_ptr);
936 return variable_ptr;
937 } else {
938 *variable_ptr_ptr = value;
939 Z_ADDREF_P(value);
940 return value;
941 }
942 }
943 } else {
944 if (EXPECTED(variable_ptr != value)) {
945 copy_value:
946 if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
947
948 ZVAL_COPY_VALUE(variable_ptr, value);
949 zendi_zval_copy_ctor(*variable_ptr);
950 } else {
951 ZVAL_COPY_VALUE(&garbage, variable_ptr);
952 ZVAL_COPY_VALUE(variable_ptr, value);
953 zendi_zval_copy_ctor(*variable_ptr);
954 _zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
955 }
956 }
957 return variable_ptr;
958 }
959 }
960
961 static void zval_deep_copy(zval **p)
962 {
963 zval *value;
964
965 ALLOC_ZVAL(value);
966 *value = **p;
967 if (Z_TYPE_P(value) == IS_ARRAY) {
968 HashTable *ht;
969
970 ALLOC_HASHTABLE(ht);
971 zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(value)), NULL, ZVAL_PTR_DTOR, 0);
972 zend_hash_copy(ht, Z_ARRVAL_P(value), (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *));
973 Z_ARRVAL_P(value) = ht;
974 } else {
975 zval_copy_ctor(value);
976 }
977 INIT_PZVAL(value);
978 *p = value;
979 }
980
981
982 static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
983 {
984 if (extension->statement_handler) {
985 extension->statement_handler(op_array);
986 }
987 }
988
989
990 static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
991 {
992 if (extension->fcall_begin_handler) {
993 extension->fcall_begin_handler(op_array);
994 }
995 }
996
997
998 static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
999 {
1000 if (extension->fcall_end_handler) {
1001 extension->fcall_end_handler(op_array);
1002 }
1003 }
1004
1005
1006 static inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC)
1007 {
1008 switch (fetch_type) {
1009 case ZEND_FETCH_LOCAL:
1010 if (!EG(active_symbol_table)) {
1011 zend_rebuild_symbol_table(TSRMLS_C);
1012 }
1013 return EG(active_symbol_table);
1014 break;
1015 case ZEND_FETCH_GLOBAL:
1016 case ZEND_FETCH_GLOBAL_LOCK:
1017 return &EG(symbol_table);
1018 break;
1019 case ZEND_FETCH_STATIC:
1020 if (!EG(active_op_array)->static_variables) {
1021 ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
1022 zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
1023 }
1024 return EG(active_op_array)->static_variables;
1025 break;
1026 EMPTY_SWITCH_DEFAULT_CASE()
1027 }
1028 return NULL;
1029 }
1030
1031 static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
1032 {
1033 zval **retval;
1034 char *offset_key;
1035 int offset_key_length;
1036 ulong hval;
1037
1038 switch (dim->type) {
1039 case IS_NULL:
1040 offset_key = "";
1041 offset_key_length = 0;
1042 hval = zend_inline_hash_func("", 1);
1043 goto fetch_string_dim;
1044
1045 case IS_STRING:
1046
1047 offset_key = dim->value.str.val;
1048 offset_key_length = dim->value.str.len;
1049
1050 if (dim_type == IS_CONST) {
1051 hval = Z_HASH_P(dim);
1052 } else {
1053 ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, hval, goto num_index);
1054 hval = str_hash(offset_key, offset_key_length);
1055 }
1056 fetch_string_dim:
1057 if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) {
1058 switch (type) {
1059 case BP_VAR_R:
1060 zend_error(E_NOTICE, "Undefined index: %s", offset_key);
1061
1062 case BP_VAR_UNSET:
1063 case BP_VAR_IS:
1064 retval = &EG(uninitialized_zval_ptr);
1065 break;
1066 case BP_VAR_RW:
1067 zend_error(E_NOTICE,"Undefined index: %s", offset_key);
1068
1069 case BP_VAR_W: {
1070 zval *new_zval = &EG(uninitialized_zval);
1071
1072 Z_ADDREF_P(new_zval);
1073 zend_hash_quick_update(ht, offset_key, offset_key_length+1, hval, &new_zval, sizeof(zval *), (void **) &retval);
1074 }
1075 break;
1076 }
1077 }
1078 break;
1079 case IS_DOUBLE:
1080 hval = zend_dval_to_lval(Z_DVAL_P(dim));
1081 goto num_index;
1082 case IS_RESOURCE:
1083 zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
1084
1085 case IS_BOOL:
1086 case IS_LONG:
1087 hval = Z_LVAL_P(dim);
1088 num_index:
1089 if (zend_hash_index_find(ht, hval, (void **) &retval) == FAILURE) {
1090 switch (type) {
1091 case BP_VAR_R:
1092 zend_error(E_NOTICE,"Undefined offset: %ld", hval);
1093
1094 case BP_VAR_UNSET:
1095 case BP_VAR_IS:
1096 retval = &EG(uninitialized_zval_ptr);
1097 break;
1098 case BP_VAR_RW:
1099 zend_error(E_NOTICE,"Undefined offset: %ld", hval);
1100
1101 case BP_VAR_W: {
1102 zval *new_zval = &EG(uninitialized_zval);
1103
1104 Z_ADDREF_P(new_zval);
1105 zend_hash_index_update(ht, hval, &new_zval, sizeof(zval *), (void **) &retval);
1106 }
1107 break;
1108 }
1109 }
1110 break;
1111
1112 default:
1113 zend_error(E_WARNING, "Illegal offset type");
1114 return (type == BP_VAR_W || type == BP_VAR_RW) ?
1115 &EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
1116 }
1117 return retval;
1118 }
1119
1120 static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC)
1121 {
1122 zval *container = *container_ptr;
1123 zval **retval;
1124
1125 switch (Z_TYPE_P(container)) {
1126
1127 case IS_ARRAY:
1128 if (type != BP_VAR_UNSET && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) {
1129 SEPARATE_ZVAL(container_ptr);
1130 container = *container_ptr;
1131 }
1132 fetch_from_array:
1133 if (dim == NULL) {
1134 zval *new_zval = &EG(uninitialized_zval);
1135
1136 Z_ADDREF_P(new_zval);
1137 if (zend_hash_next_index_insert(Z_ARRVAL_P(container), &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) {
1138 zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
1139 retval = &EG(error_zval_ptr);
1140 Z_DELREF_P(new_zval);
1141 }
1142 } else {
1143 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
1144 }
1145 result->var.ptr_ptr = retval;
1146 PZVAL_LOCK(*retval);
1147 return;
1148 break;
1149
1150 case IS_NULL:
1151 if (container == &EG(error_zval)) {
1152 result->var.ptr_ptr = &EG(error_zval_ptr);
1153 PZVAL_LOCK(EG(error_zval_ptr));
1154 } else if (type != BP_VAR_UNSET) {
1155 convert_to_array:
1156 if (!PZVAL_IS_REF(container)) {
1157 SEPARATE_ZVAL(container_ptr);
1158 container = *container_ptr;
1159 }
1160 zval_dtor(container);
1161 array_init(container);
1162 goto fetch_from_array;
1163 } else {
1164
1165 result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
1166 PZVAL_LOCK(EG(uninitialized_zval_ptr));
1167 }
1168 return;
1169 break;
1170
1171 case IS_STRING: {
1172 zval tmp;
1173
1174 if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
1175 goto convert_to_array;
1176 }
1177 if (dim == NULL) {
1178 zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
1179 }
1180
1181 if (type != BP_VAR_UNSET) {
1182 SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
1183 }
1184
1185 if (Z_TYPE_P(dim) != IS_LONG) {
1186
1187 switch(Z_TYPE_P(dim)) {
1188
1189 case IS_STRING:
1190 if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
1191 break;
1192 }
1193 if (type != BP_VAR_UNSET) {
1194 zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val);
1195 }
1196
1197 break;
1198 case IS_DOUBLE:
1199 case IS_NULL:
1200 case IS_BOOL:
1201 zend_error(E_NOTICE, "String offset cast occurred");
1202 break;
1203 default:
1204 zend_error(E_WARNING, "Illegal offset type");
1205 break;
1206 }
1207
1208 tmp = *dim;
1209 zval_copy_ctor(&tmp);
1210 convert_to_long(&tmp);
1211 dim = &tmp;
1212 }
1213 container = *container_ptr;
1214 result->str_offset.str = container;
1215 PZVAL_LOCK(container);
1216 result->str_offset.offset = Z_LVAL_P(dim);
1217 result->str_offset.ptr_ptr = NULL;
1218 return;
1219 }
1220 break;
1221
1222 case IS_OBJECT:
1223 if (!Z_OBJ_HT_P(container)->read_dimension) {
1224 zend_error_noreturn(E_ERROR, "Cannot use object as array");
1225 } else {
1226 zval *overloaded_result;
1227
1228 if (dim_type == IS_TMP_VAR) {
1229 zval *orig = dim;
1230 MAKE_REAL_ZVAL_PTR(dim);
1231 ZVAL_NULL(orig);
1232 }
1233 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
1234
1235 if (overloaded_result) {
1236 if (!Z_ISREF_P(overloaded_result)) {
1237 if (Z_REFCOUNT_P(overloaded_result) > 0) {
1238 zval *tmp = overloaded_result;
1239
1240 ALLOC_ZVAL(overloaded_result);
1241 ZVAL_COPY_VALUE(overloaded_result, tmp);
1242 zval_copy_ctor(overloaded_result);
1243 Z_UNSET_ISREF_P(overloaded_result);
1244 Z_SET_REFCOUNT_P(overloaded_result, 0);
1245 }
1246 if (Z_TYPE_P(overloaded_result) != IS_OBJECT) {
1247 zend_class_entry *ce = Z_OBJCE_P(container);
1248 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name);
1249 }
1250 }
1251 AI_SET_PTR(result, overloaded_result);
1252 PZVAL_LOCK(overloaded_result);
1253 } else {
1254 result->var.ptr_ptr = &EG(error_zval_ptr);
1255 PZVAL_LOCK(EG(error_zval_ptr));
1256 }
1257 if (dim_type == IS_TMP_VAR) {
1258 zval_ptr_dtor(&dim);
1259 }
1260 }
1261 return;
1262 break;
1263
1264 case IS_BOOL:
1265 if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
1266 goto convert_to_array;
1267 }
1268
1269
1270 default:
1271 if (type == BP_VAR_UNSET) {
1272 zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
1273 result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
1274 PZVAL_LOCK(EG(uninitialized_zval_ptr));
1275 } else {
1276 zend_error(E_WARNING, "Cannot use a scalar value as an array");
1277 result->var.ptr_ptr = &EG(error_zval_ptr);
1278 PZVAL_LOCK(EG(error_zval_ptr));
1279 }
1280 break;
1281 }
1282 }
1283
1284 static void zend_fetch_dimension_address_read(temp_variable *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
1285 {
1286 zval **retval;
1287
1288 switch (Z_TYPE_P(container)) {
1289
1290 case IS_ARRAY:
1291 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
1292 result->var.ptr = *retval;
1293 PZVAL_LOCK(*retval);
1294 return;
1295
1296 case IS_NULL:
1297 result->var.ptr = &EG(uninitialized_zval);
1298 PZVAL_LOCK(&EG(uninitialized_zval));
1299 return;
1300
1301 case IS_STRING: {
1302 zval tmp;
1303 zval *ptr;
1304
1305 if (Z_TYPE_P(dim) != IS_LONG) {
1306 switch(Z_TYPE_P(dim)) {
1307
1308 case IS_STRING:
1309 if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
1310 break;
1311 }
1312 if (type != BP_VAR_IS) {
1313 zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val);
1314 }
1315 break;
1316 case IS_DOUBLE:
1317 case IS_NULL:
1318 case IS_BOOL:
1319 if (type != BP_VAR_IS) {
1320 zend_error(E_NOTICE, "String offset cast occurred");
1321 }
1322 break;
1323 default:
1324 zend_error(E_WARNING, "Illegal offset type");
1325 break;
1326 }
1327
1328 ZVAL_COPY_VALUE(&tmp, dim);
1329 zval_copy_ctor(&tmp);
1330 convert_to_long(&tmp);
1331 dim = &tmp;
1332 }
1333
1334 ALLOC_ZVAL(ptr);
1335 INIT_PZVAL(ptr);
1336 Z_TYPE_P(ptr) = IS_STRING;
1337
1338 if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) {
1339 if (type != BP_VAR_IS) {
1340 zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
1341 }
1342 Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC();
1343 Z_STRLEN_P(ptr) = 0;
1344 } else {
1345 Z_STRVAL_P(ptr) = (char*)emalloc(2);
1346 Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_LVAL_P(dim)];
1347 Z_STRVAL_P(ptr)[1] = 0;
1348 Z_STRLEN_P(ptr) = 1;
1349 }
1350 result->var.ptr = ptr;
1351 return;
1352 }
1353 break;
1354
1355 case IS_OBJECT:
1356 if (!Z_OBJ_HT_P(container)->read_dimension) {
1357 zend_error_noreturn(E_ERROR, "Cannot use object as array");
1358 } else {
1359 zval *overloaded_result;
1360
1361 if (dim_type == IS_TMP_VAR) {
1362 zval *orig = dim;
1363 MAKE_REAL_ZVAL_PTR(dim);
1364 ZVAL_NULL(orig);
1365 }
1366 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
1367
1368 if (result) {
1369 if (overloaded_result) {
1370 result->var.ptr = overloaded_result;
1371 PZVAL_LOCK(overloaded_result);
1372 } else {
1373 result->var.ptr = &EG(uninitialized_zval);
1374 PZVAL_LOCK(&EG(uninitialized_zval));
1375 }
1376 }
1377 if (dim_type == IS_TMP_VAR) {
1378 zval_ptr_dtor(&dim);
1379 }
1380 }
1381 return;
1382
1383 default:
1384 result->var.ptr = &EG(uninitialized_zval);
1385 PZVAL_LOCK(&EG(uninitialized_zval));
1386 return;
1387 }
1388 }
1389
1390 ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC) {
1391 temp_variable tmp;
1392 zend_fetch_dimension_address_read(&tmp, container, dim, IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
1393 *result = tmp.var.ptr;
1394 }
1395
1396 static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC)
1397 {
1398 zval *container = *container_ptr;
1399
1400 if (Z_TYPE_P(container) != IS_OBJECT) {
1401 if (container == &EG(error_zval)) {
1402 result->var.ptr_ptr = &EG(error_zval_ptr);
1403 PZVAL_LOCK(EG(error_zval_ptr));
1404 return;
1405 }
1406
1407
1408 if (type != BP_VAR_UNSET &&
1409 ((Z_TYPE_P(container) == IS_NULL ||
1410 (Z_TYPE_P(container) == IS_BOOL && Z_LVAL_P(container)==0) ||
1411 (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
1412 if (!PZVAL_IS_REF(container)) {
1413 SEPARATE_ZVAL(container_ptr);
1414 container = *container_ptr;
1415 }
1416 object_init(container);
1417 } else {
1418 zend_error(E_WARNING, "Attempt to modify property of non-object");
1419 result->var.ptr_ptr = &EG(error_zval_ptr);
1420 PZVAL_LOCK(EG(error_zval_ptr));
1421 return;
1422 }
1423 }
1424
1425 if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
1426 zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, key TSRMLS_CC);
1427 if (NULL == ptr_ptr) {
1428 zval *ptr;
1429
1430 if (Z_OBJ_HT_P(container)->read_property &&
1431 (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC)) != NULL) {
1432 AI_SET_PTR(result, ptr);
1433 PZVAL_LOCK(ptr);
1434 } else {
1435 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
1436 }
1437 } else {
1438 result->var.ptr_ptr = ptr_ptr;
1439 PZVAL_LOCK(*ptr_ptr);
1440 }
1441 } else if (Z_OBJ_HT_P(container)->read_property) {
1442 zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC);
1443
1444 AI_SET_PTR(result, ptr);
1445 PZVAL_LOCK(ptr);
1446 } else {
1447 zend_error(E_WARNING, "This object doesn't support property references");
1448 result->var.ptr_ptr = &EG(error_zval_ptr);
1449 PZVAL_LOCK(EG(error_zval_ptr));
1450 }
1451 }
1452
1453 static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const zend_execute_data *execute_data TSRMLS_DC)
1454 {
1455 int original_nest_levels = nest_levels;
1456 zend_brk_cont_element *jmp_to;
1457
1458 do {
1459 if (array_offset==-1) {
1460 zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
1461 }
1462 jmp_to = &op_array->brk_cont_array[array_offset];
1463 if (nest_levels>1) {
1464 zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
1465
1466 switch (brk_opline->opcode) {
1467 case ZEND_SWITCH_FREE:
1468 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
1469 zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr);
1470 }
1471 break;
1472 case ZEND_FREE:
1473 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
1474 zendi_zval_dtor(EX_T(brk_opline->op1.var).tmp_var);
1475 }
1476 break;
1477 }
1478 }
1479 array_offset = jmp_to->parent;
1480 } while (--nest_levels > 0);
1481 return jmp_to;
1482 }
1483
1484 #if ZEND_INTENSIVE_DEBUGGING
1485
1486 #define CHECK_SYMBOL_TABLES() \
1487 zend_hash_apply(&EG(symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC); \
1488 if (&EG(symbol_table)!=EG(active_symbol_table)) { \
1489 zend_hash_apply(EG(active_symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC); \
1490 }
1491
1492 static int zend_check_symbol(zval **pz TSRMLS_DC)
1493 {
1494 if (Z_TYPE_PP(pz) > 9) {
1495 fprintf(stderr, "Warning! %x has invalid type!\n", *pz);
1496
1497 #ifdef PHP_WIN32
1498 fflush(stderr);
1499 #endif
1500 } else if (Z_TYPE_PP(pz) == IS_ARRAY) {
1501 zend_hash_apply(Z_ARRVAL_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
1502 } else if (Z_TYPE_PP(pz) == IS_OBJECT) {
1503
1504
1505 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
1506 }
1507
1508 return 0;
1509 }
1510
1511
1512 #else
1513 #define CHECK_SYMBOL_TABLES()
1514 #endif
1515
1516 ZEND_API opcode_handler_t *zend_opcode_handlers;
1517
1518 ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
1519 {
1520 if (fci != NULL) {
1521 execute_data_ptr->function_state.function->internal_function.handler(
1522 fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr,
1523 fci->object_ptr, 1 TSRMLS_CC
1524 );
1525 } else {
1526 zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr;
1527 execute_data_ptr->function_state.function->internal_function.handler(
1528 execute_data_ptr->opline->extended_value + execute_data_ptr->call->num_additional_args,
1529 *return_value_ptr, return_value_ptr,
1530 execute_data_ptr->object, return_value_used TSRMLS_CC
1531 );
1532 }
1533 }
1534
1535 void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC)
1536 {
1537 if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
1538 zend_hash_destroy(symbol_table);
1539 FREE_HASHTABLE(symbol_table);
1540 } else {
1541
1542
1543 zend_hash_clean(symbol_table);
1544 *(++EG(symtable_cache_ptr)) = symbol_table;
1545 }
1546 }
1547
1548
1549 static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC)
1550 {
1551 zval ***cv = EX_CV_NUM(execute_data, 0);
1552 zval ***end = cv + EX(op_array)->last_var;
1553 while (cv != end) {
1554 if (*cv) {
1555 zval_ptr_dtor(*cv);
1556 }
1557 cv++;
1558 }
1559 }
1560
1561
1562 void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC)
1563 {
1564 i_free_compiled_variables(execute_data TSRMLS_CC);
1565 }
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610 static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC)
1611 {
1612 zend_execute_data *execute_data;
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625 size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
1626 size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
1627 size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
1628 size_t call_slots_size = ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * op_array->nested_calls;
1629 size_t stack_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * op_array->used_stack;
1630 size_t total_size = execute_data_size + Ts_size + CVs_size + call_slots_size + stack_size;
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642 if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
1643
1644
1645
1646 int args_count = zend_vm_stack_get_args_count_ex(EG(current_execute_data));
1647 size_t args_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * (args_count + 1);
1648
1649 total_size += args_size + execute_data_size;
1650
1651 EG(argument_stack) = zend_vm_stack_new_page((total_size + (sizeof(void*) - 1)) / sizeof(void*));
1652 EG(argument_stack)->prev = NULL;
1653 execute_data = (zend_execute_data*)((char*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + args_size + execute_data_size + Ts_size);
1654
1655
1656 EX(prev_execute_data) = (zend_execute_data*)((char*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + args_size);
1657 memset(EX(prev_execute_data), 0, sizeof(zend_execute_data));
1658 EX(prev_execute_data)->function_state.function = (zend_function*)op_array;
1659 EX(prev_execute_data)->function_state.arguments = (void**)((char*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * args_count);
1660
1661
1662 *EX(prev_execute_data)->function_state.arguments = (void*)(zend_uintptr_t)args_count;
1663 if (args_count > 0) {
1664 zval **arg_src = (zval**)zend_vm_stack_get_arg_ex(EG(current_execute_data), 1);
1665 zval **arg_dst = (zval**)zend_vm_stack_get_arg_ex(EX(prev_execute_data), 1);
1666 int i;
1667
1668 for (i = 0; i < args_count; i++) {
1669 arg_dst[i] = arg_src[i];
1670 Z_ADDREF_P(arg_dst[i]);
1671 }
1672 }
1673 } else {
1674 execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC);
1675 execute_data = (zend_execute_data*)((char*)execute_data + Ts_size);
1676 EX(prev_execute_data) = EG(current_execute_data);
1677 }
1678
1679 memset(EX_CV_NUM(execute_data, 0), 0, sizeof(zval **) * op_array->last_var);
1680
1681 EX(call_slots) = (call_slot*)((char *)execute_data + execute_data_size + CVs_size);
1682
1683
1684 EX(op_array) = op_array;
1685
1686 EG(argument_stack)->top = zend_vm_stack_frame_base(execute_data);
1687
1688 EX(object) = NULL;
1689 EX(current_this) = NULL;
1690 EX(old_error_reporting) = NULL;
1691 EX(symbol_table) = EG(active_symbol_table);
1692 EX(call) = NULL;
1693 EG(current_execute_data) = execute_data;
1694 EX(nested) = nested;
1695 EX(delayed_exception) = NULL;
1696
1697 if (!op_array->run_time_cache && op_array->last_cache_slot) {
1698 op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
1699 }
1700
1701 if (op_array->this_var != -1 && EG(This)) {
1702 Z_ADDREF_P(EG(This));
1703 if (!EG(active_symbol_table)) {
1704 EX_CV(op_array->this_var) = (zval **) EX_CV_NUM(execute_data, op_array->last_var + op_array->this_var);
1705 *EX_CV(op_array->this_var) = EG(This);
1706 } else {
1707 if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) EX_CV_NUM(execute_data, op_array->this_var))==FAILURE) {
1708 Z_DELREF_P(EG(This));
1709 }
1710 }
1711 }
1712
1713 EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
1714 EG(opline_ptr) = &EX(opline);
1715
1716 EX(function_state).function = (zend_function *) op_array;
1717 EX(function_state).arguments = NULL;
1718
1719 return execute_data;
1720 }
1721
1722
1723 ZEND_API zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC)
1724 {
1725 return i_create_execute_data_from_op_array(op_array, nested TSRMLS_CC);
1726 }
1727
1728
1729 static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(zend_op *opline, call_slot *call TSRMLS_DC)
1730 {
1731 zend_uint arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK;
1732 return ARG_SHOULD_BE_SENT_BY_REF(call->fbc, arg_num);
1733 }
1734
1735
1736 static void **zend_vm_stack_push_args_with_copy(int count TSRMLS_DC)
1737 {
1738 zend_vm_stack p = EG(argument_stack);
1739
1740 zend_vm_stack_extend(count + 1 TSRMLS_CC);
1741
1742 EG(argument_stack)->top += count;
1743 *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
1744 while (count-- > 0) {
1745 void *data = *(--p->top);
1746
1747 if (UNEXPECTED(p->top == ZEND_VM_STACK_ELEMETS(p))) {
1748 zend_vm_stack r = p;
1749
1750 EG(argument_stack)->prev = p->prev;
1751 p = p->prev;
1752 efree(r);
1753 }
1754 *(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + count) = data;
1755 }
1756 return EG(argument_stack)->top++;
1757 }
1758
1759
1760 static zend_always_inline void** zend_vm_stack_push_args(int count TSRMLS_DC)
1761 {
1762 if (UNEXPECTED(EG(argument_stack)->top - ZEND_VM_STACK_ELEMETS(EG(argument_stack)) < count)
1763 || UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->end)) {
1764 return zend_vm_stack_push_args_with_copy(count TSRMLS_CC);
1765 }
1766 *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
1767 return EG(argument_stack)->top++;
1768 }
1769
1770
1771
1772 #define ZEND_VM_NEXT_OPCODE() \
1773 CHECK_SYMBOL_TABLES() \
1774 ZEND_VM_INC_OPCODE(); \
1775 ZEND_VM_CONTINUE()
1776
1777 #define ZEND_VM_SET_OPCODE(new_op) \
1778 CHECK_SYMBOL_TABLES() \
1779 OPLINE = new_op
1780
1781 #define ZEND_VM_JMP(new_op) \
1782 if (EXPECTED(!EG(exception))) { \
1783 ZEND_VM_SET_OPCODE(new_op); \
1784 } else { \
1785 LOAD_OPLINE(); \
1786 } \
1787 ZEND_VM_CONTINUE()
1788
1789 #define ZEND_VM_INC_OPCODE() \
1790 OPLINE++
1791
1792 #ifdef __GNUC__
1793 # define ZEND_VM_GUARD(name) __asm__("#" #name)
1794 #else
1795 # define ZEND_VM_GUARD(name)
1796 #endif
1797
1798 #include "zend_vm_execute.h"
1799
1800 ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
1801 {
1802 if (opcode != ZEND_USER_OPCODE) {
1803 if (handler == NULL) {
1804
1805 zend_user_opcodes[opcode] = opcode;
1806 } else {
1807 zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
1808 }
1809 zend_user_opcode_handlers[opcode] = handler;
1810 return SUCCESS;
1811 }
1812 return FAILURE;
1813 }
1814
1815 ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
1816 {
1817 return zend_user_opcode_handlers[opcode];
1818 }
1819
1820 ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) {
1821 return get_zval_ptr(op_type, node, execute_data, should_free, type);
1822 }
1823
1824 ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) {
1825 return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type);
1826 }
1827
1828
1829
1830
1831
1832
1833
1834