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