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