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