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