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