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   |          Dmitry Stogov <dmitry@zend.com>                             |
18   +----------------------------------------------------------------------+
19*/
20
21/* $Id$ */
22
23/* If you change this file, please regenerate the zend_vm_execute.h and
24 * zend_vm_opcodes.h files by running:
25 * php zend_vm_gen.php
26 */
27
28ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
29{
30    USE_OPLINE
31    zend_free_op free_op1, free_op2;
32
33    SAVE_OPLINE();
34    fast_add_function(EX_VAR(opline->result.var),
35        GET_OP1_ZVAL_PTR(BP_VAR_R),
36        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
37    FREE_OP1();
38    FREE_OP2();
39    CHECK_EXCEPTION();
40    ZEND_VM_NEXT_OPCODE();
41}
42
43ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
44{
45    USE_OPLINE
46    zend_free_op free_op1, free_op2;
47
48    SAVE_OPLINE();
49    fast_sub_function(EX_VAR(opline->result.var),
50        GET_OP1_ZVAL_PTR(BP_VAR_R),
51        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
52    FREE_OP1();
53    FREE_OP2();
54    CHECK_EXCEPTION();
55    ZEND_VM_NEXT_OPCODE();
56}
57
58ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
59{
60    USE_OPLINE
61    zend_free_op free_op1, free_op2;
62
63    SAVE_OPLINE();
64    fast_mul_function(EX_VAR(opline->result.var),
65        GET_OP1_ZVAL_PTR(BP_VAR_R),
66        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
67    FREE_OP1();
68    FREE_OP2();
69    CHECK_EXCEPTION();
70    ZEND_VM_NEXT_OPCODE();
71}
72
73ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
74{
75    USE_OPLINE
76    zend_free_op free_op1, free_op2;
77
78    SAVE_OPLINE();
79    fast_div_function(EX_VAR(opline->result.var),
80        GET_OP1_ZVAL_PTR(BP_VAR_R),
81        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
82    FREE_OP1();
83    FREE_OP2();
84    CHECK_EXCEPTION();
85    ZEND_VM_NEXT_OPCODE();
86}
87
88ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
89{
90    USE_OPLINE
91    zend_free_op free_op1, free_op2;
92
93    SAVE_OPLINE();
94    fast_mod_function(EX_VAR(opline->result.var),
95        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
96        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
97    FREE_OP1();
98    FREE_OP2();
99    CHECK_EXCEPTION();
100    ZEND_VM_NEXT_OPCODE();
101}
102
103ZEND_VM_HANDLER(6, ZEND_SL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
104{
105    USE_OPLINE
106    zend_free_op free_op1, free_op2;
107
108    SAVE_OPLINE();
109    shift_left_function(EX_VAR(opline->result.var),
110        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
111        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
112    FREE_OP1();
113    FREE_OP2();
114    CHECK_EXCEPTION();
115    ZEND_VM_NEXT_OPCODE();
116}
117
118ZEND_VM_HANDLER(7, ZEND_SR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
119{
120    USE_OPLINE
121    zend_free_op free_op1, free_op2;
122
123    SAVE_OPLINE();
124    shift_right_function(EX_VAR(opline->result.var),
125        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
126        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
127    FREE_OP1();
128    FREE_OP2();
129    CHECK_EXCEPTION();
130    ZEND_VM_NEXT_OPCODE();
131}
132
133ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
134{
135    USE_OPLINE
136    zend_free_op free_op1, free_op2;
137
138    SAVE_OPLINE();
139    concat_function(EX_VAR(opline->result.var),
140        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
141        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
142    FREE_OP1();
143    FREE_OP2();
144    CHECK_EXCEPTION();
145    ZEND_VM_NEXT_OPCODE();
146}
147
148ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
149{
150    USE_OPLINE
151    zend_free_op free_op1, free_op2;
152
153    SAVE_OPLINE();
154    fast_is_identical_function(EX_VAR(opline->result.var),
155        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
156        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
157    FREE_OP1();
158    FREE_OP2();
159    CHECK_EXCEPTION();
160    ZEND_VM_NEXT_OPCODE();
161}
162
163ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
164{
165    USE_OPLINE
166    zend_free_op free_op1, free_op2;
167    zval *result = EX_VAR(opline->result.var);
168
169    SAVE_OPLINE();
170    fast_is_not_identical_function(result,
171        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
172        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
173    FREE_OP1();
174    FREE_OP2();
175    CHECK_EXCEPTION();
176    ZEND_VM_NEXT_OPCODE();
177}
178
179ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
180{
181    USE_OPLINE
182    zend_free_op free_op1, free_op2;
183    zval *result = EX_VAR(opline->result.var);
184
185    SAVE_OPLINE();
186    fast_equal_function(result,
187        GET_OP1_ZVAL_PTR(BP_VAR_R),
188        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
189    FREE_OP1();
190    FREE_OP2();
191    CHECK_EXCEPTION();
192    ZEND_VM_NEXT_OPCODE();
193}
194
195ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
196{
197    USE_OPLINE
198    zend_free_op free_op1, free_op2;
199    zval *result = EX_VAR(opline->result.var);
200
201    SAVE_OPLINE();
202    fast_not_equal_function(result,
203        GET_OP1_ZVAL_PTR(BP_VAR_R),
204        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
205    FREE_OP1();
206    FREE_OP2();
207    CHECK_EXCEPTION();
208    ZEND_VM_NEXT_OPCODE();
209}
210
211ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
212{
213    USE_OPLINE
214    zend_free_op free_op1, free_op2;
215    zval *result = EX_VAR(opline->result.var);
216
217    SAVE_OPLINE();
218    fast_is_smaller_function(result,
219        GET_OP1_ZVAL_PTR(BP_VAR_R),
220        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
221    FREE_OP1();
222    FREE_OP2();
223    CHECK_EXCEPTION();
224    ZEND_VM_NEXT_OPCODE();
225}
226
227ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
228{
229    USE_OPLINE
230    zend_free_op free_op1, free_op2;
231    zval *result = EX_VAR(opline->result.var);
232
233    SAVE_OPLINE();
234    fast_is_smaller_or_equal_function(result,
235        GET_OP1_ZVAL_PTR(BP_VAR_R),
236        GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
237    FREE_OP1();
238    FREE_OP2();
239    CHECK_EXCEPTION();
240    ZEND_VM_NEXT_OPCODE();
241}
242
243ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
244{
245    USE_OPLINE
246    zend_free_op free_op1, free_op2;
247
248    SAVE_OPLINE();
249    bitwise_or_function(EX_VAR(opline->result.var),
250        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
251        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
252    FREE_OP1();
253    FREE_OP2();
254    CHECK_EXCEPTION();
255    ZEND_VM_NEXT_OPCODE();
256}
257
258ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
259{
260    USE_OPLINE
261    zend_free_op free_op1, free_op2;
262
263    SAVE_OPLINE();
264    bitwise_and_function(EX_VAR(opline->result.var),
265        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
266        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
267    FREE_OP1();
268    FREE_OP2();
269    CHECK_EXCEPTION();
270    ZEND_VM_NEXT_OPCODE();
271}
272
273ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
274{
275    USE_OPLINE
276    zend_free_op free_op1, free_op2;
277
278    SAVE_OPLINE();
279    bitwise_xor_function(EX_VAR(opline->result.var),
280        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
281        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
282    FREE_OP1();
283    FREE_OP2();
284    CHECK_EXCEPTION();
285    ZEND_VM_NEXT_OPCODE();
286}
287
288ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
289{
290    USE_OPLINE
291    zend_free_op free_op1, free_op2;
292
293    SAVE_OPLINE();
294    boolean_xor_function(EX_VAR(opline->result.var),
295        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
296        GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
297    FREE_OP1();
298    FREE_OP2();
299    CHECK_EXCEPTION();
300    ZEND_VM_NEXT_OPCODE();
301}
302
303ZEND_VM_HANDLER(12, ZEND_BW_NOT, CONST|TMP|VAR|CV, ANY)
304{
305    USE_OPLINE
306    zend_free_op free_op1;
307
308    SAVE_OPLINE();
309    bitwise_not_function(EX_VAR(opline->result.var),
310        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
311    FREE_OP1();
312    CHECK_EXCEPTION();
313    ZEND_VM_NEXT_OPCODE();
314}
315
316ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMP|VAR|CV, ANY)
317{
318    USE_OPLINE
319    zend_free_op free_op1;
320
321    SAVE_OPLINE();
322    boolean_not_function(EX_VAR(opline->result.var),
323        GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R) TSRMLS_CC);
324    FREE_OP1();
325    CHECK_EXCEPTION();
326    ZEND_VM_NEXT_OPCODE();
327}
328
329ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
330{
331    USE_OPLINE
332    zend_free_op free_op1, free_op2, free_op_data1;
333    zval *object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
334    zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
335    zval *value;
336    zval *zptr;
337
338    if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
339        zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
340    }
341
342    if (OP1_TYPE != IS_UNUSED) {
343        object = make_real_object(object TSRMLS_CC);
344    }
345
346    value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
347
348    if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
349        zend_error(E_WARNING, "Attempt to assign property of non-object");
350        FREE_OP2();
351        FREE_OP(free_op_data1);
352
353        if (RETURN_VALUE_USED(opline)) {
354            ZVAL_NULL(EX_VAR(opline->result.var));
355        }
356    } else {
357        /* here we are sure we are dealing with an object */
358        if (opline->extended_value == ZEND_ASSIGN_OBJ
359            && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
360            && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
361
362            ZVAL_DEREF(zptr);
363            SEPARATE_ZVAL_NOREF(zptr);
364
365            binary_op(zptr, zptr, value TSRMLS_CC);
366            if (RETURN_VALUE_USED(opline)) {
367                ZVAL_COPY(EX_VAR(opline->result.var), zptr);
368            }
369        } else {
370            zval *z = NULL;
371            zval rv;
372
373            if (opline->extended_value == ZEND_ASSIGN_OBJ) {
374                if (Z_OBJ_HT_P(object)->read_property) {
375                    z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
376                }
377            } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
378                if (Z_OBJ_HT_P(object)->read_dimension) {
379                    z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC);
380                }
381            }
382            if (z) {
383                if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
384                    zval rv;
385                    zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
386
387                    if (Z_REFCOUNT_P(z) == 0) {
388                        zval_dtor(z);
389                    }
390                    ZVAL_COPY_VALUE(z, value);
391                }
392//???               if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
393                SEPARATE_ZVAL_IF_NOT_REF(z);
394                binary_op(z, z, value TSRMLS_CC);
395                if (opline->extended_value == ZEND_ASSIGN_OBJ) {
396                    Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
397                } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
398                    Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
399                }
400                if (RETURN_VALUE_USED(opline)) {
401                    ZVAL_COPY(EX_VAR(opline->result.var), z);
402                }
403                zval_ptr_dtor(z);
404            } else {
405                zend_error(E_WARNING, "Attempt to assign property of non-object");
406                if (RETURN_VALUE_USED(opline)) {
407                    ZVAL_NULL(EX_VAR(opline->result.var));
408                }
409            }
410        }
411
412        FREE_OP2();
413        FREE_OP(free_op_data1);
414    }
415
416    FREE_OP1_VAR_PTR();
417    /* assign_obj has two opcodes! */
418    CHECK_EXCEPTION();
419    ZEND_VM_INC_OPCODE();
420    ZEND_VM_NEXT_OPCODE();
421}
422
423ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
424{
425    USE_OPLINE
426    zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
427    zval *var_ptr;
428    zval *value, *container;
429
430    SAVE_OPLINE();
431    container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
432    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
433        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
434    } else if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
435        if (OP1_TYPE == IS_VAR && !OP1_FREE) {
436            Z_ADDREF_P(container);  /* undo the effect of get_obj_zval_ptr_ptr() */
437        }
438        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
439    } else {
440        zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
441
442        zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, OP2_TYPE TSRMLS_CC);
443        value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
444        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
445    }
446
447    if (UNEXPECTED(var_ptr == NULL)) {
448        zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
449    }
450
451    if (UNEXPECTED(var_ptr == &EG(error_zval))) {
452        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
453            ZVAL_NULL(EX_VAR(opline->result.var));
454        }
455    } else {
456        ZVAL_DEREF(var_ptr);
457        SEPARATE_ZVAL_NOREF(var_ptr);
458
459        binary_op(var_ptr, var_ptr, value TSRMLS_CC);
460
461        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
462            ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
463        }
464    }
465
466    FREE_OP2();
467    FREE_OP(free_op_data1);
468    FREE_OP_VAR_PTR(free_op_data2);
469    FREE_OP1_VAR_PTR();
470    CHECK_EXCEPTION();
471    ZEND_VM_INC_OPCODE();
472    ZEND_VM_NEXT_OPCODE();
473}
474
475ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
476{
477    USE_OPLINE
478    zend_free_op free_op1, free_op2;
479    zval *var_ptr;
480    zval *value;
481
482    SAVE_OPLINE();
483    value = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
484    var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
485
486    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
487        zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
488    }
489
490    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
491        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
492            ZVAL_NULL(EX_VAR(opline->result.var));
493        }
494    } else {
495        ZVAL_DEREF(var_ptr);
496        SEPARATE_ZVAL_NOREF(var_ptr);
497
498        binary_op(var_ptr, var_ptr, value TSRMLS_CC);
499
500        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
501            ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
502        }
503    }
504
505    FREE_OP2();
506    FREE_OP1_VAR_PTR();
507    CHECK_EXCEPTION();
508    ZEND_VM_NEXT_OPCODE();
509}
510
511ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
512{
513    USE_OPLINE
514
515    if (EXPECTED(opline->extended_value == 0)) {
516        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, add_function);
517    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
518        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, add_function);
519    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
520        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, add_function);
521    }
522}
523
524ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
525{
526    USE_OPLINE
527
528    if (EXPECTED(opline->extended_value == 0)) {
529        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, sub_function);
530    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
531        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, sub_function);
532    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
533        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, sub_function);
534    }
535}
536
537ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
538{
539    USE_OPLINE
540
541    if (EXPECTED(opline->extended_value == 0)) {
542        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mul_function);
543    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
544        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mul_function);
545    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
546        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, mul_function);
547    }
548}
549
550ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
551{
552    USE_OPLINE
553
554    if (EXPECTED(opline->extended_value == 0)) {
555        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, div_function);
556    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
557        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, div_function);
558    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
559        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, div_function);
560    }
561}
562
563ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
564{
565    USE_OPLINE
566
567    if (EXPECTED(opline->extended_value == 0)) {
568        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mod_function);
569    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
570        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mod_function);
571    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
572        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, mod_function);
573    }
574}
575
576ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
577{
578    USE_OPLINE
579
580    if (EXPECTED(opline->extended_value == 0)) {
581        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_left_function);
582    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
583        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
584    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
585        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, shift_left_function);
586    }
587}
588
589ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
590{
591    USE_OPLINE
592
593    if (EXPECTED(opline->extended_value == 0)) {
594        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_right_function);
595    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
596        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
597    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
598        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, shift_right_function);
599    }
600}
601
602ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
603{
604    USE_OPLINE
605
606    if (EXPECTED(opline->extended_value == 0)) {
607        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, concat_function);
608    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
609        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, concat_function);
610    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
611        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, concat_function);
612    }
613}
614
615ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
616{
617    USE_OPLINE
618
619    if (EXPECTED(opline->extended_value == 0)) {
620        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_or_function);
621    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
622        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
623    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
624        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_or_function);
625    }
626}
627
628ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
629{
630    USE_OPLINE
631
632    if (EXPECTED(opline->extended_value == 0)) {
633        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_and_function);
634    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
635        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
636    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
637        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_and_function);
638    }
639}
640
641ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
642{
643    USE_OPLINE
644
645    if (EXPECTED(opline->extended_value == 0)) {
646        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_xor_function);
647    } else if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
648        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
649    } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
650        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_xor_function);
651    }
652}
653
654ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op)
655{
656    USE_OPLINE
657    zend_free_op free_op1, free_op2;
658    zval *object;
659    zval *property;
660    zval *retval;
661    zval *zptr;
662
663    SAVE_OPLINE();
664    object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
665    property = GET_OP2_ZVAL_PTR(BP_VAR_R);
666    retval = EX_VAR(opline->result.var);
667
668    if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
669        zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
670    }
671
672    if (OP1_TYPE != IS_UNUSED) {
673        object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
674    }
675
676    if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
677        zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
678        FREE_OP2();
679        if (RETURN_VALUE_USED(opline)) {
680            ZVAL_NULL(retval);
681        }
682        FREE_OP1_VAR_PTR();
683        CHECK_EXCEPTION();
684        ZEND_VM_NEXT_OPCODE();
685    }
686
687    /* here we are sure we are dealing with an object */
688
689    if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
690        && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
691
692        ZVAL_DEREF(zptr);
693        SEPARATE_ZVAL_NOREF(zptr);
694
695        incdec_op(zptr);
696        if (RETURN_VALUE_USED(opline)) {
697            ZVAL_COPY(retval, zptr);
698        }
699    } else {
700        zval rv;
701
702        if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
703            zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
704
705            if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
706                zval rv;
707                zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
708
709                if (Z_REFCOUNT_P(z) == 0) {
710                    zval_dtor(z);
711                }
712                ZVAL_COPY_VALUE(z, value);
713            }
714            if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
715            SEPARATE_ZVAL_IF_NOT_REF(z);
716            incdec_op(z);
717            ZVAL_COPY_VALUE(retval, z);
718            Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
719            SELECTIVE_PZVAL_LOCK(retval, opline);
720            zval_ptr_dtor(z);
721        } else {
722            zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
723            if (RETURN_VALUE_USED(opline)) {
724                ZVAL_NULL(retval);
725            }
726        }
727    }
728
729    FREE_OP2();
730    FREE_OP1_VAR_PTR();
731    CHECK_EXCEPTION();
732    ZEND_VM_NEXT_OPCODE();
733}
734
735ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
736{
737    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, increment_function);
738}
739
740ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
741{
742    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, decrement_function);
743}
744
745ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op)
746{
747    USE_OPLINE
748    zend_free_op free_op1, free_op2;
749    zval *object;
750    zval *property;
751    zval *retval;
752    zval *zptr;
753
754    SAVE_OPLINE();
755    object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
756    property = GET_OP2_ZVAL_PTR(BP_VAR_R);
757    retval = EX_VAR(opline->result.var);
758
759    if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
760        zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
761    }
762
763    if (OP1_TYPE != IS_UNUSED) {
764        object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
765    }
766
767    if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
768        zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
769        FREE_OP2();
770        ZVAL_NULL(retval);
771        FREE_OP1_VAR_PTR();
772        CHECK_EXCEPTION();
773        ZEND_VM_NEXT_OPCODE();
774    }
775
776    /* here we are sure we are dealing with an object */
777
778    if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
779        && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
780
781        ZVAL_DEREF(zptr);
782        ZVAL_COPY(retval, zptr);
783
784        SEPARATE_ZVAL_NOREF(zptr);
785        incdec_op(zptr);
786    } else {
787        if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
788            zval rv;
789            zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
790            zval z_copy;
791
792            if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
793                zval rv;
794                zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
795
796                if (Z_REFCOUNT_P(z) == 0) {
797                    zval_dtor(z);
798                }
799                ZVAL_COPY_VALUE(z, value);
800            }
801            ZVAL_DUP(retval, z);
802            ZVAL_DUP(&z_copy, z);
803            incdec_op(&z_copy);
804            if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
805            Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
806            zval_ptr_dtor(&z_copy);
807            zval_ptr_dtor(z);
808        } else {
809            zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
810            ZVAL_NULL(retval);
811        }
812    }
813
814    FREE_OP2();
815    FREE_OP1_VAR_PTR();
816    CHECK_EXCEPTION();
817    ZEND_VM_NEXT_OPCODE();
818}
819
820ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
821{
822    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, increment_function);
823}
824
825ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
826{
827    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, decrement_function);
828}
829
830ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
831{
832    USE_OPLINE
833    zend_free_op free_op1;
834    zval *var_ptr;
835
836    SAVE_OPLINE();
837    var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
838
839    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
840        zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
841    }
842
843    if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
844        fast_increment_function(var_ptr);
845        if (RETURN_VALUE_USED(opline)) {
846            ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
847        }
848        ZEND_VM_NEXT_OPCODE();
849    }
850
851    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
852        if (RETURN_VALUE_USED(opline)) {
853            ZVAL_NULL(EX_VAR(opline->result.var));
854        }
855        CHECK_EXCEPTION();
856        ZEND_VM_NEXT_OPCODE();
857    }
858
859    ZVAL_DEREF(var_ptr);
860    SEPARATE_ZVAL_NOREF(var_ptr);
861
862    increment_function(var_ptr);
863
864    if (RETURN_VALUE_USED(opline)) {
865        ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
866    }
867
868    FREE_OP1_VAR_PTR();
869    CHECK_EXCEPTION();
870    ZEND_VM_NEXT_OPCODE();
871}
872
873ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
874{
875    USE_OPLINE
876    zend_free_op free_op1;
877    zval *var_ptr;
878
879    SAVE_OPLINE();
880    var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
881
882    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
883        zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
884    }
885
886    if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
887        fast_decrement_function(var_ptr);
888        if (RETURN_VALUE_USED(opline)) {
889            ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
890        }
891        ZEND_VM_NEXT_OPCODE();
892    }
893
894    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
895        if (RETURN_VALUE_USED(opline)) {
896            ZVAL_NULL(EX_VAR(opline->result.var));
897        }
898        CHECK_EXCEPTION();
899        ZEND_VM_NEXT_OPCODE();
900    }
901
902    ZVAL_DEREF(var_ptr);
903    SEPARATE_ZVAL_NOREF(var_ptr);
904
905    decrement_function(var_ptr);
906
907    if (RETURN_VALUE_USED(opline)) {
908        ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
909    }
910
911    FREE_OP1_VAR_PTR();
912    CHECK_EXCEPTION();
913    ZEND_VM_NEXT_OPCODE();
914}
915
916ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
917{
918    USE_OPLINE
919    zend_free_op free_op1;
920    zval *var_ptr;
921
922    SAVE_OPLINE();
923    var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
924
925    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
926        zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
927    }
928
929    if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
930        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
931        fast_increment_function(var_ptr);
932        ZEND_VM_NEXT_OPCODE();
933    }
934
935    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
936        ZVAL_NULL(EX_VAR(opline->result.var));
937        CHECK_EXCEPTION();
938        ZEND_VM_NEXT_OPCODE();
939    }
940
941    if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
942        var_ptr = Z_REFVAL_P(var_ptr);
943        ZVAL_DUP(EX_VAR(opline->result.var), var_ptr);
944    } else {
945        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
946        zval_opt_copy_ctor(var_ptr);
947    }
948
949    increment_function(var_ptr);
950
951    FREE_OP1_VAR_PTR();
952    CHECK_EXCEPTION();
953    ZEND_VM_NEXT_OPCODE();
954}
955
956ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
957{
958    USE_OPLINE
959    zend_free_op free_op1;
960    zval *var_ptr;
961
962    SAVE_OPLINE();
963    var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
964
965    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
966        zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
967    }
968
969    if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
970        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
971        fast_decrement_function(var_ptr);
972        ZEND_VM_NEXT_OPCODE();
973    }
974
975    if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
976        ZVAL_NULL(EX_VAR(opline->result.var));
977        CHECK_EXCEPTION();
978        ZEND_VM_NEXT_OPCODE();
979    }
980
981    if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
982        var_ptr = Z_REFVAL_P(var_ptr);
983        ZVAL_DUP(EX_VAR(opline->result.var), var_ptr);
984    } else {
985        ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
986        zval_opt_copy_ctor(var_ptr);
987    }
988
989    decrement_function(var_ptr);
990
991    FREE_OP1_VAR_PTR();
992    CHECK_EXCEPTION();
993    ZEND_VM_NEXT_OPCODE();
994}
995
996ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
997{
998    USE_OPLINE
999    zend_free_op free_op1;
1000    zval *z;
1001
1002    SAVE_OPLINE();
1003    z = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1004
1005    zend_print_variable(z TSRMLS_CC);
1006
1007    FREE_OP1();
1008    CHECK_EXCEPTION();
1009    ZEND_VM_NEXT_OPCODE();
1010}
1011
1012ZEND_VM_HANDLER(41, ZEND_PRINT, CONST|TMP|VAR|CV, ANY)
1013{
1014    USE_OPLINE
1015
1016    ZVAL_LONG(EX_VAR(opline->result.var), 1);
1017    ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ECHO);
1018}
1019
1020ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|VAR, int type)
1021{
1022    USE_OPLINE
1023    zend_free_op free_op1;
1024    zval *varname;
1025    zval *retval;
1026    zend_string *name;
1027    HashTable *target_symbol_table;
1028
1029    SAVE_OPLINE();
1030    varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
1031
1032    if (OP1_TYPE == IS_CONST) {
1033        name = Z_STR_P(varname);
1034    } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
1035        name = Z_STR_P(varname);
1036        zend_string_addref(name);
1037    } else {
1038        name = zval_get_string(varname);
1039    }
1040
1041    if (OP2_TYPE != IS_UNUSED) {
1042        zend_class_entry *ce;
1043
1044        if (OP2_TYPE == IS_CONST) {
1045            if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
1046                ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
1047            } else {
1048                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
1049                if (UNEXPECTED(ce == NULL)) {
1050                    if (OP1_TYPE != IS_CONST) {
1051                        zend_string_release(name);
1052                    }
1053                    FREE_OP1();
1054                    CHECK_EXCEPTION();
1055                    ZEND_VM_NEXT_OPCODE();
1056                }
1057                CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
1058            }
1059        } else {
1060            ce = Z_CE_P(EX_VAR(opline->op2.var));
1061        }
1062        retval = zend_std_get_static_property(ce, name, 0, ((OP1_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
1063        FREE_OP1();
1064    } else {
1065        target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
1066        retval = zend_hash_find(target_symbol_table, name);
1067        if (retval == NULL) {
1068            switch (type) {
1069                case BP_VAR_R:
1070                case BP_VAR_UNSET:
1071                    zend_error(E_NOTICE,"Undefined variable: %s", name->val);
1072                    /* break missing intentionally */
1073                case BP_VAR_IS:
1074                    retval = &EG(uninitialized_zval);
1075                    break;
1076                case BP_VAR_RW:
1077                    zend_error(E_NOTICE,"Undefined variable: %s", name->val);
1078                    /* break missing intentionally */
1079                case BP_VAR_W:
1080                    retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
1081                    break;
1082                EMPTY_SWITCH_DEFAULT_CASE()
1083            }
1084        /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
1085        } else if (Z_TYPE_P(retval) == IS_INDIRECT) {
1086            retval = Z_INDIRECT_P(retval);
1087            if (Z_TYPE_P(retval) == IS_UNDEF) {
1088                switch (type) {
1089                    case BP_VAR_R:
1090                    case BP_VAR_UNSET:
1091                        zend_error(E_NOTICE,"Undefined variable: %s", name->val);
1092                        /* break missing intentionally */
1093                    case BP_VAR_IS:
1094                        retval = &EG(uninitialized_zval);
1095                        break;
1096                    case BP_VAR_RW:
1097                        zend_error(E_NOTICE,"Undefined variable: %s", name->val);
1098                        /* break missing intentionally */
1099                    case BP_VAR_W:
1100                        ZVAL_NULL(retval);
1101                        break;
1102                    EMPTY_SWITCH_DEFAULT_CASE()
1103                }
1104            }
1105        }
1106        if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
1107            if (Z_CONSTANT_P(retval)) {
1108                zval_update_constant(retval, 1 TSRMLS_CC);
1109            }
1110        } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
1111            FREE_OP1();
1112        }
1113    }
1114
1115    if (OP1_TYPE != IS_CONST) {
1116        zend_string_release(name);
1117    }
1118
1119    ZEND_ASSERT(retval != NULL);
1120    if (type == BP_VAR_R || type == BP_VAR_IS) {
1121        if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
1122            ZVAL_UNREF(retval);
1123        }
1124        ZVAL_COPY(EX_VAR(opline->result.var), retval);
1125    } else {
1126        if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
1127            ZVAL_MAKE_REF(retval);
1128        }
1129        ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
1130    }
1131    CHECK_EXCEPTION();
1132    ZEND_VM_NEXT_OPCODE();
1133}
1134
1135ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1136{
1137    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R);
1138}
1139
1140ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1141{
1142    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W);
1143}
1144
1145ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1146{
1147    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW);
1148}
1149
1150ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1151{
1152    USE_OPLINE
1153
1154    if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) {
1155        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W);
1156    } else {
1157        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R);
1158    }
1159}
1160
1161ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1162{
1163    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
1164}
1165
1166ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1167{
1168    ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS);
1169}
1170
1171ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
1172{
1173    USE_OPLINE
1174    zend_free_op free_op1, free_op2;
1175    zval *container;
1176
1177    SAVE_OPLINE();
1178    container = GET_OP1_ZVAL_PTR(BP_VAR_R);
1179    zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1180    FREE_OP2();
1181    FREE_OP1();
1182    CHECK_EXCEPTION();
1183    ZEND_VM_NEXT_OPCODE();
1184}
1185
1186ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1187{
1188    USE_OPLINE
1189    zend_free_op free_op1, free_op2;
1190    zval *container;
1191
1192    SAVE_OPLINE();
1193    container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1194
1195    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1196        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1197    }
1198    if (EXPECTED(opline->extended_value == 0)) {
1199        zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1200    } else {
1201        zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1202    }
1203    FREE_OP2();
1204    if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1205        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1206    }
1207    FREE_OP1_VAR_PTR();
1208    CHECK_EXCEPTION();
1209    ZEND_VM_NEXT_OPCODE();
1210}
1211
1212ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1213{
1214    USE_OPLINE
1215    zend_free_op free_op1, free_op2;
1216    zval *container;
1217
1218    SAVE_OPLINE();
1219    container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
1220
1221    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1222        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1223    }
1224    zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1225    FREE_OP2();
1226    if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1227        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1228    }
1229    FREE_OP1_VAR_PTR();
1230    CHECK_EXCEPTION();
1231    ZEND_VM_NEXT_OPCODE();
1232}
1233
1234ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
1235{
1236    USE_OPLINE
1237    zend_free_op free_op1, free_op2;
1238    zval *container;
1239
1240    SAVE_OPLINE();
1241    container = GET_OP1_ZVAL_PTR(BP_VAR_IS);
1242    zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1243    FREE_OP2();
1244    FREE_OP1();
1245    CHECK_EXCEPTION();
1246    ZEND_VM_NEXT_OPCODE();
1247}
1248
1249ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1250{
1251    USE_OPLINE
1252    zval *container;
1253    zend_free_op free_op1, free_op2;
1254
1255    SAVE_OPLINE();
1256
1257    if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) {
1258        if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
1259            zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context");
1260        }
1261        container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1262        if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1263            zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1264        }
1265        zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1266        if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1267            EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1268        }
1269        FREE_OP2();
1270        FREE_OP1_VAR_PTR();
1271    } else {
1272        if (OP2_TYPE == IS_UNUSED) {
1273            zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
1274        }
1275        container = GET_OP1_ZVAL_PTR(BP_VAR_R);
1276        zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1277        FREE_OP2();
1278        FREE_OP1();
1279    }
1280    CHECK_EXCEPTION();
1281    ZEND_VM_NEXT_OPCODE();
1282}
1283
1284ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
1285{
1286    USE_OPLINE
1287    zend_free_op free_op1, free_op2;
1288    zval *container;
1289
1290    SAVE_OPLINE();
1291    container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET);
1292
1293    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1294        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1295    }
1296    zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
1297    FREE_OP2();
1298    if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1299        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1300    }
1301    FREE_OP1_VAR_PTR();
1302    CHECK_EXCEPTION();
1303    ZEND_VM_NEXT_OPCODE();
1304}
1305
1306ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1307{
1308    USE_OPLINE
1309    zend_free_op free_op1;
1310    zval *container;
1311    zend_free_op free_op2;
1312    zval *offset;
1313
1314    SAVE_OPLINE();
1315    container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
1316    offset  = GET_OP2_ZVAL_PTR(BP_VAR_R);
1317
1318    if ((OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) ||
1319        UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
1320        zend_error(E_NOTICE, "Trying to get property of non-object");
1321        ZVAL_NULL(EX_VAR(opline->result.var));
1322    } else {
1323        zval *retval;
1324
1325        /* here we are sure we are dealing with an object */
1326        retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
1327
1328        if (retval != EX_VAR(opline->result.var)) {
1329            ZVAL_COPY(EX_VAR(opline->result.var), retval);
1330        }
1331    }
1332
1333    FREE_OP2();
1334    FREE_OP1();
1335    CHECK_EXCEPTION();
1336    ZEND_VM_NEXT_OPCODE();
1337}
1338
1339ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1340{
1341    USE_OPLINE
1342    zend_free_op free_op1, free_op2;
1343    zval *property;
1344    zval *container;
1345
1346    SAVE_OPLINE();
1347    property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1348
1349    container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
1350    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1351        zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1352    }
1353
1354    zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
1355    FREE_OP2();
1356    if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1357        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1358    }
1359    FREE_OP1_VAR_PTR();
1360    CHECK_EXCEPTION();
1361    ZEND_VM_NEXT_OPCODE();
1362}
1363
1364ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1365{
1366    USE_OPLINE
1367    zend_free_op free_op1, free_op2;
1368    zval *property;
1369    zval *container;
1370
1371    SAVE_OPLINE();
1372    property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1373    container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
1374
1375    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1376        zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1377    }
1378    zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
1379    FREE_OP2();
1380    if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1381        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1382    }
1383    FREE_OP1_VAR_PTR();
1384    CHECK_EXCEPTION();
1385    ZEND_VM_NEXT_OPCODE();
1386}
1387
1388ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1389{
1390    USE_OPLINE
1391    zend_free_op free_op1;
1392    zval *container;
1393    zend_free_op free_op2;
1394    zval *offset;
1395
1396    SAVE_OPLINE();
1397    container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
1398    offset  = GET_OP2_ZVAL_PTR(BP_VAR_R);
1399
1400    if ((OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) ||
1401        UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
1402        ZVAL_NULL(EX_VAR(opline->result.var));
1403    } else {
1404        zval *retval;
1405
1406        /* here we are sure we are dealing with an object */
1407        retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
1408
1409        if (retval != EX_VAR(opline->result.var)) {
1410            ZVAL_COPY(EX_VAR(opline->result.var), retval);
1411        }
1412    }
1413
1414    FREE_OP2();
1415    FREE_OP1();
1416    CHECK_EXCEPTION();
1417    ZEND_VM_NEXT_OPCODE();
1418}
1419
1420ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1421{
1422    USE_OPLINE
1423    zval *container;
1424
1425    if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) {
1426        /* Behave like FETCH_OBJ_W */
1427        zend_free_op free_op1, free_op2;
1428        zval *property;
1429
1430        SAVE_OPLINE();
1431        property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1432        container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
1433
1434        if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
1435            zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context");
1436        }
1437        if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1438            zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1439        }
1440        zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
1441        FREE_OP2();
1442        if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1443            EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1444        }
1445        FREE_OP1_VAR_PTR();
1446        CHECK_EXCEPTION();
1447        ZEND_VM_NEXT_OPCODE();
1448    } else {
1449        ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
1450    }
1451}
1452
1453ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1454{
1455    USE_OPLINE
1456    zend_free_op free_op1, free_op2;
1457    zval *container, *property;
1458
1459    SAVE_OPLINE();
1460    container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
1461    property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1462
1463    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1464        zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1465    }
1466    zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
1467    FREE_OP2();
1468    if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
1469        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1470    }
1471    FREE_OP1_VAR_PTR();
1472    CHECK_EXCEPTION();
1473    ZEND_VM_NEXT_OPCODE();
1474}
1475
1476ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMP|VAR|CV, CONST)
1477{
1478    USE_OPLINE
1479    zend_free_op free_op1;
1480    zval *container;
1481
1482    SAVE_OPLINE();
1483    container = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1484
1485    if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1486        zend_free_op free_op2;
1487        zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
1488
1489        ZVAL_COPY(EX_VAR(opline->result.var), value);
1490    } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
1491               EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
1492        zval *result = EX_VAR(opline->result.var);
1493        zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), BP_VAR_R, result TSRMLS_CC);
1494
1495        if (retval) {
1496            if (result != retval) {
1497                ZVAL_COPY(result, retval);
1498            }
1499        } else {
1500            ZVAL_NULL(result);
1501        }
1502    } else {
1503        ZVAL_NULL(EX_VAR(opline->result.var));
1504    }
1505    CHECK_EXCEPTION();
1506    ZEND_VM_NEXT_OPCODE();
1507}
1508
1509ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1510{
1511    USE_OPLINE
1512    zend_free_op free_op1, free_op2;
1513    zval *object;
1514    zval *property_name;
1515
1516    SAVE_OPLINE();
1517    object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
1518    property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
1519
1520    if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
1521        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1522    }
1523    zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
1524    FREE_OP2();
1525    FREE_OP1_VAR_PTR();
1526    /* assign_obj has two opcodes! */
1527    CHECK_EXCEPTION();
1528    ZEND_VM_INC_OPCODE();
1529    ZEND_VM_NEXT_OPCODE();
1530}
1531
1532ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1533{
1534    USE_OPLINE
1535    zend_free_op free_op1;
1536    zval *object_ptr;
1537
1538    SAVE_OPLINE();
1539    object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1540
1541    if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
1542        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1543    }
1544    if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
1545        object_ptr = Z_REFVAL_P(object_ptr);
1546    }
1547    if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
1548        zend_free_op free_op2;
1549        zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
1550
1551        zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
1552        FREE_OP2();
1553    } else {
1554        zend_free_op free_op2, free_op_data1, free_op_data2;
1555        zval *value;
1556        zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
1557        zval *variable_ptr;
1558
1559        variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
1560        FREE_OP2();
1561        value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
1562        if (UNEXPECTED(variable_ptr != NULL)) {
1563            zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
1564            FREE_OP(free_op_data1);
1565        } else {
1566            variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
1567            if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
1568                FREE_OP(free_op_data1);
1569                if (RETURN_VALUE_USED(opline)) {
1570                    ZVAL_NULL(EX_VAR(opline->result.var));
1571                }
1572            } else {
1573                value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC);
1574                if ((opline+1)->op1_type == IS_VAR) {
1575                    FREE_OP(free_op_data1);
1576                }
1577                if (RETURN_VALUE_USED(opline)) {
1578                    ZVAL_COPY(EX_VAR(opline->result.var), value);
1579                }
1580                FREE_OP_VAR_PTR(free_op_data2);
1581            }
1582        }
1583    }
1584    FREE_OP1_VAR_PTR();
1585    /* assign_dim has two opcodes! */
1586    CHECK_EXCEPTION();
1587    ZEND_VM_INC_OPCODE();
1588    ZEND_VM_NEXT_OPCODE();
1589}
1590
1591ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
1592{
1593    USE_OPLINE
1594    zend_free_op free_op1, free_op2;
1595    zval *value;
1596    zval *variable_ptr;
1597
1598    SAVE_OPLINE();
1599    value = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
1600    variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1601
1602    if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
1603        if (OP2_TYPE == IS_TMP_VAR) {
1604            FREE_OP2();
1605        }
1606        if (RETURN_VALUE_USED(opline)) {
1607            ZVAL_NULL(EX_VAR(opline->result.var));
1608        }
1609    } else {
1610        value = zend_assign_to_variable(variable_ptr, value, OP2_TYPE TSRMLS_CC);
1611        if (RETURN_VALUE_USED(opline)) {
1612            ZVAL_COPY(EX_VAR(opline->result.var), value);
1613        }
1614        FREE_OP1_VAR_PTR();
1615    }
1616
1617    /* zend_assign_to_variable() always takes care of op2, never free it! */
1618    FREE_OP2_IF_VAR();
1619
1620    CHECK_EXCEPTION();
1621    ZEND_VM_NEXT_OPCODE();
1622}
1623
1624ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
1625{
1626    USE_OPLINE
1627    zend_free_op free_op1, free_op2;
1628    zval *variable_ptr;
1629    zval *value_ptr;
1630
1631    SAVE_OPLINE();
1632    value_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);
1633
1634    if (OP2_TYPE == IS_VAR &&
1635        opline->extended_value == ZEND_RETURNS_FUNCTION &&
1636        !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
1637        !Z_ISREF_P(value_ptr)) {
1638        if (!OP2_FREE) {
1639            PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
1640        }
1641        zend_error(E_STRICT, "Only variables should be assigned by reference");
1642        if (UNEXPECTED(EG(exception) != NULL)) {
1643            FREE_OP2_VAR_PTR();
1644            HANDLE_EXCEPTION();
1645        }
1646        ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
1647    } else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
1648        if (!OP2_FREE) {
1649            PZVAL_LOCK(value_ptr);
1650        }
1651    }
1652
1653    variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1654    if (OP1_TYPE == IS_VAR &&
1655        UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
1656        UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
1657        zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
1658    }
1659    if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
1660        (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
1661        zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
1662    }
1663    if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
1664        (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
1665        variable_ptr = &EG(uninitialized_zval);
1666    } else {
1667        zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
1668    }
1669
1670    if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
1671        if (!OP2_FREE) {
1672            Z_DELREF_P(variable_ptr);
1673        }
1674    }
1675
1676    if (RETURN_VALUE_USED(opline)) {
1677        ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
1678    }
1679
1680    FREE_OP1_VAR_PTR();
1681    FREE_OP2_VAR_PTR();
1682
1683    CHECK_EXCEPTION();
1684    ZEND_VM_NEXT_OPCODE();
1685}
1686
1687ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
1688{
1689    vm_frame_kind frame_kind = VM_FRAME_KIND(EX(frame_info));
1690
1691    if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
1692        zend_object *object;
1693
1694        i_free_compiled_variables(execute_data TSRMLS_CC);
1695        if (UNEXPECTED(EX(symbol_table) != NULL)) {
1696            zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
1697        }
1698        zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
1699        EG(current_execute_data) = EX(prev_execute_data);
1700        if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
1701            OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
1702        }
1703        object = Z_OBJ(EX(This));
1704        zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
1705
1706        execute_data = EG(current_execute_data);
1707
1708        if (object) {
1709            if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
1710                if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
1711                    GC_REFCOUNT(object)--;
1712                }
1713                if (GC_REFCOUNT(object) == 1) {
1714                    zend_object_store_ctor_failed(object TSRMLS_CC);
1715                }
1716            }
1717            OBJ_RELEASE(object);
1718        }
1719        EG(scope) = EX(scope);
1720
1721        if (UNEXPECTED(EG(exception) != NULL)) {
1722            const zend_op *opline = EX(opline);
1723            zend_throw_exception_internal(NULL TSRMLS_CC);
1724            if (RETURN_VALUE_USED(opline)) {
1725                zval_ptr_dtor(EX_VAR(opline->result.var));
1726            }
1727            HANDLE_EXCEPTION_LEAVE();
1728        }
1729
1730        LOAD_OPLINE();
1731        ZEND_VM_INC_OPCODE();
1732        ZEND_VM_LEAVE();
1733    } else if (frame_kind == VM_FRAME_NESTED_CODE) {
1734        zend_detach_symbol_table(execute_data);
1735        destroy_op_array(&EX(func)->op_array TSRMLS_CC);
1736        efree_size(EX(func), sizeof(zend_op_array));
1737        EG(current_execute_data) = EX(prev_execute_data);
1738        zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
1739
1740        execute_data = EG(current_execute_data);
1741        zend_attach_symbol_table(execute_data);
1742        if (UNEXPECTED(EG(exception) != NULL)) {
1743            zend_throw_exception_internal(NULL TSRMLS_CC);
1744            HANDLE_EXCEPTION_LEAVE();
1745        }
1746
1747        LOAD_OPLINE();
1748        ZEND_VM_INC_OPCODE();
1749        ZEND_VM_LEAVE();
1750    } else {
1751        if (frame_kind == VM_FRAME_TOP_FUNCTION) {
1752            i_free_compiled_variables(execute_data TSRMLS_CC);
1753            if (UNEXPECTED(EX(symbol_table) != NULL)) {
1754                zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
1755            }
1756            zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
1757            EG(current_execute_data) = EX(prev_execute_data);
1758            if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
1759                OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
1760            }
1761        } else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
1762            zend_array *symbol_table = EX(symbol_table);
1763            zend_execute_data *old_execute_data;
1764
1765            zend_detach_symbol_table(execute_data);
1766            old_execute_data = EX(prev_execute_data);
1767            while (old_execute_data) {
1768                if (old_execute_data->func && ZEND_USER_CODE(old_execute_data->func->op_array.type)) {
1769                    if (old_execute_data->symbol_table == symbol_table) {
1770                        zend_attach_symbol_table(old_execute_data);
1771                    }
1772                    break;
1773                }
1774                old_execute_data = old_execute_data->prev_execute_data;
1775            }
1776            EG(current_execute_data) = EX(prev_execute_data);
1777        }
1778        zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
1779
1780        ZEND_VM_RETURN();
1781    }
1782}
1783
1784ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
1785{
1786    USE_OPLINE
1787
1788    ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
1789    ZEND_VM_CONTINUE();
1790}
1791
1792ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY)
1793{
1794    USE_OPLINE
1795    zend_free_op free_op1;
1796    zval *val;
1797
1798    SAVE_OPLINE();
1799    val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1800
1801    if (OP1_TYPE == IS_TMP_VAR) {
1802        if (Z_TYPE_P(val) == IS_TRUE) {
1803            ZEND_VM_SET_OPCODE(opline + 1);
1804            ZEND_VM_CONTINUE();
1805        } else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
1806            ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1807            ZEND_VM_CONTINUE();
1808        }
1809    }
1810
1811    if (i_zend_is_true(val TSRMLS_CC)) {
1812        opline++;
1813    } else {
1814        opline = opline->op2.jmp_addr;
1815    }
1816    FREE_OP1();
1817    if (UNEXPECTED(EG(exception) != NULL)) {
1818        HANDLE_EXCEPTION();
1819    }
1820    ZEND_VM_JMP(opline);
1821}
1822
1823ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY)
1824{
1825    USE_OPLINE
1826    zend_free_op free_op1;
1827    zval *val;
1828
1829    SAVE_OPLINE();
1830    val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1831
1832    if (OP1_TYPE == IS_TMP_VAR) {
1833        if (Z_TYPE_P(val) == IS_TRUE) {
1834            ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1835            ZEND_VM_CONTINUE();
1836        } else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
1837            ZEND_VM_SET_OPCODE(opline + 1);
1838            ZEND_VM_CONTINUE();
1839        }
1840    }
1841
1842    if (i_zend_is_true(val TSRMLS_CC)) {
1843        opline = opline->op2.jmp_addr;
1844    } else {
1845        opline++;
1846    }
1847    FREE_OP1();
1848    if (UNEXPECTED(EG(exception) != NULL)) {
1849        HANDLE_EXCEPTION();
1850    }
1851    ZEND_VM_JMP(opline);
1852}
1853
1854ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY)
1855{
1856    USE_OPLINE
1857    zend_free_op free_op1;
1858    zval *val;
1859
1860    SAVE_OPLINE();
1861    val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1862
1863    if (OP1_TYPE == IS_TMP_VAR) {
1864        if (EXPECTED(Z_TYPE_P(val) == IS_TRUE)) {
1865            ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
1866            ZEND_VM_CONTINUE();
1867        } else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
1868            ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1869            ZEND_VM_CONTINUE();
1870        }
1871    }
1872
1873    if (i_zend_is_true(val TSRMLS_CC)) {
1874        opline = (zend_op*)(((char*)opline) + opline->extended_value);
1875    } else {
1876        opline = opline->op2.jmp_addr;
1877    }
1878    FREE_OP1();
1879    if (UNEXPECTED(EG(exception) != NULL)) {
1880        HANDLE_EXCEPTION();
1881    }
1882    ZEND_VM_JMP(opline);
1883}
1884
1885ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|VAR|CV, ANY)
1886{
1887    USE_OPLINE
1888    zend_free_op free_op1;
1889    zval *val;
1890
1891    SAVE_OPLINE();
1892    val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1893
1894    if (OP1_TYPE == IS_TMP_VAR) {
1895        if (Z_TYPE_P(val) == IS_TRUE) {
1896            ZVAL_TRUE(EX_VAR(opline->result.var));
1897            ZEND_VM_SET_OPCODE(opline + 1);
1898            ZEND_VM_CONTINUE();
1899        } else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
1900            ZVAL_FALSE(EX_VAR(opline->result.var));
1901            ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1902            ZEND_VM_CONTINUE();
1903        }
1904    }
1905
1906    if (i_zend_is_true(val TSRMLS_CC)) {
1907        ZVAL_TRUE(EX_VAR(opline->result.var));
1908        opline++;
1909    } else {
1910        ZVAL_FALSE(EX_VAR(opline->result.var));
1911        opline = opline->op2.jmp_addr;
1912    }
1913    FREE_OP1();
1914    if (UNEXPECTED(EG(exception) != NULL)) {
1915        HANDLE_EXCEPTION();
1916    }
1917    ZEND_VM_JMP(opline);
1918}
1919
1920ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|VAR|CV, ANY)
1921{
1922    USE_OPLINE
1923    zend_free_op free_op1;
1924    zval *val;
1925
1926    SAVE_OPLINE();
1927    val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
1928
1929    if (OP1_TYPE == IS_TMP_VAR) {
1930        if (Z_TYPE_P(val) == IS_TRUE) {
1931            ZVAL_TRUE(EX_VAR(opline->result.var));
1932            ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1933            ZEND_VM_CONTINUE();
1934        } else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
1935            ZVAL_FALSE(EX_VAR(opline->result.var));
1936            ZEND_VM_SET_OPCODE(opline + 1);
1937            ZEND_VM_CONTINUE();
1938        }
1939    }
1940    if (i_zend_is_true(val TSRMLS_CC)) {
1941        ZVAL_TRUE(EX_VAR(opline->result.var));
1942        opline = opline->op2.jmp_addr;
1943    } else {
1944        ZVAL_FALSE(EX_VAR(opline->result.var));
1945        opline++;
1946    }
1947    FREE_OP1();
1948    if (UNEXPECTED(EG(exception) != NULL)) {
1949        HANDLE_EXCEPTION();
1950    }
1951    ZEND_VM_JMP(opline);
1952}
1953
1954ZEND_VM_HANDLER(70, ZEND_FREE, TMP|VAR, ANY)
1955{
1956    USE_OPLINE
1957
1958    SAVE_OPLINE();
1959    zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
1960    CHECK_EXCEPTION();
1961    ZEND_VM_NEXT_OPCODE();
1962}
1963
1964ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST)
1965{
1966    USE_OPLINE
1967    zval *str = EX_VAR(opline->result.var);
1968
1969    SAVE_OPLINE();
1970
1971    if (OP1_TYPE == IS_UNUSED) {
1972        /* Initialize for erealloc in add_char_to_string */
1973        ZVAL_EMPTY_STRING(str);
1974    }
1975
1976    add_char_to_string(str, str, opline->op2.zv);
1977
1978    /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
1979    /*CHECK_EXCEPTION();*/
1980    ZEND_VM_NEXT_OPCODE();
1981}
1982
1983ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP|UNUSED, CONST)
1984{
1985    USE_OPLINE
1986    zval *str = EX_VAR(opline->result.var);
1987
1988    SAVE_OPLINE();
1989
1990    if (OP1_TYPE == IS_UNUSED) {
1991        /* Initialize for erealloc in add_string_to_string */
1992        ZVAL_EMPTY_STRING(str);
1993    }
1994
1995    add_string_to_string(str, str, opline->op2.zv);
1996
1997    /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
1998    /*CHECK_EXCEPTION();*/
1999    ZEND_VM_NEXT_OPCODE();
2000}
2001
2002ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV)
2003{
2004    USE_OPLINE
2005    zend_free_op free_op2;
2006    zval *str = EX_VAR(opline->result.var);
2007    zval *var;
2008    zval var_copy;
2009    int use_copy = 0;
2010
2011    SAVE_OPLINE();
2012    var = GET_OP2_ZVAL_PTR(BP_VAR_R);
2013
2014    if (OP1_TYPE == IS_UNUSED) {
2015        /* Initialize for erealloc in add_string_to_string */
2016        ZVAL_EMPTY_STRING(str);
2017    }
2018
2019    if (Z_TYPE_P(var) != IS_STRING) {
2020        ZVAL_DEREF(var);
2021        if (Z_TYPE_P(var) != IS_STRING) {
2022            use_copy = zend_make_printable_zval(var, &var_copy TSRMLS_CC);
2023
2024            if (use_copy) {
2025                var = &var_copy;
2026            }
2027        }
2028    }
2029    add_string_to_string(str, str, var);
2030
2031    if (use_copy) {
2032        zval_dtor(var);
2033    }
2034    /* original comment, possibly problematic:
2035     * FREE_OP is missing intentionally here - we're always working on the same temporary variable
2036     * (Zeev):  I don't think it's problematic, we only use variables
2037     * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
2038     * string offsets or overloaded objects
2039     */
2040    FREE_OP2();
2041
2042    CHECK_EXCEPTION();
2043    ZEND_VM_NEXT_OPCODE();
2044}
2045
2046ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
2047{
2048    USE_OPLINE
2049
2050    SAVE_OPLINE();
2051    if (EG(exception)) {
2052        zend_exception_save(TSRMLS_C);
2053    }
2054    if (OP2_TYPE == IS_UNUSED) {
2055        Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->extended_value TSRMLS_CC);
2056        CHECK_EXCEPTION();
2057        ZEND_VM_NEXT_OPCODE();
2058    } else {
2059        zend_free_op free_op2;
2060        zval *class_name = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
2061
2062        if (OP2_TYPE == IS_CONST) {
2063            if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
2064                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
2065            } else {
2066                Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
2067                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
2068            }
2069        } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
2070            Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
2071        } else if (Z_TYPE_P(class_name) == IS_STRING) {
2072            Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
2073        } else {
2074            if (UNEXPECTED(EG(exception) != NULL)) {
2075                HANDLE_EXCEPTION();
2076            }
2077            zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
2078        }
2079
2080        FREE_OP2();
2081        CHECK_EXCEPTION();
2082        ZEND_VM_NEXT_OPCODE();
2083    }
2084}
2085
2086ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
2087{
2088    USE_OPLINE
2089    zval *function_name;
2090    zend_free_op free_op1, free_op2;
2091    zval *object;
2092    zend_function *fbc;
2093    zend_class_entry *called_scope;
2094    zend_object *obj;
2095
2096    SAVE_OPLINE();
2097
2098    function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2099
2100    if (OP2_TYPE != IS_CONST &&
2101        UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
2102        if (UNEXPECTED(EG(exception) != NULL)) {
2103            HANDLE_EXCEPTION();
2104        }
2105        zend_error_noreturn(E_ERROR, "Method name must be a string");
2106    }
2107
2108    object = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
2109
2110    if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
2111        uint32_t nesting = 1;
2112
2113        if (UNEXPECTED(EG(exception) != NULL)) {
2114            FREE_OP2();
2115            HANDLE_EXCEPTION();
2116        }
2117
2118        zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s",  Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
2119        FREE_OP2();
2120        FREE_OP1_IF_VAR();
2121
2122        if (EG(exception) != NULL) {
2123            HANDLE_EXCEPTION();
2124        }
2125
2126        /* No exception raised: Skip over arguments until fcall opcode with correct
2127         * nesting level. Return NULL (except when return value unused) */
2128        do {
2129            opline++;
2130            if (opline->opcode == ZEND_INIT_FCALL ||
2131                opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
2132                opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
2133                opline->opcode == ZEND_INIT_METHOD_CALL ||
2134                opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
2135                opline->opcode == ZEND_INIT_USER_CALL ||
2136                opline->opcode == ZEND_NEW
2137            ) {
2138                nesting++;
2139            } else if (opline->opcode == ZEND_DO_FCALL) {
2140                nesting--;
2141            }
2142        } while (nesting);
2143
2144        if (RETURN_VALUE_USED(opline)) {
2145            ZVAL_NULL(EX_VAR(opline->result.var));
2146        }
2147
2148        /* We've skipped EXT_FCALL_BEGIND, so also skip the ending opcode */
2149        if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) {
2150            opline++;
2151        }
2152        ZEND_VM_JMP(++opline);
2153    }
2154
2155    obj = Z_OBJ_P(object);
2156    called_scope = obj->ce;
2157
2158    if (OP2_TYPE != IS_CONST ||
2159        EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
2160        zend_object *orig_obj = obj;
2161
2162        if (UNEXPECTED(obj->handlers->get_method == NULL)) {
2163            zend_error_noreturn(E_ERROR, "Object does not support method calls");
2164        }
2165
2166        /* First, locate the function. */
2167        fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
2168        if (UNEXPECTED(fbc == NULL)) {
2169            zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", obj->ce->name->val, Z_STRVAL_P(function_name));
2170        }
2171        if (OP2_TYPE == IS_CONST &&
2172            EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
2173            EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
2174            EXPECTED(obj == orig_obj)) {
2175            CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
2176        }
2177    }
2178
2179    if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
2180        obj = NULL;
2181    } else {
2182        GC_REFCOUNT(obj)++; /* For $this pointer */
2183    }
2184
2185    EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2186        fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC);
2187
2188    FREE_OP2();
2189    FREE_OP1_IF_VAR();
2190
2191    CHECK_EXCEPTION();
2192    ZEND_VM_NEXT_OPCODE();
2193}
2194
2195ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUSED|CV)
2196{
2197    USE_OPLINE
2198    zval *function_name;
2199    zend_class_entry *ce;
2200    zend_object *object;
2201    zend_function *fbc;
2202
2203    SAVE_OPLINE();
2204
2205    if (OP1_TYPE == IS_CONST) {
2206        /* no function found. try a static method in class */
2207        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
2208            ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
2209        } else {
2210            ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
2211            if (UNEXPECTED(EG(exception) != NULL)) {
2212                HANDLE_EXCEPTION();
2213            }
2214            if (UNEXPECTED(ce == NULL)) {
2215                zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op1.zv));
2216            }
2217            CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
2218        }
2219    } else {
2220        ce = Z_CE_P(EX_VAR(opline->op1.var));
2221    }
2222
2223    if (OP1_TYPE == IS_CONST &&
2224        OP2_TYPE == IS_CONST &&
2225        CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
2226        fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
2227    } else if (OP1_TYPE != IS_CONST &&
2228               OP2_TYPE == IS_CONST &&
2229               (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
2230        /* do nothing */
2231    } else if (OP2_TYPE != IS_UNUSED) {
2232        zend_free_op free_op2;
2233
2234        function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2235        if (OP2_TYPE != IS_CONST) {
2236            if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
2237                if (UNEXPECTED(EG(exception) != NULL)) {
2238                    HANDLE_EXCEPTION();
2239                }
2240                zend_error_noreturn(E_ERROR, "Function name must be a string");
2241            }
2242        }
2243
2244        if (ce->get_static_method) {
2245            fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
2246        } else {
2247            fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
2248        }
2249        if (UNEXPECTED(fbc == NULL)) {
2250            zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
2251        }
2252        if (OP2_TYPE == IS_CONST &&
2253            EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
2254            EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
2255            if (OP1_TYPE == IS_CONST) {
2256                CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
2257            } else {
2258                CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
2259            }
2260        }
2261        if (OP2_TYPE != IS_CONST) {
2262            FREE_OP2();
2263        }
2264    } else {
2265        if (UNEXPECTED(ce->constructor == NULL)) {
2266            zend_error_noreturn(E_ERROR, "Cannot call constructor");
2267        }
2268        if (Z_OBJ(EX(This)) && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
2269            zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
2270        }
2271        fbc = ce->constructor;
2272    }
2273
2274    object = NULL;
2275    if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
2276        if (Z_OBJ(EX(This))) {
2277            object = Z_OBJ(EX(This));
2278            GC_REFCOUNT(object)++;
2279        }
2280        if (!object ||
2281            !instanceof_function(object->ce, ce TSRMLS_CC)) {
2282            /* We are calling method of the other (incompatible) class,
2283               but passing $this. This is done for compatibility with php-4. */
2284            if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
2285                zend_error(
2286                    object ? E_DEPRECATED : E_STRICT,
2287                    "Non-static method %s::%s() should not be called statically%s",
2288                    fbc->common.scope->name->val, fbc->common.function_name->val,
2289                    object ? ", assuming $this from incompatible context" : "");
2290            } else {
2291                /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2292                zend_error_noreturn(
2293                    E_ERROR,
2294                    "Non-static method %s::%s() cannot be called statically%s",
2295                    fbc->common.scope->name->val, fbc->common.function_name->val,
2296                    object ? ", assuming $this from incompatible context" : "");
2297            }
2298        }
2299    }
2300
2301    if (OP1_TYPE != IS_CONST) {
2302        /* previous opcode is ZEND_FETCH_CLASS */
2303        if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) {
2304            ce = EX(called_scope);
2305        }
2306    }
2307
2308    EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2309        fbc, opline->extended_value, ce, object, EX(call) TSRMLS_CC);
2310
2311    if (OP2_TYPE == IS_UNUSED) {
2312        EX(call)->return_value = NULL;
2313    }
2314
2315    CHECK_EXCEPTION();
2316    ZEND_VM_NEXT_OPCODE();
2317}
2318
2319ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
2320{
2321    USE_OPLINE
2322    zend_function *fbc;
2323    zval *function_name, *func;
2324
2325    if (OP2_TYPE == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) {
2326        function_name = (zval*)(opline->op2.zv+1);
2327        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
2328            fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
2329        } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
2330            SAVE_OPLINE();
2331            zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
2332        } else {
2333            fbc = Z_FUNC_P(func);
2334            CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
2335        }
2336
2337        EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2338            fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
2339
2340        /*CHECK_EXCEPTION();*/
2341        ZEND_VM_NEXT_OPCODE();
2342    } else {
2343        zend_string *lcname;
2344        zend_free_op free_op2;
2345        zend_class_entry *called_scope;
2346        zend_object *object;
2347        zval *function_name_ptr;
2348
2349        SAVE_OPLINE();
2350        function_name_ptr = function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2351
2352        ZVAL_DEREF(function_name);
2353        if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
2354            if (Z_STRVAL_P(function_name)[0] == '\\') {
2355                lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
2356                zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
2357            } else {
2358                lcname = zend_string_alloc(Z_STRLEN_P(function_name), 0);
2359                zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
2360            }
2361            if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
2362                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
2363            }
2364            zend_string_free(lcname);
2365            FREE_OP2();
2366
2367            fbc = Z_FUNC_P(func);
2368            called_scope = NULL;
2369            object = NULL;
2370        } else if (OP2_TYPE != IS_CONST &&
2371            EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
2372            Z_OBJ_HANDLER_P(function_name, get_closure) &&
2373            Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object TSRMLS_CC) == SUCCESS) {
2374            if (object) {
2375                GC_REFCOUNT(object)++;
2376            }
2377            if (OP2_TYPE == IS_VAR && OP2_FREE && Z_REFCOUNT_P(function_name) == 1 &&
2378                fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
2379                /* Delay closure destruction until its invocation */
2380                fbc->common.prototype = (zend_function*)Z_OBJ_P(function_name_ptr);
2381            } else if (OP2_TYPE == IS_CV) {
2382                FREE_OP2();
2383            }
2384        } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
2385                zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
2386            zval *obj;
2387            zval *method;
2388
2389            obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
2390            method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
2391
2392            if (!obj || !method) {
2393                zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
2394            }
2395
2396            ZVAL_DEREF(obj);
2397            if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
2398                zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
2399            }
2400
2401            ZVAL_DEREF(method);
2402            if (Z_TYPE_P(method) != IS_STRING) {
2403                zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
2404            }
2405
2406            if (Z_TYPE_P(obj) == IS_STRING) {
2407                object = NULL;
2408                called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
2409                if (UNEXPECTED(called_scope == NULL)) {
2410                    CHECK_EXCEPTION();
2411                    ZEND_VM_NEXT_OPCODE();
2412                }
2413
2414                if (called_scope->get_static_method) {
2415                    fbc = called_scope->get_static_method(called_scope, Z_STR_P(method) TSRMLS_CC);
2416                } else {
2417                    fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL TSRMLS_CC);
2418                }
2419                if (UNEXPECTED(fbc == NULL)) {
2420                    zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
2421                }
2422                if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
2423                    if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
2424                        zend_error(E_STRICT,
2425                        "Non-static method %s::%s() should not be called statically",
2426                        fbc->common.scope->name->val, fbc->common.function_name->val);
2427                    } else {
2428                        zend_error_noreturn(
2429                            E_ERROR,
2430                            "Non-static method %s::%s() cannot be called statically",
2431                            fbc->common.scope->name->val, fbc->common.function_name->val);
2432                    }
2433                }
2434            } else {
2435                called_scope = Z_OBJCE_P(obj);
2436                object = Z_OBJ_P(obj);
2437
2438                fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL TSRMLS_CC);
2439                if (UNEXPECTED(fbc == NULL)) {
2440                    zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
2441                }
2442
2443                if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
2444                    object = NULL;
2445                } else {
2446                    GC_REFCOUNT(object)++; /* For $this pointer */
2447                }
2448            }
2449            FREE_OP2();
2450        } else {
2451            if (UNEXPECTED(EG(exception) != NULL)) {
2452                HANDLE_EXCEPTION();
2453            }
2454            zend_error_noreturn(E_ERROR, "Function name must be a string");
2455            ZEND_VM_CONTINUE(); /* Never reached */
2456        }
2457        EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2458            fbc, opline->extended_value, called_scope, object, EX(call) TSRMLS_CC);
2459
2460        CHECK_EXCEPTION();
2461        ZEND_VM_NEXT_OPCODE();
2462    }
2463}
2464
2465ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMP|VAR|CV)
2466{
2467    USE_OPLINE
2468    zend_free_op free_op2;
2469    zval *function_name = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
2470    zend_fcall_info_cache fcc;
2471    char *error = NULL;
2472    zend_function *func;
2473    zend_class_entry *called_scope;
2474    zend_object *object;
2475
2476    if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error TSRMLS_CC)) {
2477        if (error) {
2478            efree(error);
2479        }
2480        func = fcc.function_handler;
2481        if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
2482            /* Delay closure destruction until its invocation */
2483            func->common.prototype = (zend_function*)Z_OBJ_P(function_name);
2484            Z_ADDREF_P(function_name);
2485        }
2486        called_scope = fcc.called_scope;
2487        object = fcc.object;
2488        if (object) {
2489            GC_REFCOUNT(object)++; /* For $this pointer */
2490        } else if (func->common.scope &&
2491                   !(func->common.fn_flags & ZEND_ACC_STATIC)) {
2492            if (func->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
2493                zend_error(E_STRICT,
2494                "Non-static method %s::%s() should not be called statically",
2495                func->common.scope->name->val, func->common.function_name->val);
2496            } else {
2497                zend_error_noreturn(
2498                    E_ERROR,
2499                    "Non-static method %s::%s() cannot be called statically",
2500                    func->common.scope->name->val, func->common.function_name->val);
2501            }
2502        }
2503    } else {
2504        zend_error(E_WARNING, "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(opline->op1.zv), error);
2505        efree(error);
2506        func = (zend_function*)&zend_pass_function;
2507        called_scope = NULL;
2508        object = NULL;
2509    }
2510
2511    EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2512        func, opline->extended_value, called_scope, object, EX(call) TSRMLS_CC);
2513
2514    FREE_OP2();
2515    CHECK_EXCEPTION();
2516    ZEND_VM_NEXT_OPCODE();
2517}
2518
2519ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
2520{
2521    USE_OPLINE
2522    zval *func_name;
2523    zval *func;
2524    zend_function *fbc;
2525
2526    func_name = opline->op2.zv + 1;
2527    if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
2528        fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
2529    } else if ((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL) {
2530        func_name++;
2531        if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL)) {
2532            SAVE_OPLINE();
2533            zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
2534        } else {
2535            fbc = Z_FUNC_P(func);
2536            CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
2537        }
2538    } else {
2539        fbc = Z_FUNC_P(func);
2540        CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
2541    }
2542
2543    EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2544        fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
2545
2546    ZEND_VM_NEXT_OPCODE();
2547}
2548
2549ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
2550{
2551    USE_OPLINE
2552    zend_free_op free_op2;
2553    zval *fname = GET_OP2_ZVAL_PTR(BP_VAR_R);
2554    zval *func;
2555    zend_function *fbc;
2556
2557    if (CACHED_PTR(Z_CACHE_SLOT_P(fname))) {
2558        fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname));
2559    } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(fname))) == NULL)) {
2560        SAVE_OPLINE();
2561        zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(fname));
2562    } else {
2563        fbc = Z_FUNC_P(func);
2564        CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc);
2565    }
2566
2567    EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
2568        fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
2569
2570    FREE_OP2();
2571
2572    ZEND_VM_NEXT_OPCODE();
2573}
2574
2575ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
2576{
2577    USE_OPLINE
2578    zend_execute_data *call = EX(call);
2579    zend_function *fbc = call->func;
2580    zend_object *object = Z_OBJ(call->This);
2581
2582    SAVE_OPLINE();
2583    EX(call) = call->prev_execute_data;
2584    if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
2585        if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
2586            zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
2587        }
2588        if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
2589            zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
2590                fbc->common.scope ? fbc->common.scope->name->val : "",
2591                fbc->common.scope ? "::" : "",
2592                fbc->common.function_name->val);
2593            if (UNEXPECTED(EG(exception) != NULL)) {
2594                HANDLE_EXCEPTION();
2595            }
2596        }
2597    }
2598
2599    LOAD_OPLINE();
2600
2601    if (UNEXPECTED(fbc->type == ZEND_INTERNAL_FUNCTION)) {
2602        int should_change_scope = 0;
2603        zval *ret;
2604
2605        if (fbc->common.scope) {
2606            should_change_scope = 1;
2607            /* TODO: we don't set scope if we call an object method ??? */
2608            /* See: ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt */
2609#if 1
2610            EG(scope) = object ? NULL : fbc->common.scope;
2611#else
2612            EG(scope) = fbc->common.scope;
2613#endif
2614        } else {
2615            call->called_scope = EX(called_scope);
2616            Z_OBJ(call->This) = Z_OBJ(EX(This));
2617        }
2618
2619        call->prev_execute_data = execute_data;
2620        EG(current_execute_data) = call;
2621
2622        if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
2623            uint32_t i;
2624            zval *p = ZEND_CALL_ARG(call, 1);
2625
2626            for (i = 0; i < call->num_args; ++i) {
2627                zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
2628                p++;
2629            }
2630            if (UNEXPECTED(EG(exception) != NULL)) {
2631                EG(current_execute_data) = call->prev_execute_data;
2632                zend_vm_stack_free_args(call TSRMLS_CC);
2633                zend_vm_stack_free_call_frame(call TSRMLS_CC);
2634                if (RETURN_VALUE_USED(opline)) {
2635                    ZVAL_UNDEF(EX_VAR(opline->result.var));
2636                }
2637                if (UNEXPECTED(should_change_scope)) {
2638                    ZEND_VM_C_GOTO(fcall_end_change_scope);
2639                } else {
2640                    ZEND_VM_C_GOTO(fcall_end);
2641                }
2642            }
2643        }
2644
2645        ret = EX_VAR(opline->result.var);
2646        ZVAL_NULL(ret);
2647        Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
2648
2649        if (!zend_execute_internal) {
2650            /* saves one function call if zend_execute_internal is not used */
2651            fbc->internal_function.handler(call, ret TSRMLS_CC);
2652        } else {
2653            zend_execute_internal(call, ret TSRMLS_CC);
2654        }
2655        EG(current_execute_data) = call->prev_execute_data;
2656        zend_vm_stack_free_args(call TSRMLS_CC);
2657        zend_vm_stack_free_call_frame(call TSRMLS_CC);
2658
2659        if (!RETURN_VALUE_USED(opline)) {
2660            zval_ptr_dtor(ret);
2661        }
2662
2663        if (UNEXPECTED(should_change_scope)) {
2664            ZEND_VM_C_GOTO(fcall_end_change_scope);
2665        } else {
2666            ZEND_VM_C_GOTO(fcall_end);
2667        }
2668    } else if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
2669        call->scope = EG(scope) = fbc->common.scope;
2670        if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
2671            if (RETURN_VALUE_USED(opline)) {
2672                zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
2673            } else {
2674                zend_vm_stack_free_args(call TSRMLS_CC);
2675            }
2676
2677            zend_vm_stack_free_call_frame(call TSRMLS_CC);
2678        } else {
2679            zval *return_value = NULL;
2680
2681            call->symbol_table = NULL;
2682            if (RETURN_VALUE_USED(opline)) {
2683                return_value = EX_VAR(opline->result.var);
2684
2685                ZVAL_NULL(return_value);
2686                Z_VAR_FLAGS_P(return_value) = 0;
2687            }
2688
2689            call->prev_execute_data = execute_data;
2690            i_init_func_execute_data(call, &fbc->op_array, return_value TSRMLS_CC);
2691
2692            if (EXPECTED(zend_execute_ex == execute_ex)) {
2693                ZEND_VM_ENTER();
2694            } else {
2695                call->frame_info = VM_FRAME_INFO(
2696                    VM_FRAME_TOP_FUNCTION,
2697                    VM_FRAME_FLAGS(call->frame_info));
2698                zend_execute_ex(call TSRMLS_CC);
2699            }
2700        }
2701    } else { /* ZEND_OVERLOADED_FUNCTION */
2702        EG(scope) = fbc->common.scope;
2703
2704        ZVAL_NULL(EX_VAR(opline->result.var));
2705
2706        /* Not sure what should be done here if it's a static method */
2707        if (EXPECTED(object != NULL)) {
2708            call->prev_execute_data = execute_data;
2709            EG(current_execute_data) = call;
2710            object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var) TSRMLS_CC);
2711            EG(current_execute_data) = call->prev_execute_data;
2712        } else {
2713            zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
2714        }
2715
2716        zend_vm_stack_free_args(call TSRMLS_CC);
2717
2718        zend_vm_stack_free_call_frame(call TSRMLS_CC);
2719
2720        if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
2721            zend_string_release(fbc->common.function_name);
2722        }
2723        efree(fbc);
2724
2725        if (!RETURN_VALUE_USED(opline)) {
2726            zval_ptr_dtor(EX_VAR(opline->result.var));
2727        } else {
2728//???           Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
2729//???           Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
2730            Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0;
2731        }
2732    }
2733
2734ZEND_VM_C_LABEL(fcall_end_change_scope):
2735    if (object) {
2736        if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) {
2737            if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
2738                GC_REFCOUNT(object)--;
2739            }
2740            if (GC_REFCOUNT(object) == 1) {
2741                zend_object_store_ctor_failed(object TSRMLS_CC);
2742            }
2743        }
2744        OBJ_RELEASE(object);
2745    }
2746    EG(scope) = EX(scope);
2747
2748ZEND_VM_C_LABEL(fcall_end):
2749    if (UNEXPECTED(EG(exception) != NULL)) {
2750        zend_throw_exception_internal(NULL TSRMLS_CC);
2751        if (RETURN_VALUE_USED(opline)) {
2752            zval_ptr_dtor(EX_VAR(opline->result.var));
2753        }
2754        HANDLE_EXCEPTION();
2755    }
2756
2757    ZEND_VM_NEXT_OPCODE();
2758}
2759
2760ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
2761{
2762    USE_OPLINE
2763    zval *retval_ptr;
2764    zend_free_op free_op1;
2765
2766    SAVE_OPLINE();
2767    retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
2768
2769    if (!EX(return_value)) {
2770        FREE_OP1();
2771    } else {
2772        if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
2773            ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
2774            if (OP1_TYPE == IS_CONST) {
2775                if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) {
2776                    zval_copy_ctor_func(EX(return_value));
2777                }
2778            }
2779        } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(retval_ptr)) {
2780            ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
2781            FREE_OP1_IF_VAR();
2782        } else {
2783            ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
2784            if (OP1_TYPE == IS_CV) {
2785                if (Z_OPT_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
2786            }
2787        }
2788    }
2789    ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
2790}
2791
2792ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
2793{
2794    USE_OPLINE
2795    zval *retval_ptr;
2796    zend_free_op free_op1;
2797
2798    SAVE_OPLINE();
2799
2800    do {
2801        if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR ||
2802            (OP1_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
2803            /* Not supposed to happen, but we'll allow it */
2804            zend_error(E_NOTICE, "Only variable references should be returned by reference");
2805
2806            retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
2807            if (!EX(return_value)) {
2808                if (OP1_TYPE == IS_TMP_VAR) {
2809                    FREE_OP1();
2810                }
2811            } else {
2812                ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
2813                Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
2814                if (OP1_TYPE != IS_TMP_VAR) {
2815                    zval_opt_copy_ctor_no_imm(EX(return_value));
2816                }
2817            }
2818            break;
2819        }
2820
2821        retval_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
2822
2823        if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
2824            zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
2825        }
2826
2827        if (OP1_TYPE == IS_VAR && !Z_ISREF_P(retval_ptr)) {
2828            if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
2829                (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
2830            } else {
2831                zend_error(E_NOTICE, "Only variable references should be returned by reference");
2832                if (EX(return_value)) {
2833                    ZVAL_NEW_REF(EX(return_value), retval_ptr);
2834                    Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
2835                    if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
2836                }
2837                break;
2838            }
2839        }
2840
2841        if (EX(return_value)) {
2842            ZVAL_MAKE_REF(retval_ptr);
2843            Z_ADDREF_P(retval_ptr);
2844            ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
2845            Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
2846        }
2847    } while (0);
2848
2849    FREE_OP1_VAR_PTR();
2850    ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
2851}
2852
2853ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, ANY, ANY)
2854{
2855    /* The generator object is stored in EX(return_value) */
2856    zend_generator *generator = (zend_generator *) EX(return_value);
2857
2858    /* Close the generator to free up resources */
2859    zend_generator_close(generator, 1 TSRMLS_CC);
2860
2861    /* Pass execution back to handling code */
2862    ZEND_VM_RETURN();
2863}
2864
2865ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
2866{
2867    USE_OPLINE
2868    zval *value;
2869    zend_free_op free_op1;
2870
2871    SAVE_OPLINE();
2872    value = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
2873
2874    if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
2875        if (UNEXPECTED(EG(exception) != NULL)) {
2876            HANDLE_EXCEPTION();
2877        }
2878        zend_error_noreturn(E_ERROR, "Can only throw objects");
2879    }
2880
2881    zend_exception_save(TSRMLS_C);
2882    if (OP1_TYPE != IS_TMP_VAR) {
2883        if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
2884    }
2885
2886    zend_throw_exception_object(value TSRMLS_CC);
2887    zend_exception_restore(TSRMLS_C);
2888    FREE_OP1_IF_VAR();
2889    HANDLE_EXCEPTION();
2890}
2891
2892ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
2893{
2894    USE_OPLINE
2895    zend_class_entry *ce, *catch_ce;
2896    zend_object *exception;
2897
2898    SAVE_OPLINE();
2899    /* Check whether an exception has been thrown, if not, jump over code */
2900    zend_exception_restore(TSRMLS_C);
2901    if (EG(exception) == NULL) {
2902        ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
2903        ZEND_VM_CONTINUE(); /* CHECK_ME */
2904    }
2905    if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
2906        catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
2907    } else {
2908        catch_ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
2909
2910        CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), catch_ce);
2911    }
2912    ce = EG(exception)->ce;
2913
2914#ifdef HAVE_DTRACE
2915    if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
2916        DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
2917    }
2918#endif /* HAVE_DTRACE */
2919
2920    if (ce != catch_ce) {
2921        if (!instanceof_function(ce, catch_ce TSRMLS_CC)) {
2922            if (opline->result.num) {
2923                zend_throw_exception_internal(NULL TSRMLS_CC);
2924                HANDLE_EXCEPTION();
2925            }
2926            ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
2927            ZEND_VM_CONTINUE(); /* CHECK_ME */
2928        }
2929    }
2930
2931    exception = EG(exception);
2932    if (Z_REFCOUNTED_P(EX_VAR(opline->op2.var))) {
2933        zval_ptr_dtor(EX_VAR(opline->op2.var));
2934    }
2935    ZVAL_OBJ(EX_VAR(opline->op2.var), EG(exception));
2936    if (UNEXPECTED(EG(exception) != exception)) {
2937        GC_REFCOUNT(EG(exception))++;
2938        HANDLE_EXCEPTION();
2939    } else {
2940        EG(exception) = NULL;
2941        ZEND_VM_NEXT_OPCODE();
2942    }
2943}
2944
2945ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
2946{
2947    USE_OPLINE
2948    zval *value, *arg;
2949    zend_free_op free_op1;
2950
2951    SAVE_OPLINE();
2952    value = GET_OP1_ZVAL_PTR(BP_VAR_R);
2953    arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
2954    EX(call)->num_args = opline->op2.num;
2955    ZVAL_COPY_VALUE(arg, value);
2956    if (OP1_TYPE == IS_CONST) {
2957        if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
2958            zval_copy_ctor_func(arg);
2959        }
2960    }
2961    ZEND_VM_NEXT_OPCODE();
2962}
2963
2964ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, ANY)
2965{
2966    USE_OPLINE
2967    zval *value, *arg;
2968    zend_free_op free_op1;
2969
2970    SAVE_OPLINE();
2971    if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
2972        zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num);
2973    }
2974    value = GET_OP1_ZVAL_PTR(BP_VAR_R);
2975    arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
2976    EX(call)->num_args = opline->op2.num;
2977    ZVAL_COPY_VALUE(arg, value);
2978    if (OP1_TYPE == IS_CONST) {
2979        if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
2980            zval_copy_ctor_func(arg);
2981        }
2982    }
2983    ZEND_VM_NEXT_OPCODE();
2984}
2985
2986ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY)
2987{
2988    USE_OPLINE
2989    zval *varptr, *arg;
2990    zend_free_op free_op1;
2991
2992    varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
2993    arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
2994    EX(call)->num_args = opline->op2.num;
2995    if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
2996        ZVAL_COPY(arg, Z_REFVAL_P(varptr));
2997        FREE_OP1();
2998    } else {
2999        ZVAL_COPY_VALUE(arg, varptr);
3000        if (OP1_TYPE == IS_CV) {
3001            if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
3002        }
3003    }
3004    ZEND_VM_NEXT_OPCODE();
3005}
3006
3007ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
3008{
3009    USE_OPLINE
3010    zend_free_op free_op1;
3011    zval *varptr, *arg;
3012
3013    SAVE_OPLINE();
3014    if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
3015        if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
3016            ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
3017        }
3018    } else {
3019        if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
3020            ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
3021        }
3022    }
3023
3024    varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3025    if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
3026         (Z_VAR_FLAGS_P(varptr) & IS_VAR_RET_REF)) &&
3027        (Z_ISREF_P(varptr) || Z_TYPE_P(varptr) == IS_OBJECT)) {
3028
3029        ZVAL_MAKE_REF(varptr);
3030        if (OP1_TYPE == IS_CV) {
3031            Z_ADDREF_P(varptr);
3032        }
3033        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
3034        EX(call)->num_args = opline->op2.num;
3035        ZVAL_COPY_VALUE(arg, varptr);
3036    } else {
3037        if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
3038            !(opline->extended_value & ZEND_ARG_SEND_SILENT) :
3039            !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
3040            zend_error(E_STRICT, "Only variables should be passed by reference");
3041        }
3042        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
3043        EX(call)->num_args = opline->op2.num;
3044        ZVAL_COPY(arg, varptr);
3045        FREE_OP1_IF_VAR();
3046    }
3047    CHECK_EXCEPTION();
3048    ZEND_VM_NEXT_OPCODE();
3049}
3050
3051ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
3052{
3053    USE_OPLINE
3054    zend_free_op free_op1;
3055    zval *varptr, *arg;
3056
3057    SAVE_OPLINE();
3058    varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
3059
3060    if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == NULL)) {
3061        zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
3062    }
3063
3064    arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
3065    EX(call)->num_args = opline->op2.num;
3066    if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
3067        ZVAL_NEW_REF(arg, &EG(uninitialized_zval));
3068        ZEND_VM_NEXT_OPCODE();
3069    }
3070
3071    if (Z_ISREF_P(varptr)) {
3072        Z_ADDREF_P(varptr);
3073        ZVAL_COPY_VALUE(arg, varptr);
3074    } else if (OP1_TYPE == IS_VAR &&
3075        UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
3076        ZVAL_COPY_VALUE(arg, varptr);
3077        ZVAL_MAKE_REF(arg);
3078    } else {
3079        ZVAL_MAKE_REF(varptr);
3080        Z_ADDREF_P(varptr);
3081        ZVAL_REF(arg, Z_REF_P(varptr));
3082    }
3083
3084    FREE_OP1_VAR_PTR();
3085    ZEND_VM_NEXT_OPCODE();
3086}
3087
3088ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY)
3089{
3090    USE_OPLINE
3091    zval *varptr, *arg;
3092    zend_free_op free_op1;
3093
3094    if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
3095        ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
3096    }
3097    varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3098    arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
3099    EX(call)->num_args = opline->op2.num;
3100    if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
3101        ZVAL_COPY(arg, Z_REFVAL_P(varptr));
3102        FREE_OP1();
3103    } else {
3104        ZVAL_COPY_VALUE(arg, varptr);
3105        if (OP1_TYPE == IS_CV) {
3106            if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
3107        }
3108    }
3109    ZEND_VM_NEXT_OPCODE();
3110}
3111
3112ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
3113{
3114    USE_OPLINE
3115    zend_free_op free_op1;
3116    zval *args;
3117    int arg_num;
3118    SAVE_OPLINE();
3119
3120    args = GET_OP1_ZVAL_PTR(BP_VAR_R);
3121    arg_num = EX(call)->num_args + 1;
3122
3123ZEND_VM_C_LABEL(send_again):
3124    switch (Z_TYPE_P(args)) {
3125        case IS_ARRAY: {
3126            HashTable *ht = Z_ARRVAL_P(args);
3127            zval *arg, *top;
3128            zend_string *name;
3129
3130            zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht) TSRMLS_CC);
3131
3132            if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
3133                uint32_t i;
3134                int separate = 0;
3135
3136                /* check if any of arguments are going to be passed by reference */
3137                for (i = 0; i < zend_hash_num_elements(ht); i++) {
3138                    if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
3139                        separate = 1;
3140                        break;
3141                    }
3142                }
3143                if (separate) {
3144                    zval_copy_ctor(args);
3145                    ht = Z_ARRVAL_P(args);
3146                }
3147            }
3148
3149            ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
3150                if (name) {
3151                    zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys");
3152                    FREE_OP1();
3153                    CHECK_EXCEPTION();
3154                    ZEND_VM_NEXT_OPCODE();
3155                }
3156
3157                top = ZEND_CALL_ARG(EX(call), arg_num);
3158                if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
3159                    if (!Z_IMMUTABLE_P(args)) {
3160                        ZVAL_MAKE_REF(arg);
3161                        Z_ADDREF_P(arg);
3162                        ZVAL_REF(top, Z_REF_P(arg));
3163                    } else {
3164                        ZVAL_DUP(top, arg);
3165                    }
3166                } else if (Z_ISREF_P(arg)) {
3167                    ZVAL_COPY(top, Z_REFVAL_P(arg));
3168                } else {
3169                    ZVAL_COPY(top, arg);
3170                }
3171
3172                EX(call)->num_args++;
3173                arg_num++;
3174            } ZEND_HASH_FOREACH_END();
3175
3176            break;
3177        }
3178        case IS_OBJECT: {
3179            zend_class_entry *ce = Z_OBJCE_P(args);
3180            zend_object_iterator *iter;
3181
3182            if (!ce || !ce->get_iterator) {
3183                zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
3184                break;
3185            }
3186
3187            iter = ce->get_iterator(ce, args, 0 TSRMLS_CC);
3188            if (UNEXPECTED(!iter)) {
3189                FREE_OP1();
3190                if (!EG(exception)) {
3191                    zend_throw_exception_ex(
3192                        NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name->val
3193                    );
3194                }
3195                HANDLE_EXCEPTION();
3196            }
3197
3198            if (iter->funcs->rewind) {
3199                iter->funcs->rewind(iter TSRMLS_CC);
3200                if (UNEXPECTED(EG(exception) != NULL)) {
3201                    ZEND_VM_C_GOTO(unpack_iter_dtor);
3202                }
3203            }
3204
3205            for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) {
3206                zval *arg, *top;
3207
3208                if (UNEXPECTED(EG(exception) != NULL)) {
3209                    ZEND_VM_C_GOTO(unpack_iter_dtor);
3210                }
3211
3212                arg = iter->funcs->get_current_data(iter TSRMLS_CC);
3213                if (UNEXPECTED(EG(exception) != NULL)) {
3214                    ZEND_VM_C_GOTO(unpack_iter_dtor);
3215                }
3216
3217                if (iter->funcs->get_current_key) {
3218                    zval key;
3219                    iter->funcs->get_current_key(iter, &key TSRMLS_CC);
3220                    if (UNEXPECTED(EG(exception) != NULL)) {
3221                        ZEND_VM_C_GOTO(unpack_iter_dtor);
3222                    }
3223
3224                    if (Z_TYPE(key) == IS_STRING) {
3225                        zend_error(E_RECOVERABLE_ERROR,
3226                            "Cannot unpack Traversable with string keys");
3227                        zval_dtor(&key);
3228                        ZEND_VM_C_GOTO(unpack_iter_dtor);
3229                    }
3230
3231                    zval_dtor(&key);
3232                }
3233
3234                if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
3235                    zend_error(
3236                        E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
3237                        " by unpacking a Traversable, passing by-value instead", arg_num,
3238                        EX(call)->func->common.scope ? EX(call)->func->common.scope->name->val : "",
3239                        EX(call)->func->common.scope ? "::" : "",
3240                        EX(call)->func->common.function_name->val
3241                    );
3242                }
3243
3244                if (Z_ISREF_P(arg)) {
3245                    ZVAL_DUP(arg, Z_REFVAL_P(arg));
3246                } else {
3247                    if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
3248                }
3249
3250                zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1 TSRMLS_CC);
3251                top = ZEND_CALL_ARG(EX(call), arg_num);
3252                ZVAL_COPY_VALUE(top, arg);
3253                EX(call)->num_args++;
3254
3255                iter->funcs->move_forward(iter TSRMLS_CC);
3256                if (UNEXPECTED(EG(exception) != NULL)) {
3257                    ZEND_VM_C_GOTO(unpack_iter_dtor);
3258                }
3259            }
3260
3261ZEND_VM_C_LABEL(unpack_iter_dtor):
3262            zend_iterator_dtor(iter TSRMLS_CC);
3263            break;
3264        }
3265        case IS_REFERENCE:
3266            args = Z_REFVAL_P(args);
3267            ZEND_VM_C_GOTO(send_again);
3268            break;
3269        default:
3270            zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
3271    }
3272
3273    FREE_OP1();
3274    CHECK_EXCEPTION();
3275    ZEND_VM_NEXT_OPCODE();
3276}
3277
3278ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY)
3279{
3280    USE_OPLINE
3281    zend_free_op free_op1;
3282    zval *args;
3283    SAVE_OPLINE();
3284
3285    args = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
3286
3287    if (Z_TYPE_P(args) != IS_ARRAY) {
3288        zend_error(E_WARNING, "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args)));
3289        if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) {
3290            OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
3291        }
3292        if (Z_OBJ(EX(call)->This)) {
3293            OBJ_RELEASE(Z_OBJ(EX(call)->This));
3294        }
3295        EX(call)->func = (zend_function*)&zend_pass_function;
3296        EX(call)->called_scope = NULL;
3297        Z_OBJ(EX(call)->This) = NULL;
3298    } else {
3299        uint32_t arg_num = 1;
3300
3301        HashTable *ht = Z_ARRVAL_P(args);
3302        zval *arg, *param, tmp;
3303
3304        zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht) TSRMLS_CC);
3305
3306        if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
3307            uint32_t i;
3308            int separate = 0;
3309
3310            /* check if any of arguments are going to be passed by reference */
3311            for (i = 0; i < zend_hash_num_elements(ht); i++) {
3312                if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
3313                    separate = 1;
3314                    break;
3315                }
3316            }
3317            if (separate) {
3318                zval_copy_ctor(args);
3319                ht = Z_ARRVAL_P(args);
3320            }
3321        }
3322
3323        param = ZEND_CALL_ARG(EX(call), arg_num);
3324        ZEND_HASH_FOREACH_VAL(ht, arg) {
3325            if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
3326                // TODO: Scalar values don't have reference counters anymore.
3327                // They are assumed to be 1, and they may be easily passed by
3328                // reference now. However, previously scalars with refcount==1
3329                // might be passed and with refcount>1 might not. We can support
3330                // only single behavior ???
3331#if 0
3332                if (Z_REFCOUNTED_P(arg) &&
3333                    // This solution breaks the following test (omit warning message) ???
3334                    // Zend/tests/bug61273.phpt
3335                    // ext/reflection/tests/bug42976.phpt
3336                    // ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt
3337#else
3338                if (!Z_REFCOUNTED_P(arg) ||
3339                    // This solution breaks the following test (emit warning message) ???
3340                    // ext/pdo_sqlite/tests/pdo_005.phpt
3341#endif
3342                    (!Z_ISREF_P(arg) && Z_REFCOUNT_P(arg) > 1)) {
3343
3344                    if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
3345
3346                        zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
3347                            arg_num,
3348                            EX(call)->func->common.scope ? EX(call)->func->common.scope->name->val : "",
3349                            EX(call)->func->common.scope ? "::" : "",
3350                            EX(call)->func->common.function_name->val);
3351
3352                        if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) {
3353                            OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
3354                        }
3355                        if (Z_OBJ(EX(call)->This)) {
3356                            OBJ_RELEASE(Z_OBJ(EX(call)->This));
3357                        }
3358                        EX(call)->func = (zend_function*)&zend_pass_function;
3359                        EX(call)->called_scope = NULL;
3360                        Z_OBJ(EX(call)->This) = NULL;
3361
3362                        break;
3363                    }
3364
3365                    if (Z_REFCOUNTED_P(arg)) {
3366                        Z_DELREF_P(arg);
3367                    }
3368                    ZVAL_DUP(&tmp, arg);
3369                    ZVAL_NEW_REF(arg, &tmp);
3370                    Z_ADDREF_P(arg);
3371                } else if (!Z_ISREF_P(arg)) {
3372                    ZVAL_NEW_REF(arg, arg);
3373                    Z_ADDREF_P(arg);
3374                } else if (Z_REFCOUNTED_P(arg)) {
3375                    Z_ADDREF_P(arg);
3376                }
3377                ZVAL_COPY_VALUE(param, arg);
3378            } else if (Z_ISREF_P(arg) &&
3379                   /* don't separate references for __call */
3380                   (EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0) {
3381                ZVAL_DUP(param, Z_REFVAL_P(arg));
3382            } else {
3383                ZVAL_COPY(param, arg);
3384            }
3385            EX(call)->num_args++;
3386            arg_num++;
3387            param++;
3388        } ZEND_HASH_FOREACH_END();
3389    }
3390    FREE_OP1();
3391    CHECK_EXCEPTION();
3392    ZEND_VM_NEXT_OPCODE();
3393}
3394
3395ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY)
3396{
3397    USE_OPLINE
3398    zval *arg, *param, tmp;
3399    zend_free_op free_op1;
3400
3401    arg = GET_OP1_ZVAL_PTR(BP_VAR_R);
3402    param = ZEND_CALL_ARG(EX(call), opline->op2.num);
3403
3404    if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
3405        // TODO: Scalar values don't have reference counters anymore.
3406        // They are assumed to be 1, and they may be easily passed by
3407        // reference now. However, previously scalars with refcount==1
3408        // might be passed and with refcount>1 might not. We can support
3409        // only single behavior ???
3410#if 0
3411        if (Z_REFCOUNTED_P(arg) &&
3412            // This solution breaks the following test (omit warning message) ???
3413            // Zend/tests/bug61273.phpt
3414            // ext/reflection/tests/bug42976.phpt
3415            // ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt
3416#else
3417        if (!Z_REFCOUNTED_P(arg) ||
3418            // This solution breaks the following test (emit warning message) ???
3419            // ext/pdo_sqlite/tests/pdo_005.phpt
3420#endif
3421            (!Z_ISREF_P(arg) /*&& Z_REFCOUNT_P(arg) > 1???*/)) {
3422
3423            if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
3424
3425                zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
3426                    opline->op2.num,
3427                    EX(call)->func->common.scope ? EX(call)->func->common.scope->name->val : "",
3428                    EX(call)->func->common.scope ? "::" : "",
3429                    EX(call)->func->common.function_name->val);
3430
3431                if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) {
3432                    OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
3433                }
3434                if (Z_OBJ(EX(call)->This)) {
3435                    OBJ_RELEASE(Z_OBJ(EX(call)->This));
3436                }
3437                EX(call)->func = (zend_function*)&zend_pass_function;
3438                EX(call)->called_scope = NULL;
3439                Z_OBJ(EX(call)->This) = NULL;
3440
3441                FREE_OP1();
3442                CHECK_EXCEPTION();
3443                ZEND_VM_NEXT_OPCODE();
3444            }
3445
3446            if (Z_REFCOUNTED_P(arg)) {
3447                Z_DELREF_P(arg);
3448            }
3449            ZVAL_DUP(&tmp, arg);
3450            ZVAL_NEW_REF(arg, &tmp);
3451            Z_ADDREF_P(arg);
3452        } else if (!Z_ISREF_P(arg)) {
3453            ZVAL_NEW_REF(arg, arg);
3454            Z_ADDREF_P(arg);
3455        } else if (Z_REFCOUNTED_P(arg)) {
3456            Z_ADDREF_P(arg);
3457        }
3458        ZVAL_COPY_VALUE(param, arg);
3459    } else if (Z_ISREF_P(arg) &&
3460               /* don't separate references for __call */
3461               (EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0) {
3462        ZVAL_DUP(param, Z_REFVAL_P(arg));
3463    } else {
3464        ZVAL_COPY(param, arg);
3465    }
3466
3467    EX(call)->num_args = opline->op2.num;
3468
3469    FREE_OP1();
3470    CHECK_EXCEPTION();
3471    ZEND_VM_NEXT_OPCODE();
3472}
3473
3474ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
3475{
3476    USE_OPLINE
3477    uint32_t arg_num = opline->op1.num;
3478
3479    SAVE_OPLINE();
3480    if (UNEXPECTED(arg_num > EX(num_args))) {
3481        zend_verify_missing_arg(execute_data, arg_num TSRMLS_CC);
3482        CHECK_EXCEPTION();
3483    } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
3484        zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
3485
3486        zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
3487        CHECK_EXCEPTION();
3488    }
3489
3490    ZEND_VM_NEXT_OPCODE();
3491}
3492
3493ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
3494{
3495    USE_OPLINE
3496    uint32_t arg_num = opline->op1.num;
3497    zval *param;
3498
3499    SAVE_OPLINE();
3500    param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
3501    if (arg_num > EX(num_args)) {
3502        ZVAL_COPY_VALUE(param, opline->op2.zv);
3503        if (Z_OPT_CONSTANT_P(param)) {
3504            zval_update_constant(param, 0 TSRMLS_CC);
3505        } else {
3506            /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
3507            if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) {
3508                zval_copy_ctor_func(param);
3509            }
3510        }
3511    }
3512
3513    if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
3514        zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
3515    }
3516
3517    CHECK_EXCEPTION();
3518    ZEND_VM_NEXT_OPCODE();
3519}
3520
3521ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
3522{
3523    USE_OPLINE
3524    uint32_t arg_num = opline->op1.num;
3525    uint32_t arg_count = EX(num_args);
3526    zval *params;
3527
3528    SAVE_OPLINE();
3529
3530    params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
3531
3532    if (arg_num <= arg_count) {
3533        zval *param;
3534
3535        array_init_size(params, arg_count - arg_num + 1);
3536        param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
3537        if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
3538            do {
3539                zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
3540                zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
3541                if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
3542                param++;
3543            } while (++arg_num <= arg_count);
3544        } else {
3545            do {
3546                zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
3547                if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
3548                param++;
3549            } while (++arg_num <= arg_count);
3550        }
3551    } else {
3552        array_init(params);
3553    }
3554
3555    CHECK_EXCEPTION();
3556    ZEND_VM_NEXT_OPCODE();
3557}
3558
3559ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY)
3560{
3561    USE_OPLINE
3562    zend_free_op free_op1;
3563    zval *retval = EX_VAR(opline->result.var);
3564
3565    SAVE_OPLINE();
3566    /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
3567    ZVAL_BOOL(retval, i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
3568    FREE_OP1();
3569
3570    CHECK_EXCEPTION();
3571    ZEND_VM_NEXT_OPCODE();
3572}
3573
3574ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
3575{
3576    USE_OPLINE
3577    zend_brk_cont_element *el;
3578
3579    SAVE_OPLINE();
3580    el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
3581                       &EX(func)->op_array, execute_data TSRMLS_CC);
3582    ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
3583}
3584
3585ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
3586{
3587    USE_OPLINE
3588    zend_brk_cont_element *el;
3589
3590    SAVE_OPLINE();
3591    el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
3592                       &EX(func)->op_array, execute_data TSRMLS_CC);
3593    ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
3594}
3595
3596ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
3597{
3598    zend_op *brk_opline;
3599    USE_OPLINE
3600    zend_brk_cont_element *el;
3601
3602    SAVE_OPLINE();
3603    el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
3604                       &EX(func)->op_array, execute_data TSRMLS_CC);
3605
3606    brk_opline = EX(func)->op_array.opcodes + el->brk;
3607
3608    if (brk_opline->opcode == ZEND_FREE) {
3609        if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
3610            zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
3611        }
3612    }
3613    ZEND_VM_JMP(opline->op1.jmp_addr);
3614}
3615
3616ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
3617{
3618    USE_OPLINE
3619    zend_free_op free_op1, free_op2;
3620    zval *result = EX_VAR(opline->result.var);
3621
3622    SAVE_OPLINE();
3623    fast_equal_function(result,
3624         GET_OP1_ZVAL_PTR(BP_VAR_R),
3625         GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
3626
3627    FREE_OP2();
3628    CHECK_EXCEPTION();
3629    ZEND_VM_NEXT_OPCODE();
3630}
3631
3632ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
3633{
3634    USE_OPLINE
3635    zval object_zval;
3636    zend_function *constructor;
3637
3638    SAVE_OPLINE();
3639    if (UNEXPECTED((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
3640        if (Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_INTERFACE) {
3641            zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
3642        } else if ((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
3643            zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
3644        } else {
3645            zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
3646        }
3647    }
3648    object_init_ex(&object_zval, Z_CE_P(EX_VAR(opline->op1.var)));
3649    constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
3650
3651    if (constructor == NULL) {
3652        if (RETURN_VALUE_USED(opline)) {
3653            ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
3654        } else {
3655            zval_ptr_dtor(&object_zval);
3656        }
3657        ZEND_VM_JMP(opline->op2.jmp_addr);
3658    } else {
3659        /* We are not handling overloaded classes right now */
3660        EX(call) = zend_vm_stack_push_call_frame(
3661            VM_FRAME_INFO(
3662                VM_FRAME_NESTED_FUNCTION,
3663                RETURN_VALUE_USED(opline) ?
3664                    ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
3665            constructor,
3666            opline->extended_value,
3667            Z_CE_P(EX_VAR(opline->op1.var)),
3668            Z_OBJ(object_zval),
3669            EX(call) TSRMLS_CC);
3670
3671        if (RETURN_VALUE_USED(opline)) {
3672            ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
3673            EX(call)->return_value = EX_VAR(opline->result.var);
3674        } else {
3675            EX(call)->return_value = NULL;
3676        }
3677
3678        CHECK_EXCEPTION();
3679        ZEND_VM_NEXT_OPCODE();
3680    }
3681}
3682
3683ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
3684{
3685    USE_OPLINE
3686    zend_free_op free_op1;
3687    zval *obj;
3688    zend_class_entry *ce;
3689    zend_function *clone;
3690    zend_object_clone_obj_t clone_call;
3691
3692    SAVE_OPLINE();
3693    obj = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
3694
3695    if (OP1_TYPE == IS_CONST ||
3696        (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
3697        if (UNEXPECTED(EG(exception) != NULL)) {
3698            HANDLE_EXCEPTION();
3699        }
3700        zend_error_noreturn(E_ERROR, "__clone method called on non-object");
3701    }
3702
3703    ce = Z_OBJCE_P(obj);
3704    clone = ce ? ce->clone : NULL;
3705    clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
3706    if (UNEXPECTED(clone_call == NULL)) {
3707        if (ce) {
3708            zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name->val);
3709        } else {
3710            zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
3711        }
3712    }
3713
3714    if (ce && clone) {
3715        if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
3716            /* Ensure that if we're calling a private function, we're allowed to do so.
3717             */
3718            if (UNEXPECTED(ce != EX(scope))) {
3719                zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
3720            }
3721        } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
3722            /* Ensure that if we're calling a protected function, we're allowed to do so.
3723             */
3724            if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
3725                zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
3726            }
3727        }
3728    }
3729
3730    if (EXPECTED(EG(exception) == NULL)) {
3731        ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC));
3732        if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) {
3733            zval_ptr_dtor(EX_VAR(opline->result.var));
3734        }
3735    }
3736    FREE_OP1_IF_VAR();
3737    CHECK_EXCEPTION();
3738    ZEND_VM_NEXT_OPCODE();
3739}
3740
3741ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
3742{
3743    USE_OPLINE
3744
3745    SAVE_OPLINE();
3746    if (OP1_TYPE == IS_UNUSED) {
3747        zend_constant *c;
3748        zval *retval;
3749
3750        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
3751            c = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
3752        } else if ((c = zend_quick_get_constant(opline->op2.zv + 1, opline->extended_value TSRMLS_CC)) == NULL) {
3753            if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
3754                char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
3755                if(!actual) {
3756                    actual = Z_STRVAL_P(opline->op2.zv);
3757                } else {
3758                    actual++;
3759                }
3760                /* non-qualified constant - allow text substitution */
3761                zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
3762                ZVAL_STRINGL(EX_VAR(opline->result.var), actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)));
3763                CHECK_EXCEPTION();
3764                ZEND_VM_NEXT_OPCODE();
3765            } else {
3766                zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
3767            }
3768        } else {
3769            CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), c);
3770        }
3771        retval = EX_VAR(opline->result.var);
3772        ZVAL_COPY_VALUE(retval, &c->value);
3773        if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
3774            if (Z_OPT_COPYABLE_P(retval)) {
3775                zval_copy_ctor_func(retval);
3776            } else {
3777                Z_ADDREF_P(retval);
3778            }
3779        }
3780    } else {
3781        /* class constant */
3782        zend_class_entry *ce;
3783        zval *value;
3784
3785        if (OP1_TYPE == IS_CONST) {
3786            if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
3787                value = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
3788                ZVAL_DEREF(value);
3789                ZVAL_DUP(EX_VAR(opline->result.var), value);
3790                ZEND_VM_C_GOTO(constant_fetch_end);
3791            } else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
3792                ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
3793            } else {
3794                ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
3795                if (UNEXPECTED(EG(exception) != NULL)) {
3796                    HANDLE_EXCEPTION();
3797                }
3798                if (UNEXPECTED(ce == NULL)) {
3799                    zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op1.zv));
3800                }
3801                CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
3802            }
3803        } else {
3804            ce = Z_CE_P(EX_VAR(opline->op1.var));
3805            if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce)) != NULL) {
3806                ZVAL_DEREF(value);
3807                ZVAL_DUP(EX_VAR(opline->result.var), value);
3808                ZEND_VM_C_GOTO(constant_fetch_end);
3809            }
3810        }
3811
3812        if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(opline->op2.zv))) != NULL)) {
3813            ZVAL_DEREF(value);
3814            if (Z_CONSTANT_P(value)) {
3815                EG(scope) = ce;
3816                zval_update_constant(value, 1 TSRMLS_CC);
3817                EG(scope) = EX(scope);
3818            }
3819            if (OP1_TYPE == IS_CONST) {
3820                CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), value);
3821            } else {
3822                CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce, value);
3823            }
3824            ZVAL_DUP(EX_VAR(opline->result.var), value);
3825        } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) {
3826            /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
3827            ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
3828        } else {
3829            zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
3830        }
3831    }
3832ZEND_VM_C_LABEL(constant_fetch_end):
3833    CHECK_EXCEPTION();
3834    ZEND_VM_NEXT_OPCODE();
3835}
3836
3837ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV)
3838{
3839    USE_OPLINE
3840    zend_free_op free_op1;
3841    zval *expr_ptr, new_expr;
3842
3843    SAVE_OPLINE();
3844    if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) &&
3845        (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
3846        expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
3847        if (OP1_TYPE == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
3848            zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
3849        }
3850        ZVAL_MAKE_REF(expr_ptr);
3851        Z_ADDREF_P(expr_ptr);
3852        FREE_OP1_VAR_PTR();
3853    } else {
3854        expr_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3855        if (OP1_TYPE == IS_TMP_VAR) {
3856            ZVAL_COPY_VALUE(&new_expr, expr_ptr);
3857            expr_ptr = &new_expr;
3858        } else if (OP1_TYPE == IS_CONST) {
3859            if (!Z_IMMUTABLE_P(expr_ptr)) {
3860                ZVAL_DUP(&new_expr, expr_ptr);
3861                expr_ptr = &new_expr;
3862            }
3863        } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(expr_ptr)) {
3864            expr_ptr = Z_REFVAL_P(expr_ptr);
3865            if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
3866            FREE_OP1_IF_VAR();
3867        } else if (OP1_TYPE == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
3868            Z_ADDREF_P(expr_ptr);
3869        }
3870    }
3871
3872    if (OP2_TYPE != IS_UNUSED) {
3873        zend_free_op free_op2;
3874        zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
3875        zend_string *str;
3876        zend_ulong hval;
3877
3878ZEND_VM_C_LABEL(add_again):
3879        switch (Z_TYPE_P(offset)) {
3880            case IS_DOUBLE:
3881                hval = zend_dval_to_lval(Z_DVAL_P(offset));
3882                ZEND_VM_C_GOTO(num_index);
3883            case IS_LONG:
3884                hval = Z_LVAL_P(offset);
3885ZEND_VM_C_LABEL(num_index):
3886                zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
3887                break;
3888            case IS_STRING:
3889                str = Z_STR_P(offset);
3890                if (OP2_TYPE != IS_CONST) {
3891                    if (ZEND_HANDLE_NUMERIC(str, hval)) {
3892                        ZEND_VM_C_GOTO(num_index);
3893                    }
3894                }
3895ZEND_VM_C_LABEL(str_index):
3896                zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
3897                break;
3898            case IS_NULL:
3899                str = STR_EMPTY_ALLOC();
3900                ZEND_VM_C_GOTO(str_index);
3901            case IS_FALSE:
3902                hval = 0;
3903                ZEND_VM_C_GOTO(num_index);
3904            case IS_TRUE:
3905                hval = 1;
3906                ZEND_VM_C_GOTO(num_index);
3907            case IS_REFERENCE:
3908                offset = Z_REFVAL_P(offset);
3909                ZEND_VM_C_GOTO(add_again);
3910                break;
3911            default:
3912                zend_error(E_WARNING, "Illegal offset type");
3913                zval_ptr_dtor(expr_ptr);
3914                /* do nothing */
3915                break;
3916        }
3917        FREE_OP2();
3918    } else {
3919        zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr);
3920    }
3921    CHECK_EXCEPTION();
3922    ZEND_VM_NEXT_OPCODE();
3923}
3924
3925ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
3926{
3927    zval *array;
3928    uint32_t size;
3929    USE_OPLINE
3930
3931    array = EX_VAR(opline->result.var);
3932    if (OP1_TYPE != IS_UNUSED) {
3933        size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
3934    } else {
3935        size = 0;
3936    }
3937    ZVAL_NEW_ARR(array);
3938    zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0);
3939
3940    if (OP1_TYPE != IS_UNUSED) {
3941        /* Explicitly initialize array as not-packed if flag is set */
3942        if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
3943            zend_hash_real_init(Z_ARRVAL_P(array), 0);
3944        }
3945    }
3946
3947    if (OP1_TYPE == IS_UNUSED) {
3948        ZEND_VM_NEXT_OPCODE();
3949#if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED
3950    } else {
3951        ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
3952#endif
3953    }
3954}
3955
3956ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
3957{
3958    USE_OPLINE
3959    zend_free_op free_op1;
3960    zval *expr;
3961    zval *result = EX_VAR(opline->result.var);
3962
3963    SAVE_OPLINE();
3964    expr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
3965
3966    switch (opline->extended_value) {
3967        case IS_NULL:
3968            /* This code is taken from convert_to_null. However, it does not seems very useful,
3969             * because a conversion to null always results in the same value. This could only
3970             * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */
3971#if 0
3972            if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
3973                ZVAL_DEREF(expr);
3974            }
3975            if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) {
3976                if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL TSRMLS_CC) == SUCCESS) {
3977                    break;
3978                }
3979            }
3980#endif
3981
3982            ZVAL_NULL(result);
3983            break;
3984        case _IS_BOOL:
3985            ZVAL_BOOL(result, zend_is_true(expr TSRMLS_CC));
3986            break;
3987        case IS_LONG:
3988            ZVAL_LONG(result, zval_get_long(expr));
3989            break;
3990        case IS_DOUBLE:
3991            ZVAL_DOUBLE(result, zval_get_double(expr));
3992            break;
3993        case IS_STRING:
3994            ZVAL_STR(result, zval_get_string(expr));
3995            break;
3996        default:
3997            /* If value is already of correct type, return it directly */
3998            if (Z_TYPE_P(expr) == opline->extended_value) {
3999                ZVAL_COPY_VALUE(result, expr);
4000                if (OP1_TYPE == IS_CONST) {
4001                    if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) {
4002                        zval_copy_ctor_func(result);
4003                    }
4004                } else if (OP1_TYPE != IS_TMP_VAR) {
4005                    if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
4006                }
4007
4008                FREE_OP1_IF_VAR();
4009                CHECK_EXCEPTION();
4010                ZEND_VM_NEXT_OPCODE();
4011            }
4012
4013            if (opline->extended_value == IS_ARRAY) {
4014                if (Z_TYPE_P(expr) != IS_OBJECT) {
4015                    ZVAL_NEW_ARR(result);
4016                    zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0);
4017                    if (Z_TYPE_P(expr) != IS_NULL) {
4018                        expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
4019                        if (OP1_TYPE == IS_CONST) {
4020                            if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
4021                                zval_copy_ctor_func(expr);
4022                            }
4023                        } else {
4024                            if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
4025                        }
4026                    }
4027                } else {
4028                    ZVAL_COPY_VALUE(result, expr);
4029                    Z_ADDREF_P(result);
4030                    convert_to_array(result);
4031                }
4032            } else {
4033                if (Z_TYPE_P(expr) != IS_ARRAY) {
4034                    object_init(result);
4035                    if (Z_TYPE_P(expr) != IS_NULL) {
4036                        expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
4037                        if (OP1_TYPE == IS_CONST) {
4038                            if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
4039                                zval_copy_ctor_func(expr);
4040                            }
4041                        } else {
4042                            if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
4043                        }
4044                    }
4045                } else {
4046                    ZVAL_COPY_VALUE(result, expr);
4047                    zval_opt_copy_ctor(result);
4048                    convert_to_object(result);
4049                }
4050            }
4051    }
4052
4053    FREE_OP1();
4054    CHECK_EXCEPTION();
4055    ZEND_VM_NEXT_OPCODE();
4056}
4057
4058ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
4059{
4060    USE_OPLINE
4061    zend_op_array *new_op_array=NULL;
4062    zend_free_op free_op1;
4063    zval *inc_filename;
4064    zval tmp_inc_filename;
4065    zend_bool failure_retval=0;
4066
4067    SAVE_OPLINE();
4068    inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R);
4069
4070    ZVAL_UNDEF(&tmp_inc_filename);
4071    if (Z_TYPE_P(inc_filename) != IS_STRING) {
4072        ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename));
4073        inc_filename = &tmp_inc_filename;
4074    }
4075
4076    if (opline->extended_value != ZEND_EVAL && strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)) {
4077        if (opline->extended_value == ZEND_INCLUDE_ONCE || opline->extended_value == ZEND_INCLUDE) {
4078            zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
4079        } else {
4080            zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
4081        }
4082    } else {
4083        switch (opline->extended_value) {
4084            case ZEND_INCLUDE_ONCE:
4085            case ZEND_REQUIRE_ONCE: {
4086                    zend_file_handle file_handle;
4087                    char *resolved_path;
4088
4089                    resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename) TSRMLS_CC);
4090                    if (resolved_path) {
4091                        failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, (int)strlen(resolved_path));
4092                    } else {
4093                        resolved_path = Z_STRVAL_P(inc_filename);
4094                    }
4095
4096                    if (failure_retval) {
4097                        /* do nothing, file already included */
4098                    } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) {
4099
4100                        if (!file_handle.opened_path) {
4101                            file_handle.opened_path = estrdup(resolved_path);
4102                        }
4103
4104                        if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, (int)strlen(file_handle.opened_path))) {
4105                            new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
4106                            zend_destroy_file_handle(&file_handle TSRMLS_CC);
4107                        } else {
4108                            zend_file_handle_dtor(&file_handle TSRMLS_CC);
4109                            failure_retval=1;
4110                        }
4111                    } else {
4112                        if (opline->extended_value == ZEND_INCLUDE_ONCE) {
4113                            zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
4114                        } else {
4115                            zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
4116                        }
4117                    }
4118                    if (resolved_path != Z_STRVAL_P(inc_filename)) {
4119                        efree(resolved_path);
4120                    }
4121                }
4122                break;
4123            case ZEND_INCLUDE:
4124            case ZEND_REQUIRE:
4125                new_op_array = compile_filename(opline->extended_value, inc_filename TSRMLS_CC);
4126                break;
4127            case ZEND_EVAL: {
4128                    char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
4129
4130                    new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
4131                    efree(eval_desc);
4132                }
4133                break;
4134            EMPTY_SWITCH_DEFAULT_CASE()
4135        }
4136    }
4137    if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) {
4138        zval_ptr_dtor(&tmp_inc_filename);
4139    }
4140    FREE_OP1();
4141    if (UNEXPECTED(EG(exception) != NULL)) {
4142        HANDLE_EXCEPTION();
4143    } else if (EXPECTED(new_op_array != NULL)) {
4144        zval *return_value = NULL;
4145        zend_execute_data *call;
4146
4147        if (RETURN_VALUE_USED(opline)) {
4148            return_value = EX_VAR(opline->result.var);
4149        }
4150
4151        call = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_CODE,
4152            (zend_function*)new_op_array, 0, EX(called_scope), Z_OBJ(EX(This)), NULL TSRMLS_CC);
4153
4154        if (EX(symbol_table)) {
4155            call->symbol_table = EX(symbol_table);
4156        } else {
4157            call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
4158        }
4159
4160        call->prev_execute_data = execute_data;
4161        i_init_code_execute_data(call, new_op_array, return_value TSRMLS_CC);
4162        if (EXPECTED(zend_execute_ex == execute_ex)) {
4163            ZEND_VM_ENTER();
4164        } else {
4165            call->frame_info = VM_FRAME_TOP_CODE;
4166            zend_execute_ex(call TSRMLS_CC);
4167        }
4168
4169        destroy_op_array(new_op_array TSRMLS_CC);
4170        efree_size(new_op_array, sizeof(zend_op_array));
4171        if (UNEXPECTED(EG(exception) != NULL)) {
4172            zend_throw_exception_internal(NULL TSRMLS_CC);
4173            HANDLE_EXCEPTION();
4174        }
4175
4176    } else if (RETURN_VALUE_USED(opline)) {
4177        ZVAL_BOOL(EX_VAR(opline->result.var), failure_retval);
4178    }
4179    ZEND_VM_NEXT_OPCODE();
4180}
4181
4182ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
4183{
4184    USE_OPLINE
4185    zval tmp, *varname;
4186    HashTable *target_symbol_table;
4187    zend_free_op free_op1;
4188
4189    SAVE_OPLINE();
4190    if (OP1_TYPE == IS_CV &&
4191        OP2_TYPE == IS_UNUSED &&
4192        (opline->extended_value & ZEND_QUICK_SET)) {
4193        zval *var = EX_VAR(opline->op1.var);
4194
4195        if (Z_REFCOUNTED_P(var)) {
4196            zend_refcounted *garbage = Z_COUNTED_P(var);
4197
4198            if (!--GC_REFCOUNT(garbage)) {
4199                ZVAL_UNDEF(var);
4200                _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
4201            } else {
4202                GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
4203                ZVAL_UNDEF(var);
4204            }
4205        } else {
4206            ZVAL_UNDEF(var);
4207        }
4208        CHECK_EXCEPTION();
4209        ZEND_VM_NEXT_OPCODE();
4210    }
4211
4212    varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
4213
4214    ZVAL_UNDEF(&tmp);
4215    if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
4216        ZVAL_STR(&tmp, zval_get_string(varname));
4217        varname = &tmp;
4218    }
4219
4220    if (OP2_TYPE != IS_UNUSED) {
4221        zend_class_entry *ce;
4222
4223        if (OP2_TYPE == IS_CONST) {
4224            if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
4225                ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
4226            } else {
4227                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
4228                if (UNEXPECTED(EG(exception) != NULL)) {
4229                    if (OP1_TYPE != IS_CONST) {
4230                        zval_dtor(&tmp);
4231                    }
4232                    FREE_OP1();
4233                    HANDLE_EXCEPTION();
4234                }
4235                if (UNEXPECTED(ce == NULL)) {
4236                    zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op2.zv));
4237                }
4238                CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
4239            }
4240        } else {
4241            ce = Z_CE_P(EX_VAR(opline->op2.var));
4242        }
4243        zend_std_unset_static_property(ce, Z_STR_P(varname), ((OP1_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
4244    } else {
4245        target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
4246        zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
4247    }
4248
4249    if (OP1_TYPE != IS_CONST) {
4250        zval_dtor(&tmp);
4251    }
4252    FREE_OP1();
4253    CHECK_EXCEPTION();
4254    ZEND_VM_NEXT_OPCODE();
4255}
4256
4257ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4258{
4259    USE_OPLINE
4260    zend_free_op free_op1, free_op2;
4261    zval *container;
4262    zval *offset;
4263    zend_ulong hval;
4264
4265    SAVE_OPLINE();
4266    container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
4267    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
4268        zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
4269    }
4270    if (OP1_TYPE != IS_UNUSED) {
4271        ZVAL_DEREF(container);
4272        SEPARATE_ZVAL_NOREF(container);
4273    }
4274    offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
4275
4276    if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
4277        HashTable *ht = Z_ARRVAL_P(container);
4278ZEND_VM_C_LABEL(offset_again):
4279        switch (Z_TYPE_P(offset)) {
4280            case IS_DOUBLE:
4281                hval = zend_dval_to_lval(Z_DVAL_P(offset));
4282                zend_hash_index_del(ht, hval);
4283                break;
4284            case IS_LONG:
4285                hval = Z_LVAL_P(offset);
4286ZEND_VM_C_LABEL(num_index_dim):
4287                zend_hash_index_del(ht, hval);
4288                break;
4289            case IS_STRING:
4290                if (OP2_TYPE != IS_CONST) {
4291                    if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
4292                        ZEND_VM_C_GOTO(num_index_dim);
4293                    }
4294                }
4295                if (ht == &EG(symbol_table).ht) {
4296                    zend_delete_global_variable(Z_STR_P(offset) TSRMLS_CC);
4297                } else {
4298                    zend_hash_del(ht, Z_STR_P(offset));
4299                }
4300                break;
4301            case IS_NULL:
4302                zend_hash_del(ht, STR_EMPTY_ALLOC());
4303                break;
4304            case IS_FALSE:
4305                hval = 0;
4306                ZEND_VM_C_GOTO(num_index_dim);
4307            case IS_TRUE:
4308                hval = 1;
4309                ZEND_VM_C_GOTO(num_index_dim);
4310            case IS_RESOURCE:
4311                hval = Z_RES_HANDLE_P(offset);
4312                ZEND_VM_C_GOTO(num_index_dim);
4313            case IS_REFERENCE:
4314                offset = Z_REFVAL_P(offset);
4315                ZEND_VM_C_GOTO(offset_again);
4316                break;
4317            default:
4318                zend_error(E_WARNING, "Illegal offset type in unset");
4319                break;
4320        }
4321        FREE_OP2();
4322    } else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
4323        if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
4324            zend_error_noreturn(E_ERROR, "Cannot use object as array");
4325        }
4326//???       if (OP2_TYPE == IS_CONST) {
4327//???           zval_copy_ctor(offset);
4328//???       }
4329        Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC);
4330        FREE_OP2();
4331    } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
4332        zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
4333        ZEND_VM_CONTINUE(); /* bailed out before */
4334    } else {
4335        FREE_OP2();
4336    }
4337    FREE_OP1_VAR_PTR();
4338    CHECK_EXCEPTION();
4339    ZEND_VM_NEXT_OPCODE();
4340}
4341
4342ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4343{
4344    USE_OPLINE
4345    zend_free_op free_op1, free_op2;
4346    zval *container;
4347    zval *offset;
4348
4349    SAVE_OPLINE();
4350    container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
4351    if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
4352        zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
4353    }
4354    offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
4355
4356    ZVAL_DEREF(container);
4357    if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
4358        if (Z_OBJ_HT_P(container)->unset_property) {
4359            Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
4360        } else {
4361            zend_error(E_NOTICE, "Trying to unset property of non-object");
4362        }
4363    }
4364    FREE_OP2();
4365    FREE_OP1_VAR_PTR();
4366    CHECK_EXCEPTION();
4367    ZEND_VM_NEXT_OPCODE();
4368}
4369
4370ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
4371{
4372    USE_OPLINE
4373    zend_free_op free_op1;
4374    zval *array_ptr, *array_ref, iterator, tmp;
4375    HashTable *fe_ht;
4376    zend_object_iterator *iter = NULL;
4377    zend_class_entry *ce = NULL;
4378    zend_bool is_empty = 0;
4379
4380    SAVE_OPLINE();
4381
4382    if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
4383        (opline->extended_value & ZEND_FE_FETCH_BYREF)) {
4384        array_ptr = array_ref = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
4385        ZVAL_DEREF(array_ptr);
4386        if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
4387            SEPARATE_ARRAY(array_ptr);
4388            if (!Z_ISREF_P(array_ref)) {
4389                ZVAL_NEW_REF(array_ref, array_ref);
4390                array_ptr = Z_REFVAL_P(array_ref);
4391            }
4392            if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
4393        } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
4394            ce = Z_OBJCE_P(array_ptr);
4395            if (ce->get_iterator == NULL) {
4396                Z_ADDREF_P(array_ptr);
4397            }
4398            array_ref = array_ptr;
4399        } else {
4400            if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
4401        }
4402    } else {
4403        array_ptr = array_ref = GET_OP1_ZVAL_PTR(BP_VAR_R);
4404        ZVAL_DEREF(array_ptr);
4405        if (OP1_TYPE == IS_TMP_VAR) {
4406            ZVAL_COPY_VALUE(&tmp, array_ptr);
4407            if (Z_OPT_IMMUTABLE_P(&tmp)) {
4408                zval_copy_ctor_func(&tmp);
4409            }
4410            array_ref = array_ptr = &tmp;
4411            if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
4412                ce = Z_OBJCE_P(array_ptr);
4413                if (ce && ce->get_iterator) {
4414                    Z_DELREF_P(array_ref);
4415                }
4416            }
4417        } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
4418            ce = Z_OBJCE_P(array_ptr);
4419            if (!ce->get_iterator) {
4420                if (OP1_TYPE == IS_CV) {
4421                    Z_ADDREF_P(array_ref);
4422                }
4423            }
4424        } else if (Z_IMMUTABLE_P(array_ref)) {
4425            if (OP1_TYPE == IS_CV) {
4426                zval_copy_ctor_func(array_ref);
4427                Z_ADDREF_P(array_ref);
4428            } else {
4429                ZVAL_COPY_VALUE(&tmp, array_ref);
4430                zval_copy_ctor_func(&tmp);
4431                array_ptr = array_ref = &tmp;
4432            }
4433        } else if (Z_REFCOUNTED_P(array_ref)) {
4434            if (OP1_TYPE == IS_CONST ||
4435                       (OP1_TYPE == IS_CV &&
4436                        !Z_ISREF_P(array_ref) &&
4437                        Z_REFCOUNT_P(array_ref) > 1) ||
4438                       (OP1_TYPE == IS_VAR &&
4439                        !Z_ISREF_P(array_ref) &&
4440                        Z_REFCOUNT_P(array_ref) > 2)) {
4441                if (OP1_TYPE == IS_VAR) {
4442                    Z_DELREF_P(array_ref);
4443                }
4444                ZVAL_DUP(&tmp, array_ref);
4445                array_ptr = array_ref = &tmp;
4446            } else if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
4447                if (Z_ISREF_P(array_ref) && Z_REFCOUNT_P(array_ref) == 1) {
4448                    ZVAL_UNREF(array_ref);
4449                    array_ptr = array_ref;
4450                }
4451                if (Z_IMMUTABLE_P(array_ptr)) {
4452                    zval_copy_ctor_func(array_ptr);
4453                } else if (Z_ISREF_P(array_ref) &&
4454                           Z_COPYABLE_P(array_ptr) &&
4455                           Z_REFCOUNT_P(array_ptr) > 1) {
4456                    Z_DELREF_P(array_ptr);
4457                    zval_copy_ctor_func(array_ptr);
4458                }
4459                if (OP1_TYPE == IS_CV) {
4460                    Z_ADDREF_P(array_ref);
4461                }
4462            }
4463        }
4464    }
4465
4466    if (ce && ce->get_iterator) {
4467        iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_FETCH_BYREF TSRMLS_CC);
4468
4469        if (OP1_TYPE == IS_VAR && !(opline->extended_value & ZEND_FE_FETCH_BYREF)) {
4470            FREE_OP1_IF_VAR();
4471        }
4472        if (iter && EXPECTED(EG(exception) == NULL)) {
4473            ZVAL_OBJ(&iterator, &iter->std);
4474            array_ptr = array_ref = &iterator;
4475        } else {
4476            if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) {
4477                FREE_OP1_VAR_PTR();
4478            }
4479            if (!EG(exception)) {
4480                zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name->val);
4481            }
4482            zend_throw_exception_internal(NULL TSRMLS_CC);
4483            HANDLE_EXCEPTION();
4484        }
4485    }
4486
4487    ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
4488
4489    if (iter) {
4490        iter->index = 0;
4491        if (iter->funcs->rewind) {
4492            iter->funcs->rewind(iter TSRMLS_CC);
4493            if (UNEXPECTED(EG(exception) != NULL)) {
4494                zval_ptr_dtor(array_ref);
4495                if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) {
4496                    FREE_OP1_VAR_PTR();
4497                }
4498                HANDLE_EXCEPTION();
4499            }
4500        }
4501        is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
4502        if (UNEXPECTED(EG(exception) != NULL)) {
4503            zval_ptr_dtor(array_ref);
4504            if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) {
4505                FREE_OP1_VAR_PTR();
4506            }
4507            HANDLE_EXCEPTION();
4508        }
4509        iter->index = -1; /* will be set to 0 before using next handler */
4510    } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
4511        HashPointer *ptr = (HashPointer*)EX_VAR((opline+2)->op1.var);
4512        HashPosition pos = 0;
4513        Bucket *p;
4514
4515        while (1) {
4516            if (pos >= fe_ht->nNumUsed) {
4517                is_empty = 1;
4518                if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) {
4519                    FREE_OP1_VAR_PTR();
4520                }
4521                ZEND_VM_JMP(opline->op2.jmp_addr);
4522            }
4523            p = fe_ht->arData + pos;
4524            if (Z_TYPE(p->val) == IS_UNDEF ||
4525                (Z_TYPE(p->val) == IS_INDIRECT &&
4526                 Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) {
4527                pos++;
4528                continue;
4529            }
4530            if (!ce ||
4531                !p->key ||
4532                zend_check_property_access(Z_OBJ_P(array_ptr), p->key TSRMLS_CC) == SUCCESS) {
4533                break;
4534            }
4535            pos++;
4536        }
4537        fe_ht->nInternalPointer = pos;
4538        ptr->pos = pos;
4539        ptr->ht = fe_ht;
4540        ptr->h = fe_ht->arData[pos].h;
4541        ptr->key = fe_ht->arData[pos].key;
4542        is_empty = 0;
4543    } else {
4544        zend_error(E_WARNING, "Invalid argument supplied for foreach()");
4545        is_empty = 1;
4546    }
4547
4548    if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) {
4549        FREE_OP1_VAR_PTR();
4550    }
4551    if (is_empty) {
4552        ZEND_VM_JMP(opline->op2.jmp_addr);
4553    } else {
4554        CHECK_EXCEPTION();
4555        ZEND_VM_NEXT_OPCODE();
4556    }
4557}
4558
4559ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
4560{
4561    USE_OPLINE
4562    zend_free_op free_op1;
4563    zval *array, *array_ref;
4564    zval *value;
4565    HashTable *fe_ht;
4566    HashPointer *ptr;
4567    HashPosition pos;
4568    Bucket *p;
4569
4570    array = array_ref = EX_VAR(opline->op1.var);
4571    if (Z_ISREF_P(array)) {
4572        array = Z_REFVAL_P(array);
4573        // TODO: referenced value might be changed to different array ???
4574        if (Z_IMMUTABLE_P(array)) {
4575            zval_copy_ctor_func(array);
4576        }
4577    }
4578
4579    SAVE_OPLINE();
4580
4581    if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
4582        fe_ht = Z_ARRVAL_P(array);
4583        ptr = (HashPointer*)EX_VAR((opline+1)->op1.var);
4584        pos = ptr->pos;
4585        if (UNEXPECTED(pos == INVALID_IDX)) {
4586            /* reached end of iteration */
4587            ZEND_VM_JMP(opline->op2.jmp_addr);
4588        } else if (UNEXPECTED(ptr->ht != fe_ht)) {
4589            ptr->ht = fe_ht;
4590            pos = 0;
4591        } else if (UNEXPECTED(fe_ht->nInternalPointer != ptr->pos)) {
4592            if (fe_ht->u.flags & HASH_FLAG_PACKED) {
4593                pos = ptr->h;
4594            } else {
4595                pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
4596                while (1) {
4597                    if (pos == INVALID_IDX) {
4598                        pos = fe_ht->nInternalPointer;
4599                        break;
4600                    } else if (fe_ht->arData[pos].h == ptr->h && fe_ht->arData[pos].key == ptr->key) {
4601                        break;
4602                    }
4603                    pos = Z_NEXT(fe_ht->arData[pos].val);
4604                }
4605            }
4606        }
4607        while (1) {
4608            if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
4609                /* reached end of iteration */
4610                ZEND_VM_JMP(opline->op2.jmp_addr);
4611            }
4612            p = fe_ht->arData + pos;
4613            value = &p->val;
4614            if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
4615                pos++;
4616                continue;
4617            } else if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
4618                value = Z_INDIRECT_P(value);
4619                if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
4620                    pos++;
4621                    continue;
4622                }
4623            }
4624            if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
4625                ZVAL_MAKE_REF(value);
4626                Z_ADDREF_P(value);
4627                ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
4628            } else {
4629                ZVAL_COPY(EX_VAR(opline->result.var), value);
4630            }
4631            if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
4632                if (!p->key) {
4633                    ZVAL_LONG(EX_VAR((opline+1)->result.var), p->h);
4634                } else {
4635                    ZVAL_STR_COPY(EX_VAR((opline+1)->result.var), p->key);
4636                }
4637            }
4638            break;
4639        }
4640        do {
4641            pos++;
4642            if (pos >= fe_ht->nNumUsed) {
4643                fe_ht->nInternalPointer = ptr->pos = INVALID_IDX;
4644                ZEND_VM_INC_OPCODE();
4645                ZEND_VM_NEXT_OPCODE();
4646            }
4647            p = fe_ht->arData + pos;
4648        } while (Z_TYPE(p->val) == IS_UNDEF ||
4649                 (Z_TYPE(p->val) == IS_INDIRECT &&
4650                  Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF));
4651        fe_ht->nInternalPointer = ptr->pos = pos;
4652        ptr->h = fe_ht->arData[pos].h;
4653        ptr->key = fe_ht->arData[pos].key;
4654        ZEND_VM_INC_OPCODE();
4655        ZEND_VM_NEXT_OPCODE();
4656    } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
4657        zend_object_iterator *iter;
4658
4659        if ((iter = zend_iterator_unwrap(array TSRMLS_CC)) == NULL) {
4660            /* plain object */
4661            zend_object *zobj = Z_OBJ_P(array);
4662
4663            fe_ht = Z_OBJPROP_P(array);
4664            ptr = (HashPointer*)EX_VAR((opline+1)->op1.var);
4665            pos = ptr->pos;
4666            if (pos == INVALID_IDX) {
4667                /* reached end of iteration */
4668                ZEND_VM_JMP(opline->op2.jmp_addr);
4669            } else if (UNEXPECTED(ptr->ht != fe_ht)) {
4670                ptr->ht = fe_ht;
4671                pos = 0;
4672            } else if (UNEXPECTED(fe_ht->nInternalPointer != ptr->pos)) {
4673                if (fe_ht->u.flags & HASH_FLAG_PACKED) {
4674                    pos = ptr->h;
4675                } else {
4676                    pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
4677                    while (1) {
4678                        if (pos == INVALID_IDX) {
4679                            pos = fe_ht->nInternalPointer;
4680                            break;
4681                        } else if (fe_ht->arData[pos].h == ptr->h && fe_ht->arData[pos].key == ptr->key) {
4682                            break;
4683                        }
4684                        pos = Z_NEXT(fe_ht->arData[pos].val);
4685                    }
4686                }
4687            }
4688            while (1) {
4689                if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
4690                    /* reached end of iteration */
4691                    ZEND_VM_JMP(opline->op2.jmp_addr);
4692                }
4693
4694                p = fe_ht->arData + pos;
4695                value = &p->val;
4696                if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
4697                    pos++;
4698                    continue;
4699                } else if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
4700                    value = Z_INDIRECT_P(value);
4701                    if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
4702                        pos++;
4703                        continue;
4704                    }
4705                }
4706
4707                if (UNEXPECTED(!p->key)) {
4708                    if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
4709                        ZVAL_LONG(EX_VAR((opline+1)->result.var), p->h);
4710                    }
4711                    break;
4712                } else if (zend_check_property_access(zobj, p->key TSRMLS_CC) == SUCCESS) {
4713                    if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
4714                        if (p->key->val[0]) {
4715                            ZVAL_STR_COPY(EX_VAR((opline+1)->result.var), p->key);
4716                        } else {
4717                            const char *class_name, *prop_name;
4718                            size_t prop_name_len;
4719                            zend_unmangle_property_name_ex(
4720                                p->key, &class_name, &prop_name, &prop_name_len);
4721                            ZVAL_STRINGL(EX_VAR((opline+1)->result.var), prop_name, prop_name_len);
4722                        }
4723                    }
4724                    break;
4725                }
4726                pos++;
4727            }
4728            if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
4729                ZVAL_MAKE_REF(value);
4730                Z_ADDREF_P(value);
4731                ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
4732            } else {
4733                ZVAL_COPY(EX_VAR(opline->result.var), value);
4734            }
4735            do {
4736                pos++;
4737                if (pos >= fe_ht->nNumUsed) {
4738                    fe_ht->nInternalPointer = ptr->pos = INVALID_IDX;
4739                    ZEND_VM_INC_OPCODE();
4740                    ZEND_VM_NEXT_OPCODE();
4741                }
4742                p = fe_ht->arData + pos;
4743            } while (Z_TYPE(p->val) == IS_UNDEF ||
4744                     (Z_TYPE(p->val) == IS_INDIRECT &&
4745                      Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) ||
4746                     (EXPECTED(p->key != NULL) &&
4747                      zend_check_property_access(zobj, p->key TSRMLS_CC) == FAILURE));
4748            fe_ht->nInternalPointer = ptr->pos = pos;
4749            ptr->h = fe_ht->arData[pos].h;
4750            ptr->key = fe_ht->arData[pos].key;
4751            ZEND_VM_INC_OPCODE();
4752            ZEND_VM_NEXT_OPCODE();
4753        } else {
4754            /* !iter happens from exception */
4755            if (iter && ++iter->index > 0) {
4756                /* This could cause an endless loop if index becomes zero again.
4757                 * In case that ever happens we need an additional flag. */
4758                iter->funcs->move_forward(iter TSRMLS_CC);
4759                if (UNEXPECTED(EG(exception) != NULL)) {
4760                    zval_ptr_dtor(array_ref);
4761                    HANDLE_EXCEPTION();
4762                }
4763            }
4764            /* If index is zero we come from FE_RESET and checked valid() already. */
4765            if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) {
4766                /* reached end of iteration */
4767                if (UNEXPECTED(EG(exception) != NULL)) {
4768                    zval_ptr_dtor(array_ref);
4769                    HANDLE_EXCEPTION();
4770                }
4771                ZEND_VM_JMP(opline->op2.jmp_addr);
4772            }
4773            value = iter->funcs->get_current_data(iter TSRMLS_CC);
4774            if (UNEXPECTED(EG(exception) != NULL)) {
4775                zval_ptr_dtor(array_ref);
4776                HANDLE_EXCEPTION();
4777            }
4778            if (!value) {
4779                /* failure in get_current_data */
4780                ZEND_VM_JMP(opline->op2.jmp_addr);
4781            }
4782            if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
4783                ZVAL_MAKE_REF(value);
4784                Z_ADDREF_P(value);
4785                ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
4786            } else {
4787                ZVAL_COPY(EX_VAR(opline->result.var), value);
4788            }
4789            if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
4790                if (iter->funcs->get_current_key) {
4791                    iter->funcs->get_current_key(iter, EX_VAR((opline+1)->result.var) TSRMLS_CC);
4792                    if (UNEXPECTED(EG(exception) != NULL)) {
4793                        zval_ptr_dtor(array_ref);
4794                        HANDLE_EXCEPTION();
4795                    }
4796                } else {
4797                    ZVAL_LONG(EX_VAR((opline+1)->result.var), iter->index);
4798                }
4799            }
4800            ZEND_VM_INC_OPCODE();
4801            ZEND_VM_NEXT_OPCODE();
4802        }
4803    } else {
4804        zend_error(E_WARNING, "Invalid argument supplied for foreach()");
4805        ZEND_VM_JMP(opline->op2.jmp_addr);
4806    }
4807}
4808
4809ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
4810{
4811    USE_OPLINE
4812    zval *value;
4813
4814    SAVE_OPLINE();
4815    if (OP1_TYPE == IS_CV &&
4816        OP2_TYPE == IS_UNUSED &&
4817        (opline->extended_value & ZEND_QUICK_SET)) {
4818        value = EX_VAR(opline->op1.var);
4819        if (opline->extended_value & ZEND_ISSET) {
4820            ZVAL_BOOL(EX_VAR(opline->result.var),
4821                Z_TYPE_P(value) > IS_NULL &&
4822                (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL));
4823        } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
4824            ZVAL_BOOL(EX_VAR(opline->result.var),
4825                !i_zend_is_true(value TSRMLS_CC));
4826            CHECK_EXCEPTION();
4827        }
4828        ZEND_VM_NEXT_OPCODE();
4829    } else {
4830        zend_free_op free_op1;
4831        zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
4832
4833        if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
4834            ZVAL_STR(&tmp, zval_get_string(varname));
4835            varname = &tmp;
4836        }
4837
4838        if (OP2_TYPE != IS_UNUSED) {
4839            zend_class_entry *ce;
4840
4841            if (OP2_TYPE == IS_CONST) {
4842                if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
4843                    ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
4844                } else {
4845                    ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
4846                    if (UNEXPECTED(ce == NULL)) {
4847                        CHECK_EXCEPTION();
4848                        ZEND_VM_NEXT_OPCODE();
4849                    }
4850                    CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
4851                }
4852            } else {
4853                ce = Z_CE_P(EX_VAR(opline->op2.var));
4854            }
4855            value = zend_std_get_static_property(ce, Z_STR_P(varname), 1, ((OP1_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
4856        } else {
4857            HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
4858            value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));
4859        }
4860
4861        if (OP1_TYPE != IS_CONST && varname == &tmp) {
4862            zval_dtor(&tmp);
4863        }
4864        FREE_OP1();
4865
4866        if (opline->extended_value & ZEND_ISSET) {
4867            ZVAL_BOOL(EX_VAR(opline->result.var),
4868                value && Z_TYPE_P(value) > IS_NULL &&
4869                (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL));
4870        } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
4871            ZVAL_BOOL(EX_VAR(opline->result.var),
4872                !value || !i_zend_is_true(value TSRMLS_CC));
4873        }
4874
4875        CHECK_EXCEPTION();
4876        ZEND_VM_NEXT_OPCODE();
4877    }
4878}
4879
4880ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4881{
4882    USE_OPLINE
4883    zend_free_op free_op1, free_op2;
4884    zval *container;
4885    int result;
4886    zend_ulong hval;
4887    zval *offset;
4888
4889    SAVE_OPLINE();
4890    container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
4891    offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
4892
4893    if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
4894        HashTable *ht = Z_ARRVAL_P(container);
4895        zval *value;
4896        zend_string *str;
4897
4898ZEND_VM_C_LABEL(isset_again):
4899        if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
4900            str = Z_STR_P(offset);
4901            if (OP2_TYPE != IS_CONST) {
4902                if (ZEND_HANDLE_NUMERIC(str, hval)) {
4903                    ZEND_VM_C_GOTO(num_index_prop);
4904                }
4905            }
4906ZEND_VM_C_LABEL(str_index_prop):
4907            value = zend_hash_find_ind(ht, str);
4908        } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
4909            hval = Z_LVAL_P(offset);
4910ZEND_VM_C_LABEL(num_index_prop):
4911            value = zend_hash_index_find(ht, hval);
4912        } else {
4913            switch (Z_TYPE_P(offset)) {
4914                case IS_DOUBLE:
4915                    hval = zend_dval_to_lval(Z_DVAL_P(offset));
4916                    ZEND_VM_C_GOTO(num_index_prop);
4917                case IS_NULL:
4918                    str = STR_EMPTY_ALLOC();
4919                    ZEND_VM_C_GOTO(str_index_prop);
4920                case IS_FALSE:
4921                    hval = 0;
4922                    ZEND_VM_C_GOTO(num_index_prop);
4923                case IS_TRUE:
4924                    hval = 1;
4925                    ZEND_VM_C_GOTO(num_index_prop);
4926                case IS_RESOURCE:
4927                    hval = Z_RES_HANDLE_P(offset);
4928                    ZEND_VM_C_GOTO(num_index_prop);
4929                case IS_REFERENCE:
4930                    offset = Z_REFVAL_P(offset);
4931                    ZEND_VM_C_GOTO(isset_again);
4932                default:
4933                    zend_error(E_WARNING, "Illegal offset type in isset or empty");
4934                    value = NULL;
4935                    break;
4936            }
4937        }
4938
4939        if (opline->extended_value & ZEND_ISSET) {
4940            /* > IS_NULL means not IS_UNDEF and not IS_NULL */
4941            result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
4942                (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
4943        } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
4944            result = (value == NULL || !i_zend_is_true(value TSRMLS_CC));
4945        }
4946    } else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
4947        if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
4948            result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0 TSRMLS_CC);
4949        } else {
4950            zend_error(E_NOTICE, "Trying to check element of non-array");
4951            result = 0;
4952        }
4953        if ((opline->extended_value & ZEND_ISSET) == 0) {
4954            result = !result;
4955        }
4956    } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
4957        zval tmp;
4958
4959        result = 0;
4960        if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
4961            if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
4962                ZVAL_DEREF(offset);
4963            }
4964            if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
4965                    || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
4966                        && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
4967                ZVAL_DUP(&tmp, offset);
4968                convert_to_long(&tmp);
4969                offset = &tmp;
4970            }
4971        }
4972        if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
4973            if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
4974                if ((opline->extended_value & ZEND_ISSET) ||
4975                    Z_STRVAL_P(container)[offset->value.lval] != '0') {
4976                    result = 1;
4977                }
4978            }
4979        }
4980        if ((opline->extended_value & ZEND_ISSET) == 0) {
4981            result = !result;
4982        }
4983    } else {
4984        result = ((opline->extended_value & ZEND_ISSET) == 0);
4985    }
4986
4987    FREE_OP2();
4988    ZVAL_BOOL(EX_VAR(opline->result.var), result);
4989    FREE_OP1();
4990    CHECK_EXCEPTION();
4991    ZEND_VM_NEXT_OPCODE();
4992}
4993
4994ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4995{
4996    USE_OPLINE
4997    zend_free_op free_op1, free_op2;
4998    zval *container;
4999    int result;
5000    zval *offset;
5001
5002    SAVE_OPLINE();
5003    container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
5004    offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
5005
5006    if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
5007        if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) {
5008            result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
5009        } else {
5010            zend_error(E_NOTICE, "Trying to check property of non-object");
5011            result = 0;
5012        }
5013        if ((opline->extended_value & ZEND_ISSET) == 0) {
5014            result = !result;
5015        }
5016    } else {
5017        result = ((opline->extended_value & ZEND_ISSET) == 0);
5018    }
5019
5020    FREE_OP2();
5021    ZVAL_BOOL(EX_VAR(opline->result.var), result);
5022    FREE_OP1();
5023    CHECK_EXCEPTION();
5024    ZEND_VM_NEXT_OPCODE();
5025}
5026
5027ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMP|VAR|UNUSED|CV, ANY)
5028{
5029#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
5030    USE_OPLINE
5031
5032    SAVE_OPLINE();
5033    if (OP1_TYPE != IS_UNUSED) {
5034        zend_free_op free_op1;
5035        zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
5036
5037        if (Z_TYPE_P(ptr) == IS_LONG) {
5038            EG(exit_status) = Z_LVAL_P(ptr);
5039        } else {
5040            zend_print_variable(ptr TSRMLS_CC);
5041        }
5042        FREE_OP1();
5043    }
5044#endif
5045    zend_bailout();
5046    ZEND_VM_NEXT_OPCODE(); /* Never reached */
5047}
5048
5049ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
5050{
5051    USE_OPLINE
5052
5053    SAVE_OPLINE();
5054    ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
5055    if (EX(silence_op_num) == -1) {
5056        EX(silence_op_num) = opline->op2.num;
5057        EX(old_error_reporting) = EG(error_reporting);
5058    }
5059
5060    if (EG(error_reporting)) {
5061        do {
5062            EG(error_reporting) = 0;
5063            if (!EG(error_reporting_ini_entry)) {
5064                zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
5065                if (p) {
5066                    EG(error_reporting_ini_entry) = p;
5067                } else {
5068                    break;
5069                }
5070            }
5071            if (!EG(error_reporting_ini_entry)->modified) {
5072                if (!EG(modified_ini_directives)) {
5073                    ALLOC_HASHTABLE(EG(modified_ini_directives));
5074                    zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
5075                }
5076                if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, EG(error_reporting_ini_entry)) != NULL)) {
5077                    EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
5078                    EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
5079                    EG(error_reporting_ini_entry)->modified = 1;
5080                }
5081            }
5082        } while (0);
5083    }
5084    CHECK_EXCEPTION();
5085    ZEND_VM_NEXT_OPCODE();
5086}
5087
5088ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
5089{
5090    USE_OPLINE
5091
5092    SAVE_OPLINE();
5093    if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
5094        EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
5095    }
5096    if (EX(