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