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