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