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