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