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