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