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