1/*
2   +----------------------------------------------------------------------+
3   | Zend Engine                                                          |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 2.00 of the Zend license,     |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.zend.com/license/2_00.txt.                                |
11   | If you did not receive a copy of the Zend license and are unable to  |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@zend.com so we can mail you a copy immediately.              |
14   +----------------------------------------------------------------------+
15   | Authors: Andi Gutmans <andi@zend.com>                                |
16   |          Zeev Suraski <zeev@zend.com>                                |
17   |          Dmitry Stogov <dmitry@zend.com>                             |
18   +----------------------------------------------------------------------+
19*/
20
21/* $Id$ */
22
23/* If you change this file, please regenerate the zend_vm_execute.h and
24 * zend_vm_opcodes.h files by running:
25 * php zend_vm_gen.php
26 */
27
28ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
29{
30	USE_OPLINE
31	zend_free_op free_op1, free_op2;
32	zval *op1, *op2, *result;
33
34	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
35	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
36	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
37		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
38			result = EX_VAR(opline->result.var);
39			fast_long_add_function(result, op1, op2);
40			ZEND_VM_NEXT_OPCODE();
41		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
42			result = EX_VAR(opline->result.var);
43			ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
44			ZEND_VM_NEXT_OPCODE();
45		}
46	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
47		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
48			result = EX_VAR(opline->result.var);
49			ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
50			ZEND_VM_NEXT_OPCODE();
51		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
52			result = EX_VAR(opline->result.var);
53			ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
54			ZEND_VM_NEXT_OPCODE();
55		}
56	}
57
58	SAVE_OPLINE();
59	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
60		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
61	}
62	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
63		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
64	}
65	add_function(EX_VAR(opline->result.var), op1, op2);
66	FREE_OP1();
67	FREE_OP2();
68	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
69}
70
71ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
72{
73	USE_OPLINE
74	zend_free_op free_op1, free_op2;
75	zval *op1, *op2, *result;
76
77	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
78	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
79	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
80		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
81			result = EX_VAR(opline->result.var);
82			fast_long_sub_function(result, op1, op2);
83			ZEND_VM_NEXT_OPCODE();
84		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
85			result = EX_VAR(opline->result.var);
86			ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
87			ZEND_VM_NEXT_OPCODE();
88		}
89	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
90		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
91			result = EX_VAR(opline->result.var);
92			ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
93			ZEND_VM_NEXT_OPCODE();
94		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
95			result = EX_VAR(opline->result.var);
96			ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
97			ZEND_VM_NEXT_OPCODE();
98		}
99	}
100
101	SAVE_OPLINE();
102	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
103		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
104	}
105	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
106		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
107	}
108	sub_function(EX_VAR(opline->result.var), op1, op2);
109	FREE_OP1();
110	FREE_OP2();
111	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
112}
113
114ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
115{
116	USE_OPLINE
117	zend_free_op free_op1, free_op2;
118	zval *op1, *op2, *result;
119
120	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
121	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
122	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
123		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
124			zend_long overflow;
125
126			result = EX_VAR(opline->result.var);
127			ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
128			Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
129			ZEND_VM_NEXT_OPCODE();
130		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
131			result = EX_VAR(opline->result.var);
132			ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
133			ZEND_VM_NEXT_OPCODE();
134		}
135	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
136		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
137			result = EX_VAR(opline->result.var);
138			ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
139			ZEND_VM_NEXT_OPCODE();
140		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
141			result = EX_VAR(opline->result.var);
142			ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
143			ZEND_VM_NEXT_OPCODE();
144		}
145	}
146
147	SAVE_OPLINE();
148	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
149		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
150	}
151	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
152		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
153	}
154	mul_function(EX_VAR(opline->result.var), op1, op2);
155	FREE_OP1();
156	FREE_OP2();
157	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
158}
159
160ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
161{
162	USE_OPLINE
163	zend_free_op free_op1, free_op2;
164	zval *op1, *op2;
165
166	SAVE_OPLINE();
167	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
168	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
169	fast_div_function(EX_VAR(opline->result.var), op1, op2);
170	FREE_OP1();
171	FREE_OP2();
172	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
173}
174
175ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
176{
177	USE_OPLINE
178	zend_free_op free_op1, free_op2;
179	zval *op1, *op2, *result;
180
181	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
182	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
183	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
184		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
185			result = EX_VAR(opline->result.var);
186			if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
187				SAVE_OPLINE();
188				zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
189				HANDLE_EXCEPTION();
190			} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
191				/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
192				ZVAL_LONG(result, 0);
193			} else {
194				ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
195			}
196			ZEND_VM_NEXT_OPCODE();
197		}
198	}
199
200	SAVE_OPLINE();
201	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
202		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
203	}
204	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
205		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
206	}
207	mod_function(EX_VAR(opline->result.var), op1, op2);
208	FREE_OP1();
209	FREE_OP2();
210	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
211}
212
213ZEND_VM_HANDLER(6, ZEND_SL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
214{
215	USE_OPLINE
216	zend_free_op free_op1, free_op2;
217	zval *op1, *op2;
218
219	SAVE_OPLINE();
220	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
221	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
222	shift_left_function(EX_VAR(opline->result.var), op1, op2);
223	FREE_OP1();
224	FREE_OP2();
225	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
226}
227
228ZEND_VM_HANDLER(7, ZEND_SR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
229{
230	USE_OPLINE
231	zend_free_op free_op1, free_op2;
232	zval *op1, *op2;
233
234	SAVE_OPLINE();
235	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
236	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
237	shift_right_function(EX_VAR(opline->result.var), op1, op2);
238	FREE_OP1();
239	FREE_OP2();
240	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
241}
242
243ZEND_VM_HANDLER(166, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
244{
245	USE_OPLINE
246	zend_free_op free_op1, free_op2;
247	zval *op1, *op2;
248
249	SAVE_OPLINE();
250	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
251	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
252	pow_function(EX_VAR(opline->result.var), op1, op2);
253	FREE_OP1();
254	FREE_OP2();
255	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
256}
257
258ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
259{
260	USE_OPLINE
261	zend_free_op free_op1, free_op2;
262	zval *op1, *op2;
263
264	SAVE_OPLINE();
265	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
266	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
267
268	do {
269		if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
270		    (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
271			zend_string *op1_str = Z_STR_P(op1);
272			zend_string *op2_str = Z_STR_P(op2);
273			zend_string *str;
274
275			if (OP1_TYPE != IS_CONST) {
276				if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
277					ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
278					FREE_OP1();
279					break;
280				}
281			}
282			if (OP2_TYPE != IS_CONST) {
283				if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
284					ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
285					FREE_OP1();
286					break;
287				}
288			}
289			if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV &&
290			    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
291			    size_t len = ZSTR_LEN(op1_str);
292
293				str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
294				memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
295				ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
296				break;
297			} else {
298				str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
299				memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
300				memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
301				ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
302			}
303		} else {
304			if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
305				op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
306			}
307			if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
308				op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
309			}
310			concat_function(EX_VAR(opline->result.var), op1, op2);
311		}
312		FREE_OP1();
313	} while (0);
314	FREE_OP2();
315	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
316}
317
318ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
319{
320	USE_OPLINE
321	zend_free_op free_op1, free_op2;
322	zval *op1, *op2;
323	int result;
324
325	SAVE_OPLINE();
326	op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
327	op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
328	result = fast_is_identical_function(op1, op2);
329	FREE_OP1();
330	FREE_OP2();
331	ZEND_VM_SMART_BRANCH(result, 1);
332	ZVAL_BOOL(EX_VAR(opline->result.var), result);
333	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
334}
335
336ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
337{
338	USE_OPLINE
339	zend_free_op free_op1, free_op2;
340	zval *op1, *op2;
341	int result;
342
343	SAVE_OPLINE();
344	op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
345	op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
346	result = fast_is_not_identical_function(op1, op2);
347	FREE_OP1();
348	FREE_OP2();
349	ZEND_VM_SMART_BRANCH(result, 1);
350	ZVAL_BOOL(EX_VAR(opline->result.var), result);
351	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
352}
353
354ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
355{
356	USE_OPLINE
357	zend_free_op free_op1, free_op2;
358	zval *op1, *op2, *result;
359
360	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
361	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
362	do {
363		int result;
364
365		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
366			if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
367				result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
368			} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
369				result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
370			} else {
371				break;
372			}
373		} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
374			if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
375				result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
376			} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
377				result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
378			} else {
379				break;
380			}
381		} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
382			if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
383				if (Z_STR_P(op1) == Z_STR_P(op2)) {
384					result = 1;
385				} else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
386					if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
387						result = 0;
388					} else {
389						result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
390					}
391				} else {
392					result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
393				}
394				FREE_OP1();
395				FREE_OP2();
396			} else {
397				break;
398			}
399		} else {
400			break;
401		}
402		ZEND_VM_SMART_BRANCH(result, 0);
403		ZVAL_BOOL(EX_VAR(opline->result.var), result);
404		ZEND_VM_NEXT_OPCODE();
405	} while (0);
406
407	SAVE_OPLINE();
408	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
409		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
410	}
411	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
412		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
413	}
414	result = EX_VAR(opline->result.var);
415	compare_function(result, op1, op2);
416	ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
417	FREE_OP1();
418	FREE_OP2();
419	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
420}
421
422ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
423{
424	USE_OPLINE
425	zend_free_op free_op1, free_op2;
426	zval *op1, *op2, *result;
427
428	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
429	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
430	do {
431		int result;
432
433		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
434			if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
435				result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
436			} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
437				result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
438			} else {
439				break;
440			}
441		} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
442			if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
443				result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
444			} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
445				result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
446			} else {
447				break;
448			}
449		} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
450			if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
451				if (Z_STR_P(op1) == Z_STR_P(op2)) {
452					result = 0;
453				} else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
454					if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
455						result = 1;
456					} else {
457						result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
458					}
459				} else {
460					result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
461				}
462				FREE_OP1();
463				FREE_OP2();
464			} else {
465				break;
466			}
467		} else {
468			break;
469		}
470		ZEND_VM_SMART_BRANCH(result, 0);
471		ZVAL_BOOL(EX_VAR(opline->result.var), result);
472		ZEND_VM_NEXT_OPCODE();
473	} while (0);
474
475	SAVE_OPLINE();
476	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
477		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
478	}
479	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
480		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
481	}
482	result = EX_VAR(opline->result.var);
483	compare_function(result, op1, op2);
484	ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
485	FREE_OP1();
486	FREE_OP2();
487	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
488}
489
490ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
491{
492	USE_OPLINE
493	zend_free_op free_op1, free_op2;
494	zval *op1, *op2, *result;
495
496	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
497	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
498	do {
499		int result;
500
501		if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
502			if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
503				result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
504			} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
505				result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
506			} else {
507				break;
508			}
509		} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
510			if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
511				result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
512			} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
513				result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
514			} else {
515				break;
516			}
517		} else {
518			break;
519		}
520		ZEND_VM_SMART_BRANCH(result, 0);
521		ZVAL_BOOL(EX_VAR(opline->result.var), result);
522		ZEND_VM_NEXT_OPCODE();
523	} while (0);
524
525	SAVE_OPLINE();
526	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
527		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
528	}
529	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
530		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
531	}
532	result = EX_VAR(opline->result.var);
533	compare_function(result, op1, op2);
534	ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
535	FREE_OP1();
536	FREE_OP2();
537	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
538}
539
540ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
541{
542	USE_OPLINE
543	zend_free_op free_op1, free_op2;
544	zval *op1, *op2, *result;
545
546	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
547	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
548	do {
549		int result;
550
551		if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
552			if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
553				result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
554			} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
555				result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
556			} else {
557				break;
558			}
559		} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
560			if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
561				result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
562			} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
563				result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
564			} else {
565				break;
566			}
567		} else {
568			break;
569		}
570		ZEND_VM_SMART_BRANCH(result, 0);
571		ZVAL_BOOL(EX_VAR(opline->result.var), result);
572		ZEND_VM_NEXT_OPCODE();
573	} while (0);
574
575	SAVE_OPLINE();
576	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
577		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
578	}
579	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
580		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
581	}
582	result = EX_VAR(opline->result.var);
583	compare_function(result, op1, op2);
584	ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
585	FREE_OP1();
586	FREE_OP2();
587	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
588}
589
590ZEND_VM_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
591{
592	USE_OPLINE
593	zend_free_op free_op1, free_op2;
594	zval *op1, *op2;
595
596	SAVE_OPLINE();
597	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
598	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
599	compare_function(EX_VAR(opline->result.var), op1, op2);
600	FREE_OP1();
601	FREE_OP2();
602	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
603}
604
605ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
606{
607	USE_OPLINE
608	zend_free_op free_op1, free_op2;
609	zval *op1, *op2;
610
611	SAVE_OPLINE();
612	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
613	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
614	bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
615	FREE_OP1();
616	FREE_OP2();
617	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
618}
619
620ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
621{
622	USE_OPLINE
623	zend_free_op free_op1, free_op2;
624	zval *op1, *op2;
625
626	SAVE_OPLINE();
627	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
628	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
629	bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
630	FREE_OP1();
631	FREE_OP2();
632	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
633}
634
635ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
636{
637	USE_OPLINE
638	zend_free_op free_op1, free_op2;
639	zval *op1, *op2;
640
641	SAVE_OPLINE();
642	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
643	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
644	bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
645	FREE_OP1();
646	FREE_OP2();
647	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
648}
649
650ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
651{
652	USE_OPLINE
653	zend_free_op free_op1, free_op2;
654	zval *op1, *op2;
655
656	SAVE_OPLINE();
657	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
658	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
659	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
660	FREE_OP1();
661	FREE_OP2();
662	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
663}
664
665ZEND_VM_HANDLER(12, ZEND_BW_NOT, CONST|TMPVAR|CV, ANY)
666{
667	USE_OPLINE
668	zend_free_op free_op1;
669
670	SAVE_OPLINE();
671	bitwise_not_function(EX_VAR(opline->result.var),
672		GET_OP1_ZVAL_PTR(BP_VAR_R));
673	FREE_OP1();
674	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
675}
676
677ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
678{
679	USE_OPLINE
680	zval *val;
681	zend_free_op free_op1;
682
683	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
684	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
685		ZVAL_FALSE(EX_VAR(opline->result.var));
686	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
687		ZVAL_TRUE(EX_VAR(opline->result.var));
688		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
689			SAVE_OPLINE();
690			GET_OP1_UNDEF_CV(val, BP_VAR_R);
691			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
692		}
693	} else {
694		SAVE_OPLINE();
695		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
696		FREE_OP1();
697		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
698	}
699	ZEND_VM_NEXT_OPCODE();
700}
701
702ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, binary_op_type binary_op)
703{
704	USE_OPLINE
705	zend_free_op free_op1, free_op2, free_op_data1;
706	zval *object;
707	zval *property;
708	zval *value;
709	zval *zptr;
710
711	SAVE_OPLINE();
712	object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
713
714	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
715		zend_throw_error(NULL, "Using $this when not in object context");
716		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
717		FREE_UNFETCHED_OP2();
718		HANDLE_EXCEPTION();
719	}
720
721	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
722
723	do {
724		value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1);
725
726		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
727			ZVAL_DEREF(object);
728			if (UNEXPECTED(!make_real_object(object))) {
729				zend_error(E_WARNING, "Attempt to assign property of non-object");
730				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
731					ZVAL_NULL(EX_VAR(opline->result.var));
732				}
733				break;
734			}
735		}
736
737		/* here we are sure we are dealing with an object */
738		if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
739			&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
740			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
741				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
742					ZVAL_NULL(EX_VAR(opline->result.var));
743				}
744			} else {
745				ZVAL_DEREF(zptr);
746				SEPARATE_ZVAL_NOREF(zptr);
747
748				binary_op(zptr, zptr, value);
749				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
750					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
751				}
752			}
753		} else {
754			zend_assign_op_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
755		}
756	} while (0);
757
758	FREE_OP(free_op_data1);
759	FREE_OP2();
760	FREE_OP1_VAR_PTR();
761	/* assign_obj has two opcodes! */
762	ZEND_VM_NEXT_OPCODE_EX(1, 2);
763}
764
765ZEND_VM_HELPER(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, binary_op_type binary_op)
766{
767	USE_OPLINE
768	zend_free_op free_op1, free_op2, free_op_data1;
769	zval *var_ptr;
770	zval *value, *container, *dim;
771
772	SAVE_OPLINE();
773	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
774	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
775		zend_throw_error(NULL, "Using $this when not in object context");
776		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
777		FREE_UNFETCHED_OP2();
778		HANDLE_EXCEPTION();
779	}
780
781	if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
782ZEND_VM_C_LABEL(assign_dim_op_array):
783		SEPARATE_ARRAY(container);
784ZEND_VM_C_LABEL(assign_dim_op_new_array):
785		if (OP2_TYPE == IS_UNUSED) {
786			var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
787			if (UNEXPECTED(!var_ptr)) {
788				zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
789				ZEND_VM_C_GOTO(assign_dim_op_ret_null);
790			}
791		} else {
792			dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
793
794			if (OP2_TYPE == IS_CONST) {
795				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim);
796			} else {
797				var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim);
798			}
799			if (UNEXPECTED(!var_ptr)) {
800				ZEND_VM_C_GOTO(assign_dim_op_ret_null);
801			}
802			ZVAL_DEREF(var_ptr);
803			SEPARATE_ZVAL_NOREF(var_ptr);
804		}
805
806		value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1);
807
808		binary_op(var_ptr, var_ptr, value);
809
810		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
811			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
812		}
813	} else {
814		if (OP1_TYPE != IS_UNUSED) {
815			if (EXPECTED(Z_ISREF_P(container))) {
816				container = Z_REFVAL_P(container);
817				if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
818					ZEND_VM_C_GOTO(assign_dim_op_array);
819				}
820			} else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
821				container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
822				ZEND_VM_C_GOTO(assign_dim_op_convert_to_array);
823			}
824		}
825
826		dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
827
828		if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
829			value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1);
830			zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op);
831		} else if (OP1_TYPE != IS_UNUSED) {
832			if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
833				if (UNEXPECTED(Z_STRLEN_P(container) == 0)) {
834					zval_ptr_dtor_nogc(container);
835ZEND_VM_C_LABEL(assign_dim_op_convert_to_array):
836					ZVAL_NEW_ARR(container);
837					zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
838					ZEND_VM_C_GOTO(assign_dim_op_new_array);
839				}
840
841				if (OP2_TYPE == IS_UNUSED) {
842					zend_throw_error(NULL, "[] operator not supported for strings");
843				} else {
844					zend_check_string_offset(dim, BP_VAR_RW);
845					zend_wrong_string_offset();
846				}
847			} else {
848				if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
849					ZEND_VM_C_GOTO(assign_dim_op_convert_to_array);
850				}
851				if (UNEXPECTED(!Z_ISERROR_P(container))) {
852					zend_error(E_WARNING, "Cannot use a scalar value as an array");
853				}
854ZEND_VM_C_LABEL(assign_dim_op_ret_null):
855				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
856					ZVAL_NULL(EX_VAR(opline->result.var));
857				}
858			}
859			value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1);
860		}
861	}
862
863	FREE_OP2();
864	FREE_OP(free_op_data1);
865	FREE_OP1_VAR_PTR();
866	ZEND_VM_NEXT_OPCODE_EX(1, 2);
867}
868
869ZEND_VM_HELPER(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_op_type binary_op)
870{
871	USE_OPLINE
872	zend_free_op free_op1, free_op2;
873	zval *var_ptr;
874	zval *value;
875
876	SAVE_OPLINE();
877	value = GET_OP2_ZVAL_PTR(BP_VAR_R);
878	var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
879
880	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
881		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
882			ZVAL_NULL(EX_VAR(opline->result.var));
883		}
884	} else {
885		ZVAL_DEREF(var_ptr);
886		SEPARATE_ZVAL_NOREF(var_ptr);
887
888		binary_op(var_ptr, var_ptr, value);
889
890		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
891			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
892		}
893	}
894
895	FREE_OP2();
896	FREE_OP1_VAR_PTR();
897	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
898}
899
900ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
901{
902#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
903	USE_OPLINE
904
905# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
906	if (EXPECTED(opline->extended_value == 0)) {
907		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, add_function);
908	}
909# endif
910	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
911		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, add_function);
912	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
913		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, add_function);
914	}
915#else
916	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, add_function);
917#endif
918}
919
920ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
921{
922#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
923	USE_OPLINE
924
925# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
926	if (EXPECTED(opline->extended_value == 0)) {
927		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, sub_function);
928	}
929# endif
930	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
931		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, sub_function);
932	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
933		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, sub_function);
934	}
935#else
936	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, sub_function);
937#endif
938}
939
940ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
941{
942#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
943	USE_OPLINE
944
945# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
946	if (EXPECTED(opline->extended_value == 0)) {
947		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mul_function);
948	}
949# endif
950	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
951		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mul_function);
952	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
953		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, mul_function);
954	}
955#else
956	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mul_function);
957#endif
958}
959
960ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
961{
962#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
963	USE_OPLINE
964
965# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
966	if (EXPECTED(opline->extended_value == 0)) {
967		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, div_function);
968	}
969# endif
970	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
971		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, div_function);
972	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
973		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, div_function);
974	}
975#else
976	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, div_function);
977#endif
978}
979
980ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
981{
982#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
983	USE_OPLINE
984
985# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
986	if (EXPECTED(opline->extended_value == 0)) {
987		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mod_function);
988	}
989# endif
990	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
991		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mod_function);
992	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
993		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, mod_function);
994	}
995#else
996	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mod_function);
997#endif
998}
999
1000ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1001{
1002#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1003	USE_OPLINE
1004
1005# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1006	if (EXPECTED(opline->extended_value == 0)) {
1007		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_left_function);
1008	}
1009# endif
1010	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1011		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
1012	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1013		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, shift_left_function);
1014	}
1015#else
1016	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
1017#endif
1018}
1019
1020ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1021{
1022#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1023	USE_OPLINE
1024
1025# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1026	if (EXPECTED(opline->extended_value == 0)) {
1027		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_right_function);
1028	}
1029# endif
1030	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1031		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
1032	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1033		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, shift_right_function);
1034	}
1035#else
1036	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
1037#endif
1038}
1039
1040ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1041{
1042#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1043	USE_OPLINE
1044
1045# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1046	if (EXPECTED(opline->extended_value == 0)) {
1047		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, concat_function);
1048	}
1049# endif
1050	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1051		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, concat_function);
1052	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1053		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, concat_function);
1054	}
1055#else
1056	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, concat_function);
1057#endif
1058}
1059
1060ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1061{
1062#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1063	USE_OPLINE
1064
1065# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1066	if (EXPECTED(opline->extended_value == 0)) {
1067		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_or_function);
1068	}
1069# endif
1070	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1071		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
1072	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1073		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_or_function);
1074	}
1075#else
1076	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
1077#endif
1078}
1079
1080ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1081{
1082#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1083	USE_OPLINE
1084
1085# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1086	if (EXPECTED(opline->extended_value == 0)) {
1087		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_and_function);
1088	}
1089# endif
1090	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1091		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
1092	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1093		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_and_function);
1094	}
1095#else
1096	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
1097#endif
1098}
1099
1100ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1101{
1102#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1103	USE_OPLINE
1104
1105# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1106	if (EXPECTED(opline->extended_value == 0)) {
1107		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_xor_function);
1108	}
1109# endif
1110	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1111		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
1112	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1113		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_xor_function);
1114	}
1115#else
1116	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
1117#endif
1118}
1119
1120ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
1121{
1122#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
1123	USE_OPLINE
1124
1125# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
1126	if (EXPECTED(opline->extended_value == 0)) {
1127		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, pow_function);
1128	}
1129# endif
1130	if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
1131		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, pow_function);
1132	} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
1133		ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, pow_function);
1134	}
1135#else
1136	ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, pow_function);
1137#endif
1138}
1139
1140ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
1141{
1142	USE_OPLINE
1143	zend_free_op free_op1, free_op2;
1144	zval *object;
1145	zval *property;
1146	zval *zptr;
1147
1148	SAVE_OPLINE();
1149	object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
1150
1151	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1152		zend_throw_error(NULL, "Using $this when not in object context");
1153		FREE_UNFETCHED_OP2();
1154		HANDLE_EXCEPTION();
1155	}
1156
1157	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1158
1159	do {
1160		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1161			ZVAL_DEREF(object);
1162			if (UNEXPECTED(!make_real_object(object))) {
1163				zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
1164				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1165					ZVAL_NULL(EX_VAR(opline->result.var));
1166				}
1167				break;
1168			}
1169		}
1170
1171		/* here we are sure we are dealing with an object */
1172		if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
1173			&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
1174			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1175				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1176					ZVAL_NULL(EX_VAR(opline->result.var));
1177				}
1178			} else {
1179				if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
1180					if (inc) {
1181						fast_long_increment_function(zptr);
1182					} else {
1183						fast_long_decrement_function(zptr);
1184					}
1185				} else {
1186					ZVAL_DEREF(zptr);
1187					SEPARATE_ZVAL_NOREF(zptr);
1188
1189					if (inc) {
1190						increment_function(zptr);
1191					} else {
1192						decrement_function(zptr);
1193					}
1194				}
1195				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1196					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
1197				}
1198			}
1199		} else {
1200			zend_pre_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
1201		}
1202	} while (0);
1203
1204	FREE_OP2();
1205	FREE_OP1_VAR_PTR();
1206	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1207}
1208
1209ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1210{
1211	ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 1);
1212}
1213
1214ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1215{
1216	ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 0);
1217}
1218
1219ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
1220{
1221	USE_OPLINE
1222	zend_free_op free_op1, free_op2;
1223	zval *object;
1224	zval *property;
1225	zval *zptr;
1226
1227	SAVE_OPLINE();
1228	object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
1229
1230	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1231		zend_throw_error(NULL, "Using $this when not in object context");
1232		FREE_UNFETCHED_OP2();
1233		HANDLE_EXCEPTION();
1234	}
1235
1236	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1237
1238	do {
1239		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1240			ZVAL_DEREF(object);
1241			if (UNEXPECTED(!make_real_object(object))) {
1242				zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
1243				ZVAL_NULL(EX_VAR(opline->result.var));
1244				break;
1245			}
1246		}
1247
1248		/* here we are sure we are dealing with an object */
1249
1250		if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
1251			&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
1252			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1253				ZVAL_NULL(EX_VAR(opline->result.var));
1254			} else {
1255				if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
1256					ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
1257					if (inc) {
1258						fast_long_increment_function(zptr);
1259					} else {
1260						fast_long_decrement_function(zptr);
1261					}
1262				} else {
1263					ZVAL_DEREF(zptr);
1264					ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
1265					zval_opt_copy_ctor(zptr);
1266					if (inc) {
1267						increment_function(zptr);
1268					} else {
1269						decrement_function(zptr);
1270					}
1271				}
1272			}
1273		} else {
1274			zend_post_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
1275		}
1276	} while (0);
1277
1278	FREE_OP2();
1279	FREE_OP1_VAR_PTR();
1280	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1281}
1282
1283ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1284{
1285	ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 1);
1286}
1287
1288ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1289{
1290	ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 0);
1291}
1292
1293ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY, SPEC(RETVAL))
1294{
1295	USE_OPLINE
1296	zend_free_op free_op1;
1297	zval *var_ptr;
1298
1299	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1300
1301	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1302		fast_long_increment_function(var_ptr);
1303		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1304			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1305		}
1306		ZEND_VM_NEXT_OPCODE();
1307	}
1308
1309	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1310		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1311			ZVAL_NULL(EX_VAR(opline->result.var));
1312		}
1313		ZEND_VM_NEXT_OPCODE();
1314	}
1315
1316	SAVE_OPLINE();
1317	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1318		var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
1319	}
1320	ZVAL_DEREF(var_ptr);
1321	SEPARATE_ZVAL_NOREF(var_ptr);
1322
1323	increment_function(var_ptr);
1324
1325	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1326		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1327	}
1328
1329	FREE_OP1_VAR_PTR();
1330	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1331}
1332
1333ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY, SPEC(RETVAL))
1334{
1335	USE_OPLINE
1336	zend_free_op free_op1;
1337	zval *var_ptr;
1338
1339	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1340
1341	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1342		fast_long_decrement_function(var_ptr);
1343		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1344			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1345		}
1346		ZEND_VM_NEXT_OPCODE();
1347	}
1348
1349	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1350		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1351			ZVAL_NULL(EX_VAR(opline->result.var));
1352		}
1353		ZEND_VM_NEXT_OPCODE();
1354	}
1355
1356	SAVE_OPLINE();
1357	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1358		var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
1359	}
1360	ZVAL_DEREF(var_ptr);
1361	SEPARATE_ZVAL_NOREF(var_ptr);
1362
1363	decrement_function(var_ptr);
1364
1365	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1366		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1367	}
1368
1369	FREE_OP1_VAR_PTR();
1370	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1371}
1372
1373ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
1374{
1375	USE_OPLINE
1376	zend_free_op free_op1;
1377	zval *var_ptr;
1378
1379	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1380
1381	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1382		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1383		fast_long_increment_function(var_ptr);
1384		ZEND_VM_NEXT_OPCODE();
1385	}
1386
1387	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1388		ZVAL_NULL(EX_VAR(opline->result.var));
1389		ZEND_VM_NEXT_OPCODE();
1390	}
1391
1392	SAVE_OPLINE();
1393	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1394		var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
1395	}
1396	ZVAL_DEREF(var_ptr);
1397	ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1398	zval_opt_copy_ctor(var_ptr);
1399
1400	increment_function(var_ptr);
1401
1402	FREE_OP1_VAR_PTR();
1403	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1404}
1405
1406ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
1407{
1408	USE_OPLINE
1409	zend_free_op free_op1;
1410	zval *var_ptr;
1411
1412	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1413
1414	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1415		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1416		fast_long_decrement_function(var_ptr);
1417		ZEND_VM_NEXT_OPCODE();
1418	}
1419
1420	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1421		ZVAL_NULL(EX_VAR(opline->result.var));
1422		ZEND_VM_NEXT_OPCODE();
1423	}
1424
1425	SAVE_OPLINE();
1426	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1427		var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
1428	}
1429	ZVAL_DEREF(var_ptr);
1430	ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1431	zval_opt_copy_ctor(var_ptr);
1432
1433	decrement_function(var_ptr);
1434
1435	FREE_OP1_VAR_PTR();
1436	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1437}
1438
1439ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
1440{
1441	USE_OPLINE
1442	zend_free_op free_op1;
1443	zval *z;
1444
1445	SAVE_OPLINE();
1446	z = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1447
1448	if (Z_TYPE_P(z) == IS_STRING) {
1449		zend_string *str = Z_STR_P(z);
1450
1451		if (ZSTR_LEN(str) != 0) {
1452			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
1453		}
1454	} else {
1455		zend_string *str = _zval_get_string_func(z);
1456
1457		if (ZSTR_LEN(str) != 0) {
1458			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
1459		} else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
1460			GET_OP1_UNDEF_CV(z, BP_VAR_R);
1461		}
1462		zend_string_release(str);
1463	}
1464
1465	FREE_OP1();
1466	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1467}
1468
1469ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
1470{
1471	USE_OPLINE
1472	zend_free_op free_op1;
1473	zval *varname;
1474	zval *retval;
1475	zend_string *name;
1476	HashTable *target_symbol_table;
1477
1478	SAVE_OPLINE();
1479	varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1480
1481 	if (OP1_TYPE == IS_CONST) {
1482		name = Z_STR_P(varname);
1483	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
1484		name = Z_STR_P(varname);
1485		zend_string_addref(name);
1486	} else {
1487		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
1488			GET_OP1_UNDEF_CV(varname, BP_VAR_R);
1489		}
1490		name = zval_get_string(varname);
1491	}
1492
1493	target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK);
1494	retval = zend_hash_find(target_symbol_table, name);
1495	if (retval == NULL) {
1496		switch (type) {
1497			case BP_VAR_R:
1498			case BP_VAR_UNSET:
1499				zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1500				/* break missing intentionally */
1501			case BP_VAR_IS:
1502				retval = &EG(uninitialized_zval);
1503				break;
1504			case BP_VAR_RW:
1505				zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1506				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
1507				break;
1508			case BP_VAR_W:
1509				retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
1510				break;
1511			EMPTY_SWITCH_DEFAULT_CASE()
1512		}
1513	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
1514	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
1515		retval = Z_INDIRECT_P(retval);
1516		if (Z_TYPE_P(retval) == IS_UNDEF) {
1517			switch (type) {
1518				case BP_VAR_R:
1519				case BP_VAR_UNSET:
1520					zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1521					/* break missing intentionally */
1522				case BP_VAR_IS:
1523					retval = &EG(uninitialized_zval);
1524					break;
1525				case BP_VAR_RW:
1526					zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1527					/* break missing intentionally */
1528				case BP_VAR_W:
1529					ZVAL_NULL(retval);
1530					break;
1531				EMPTY_SWITCH_DEFAULT_CASE()
1532			}
1533		}
1534	}
1535
1536	if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
1537		FREE_OP1();
1538	}
1539
1540	if (OP1_TYPE != IS_CONST) {
1541		zend_string_release(name);
1542	}
1543
1544	ZEND_ASSERT(retval != NULL);
1545	if (type == BP_VAR_R || type == BP_VAR_IS) {
1546		if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
1547			ZVAL_UNREF(retval);
1548		}
1549		ZVAL_COPY(EX_VAR(opline->result.var), retval);
1550	} else {
1551		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
1552	}
1553	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1554}
1555
1556ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1557{
1558	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
1559}
1560
1561ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1562{
1563	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
1564}
1565
1566ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1567{
1568	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
1569}
1570
1571ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ARG_NUM)
1572{
1573	USE_OPLINE
1574
1575	if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) {
1576		ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
1577	} else {
1578		ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
1579	}
1580}
1581
1582ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1583{
1584	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
1585}
1586
1587ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1588{
1589	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS);
1590}
1591
1592ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type)
1593{
1594	USE_OPLINE
1595	zend_free_op free_op1;
1596	zval *varname;
1597	zval *retval;
1598	zend_string *name;
1599	zend_class_entry *ce;
1600
1601	SAVE_OPLINE();
1602	varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1603
1604 	if (OP1_TYPE == IS_CONST) {
1605		name = Z_STR_P(varname);
1606	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
1607		name = Z_STR_P(varname);
1608		zend_string_addref(name);
1609	} else {
1610		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
1611			GET_OP1_UNDEF_CV(varname, BP_VAR_R);
1612		}
1613		name = zval_get_string(varname);
1614	}
1615
1616	if (OP2_TYPE == IS_CONST) {
1617		if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) {
1618			retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*));
1619
1620			/* check if static properties were destoyed */
1621			if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
1622				zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
1623				FREE_OP1();
1624				HANDLE_EXCEPTION();
1625			}
1626
1627			ZEND_VM_C_GOTO(fetch_static_prop_return);
1628		} else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) {
1629			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);
1630			if (UNEXPECTED(ce == NULL)) {
1631				if (OP1_TYPE != IS_CONST) {
1632					zend_string_release(name);
1633				}
1634				FREE_OP1();
1635				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1636			}
1637			CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
1638		}
1639	} else {
1640		if (OP2_TYPE == IS_UNUSED) {
1641			ce = zend_fetch_class(NULL, opline->op2.num);
1642			if (UNEXPECTED(ce == NULL)) {
1643				ZEND_ASSERT(EG(exception));
1644				if (OP1_TYPE != IS_CONST) {
1645					zend_string_release(name);
1646				}
1647				FREE_OP1();
1648				HANDLE_EXCEPTION();
1649			}
1650		} else {
1651			ce = Z_CE_P(EX_VAR(opline->op2.var));
1652		}
1653		if (OP1_TYPE == IS_CONST &&
1654		    (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) {
1655
1656			/* check if static properties were destoyed */
1657			if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
1658				zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
1659				FREE_OP1();
1660				HANDLE_EXCEPTION();
1661			}
1662
1663			ZEND_VM_C_GOTO(fetch_static_prop_return);
1664		}
1665	}
1666	retval = zend_std_get_static_property(ce, name, 0);
1667	if (UNEXPECTED(EG(exception))) {
1668		if (OP1_TYPE != IS_CONST) {
1669			zend_string_release(name);
1670		}
1671		FREE_OP1();
1672		HANDLE_EXCEPTION();
1673	}
1674	if (OP1_TYPE == IS_CONST && retval) {
1675		CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval);
1676	}
1677
1678	FREE_OP1();
1679
1680	if (OP1_TYPE != IS_CONST) {
1681		zend_string_release(name);
1682	}
1683
1684ZEND_VM_C_LABEL(fetch_static_prop_return):
1685	ZEND_ASSERT(retval != NULL);
1686	if (type == BP_VAR_R || type == BP_VAR_IS) {
1687		if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
1688			ZVAL_UNREF(retval);
1689		}
1690		ZVAL_COPY(EX_VAR(opline->result.var), retval);
1691	} else {
1692		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
1693	}
1694	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1695}
1696
1697ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
1698{
1699	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
1700}
1701
1702ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
1703{
1704	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
1705}
1706
1707ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
1708{
1709	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
1710}
1711
1712ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, NUM)
1713{
1714	USE_OPLINE
1715
1716	if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) {
1717		ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
1718	} else {
1719		ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
1720	}
1721}
1722
1723ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
1724{
1725	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
1726}
1727
1728ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
1729{
1730	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS);
1731}
1732
1733ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
1734{
1735	USE_OPLINE
1736	zend_free_op free_op1, free_op2;
1737	zval *container;
1738
1739	SAVE_OPLINE();
1740	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1741	zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1742	FREE_OP2();
1743	FREE_OP1();
1744	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1745}
1746
1747ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
1748{
1749	USE_OPLINE
1750	zend_free_op free_op1, free_op2;
1751	zval *container;
1752
1753	SAVE_OPLINE();
1754	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1755
1756	zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1757	FREE_OP2();
1758	if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
1759		EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1760	}
1761	FREE_OP1_VAR_PTR();
1762	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1763}
1764
1765ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
1766{
1767	USE_OPLINE
1768	zend_free_op free_op1, free_op2;
1769	zval *container;
1770
1771	SAVE_OPLINE();
1772	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1773
1774	zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1775	FREE_OP2();
1776	if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
1777		EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1778	}
1779	FREE_OP1_VAR_PTR();
1780	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1781}
1782
1783ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
1784{
1785	USE_OPLINE
1786	zend_free_op free_op1, free_op2;
1787	zval *container;
1788
1789	SAVE_OPLINE();
1790	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_IS);
1791	zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1792	FREE_OP2();
1793	FREE_OP1();
1794	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1795}
1796
1797ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, NUM)
1798{
1799	USE_OPLINE
1800	zval *container;
1801	zend_free_op free_op1, free_op2;
1802
1803	SAVE_OPLINE();
1804
1805	if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) {
1806        if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
1807            zend_throw_error(NULL, "Cannot use temporary expression in write context");
1808			FREE_UNFETCHED_OP2();
1809			FREE_UNFETCHED_OP1();
1810			HANDLE_EXCEPTION();
1811        }
1812		container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1813		zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1814		if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
1815			EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1816		}
1817		FREE_OP2();
1818		FREE_OP1_VAR_PTR();
1819	} else {
1820		if (OP2_TYPE == IS_UNUSED) {
1821			zend_throw_error(NULL, "Cannot use [] for reading");
1822			FREE_UNFETCHED_OP2();
1823			FREE_UNFETCHED_OP1();
1824			HANDLE_EXCEPTION();
1825		}
1826		container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1827		zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1828		FREE_OP2();
1829		FREE_OP1();
1830	}
1831	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1832}
1833
1834ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
1835{
1836	USE_OPLINE
1837	zend_free_op free_op1, free_op2;
1838	zval *container;
1839
1840	SAVE_OPLINE();
1841	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
1842
1843	zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE);
1844	FREE_OP2();
1845	if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
1846		EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1847	}
1848	FREE_OP1_VAR_PTR();
1849	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1850}
1851
1852ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1853{
1854	USE_OPLINE
1855	zend_free_op free_op1;
1856	zval *container;
1857	zend_free_op free_op2;
1858	zval *offset;
1859
1860	SAVE_OPLINE();
1861	container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
1862
1863	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
1864		zend_throw_error(NULL, "Using $this when not in object context");
1865		FREE_UNFETCHED_OP2();
1866		HANDLE_EXCEPTION();
1867	}
1868
1869	offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
1870
1871	if (OP1_TYPE == IS_CONST ||
1872	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
1873		if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
1874			container = Z_REFVAL_P(container);
1875			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
1876				ZEND_VM_C_GOTO(fetch_obj_r_no_object);
1877			}
1878		} else {
1879			ZEND_VM_C_GOTO(fetch_obj_r_no_object);
1880		}
1881	}
1882
1883	/* here we are sure we are dealing with an object */
1884	do {
1885		zend_object *zobj = Z_OBJ_P(container);
1886		zval *retval;
1887
1888		if (OP2_TYPE == IS_CONST &&
1889			EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
1890			uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
1891
1892			if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
1893				retval = OBJ_PROP(zobj, prop_offset);
1894				if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
1895					ZVAL_COPY(EX_VAR(opline->result.var), retval);
1896					break;
1897				}
1898			} else if (EXPECTED(zobj->properties != NULL)) {
1899				retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
1900				if (EXPECTED(retval)) {
1901					ZVAL_COPY(EX_VAR(opline->result.var), retval);
1902					break;
1903				}
1904			}
1905		}
1906
1907		if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
1908ZEND_VM_C_LABEL(fetch_obj_r_no_object):
1909			zend_error(E_NOTICE, "Trying to get property of non-object");
1910			ZVAL_NULL(EX_VAR(opline->result.var));
1911		} else {
1912			retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
1913
1914			if (retval != EX_VAR(opline->result.var)) {
1915				ZVAL_COPY(EX_VAR(opline->result.var), retval);
1916			}
1917		}
1918	} while (0);
1919
1920	FREE_OP2();
1921	FREE_OP1();
1922	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1923}
1924
1925ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1926{
1927	USE_OPLINE
1928	zend_free_op free_op1, free_op2;
1929	zval *property;
1930	zval *container;
1931
1932	SAVE_OPLINE();
1933	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1934
1935	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1936	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
1937		zend_throw_error(NULL, "Using $this when not in object context");
1938		FREE_OP2();
1939		HANDLE_EXCEPTION();
1940	}
1941
1942	zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
1943	FREE_OP2();
1944	if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
1945		EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1946	}
1947	FREE_OP1_VAR_PTR();
1948	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1949}
1950
1951ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1952{
1953	USE_OPLINE
1954	zend_free_op free_op1, free_op2;
1955	zval *property;
1956	zval *container;
1957
1958	SAVE_OPLINE();
1959	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1960	container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
1961
1962	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
1963		zend_throw_error(NULL, "Using $this when not in object context");
1964		FREE_OP2();
1965		HANDLE_EXCEPTION();
1966	}
1967	zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW);
1968	FREE_OP2();
1969	if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
1970		EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
1971	}
1972	FREE_OP1_VAR_PTR();
1973	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1974}
1975
1976ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
1977{
1978	USE_OPLINE
1979	zend_free_op free_op1;
1980	zval *container;
1981	zend_free_op free_op2;
1982	zval *offset;
1983
1984	SAVE_OPLINE();
1985	container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
1986
1987	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
1988		zend_throw_error(NULL, "Using $this when not in object context");
1989		FREE_UNFETCHED_OP2();
1990		HANDLE_EXCEPTION();
1991	}
1992
1993	offset  = GET_OP2_ZVAL_PTR(BP_VAR_R);
1994
1995	if (OP1_TYPE == IS_CONST ||
1996	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
1997		if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
1998			container = Z_REFVAL_P(container);
1999			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
2000				ZEND_VM_C_GOTO(fetch_obj_is_no_object);
2001			}
2002		} else {
2003			ZEND_VM_C_GOTO(fetch_obj_is_no_object);
2004		}
2005	}
2006
2007	/* here we are sure we are dealing with an object */
2008	do {
2009		zend_object *zobj = Z_OBJ_P(container);
2010		zval *retval;
2011
2012		if (OP2_TYPE == IS_CONST &&
2013			EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
2014			uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
2015
2016			if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
2017				retval = OBJ_PROP(zobj, prop_offset);
2018				if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
2019					ZVAL_COPY(EX_VAR(opline->result.var), retval);
2020					break;
2021				}
2022			} else if (EXPECTED(zobj->properties != NULL)) {
2023				retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
2024				if (EXPECTED(retval)) {
2025					ZVAL_COPY(EX_VAR(opline->result.var), retval);
2026					break;
2027				}
2028			}
2029		}
2030
2031		if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
2032ZEND_VM_C_LABEL(fetch_obj_is_no_object):
2033			ZVAL_NULL(EX_VAR(opline->result.var));
2034		} else {
2035
2036			retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
2037
2038			if (retval != EX_VAR(opline->result.var)) {
2039				ZVAL_COPY(EX_VAR(opline->result.var), retval);
2040			}
2041		}
2042	} while (0);
2043
2044	FREE_OP2();
2045	FREE_OP1();
2046	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2047}
2048
2049ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM)
2050{
2051	USE_OPLINE
2052	zval *container;
2053
2054	if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) {
2055		/* Behave like FETCH_OBJ_W */
2056		zend_free_op free_op1, free_op2;
2057		zval *property;
2058
2059		SAVE_OPLINE();
2060		property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2061		container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2062
2063		if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2064			zend_throw_error(NULL, "Using $this when not in object context");
2065			FREE_OP2();
2066			HANDLE_EXCEPTION();
2067		}
2068		if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
2069			zend_throw_error(NULL, "Cannot use temporary expression in write context");
2070			FREE_OP2();
2071			FREE_OP1_VAR_PTR();
2072			HANDLE_EXCEPTION();
2073		}
2074		zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
2075		FREE_OP2();
2076		if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
2077			EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
2078		}
2079		FREE_OP1_VAR_PTR();
2080		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2081	} else {
2082		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
2083	}
2084}
2085
2086ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
2087{
2088	USE_OPLINE
2089	zend_free_op free_op1, free_op2;
2090	zval *container, *property;
2091
2092	SAVE_OPLINE();
2093	container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
2094
2095	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2096		zend_throw_error(NULL, "Using $this when not in object context");
2097		FREE_UNFETCHED_OP2();
2098		HANDLE_EXCEPTION();
2099	}
2100
2101	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2102
2103	zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET);
2104	FREE_OP2();
2105	if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
2106		EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
2107	}
2108	FREE_OP1_VAR_PTR();
2109	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2110}
2111
2112ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
2113{
2114	USE_OPLINE
2115	zend_free_op free_op1, free_op2;
2116	zval *container;
2117
2118	SAVE_OPLINE();
2119	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2120	zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R));
2121	FREE_OP2();
2122	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2123}
2124
2125ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2126{
2127	USE_OPLINE
2128	zend_free_op free_op1, free_op2, free_op_data;
2129	zval *object, *property_name, *value, tmp;
2130
2131	SAVE_OPLINE();
2132	object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2133
2134	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
2135		zend_throw_error(NULL, "Using $this when not in object context");
2136		FREE_UNFETCHED_OP2();
2137		HANDLE_EXCEPTION();
2138	}
2139
2140	property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2141	value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2142
2143	if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
2144		do {
2145			if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) {
2146				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2147					ZVAL_NULL(EX_VAR(opline->result.var));
2148				}
2149				FREE_OP_DATA();
2150				ZEND_VM_C_GOTO(exit_assign_obj);
2151			}
2152			if (Z_ISREF_P(object)) {
2153				object = Z_REFVAL_P(object);
2154				if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
2155					break;
2156				}
2157			}
2158			if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE ||
2159			    (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
2160				zend_object *obj;
2161
2162				zval_ptr_dtor(object);
2163				object_init(object);
2164				Z_ADDREF_P(object);
2165				obj = Z_OBJ_P(object);
2166				zend_error(E_WARNING, "Creating default object from empty value");
2167				if (GC_REFCOUNT(obj) == 1) {
2168					/* the enclosing container was deleted, obj is unreferenced */
2169					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2170						ZVAL_NULL(EX_VAR(opline->result.var));
2171					}
2172					FREE_OP_DATA();
2173					OBJ_RELEASE(obj);
2174					ZEND_VM_C_GOTO(exit_assign_obj);
2175				}
2176				Z_DELREF_P(object);
2177			} else {
2178				zend_error(E_WARNING, "Attempt to assign property of non-object");
2179				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2180					ZVAL_NULL(EX_VAR(opline->result.var));
2181				}
2182				FREE_OP_DATA();
2183				ZEND_VM_C_GOTO(exit_assign_obj);
2184			}
2185		} while (0);
2186	}
2187
2188	if (OP2_TYPE == IS_CONST &&
2189	    EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) {
2190		uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*));
2191		zend_object *zobj = Z_OBJ_P(object);
2192		zval *property;
2193
2194		if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
2195			property = OBJ_PROP(zobj, prop_offset);
2196			if (Z_TYPE_P(property) != IS_UNDEF) {
2197ZEND_VM_C_LABEL(fast_assign_obj):
2198				value = zend_assign_to_variable(property, value, OP_DATA_TYPE);
2199				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2200					ZVAL_COPY(EX_VAR(opline->result.var), value);
2201				}
2202				ZEND_VM_C_GOTO(exit_assign_obj);
2203			}
2204		} else {
2205			if (EXPECTED(zobj->properties != NULL)) {
2206				if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
2207					if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
2208						GC_REFCOUNT(zobj->properties)--;
2209					}
2210					zobj->properties = zend_array_dup(zobj->properties);
2211				}
2212				property = zend_hash_find(zobj->properties, Z_STR_P(property_name));
2213				if (property) {
2214					ZEND_VM_C_GOTO(fast_assign_obj);
2215				}
2216			}
2217
2218			if (!zobj->ce->__set) {
2219
2220				if (EXPECTED(zobj->properties == NULL)) {
2221					rebuild_object_properties(zobj);
2222				}
2223				/* separate our value if necessary */
2224				if (OP_DATA_TYPE == IS_CONST) {
2225					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
2226						Z_ADDREF_P(value);
2227					}
2228				} else if (OP_DATA_TYPE != IS_TMP_VAR) {
2229					if (Z_ISREF_P(value)) {
2230						if (OP_DATA_TYPE == IS_VAR) {
2231							zend_reference *ref = Z_REF_P(value);
2232							if (--GC_REFCOUNT(ref) == 0) {
2233								ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
2234								efree_size(ref, sizeof(zend_reference));
2235								value = &tmp;
2236							} else {
2237								value = Z_REFVAL_P(value);
2238								if (Z_REFCOUNTED_P(value)) {
2239									Z_ADDREF_P(value);
2240								}
2241							}
2242						} else {
2243							value = Z_REFVAL_P(value);
2244							if (Z_REFCOUNTED_P(value)) {
2245								Z_ADDREF_P(value);
2246							}
2247						}
2248					} else if (OP_DATA_TYPE == IS_CV && Z_REFCOUNTED_P(value)) {
2249						Z_ADDREF_P(value);
2250					}
2251				}
2252				zend_hash_add_new(zobj->properties, Z_STR_P(property_name), value);
2253				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2254					ZVAL_COPY(EX_VAR(opline->result.var), value);
2255				}
2256				ZEND_VM_C_GOTO(exit_assign_obj);
2257			}
2258		}
2259	}
2260
2261	if (!Z_OBJ_HT_P(object)->write_property) {
2262		zend_error(E_WARNING, "Attempt to assign property of non-object");
2263		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2264			ZVAL_NULL(EX_VAR(opline->result.var));
2265		}
2266		FREE_OP_DATA();
2267		ZEND_VM_C_GOTO(exit_assign_obj);
2268	}
2269
2270	/* separate our value if necessary */
2271	if (OP_DATA_TYPE == IS_CONST) {
2272		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
2273			Z_ADDREF_P(value);
2274		}
2275	} else if (OP_DATA_TYPE != IS_TMP_VAR) {
2276		ZVAL_DEREF(value);
2277	}
2278
2279	Z_OBJ_HT_P(object)->write_property(object, property_name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL);
2280
2281	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) {
2282		ZVAL_COPY(EX_VAR(opline->result.var), value);
2283	}
2284	if (OP_DATA_TYPE == IS_CONST) {
2285		zval_ptr_dtor_nogc(value);
2286	} else {
2287		FREE_OP_DATA();
2288	}
2289ZEND_VM_C_LABEL(exit_assign_obj):
2290	FREE_OP2();
2291	FREE_OP1_VAR_PTR();
2292	/* assign_obj has two opcodes! */
2293	ZEND_VM_NEXT_OPCODE_EX(1, 2);
2294}
2295
2296ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2297{
2298	USE_OPLINE
2299	zend_free_op free_op1;
2300	zval *object_ptr;
2301	zend_free_op free_op2, free_op_data;
2302	zval *value;
2303	zval *variable_ptr;
2304	zval *dim;
2305
2306	SAVE_OPLINE();
2307	object_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2308
2309	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
2310ZEND_VM_C_LABEL(try_assign_dim_array):
2311		SEPARATE_ARRAY(object_ptr);
2312		if (OP2_TYPE == IS_UNUSED) {
2313			variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval));
2314			if (UNEXPECTED(variable_ptr == NULL)) {
2315				zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
2316				ZEND_VM_C_GOTO(assign_dim_error);
2317			}
2318		} else {
2319			dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2320			if (OP2_TYPE == IS_CONST) {
2321				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim);
2322			} else {
2323				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim);
2324			}
2325			if (UNEXPECTED(variable_ptr == NULL)) {
2326				ZEND_VM_C_GOTO(assign_dim_error);
2327			}
2328		}
2329		value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2330		value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
2331		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2332			ZVAL_COPY(EX_VAR(opline->result.var), value);
2333		}
2334	} else {
2335		if (EXPECTED(Z_ISREF_P(object_ptr))) {
2336			object_ptr = Z_REFVAL_P(object_ptr);
2337			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
2338				ZEND_VM_C_GOTO(try_assign_dim_array);
2339			}
2340		}
2341		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
2342			dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2343			value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2344
2345			if (OP_DATA_TYPE == IS_CONST && UNEXPECTED(Z_REFCOUNTED_P(value))) {
2346				Z_ADDREF_P(value);
2347			}
2348
2349			zend_assign_to_object_dim(object_ptr, dim, value);
2350
2351			if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) {
2352				ZVAL_COPY(EX_VAR(opline->result.var), value);
2353			}
2354
2355			if (OP_DATA_TYPE == IS_CONST) {
2356				zval_ptr_dtor_nogc(value);
2357			} else {
2358				FREE_OP_DATA();
2359			}
2360		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
2361			if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
2362				if (OP2_TYPE == IS_UNUSED) {
2363					zend_throw_error(NULL, "[] operator not supported for strings");
2364					FREE_UNFETCHED_OP_DATA();
2365					FREE_OP1_VAR_PTR();
2366					HANDLE_EXCEPTION();
2367				} else {
2368					dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2369					value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
2370					zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
2371					FREE_OP_DATA();
2372				}
2373			} else {
2374				zval_ptr_dtor_nogc(object_ptr);
2375ZEND_VM_C_LABEL(assign_dim_convert_to_array):
2376				ZVAL_NEW_ARR(object_ptr);
2377				zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0);
2378				ZEND_VM_C_GOTO(try_assign_dim_array);
2379			}
2380		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
2381			ZEND_VM_C_GOTO(assign_dim_convert_to_array);
2382		} else {
2383			if (OP1_TYPE != IS_VAR || UNEXPECTED(!Z_ISERROR_P(object_ptr))) {
2384				zend_error(E_WARNING, "Cannot use a scalar value as an array");
2385			}
2386			dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2387ZEND_VM_C_LABEL(assign_dim_error):
2388			FREE_UNFETCHED_OP_DATA();
2389			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2390				ZVAL_NULL(EX_VAR(opline->result.var));
2391			}
2392		}
2393	}
2394	if (OP2_TYPE != IS_UNUSED) {
2395		FREE_OP2();
2396	}
2397	FREE_OP1_VAR_PTR();
2398	/* assign_dim has two opcodes! */
2399	ZEND_VM_NEXT_OPCODE_EX(1, 2);
2400}
2401
2402ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
2403{
2404	USE_OPLINE
2405	zend_free_op free_op1, free_op2;
2406	zval *value;
2407	zval *variable_ptr;
2408
2409	SAVE_OPLINE();
2410	value = GET_OP2_ZVAL_PTR(BP_VAR_R);
2411	variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2412
2413	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) {
2414		FREE_OP2();
2415		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2416			ZVAL_NULL(EX_VAR(opline->result.var));
2417		}
2418	} else {
2419		value = zend_assign_to_variable(variable_ptr, value, OP2_TYPE);
2420		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2421			ZVAL_COPY(EX_VAR(opline->result.var), value);
2422		}
2423		FREE_OP1_VAR_PTR();
2424		/* zend_assign_to_variable() always takes care of op2, never free it! */
2425	}
2426
2427	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2428}
2429
2430ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
2431{
2432	USE_OPLINE
2433	zend_free_op free_op1, free_op2;
2434	zval *variable_ptr;
2435	zval *value_ptr;
2436
2437	SAVE_OPLINE();
2438	value_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);
2439	variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2440
2441	if (OP1_TYPE == IS_VAR &&
2442	    UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
2443	    UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var))) &&
2444	    UNEXPECTED(!Z_ISERROR_P(EX_VAR(opline->op1.var)))) {
2445
2446		zend_throw_error(NULL, "Cannot assign by reference to overloaded object");
2447		FREE_OP2_VAR_PTR();
2448		HANDLE_EXCEPTION();
2449
2450	} else if (OP2_TYPE == IS_VAR &&
2451	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
2452			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
2453		zend_error(E_NOTICE, "Only variables should be assigned by reference");
2454		if (UNEXPECTED(EG(exception) != NULL)) {
2455			FREE_OP2_VAR_PTR();
2456			HANDLE_EXCEPTION();
2457		}
2458
2459		value_ptr = zend_assign_to_variable(variable_ptr, value_ptr, OP2_TYPE);
2460		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2461			ZVAL_COPY(EX_VAR(opline->result.var), value_ptr);
2462		}
2463		/* zend_assign_to_variable() always takes care of op2, never free it! */
2464
2465	} else {
2466
2467		if ((OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) ||
2468		    (OP2_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr)))) {
2469			variable_ptr = &EG(uninitialized_zval);
2470		} else {
2471			zend_assign_to_variable_reference(variable_ptr, value_ptr);
2472		}
2473
2474		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2475			ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
2476		}
2477
2478		FREE_OP2_VAR_PTR();
2479	}
2480
2481	FREE_OP1_VAR_PTR();
2482	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2483}
2484
2485ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
2486{
2487	zend_execute_data *old_execute_data;
2488	uint32_t call_info = EX_CALL_INFO();
2489
2490	if (EXPECTED(ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_FUNCTION)) {
2491		i_free_compiled_variables(execute_data);
2492		if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED))) {
2493			if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2494				zend_clean_and_cache_symbol_table(EX(symbol_table));
2495			}
2496			EG(current_execute_data) = EX(prev_execute_data);
2497			if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
2498				zend_object *object = Z_OBJ(execute_data->This);
2499#if 0
2500				if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
2501#else
2502				if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
2503#endif
2504					GC_REFCOUNT(object)--;
2505					if (GC_REFCOUNT(object) == 1) {
2506						zend_object_store_ctor_failed(object);
2507					}
2508				}
2509				OBJ_RELEASE(object);
2510			} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
2511				OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
2512			}
2513
2514			zend_vm_stack_free_extra_args_ex(call_info, execute_data);
2515			old_execute_data = execute_data;
2516			execute_data = EX(prev_execute_data);
2517			zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
2518		} else {
2519			EG(current_execute_data) = EX(prev_execute_data);
2520			if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
2521				zend_object *object = Z_OBJ(execute_data->This);
2522#if 0
2523				if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
2524#else
2525				if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
2526#endif
2527					GC_REFCOUNT(object)--;
2528					if (GC_REFCOUNT(object) == 1) {
2529						zend_object_store_ctor_failed(object);
2530					}
2531				}
2532				OBJ_RELEASE(object);
2533			} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
2534				OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
2535			}
2536			EG(vm_stack_top) = (zval*)execute_data;
2537			execute_data = EX(prev_execute_data);
2538		}
2539
2540		if (UNEXPECTED(EG(exception) != NULL)) {
2541			const zend_op *old_opline = EX(opline);
2542			zend_throw_exception_internal(NULL);
2543			if (RETURN_VALUE_USED(old_opline)) {
2544				zval_ptr_dtor(EX_VAR(old_opline->result.var));
2545			}
2546			HANDLE_EXCEPTION_LEAVE();
2547		}
2548
2549		LOAD_NEXT_OPLINE();
2550		ZEND_VM_LEAVE();
2551	} else if (EXPECTED((ZEND_CALL_KIND_EX(call_info) & ZEND_CALL_TOP) == 0)) {
2552		zend_detach_symbol_table(execute_data);
2553		destroy_op_array(&EX(func)->op_array);
2554		efree_size(EX(func), sizeof(zend_op_array));
2555		old_execute_data = execute_data;
2556		execute_data = EG(current_execute_data) = EX(prev_execute_data);
2557		zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
2558
2559		zend_attach_symbol_table(execute_data);
2560		if (UNEXPECTED(EG(exception) != NULL)) {
2561			zend_throw_exception_internal(NULL);
2562			HANDLE_EXCEPTION_LEAVE();
2563		}
2564
2565		LOAD_NEXT_OPLINE();
2566		ZEND_VM_LEAVE();
2567	} else {
2568		if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_TOP_FUNCTION) {
2569			i_free_compiled_variables(execute_data);
2570			if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
2571				if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2572					zend_clean_and_cache_symbol_table(EX(symbol_table));
2573				}
2574				zend_vm_stack_free_extra_args_ex(call_info, execute_data);
2575			}
2576			EG(current_execute_data) = EX(prev_execute_data);
2577			if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
2578				OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
2579			}
2580			ZEND_VM_RETURN();
2581		} else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
2582			zend_array *symbol_table = EX(symbol_table);
2583
2584			zend_detach_symbol_table(execute_data);
2585			old_execute_data = EX(prev_execute_data);
2586			while (old_execute_data) {
2587				if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2588					if (old_execute_data->symbol_table == symbol_table) {
2589						zend_attach_symbol_table(old_execute_data);
2590					}
2591					break;
2592				}
2593				old_execute_data = old_execute_data->prev_execute_data;
2594			}
2595			EG(current_execute_data) = EX(prev_execute_data);
2596			ZEND_VM_RETURN();
2597		}
2598	}
2599}
2600
2601ZEND_VM_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
2602{
2603	USE_OPLINE
2604
2605	ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
2606	ZEND_VM_CONTINUE();
2607}
2608
2609ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
2610{
2611	USE_OPLINE
2612	zend_free_op free_op1;
2613	zval *val;
2614
2615	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2616
2617	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
2618		ZEND_VM_SET_NEXT_OPCODE(opline + 1);
2619		ZEND_VM_CONTINUE();
2620	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2621		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2622			SAVE_OPLINE();
2623			GET_OP1_UNDEF_CV(val, BP_VAR_R);
2624			ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
2625		} else {
2626			ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
2627			ZEND_VM_CONTINUE();
2628		}
2629	}
2630
2631	SAVE_OPLINE();
2632	if (i_zend_is_true(val)) {
2633		opline++;
2634	} else {
2635		opline = OP_JMP_ADDR(opline, opline->op2);
2636	}
2637	FREE_OP1();
2638	if (UNEXPECTED(EG(exception) != NULL)) {
2639		HANDLE_EXCEPTION();
2640	}
2641	ZEND_VM_JMP(opline);
2642}
2643
2644ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
2645{
2646	USE_OPLINE
2647	zend_free_op free_op1;
2648	zval *val;
2649
2650	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2651
2652	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
2653		ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
2654		ZEND_VM_CONTINUE();
2655	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2656		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2657			SAVE_OPLINE();
2658			GET_OP1_UNDEF_CV(val, BP_VAR_R);
2659			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2660		} else {
2661			ZEND_VM_NEXT_OPCODE();
2662		}
2663	}
2664
2665	SAVE_OPLINE();
2666	if (i_zend_is_true(val)) {
2667		opline = OP_JMP_ADDR(opline, opline->op2);
2668	} else {
2669		opline++;
2670	}
2671	FREE_OP1();
2672	if (UNEXPECTED(EG(exception) != NULL)) {
2673		HANDLE_EXCEPTION();
2674	}
2675	ZEND_VM_JMP(opline);
2676}
2677
2678ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR)
2679{
2680	USE_OPLINE
2681	zend_free_op free_op1;
2682	zval *val;
2683
2684	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2685
2686	if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) {
2687		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
2688		ZEND_VM_CONTINUE();
2689	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2690		if (OP1_TYPE == IS_CV) {
2691			if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2692				SAVE_OPLINE();
2693				GET_OP1_UNDEF_CV(val, BP_VAR_R);
2694			}
2695			ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
2696		} else {
2697			ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
2698			ZEND_VM_CONTINUE();
2699		}
2700	}
2701
2702	SAVE_OPLINE();
2703	if (i_zend_is_true(val)) {
2704		opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
2705	} else {
2706		opline = OP_JMP_ADDR(opline, opline->op2);
2707	}
2708	FREE_OP1();
2709	if (UNEXPECTED(EG(exception) != NULL)) {
2710		HANDLE_EXCEPTION();
2711	}
2712	ZEND_VM_JMP(opline);
2713}
2714
2715ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
2716{
2717	USE_OPLINE
2718	zend_free_op free_op1;
2719	zval *val;
2720	int ret;
2721
2722	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2723
2724	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
2725		ZVAL_TRUE(EX_VAR(opline->result.var));
2726		ZEND_VM_SET_NEXT_OPCODE(opline + 1);
2727		ZEND_VM_CONTINUE();
2728	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2729		ZVAL_FALSE(EX_VAR(opline->result.var));
2730		if (OP1_TYPE == IS_CV) {
2731			if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2732				SAVE_OPLINE();
2733				GET_OP1_UNDEF_CV(val, BP_VAR_R);
2734			}
2735			ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
2736		} else {
2737			ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
2738			ZEND_VM_CONTINUE();
2739		}
2740	}
2741
2742	SAVE_OPLINE();
2743	ret = i_zend_is_true(val);
2744	FREE_OP1();
2745	if (ret) {
2746		ZVAL_TRUE(EX_VAR(opline->result.var));
2747		opline++;
2748	} else {
2749		ZVAL_FALSE(EX_VAR(opline->result.var));
2750		opline = OP_JMP_ADDR(opline, opline->op2);
2751	}
2752	if (UNEXPECTED(EG(exception) != NULL)) {
2753		HANDLE_EXCEPTION();
2754	}
2755	ZEND_VM_JMP(opline);
2756}
2757
2758ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
2759{
2760	USE_OPLINE
2761	zend_free_op free_op1;
2762	zval *val;
2763	int ret;
2764
2765	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2766
2767	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
2768		ZVAL_TRUE(EX_VAR(opline->result.var));
2769		ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
2770		ZEND_VM_CONTINUE();
2771	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2772		ZVAL_FALSE(EX_VAR(opline->result.var));
2773		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2774			SAVE_OPLINE();
2775			GET_OP1_UNDEF_CV(val, BP_VAR_R);
2776			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2777		} else {
2778			ZEND_VM_NEXT_OPCODE();
2779		}
2780	}
2781
2782	SAVE_OPLINE();
2783	ret = i_zend_is_true(val);
2784	FREE_OP1();
2785	if (ret) {
2786		ZVAL_TRUE(EX_VAR(opline->result.var));
2787		opline = OP_JMP_ADDR(opline, opline->op2);
2788	} else {
2789		ZVAL_FALSE(EX_VAR(opline->result.var));
2790		opline++;
2791	}
2792	if (UNEXPECTED(EG(exception) != NULL)) {
2793		HANDLE_EXCEPTION();
2794	}
2795	ZEND_VM_JMP(opline);
2796}
2797
2798ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, LIVE_RANGE)
2799{
2800	USE_OPLINE
2801
2802	SAVE_OPLINE();
2803	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
2804	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2805}
2806
2807ZEND_VM_HANDLER(127, ZEND_FE_FREE, TMPVAR, LIVE_RANGE)
2808{
2809	zval *var;
2810	USE_OPLINE
2811
2812	SAVE_OPLINE();
2813	var = EX_VAR(opline->op1.var);
2814	if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
2815		zend_hash_iterator_del(Z_FE_ITER_P(var));
2816	}
2817	zval_ptr_dtor_nogc(var);
2818	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2819}
2820
2821ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
2822{
2823	USE_OPLINE
2824	zend_free_op free_op1, free_op2;
2825	zval *op1, *op2;
2826	zend_string *op1_str, *op2_str, *str;
2827
2828	SAVE_OPLINE();
2829	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2830	if (OP1_TYPE == IS_CONST) {
2831		op1_str = Z_STR_P(op1);
2832	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
2833		op1_str = zend_string_copy(Z_STR_P(op1));
2834	} else {
2835		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
2836			GET_OP1_UNDEF_CV(op1, BP_VAR_R);
2837		}
2838		op1_str = _zval_get_string_func(op1);
2839	}
2840	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2841	if (OP2_TYPE == IS_CONST) {
2842		op2_str = Z_STR_P(op2);
2843	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
2844		op2_str = zend_string_copy(Z_STR_P(op2));
2845	} else {
2846		if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
2847			GET_OP2_UNDEF_CV(op2, BP_VAR_R);
2848		}
2849		op2_str = _zval_get_string_func(op2);
2850	}
2851	do {
2852		if (OP1_TYPE != IS_CONST) {
2853			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
2854				if (OP2_TYPE == IS_CONST) {
2855					zend_string_addref(op2_str);
2856				}
2857				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
2858				zend_string_release(op1_str);
2859				break;
2860			}
2861		}
2862		if (OP2_TYPE != IS_CONST) {
2863			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
2864				if (OP1_TYPE == IS_CONST) {
2865					zend_string_addref(op1_str);
2866				}
2867				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
2868				zend_string_release(op2_str);
2869				break;
2870			}
2871		}
2872		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
2873		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
2874		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
2875		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
2876		if (OP1_TYPE != IS_CONST) {
2877			zend_string_release(op1_str);
2878		}
2879		if (OP2_TYPE != IS_CONST) {
2880			zend_string_release(op2_str);
2881		}
2882	} while (0);
2883	FREE_OP1();
2884	FREE_OP2();
2885	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2886}
2887
2888ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM)
2889{
2890	USE_OPLINE
2891	zend_free_op free_op2;
2892	zend_string **rope;
2893	zval *var;
2894
2895	/* Compiler allocates the necessary number of zval slots to keep the rope */
2896	rope = (zend_string**)EX_VAR(opline->result.var);
2897	if (OP2_TYPE == IS_CONST) {
2898		var = GET_OP2_ZVAL_PTR(BP_VAR_R);
2899		rope[0] = zend_string_copy(Z_STR_P(var));
2900	} else {
2901		var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2902		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
2903			if (OP2_TYPE == IS_CV) {
2904				rope[0] = zend_string_copy(Z_STR_P(var));
2905			} else {
2906				rope[0] = Z_STR_P(var);
2907			}
2908		} else {
2909			SAVE_OPLINE();
2910			if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
2911				GET_OP2_UNDEF_CV(var, BP_VAR_R);
2912			}
2913			rope[0] = _zval_get_string_func(var);
2914			FREE_OP2();
2915			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2916		}
2917	}
2918	ZEND_VM_NEXT_OPCODE();
2919}
2920
2921ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM)
2922{
2923	USE_OPLINE
2924	zend_free_op free_op2;
2925	zend_string **rope;
2926	zval *var;
2927
2928	/* op1 and result are the same */
2929	rope = (zend_string**)EX_VAR(opline->op1.var);
2930	if (OP2_TYPE == IS_CONST) {
2931		var = GET_OP2_ZVAL_PTR(BP_VAR_R);
2932		rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
2933	} else {
2934		var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2935		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
2936			if (OP2_TYPE == IS_CV) {
2937				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
2938			} else {
2939				rope[opline->extended_value] = Z_STR_P(var);
2940			}
2941		} else {
2942			SAVE_OPLINE();
2943			if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
2944				GET_OP2_UNDEF_CV(var, BP_VAR_R);
2945			}
2946			rope[opline->extended_value] = _zval_get_string_func(var);
2947			FREE_OP2();
2948			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2949		}
2950	}
2951	ZEND_VM_NEXT_OPCODE();
2952}
2953
2954ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
2955{
2956	USE_OPLINE
2957	zend_free_op free_op2;
2958	zend_string **rope;
2959	zval *var, *ret;
2960	uint32_t i;
2961	size_t len = 0;
2962	char *target;
2963
2964	rope = (zend_string**)EX_VAR(opline->op1.var);
2965	if (OP2_TYPE == IS_CONST) {
2966		var = GET_OP2_ZVAL_PTR(BP_VAR_R);
2967		rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
2968	} else {
2969		var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2970		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
2971			if (OP2_TYPE == IS_CV) {
2972				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
2973			} else {
2974				rope[opline->extended_value] = Z_STR_P(var);
2975			}
2976		} else {
2977			SAVE_OPLINE();
2978			if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
2979				GET_OP2_UNDEF_CV(var, BP_VAR_R);
2980			}
2981			rope[opline->extended_value] = _zval_get_string_func(var);
2982			FREE_OP2();
2983			if (UNEXPECTED(EG(exception))) {
2984				for (i = 0; i <= opline->extended_value; i++) {
2985					zend_string_release(rope[i]);
2986				}
2987				HANDLE_EXCEPTION();
2988			}
2989		}
2990	}
2991	for (i = 0; i <= opline->extended_value; i++) {
2992		len += ZSTR_LEN(rope[i]);
2993	}
2994	ret = EX_VAR(opline->result.var);
2995	ZVAL_STR(ret, zend_string_alloc(len, 0));
2996	target = Z_STRVAL_P(ret);
2997	for (i = 0; i <= opline->extended_value; i++) {
2998		memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
2999		target += ZSTR_LEN(rope[i]);
3000		zend_string_release(rope[i]);
3001	}
3002	*target = '\0';
3003
3004	ZEND_VM_NEXT_OPCODE();
3005}
3006
3007ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV, CLASS_FETCH)
3008{
3009	USE_OPLINE
3010
3011	SAVE_OPLINE();
3012	if (OP2_TYPE == IS_UNUSED) {
3013		Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->extended_value);
3014		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3015	} else {
3016		zend_free_op free_op2;
3017		zval *class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3018
3019ZEND_VM_C_LABEL(try_class_name):
3020		if (OP2_TYPE == IS_CONST) {
3021			zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
3022
3023			if (UNEXPECTED(ce == NULL)) {
3024				ce = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value);
3025				CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce);
3026			}
3027			Z_CE_P(EX_VAR(opline->result.var)) = ce;
3028		} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
3029			Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
3030		} else if (Z_TYPE_P(class_name) == IS_STRING) {
3031			Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value);
3032		} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
3033			class_name = Z_REFVAL_P(class_name);
3034			ZEND_VM_C_GOTO(try_class_name);
3035		} else {
3036			if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
3037				GET_OP2_UNDEF_CV(class_name, BP_VAR_R);
3038				if (UNEXPECTED(EG(exception) != NULL)) {
3039					HANDLE_EXCEPTION();
3040				}
3041			}
3042			zend_throw_error(NULL, "Class name must be a valid object or a string");
3043		}
3044
3045		FREE_OP2();
3046		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3047	}
3048}
3049
3050ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM)
3051{
3052	USE_OPLINE
3053	zval *function_name;
3054	zend_free_op free_op1, free_op2;
3055	zval *object;
3056	zend_function *fbc;
3057	zend_class_entry *called_scope;
3058	zend_object *obj;
3059	zend_execute_data *call;
3060	uint32_t call_info;
3061
3062	SAVE_OPLINE();
3063
3064	function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3065
3066	if (OP2_TYPE != IS_CONST &&
3067	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
3068		do {
3069			if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
3070				function_name = Z_REFVAL_P(function_name);
3071				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
3072					break;
3073				}
3074			} else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
3075				GET_OP2_UNDEF_CV(function_name, BP_VAR_R);
3076				if (UNEXPECTED(EG(exception) != NULL)) {
3077					HANDLE_EXCEPTION();
3078				}
3079			}
3080			zend_throw_error(NULL, "Method name must be a string");
3081			FREE_OP2();
3082			FREE_UNFETCHED_OP1();
3083			HANDLE_EXCEPTION();
3084		} while (0);
3085	}
3086
3087	object = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
3088
3089	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
3090		zend_throw_error(NULL, "Using $this when not in object context");
3091		FREE_OP2();
3092		HANDLE_EXCEPTION();
3093	}
3094
3095	if (OP1_TYPE != IS_UNUSED) {
3096		do {
3097			if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
3098				if ((OP1_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
3099					object = Z_REFVAL_P(object);
3100					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
3101						break;
3102					}
3103				}
3104				if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
3105					object = GET_OP1_UNDEF_CV(object, BP_VAR_R);
3106					if (UNEXPECTED(EG(exception) != NULL)) {
3107						FREE_OP2();
3108						HANDLE_EXCEPTION();
3109					}
3110				}
3111				zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
3112				FREE_OP2();
3113				FREE_OP1();
3114				HANDLE_EXCEPTION();
3115			}
3116		} while (0);
3117	}
3118
3119	obj = Z_OBJ_P(object);
3120	called_scope = obj->ce;
3121
3122	if (OP2_TYPE != IS_CONST ||
3123	    UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
3124	    zend_object *orig_obj = obj;
3125
3126		if (UNEXPECTED(obj->handlers->get_method == NULL)) {
3127			zend_throw_error(NULL, "Object does not support method calls");
3128			FREE_OP2();
3129			FREE_OP1();
3130			HANDLE_EXCEPTION();
3131		}
3132
3133		/* First, locate the function. */
3134		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL));
3135		if (UNEXPECTED(fbc == NULL)) {
3136			if (EXPECTED(!EG(exception))) {
3137				zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name));
3138			}
3139			FREE_OP2();
3140			FREE_OP1();
3141			HANDLE_EXCEPTION();
3142		}
3143		if (OP2_TYPE == IS_CONST &&
3144		    EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
3145		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
3146		    EXPECTED(obj == orig_obj)) {
3147			CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
3148		}
3149		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
3150			init_func_run_time_cache(&fbc->op_array);
3151		}
3152	}
3153
3154	call_info = ZEND_CALL_NESTED_FUNCTION;
3155	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
3156		obj = NULL;
3157	} else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) {
3158		/* CV may be changed indirectly (e.g. when it's a reference) */
3159		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
3160		GC_REFCOUNT(obj)++; /* For $this pointer */
3161	}
3162
3163	call = zend_vm_stack_push_call_frame(call_info,
3164		fbc, opline->extended_value, called_scope, obj);
3165	call->prev_execute_data = EX(call);
3166	EX(call) = call;
3167
3168	FREE_OP2();
3169	FREE_OP1();
3170
3171	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3172}
3173
3174ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM)
3175{
3176	USE_OPLINE
3177	zval *function_name;
3178	zend_class_entry *ce;
3179	zend_object *object;
3180	zend_function *fbc;
3181	zend_execute_data *call;
3182
3183	SAVE_OPLINE();
3184
3185	if (OP1_TYPE == IS_CONST) {
3186		/* no function found. try a static method in class */
3187		ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
3188		if (UNEXPECTED(ce == NULL)) {
3189			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);
3190			if (UNEXPECTED(ce == NULL)) {
3191				if (UNEXPECTED(EG(exception) != NULL)) {
3192					HANDLE_EXCEPTION();
3193				}
3194				zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
3195				HANDLE_EXCEPTION();
3196			}
3197			CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
3198		}
3199	} else if (OP1_TYPE == IS_UNUSED) {
3200		ce = zend_fetch_class(NULL, opline->op1.num);
3201		if (UNEXPECTED(ce == NULL)) {
3202			ZEND_ASSERT(EG(exception));
3203			FREE_UNFETCHED_OP2();
3204			HANDLE_EXCEPTION();
3205		}
3206	} else {
3207		ce = Z_CE_P(EX_VAR(opline->op1.var));
3208	}
3209
3210	if (OP1_TYPE == IS_CONST &&
3211	    OP2_TYPE == IS_CONST &&
3212	    EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) {
3213		/* nothing to do */
3214	} else if (OP1_TYPE != IS_CONST &&
3215	           OP2_TYPE == IS_CONST &&
3216	           (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) {
3217		/* do nothing */
3218	} else if (OP2_TYPE != IS_UNUSED) {
3219		zend_free_op free_op2;
3220
3221		function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3222		if (OP2_TYPE != IS_CONST) {
3223			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
3224				do {
3225					if (OP2_TYPE & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
3226						function_name = Z_REFVAL_P(function_name);
3227						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
3228							break;
3229						}
3230					} else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
3231						GET_OP2_UNDEF_CV(function_name, BP_VAR_R);
3232						if (UNEXPECTED(EG(exception) != NULL)) {
3233							HANDLE_EXCEPTION();
3234						}
3235					}
3236					zend_throw_error(NULL, "Function name must be a string");
3237					FREE_OP2();
3238					HANDLE_EXCEPTION();
3239				} while (0);
3240 			}
3241		}
3242
3243		if (ce->get_static_method) {
3244			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
3245		} else {
3246			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL));
3247		}
3248		if (UNEXPECTED(fbc == NULL)) {
3249			if (EXPECTED(!EG(exception))) {
3250				zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name));
3251			}
3252			FREE_OP2();
3253			HANDLE_EXCEPTION();
3254		}
3255		if (OP2_TYPE == IS_CONST &&
3256		    EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
3257		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
3258			if (OP1_TYPE == IS_CONST) {
3259				CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
3260			} else {
3261				CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
3262			}
3263		}
3264		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
3265			init_func_run_time_cache(&fbc->op_array);
3266		}
3267		if (OP2_TYPE != IS_CONST) {
3268			FREE_OP2();
3269		}
3270	} else {
3271		if (UNEXPECTED(ce->constructor == NULL)) {
3272			zend_throw_error(NULL, "Cannot call constructor");
3273			HANDLE_EXCEPTION();
3274		}
3275		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
3276			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
3277			HANDLE_EXCEPTION();
3278		}
3279		fbc = ce->constructor;
3280		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
3281			init_func_run_time_cache(&fbc->op_array);
3282		}
3283	}
3284
3285	object = NULL;
3286	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
3287		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
3288			object = Z_OBJ(EX(This));
3289			ce = object->ce;
3290		} else {
3291			if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
3292				/* Allowed for PHP 4 compatibility. */
3293				zend_error(
3294					E_DEPRECATED,
3295					"Non-static method %s::%s() should not be called statically",
3296					ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
3297				if (UNEXPECTED(EG(exception) != NULL)) {
3298					HANDLE_EXCEPTION();
3299				}
3300			} else {
3301				/* An internal function assumes $this is present and won't check that.
3302				 * So PHP would crash by allowing the call. */
3303				zend_throw_error(
3304					zend_ce_error,
3305					"Non-static method %s::%s() cannot be called statically",
3306					ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
3307				HANDLE_EXCEPTION();
3308			}
3309		}
3310	}
3311
3312	if (OP1_TYPE == IS_UNUSED) {
3313		/* previous opcode is ZEND_FETCH_CLASS */
3314		if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
3315		    (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
3316			if (Z_TYPE(EX(This)) == IS_OBJECT) {
3317				ce = Z_OBJCE(EX(This));
3318			} else {
3319				ce = Z_CE(EX(This));
3320			}
3321		}
3322	}
3323
3324	call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3325		fbc, opline->extended_value, ce, object);
3326	call->prev_execute_data = EX(call);
3327	EX(call) = call;
3328
3329	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3330}
3331
3332ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM)
3333{
3334	USE_OPLINE
3335	zend_function *fbc;
3336	zval *function_name, *func;
3337	zend_execute_data *call;
3338
3339	function_name = (zval*)EX_CONSTANT(opline->op2);
3340	fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name));
3341	if (UNEXPECTED(fbc == NULL)) {
3342		func = zend_hash_find(EG(function_table), Z_STR_P(function_name+1));
3343		if (UNEXPECTED(func == NULL)) {
3344			SAVE_OPLINE();
3345			zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name));
3346			HANDLE_EXCEPTION();
3347		}
3348		fbc = Z_FUNC_P(func);
3349		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
3350			init_func_run_time_cache(&fbc->op_array);
3351		}
3352		CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
3353	}
3354	call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3355		fbc, opline->extended_value, NULL, NULL);
3356	call->prev_execute_data = EX(call);
3357	EX(call) = call;
3358
3359	ZEND_VM_NEXT_OPCODE();
3360}
3361
3362ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV, NUM)
3363{
3364	USE_OPLINE
3365	zend_free_op free_op2;
3366	zval *function_name;
3367	zend_execute_data *call;
3368
3369	SAVE_OPLINE();
3370	function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3371
3372ZEND_VM_C_LABEL(try_function_name):
3373	if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
3374		call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value);
3375	} else if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
3376		call = zend_init_dynamic_call_object(function_name, opline->extended_value);
3377	} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) {
3378		call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value);
3379	} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
3380		function_name = Z_REFVAL_P(function_name);
3381		ZEND_VM_C_GOTO(try_function_name);
3382	} else {
3383		if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
3384			GET_OP2_UNDEF_CV(function_name, BP_VAR_R);
3385			if (UNEXPECTED(EG(exception) != NULL)) {
3386				HANDLE_EXCEPTION();
3387			}
3388		}
3389		zend_throw_error(NULL, "Function name must be a string");
3390		call = NULL;
3391	}
3392
3393	FREE_OP2();
3394
3395	if (UNEXPECTED(!call)) {
3396		HANDLE_EXCEPTION();
3397	}
3398
3399	call->prev_execute_data = EX(call);
3400	EX(call) = call;
3401
3402	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3403}
3404
3405ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
3406{
3407	USE_OPLINE
3408	zend_free_op free_op2;
3409	zval *function_name;
3410	zend_fcall_info_cache fcc;
3411	char *error = NULL;
3412	zend_function *func;
3413	zend_class_entry *called_scope;
3414	zend_object *object;
3415	zend_execute_data *call;
3416	uint32_t call_info = ZEND_CALL_NESTED_FUNCTION;
3417
3418	SAVE_OPLINE();
3419	function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
3420	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
3421		func = fcc.function_handler;
3422		called_scope = fcc.called_scope;
3423		object = fcc.object;
3424		if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
3425			/* Delay closure destruction until its invocation */
3426			if (OP2_TYPE & (IS_VAR|IS_CV)) {
3427				ZVAL_DEREF(function_name);
3428			}
3429			ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
3430			GC_REFCOUNT((zend_object*)func->common.prototype)++;
3431			call_info |= ZEND_CALL_CLOSURE;
3432		} else if (object) {
3433			call_info |= ZEND_CALL_RELEASE_THIS;
3434			GC_REFCOUNT(object)++; /* For $this pointer */
3435		}
3436		if (error) {
3437			efree(error);
3438			/* This is the only soft error is_callable() can generate */
3439			zend_error(E_DEPRECATED,
3440				"Non-static method %s::%s() should not be called statically",
3441				ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
3442			if (UNEXPECTED(EG(exception) != NULL)) {
3443				HANDLE_EXCEPTION();
3444			}
3445		}
3446		if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) {
3447			init_func_run_time_cache(&func->op_array);
3448		}
3449	} else {
3450		zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error);
3451		efree(error);
3452		func = (zend_function*)&zend_pass_function;
3453		called_scope = NULL;
3454		object = NULL;
3455	}
3456
3457	call = zend_vm_stack_push_call_frame(call_info,
3458		func, opline->extended_value, called_scope, object);
3459	call->prev_execute_data = EX(call);
3460	EX(call) = call;
3461
3462	FREE_OP2();
3463	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3464}
3465
3466ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM)
3467{
3468	USE_OPLINE
3469	zval *func_name;
3470	zval *func;
3471	zend_function *fbc;
3472	zend_execute_data *call;
3473
3474	func_name = EX_CONSTANT(opline->op2) + 1;
3475	fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
3476	if (UNEXPECTED(fbc == NULL)) {
3477		func = zend_hash_find(EG(function_table), Z_STR_P(func_name));
3478		if (func == NULL) {
3479			func_name++;
3480			func = zend_hash_find(EG(function_table), Z_STR_P(func_name));
3481			if (UNEXPECTED(func == NULL)) {
3482				SAVE_OPLINE();
3483				zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
3484				HANDLE_EXCEPTION();
3485			}
3486		}
3487		fbc = Z_FUNC_P(func);
3488		CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
3489		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
3490			init_func_run_time_cache(&fbc->op_array);
3491		}
3492	}
3493
3494	call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3495		fbc, opline->extended_value, NULL, NULL);
3496	call->prev_execute_data = EX(call);
3497	EX(call) = call;
3498
3499	ZEND_VM_NEXT_OPCODE();
3500}
3501
3502ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM)
3503{
3504	USE_OPLINE
3505	zend_free_op free_op2;
3506	zval *fname = GET_OP2_ZVAL_PTR(BP_VAR_R);
3507	zval *func;
3508	zend_function *fbc;
3509	zend_execute_data *call;
3510
3511	fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname));
3512	if (UNEXPECTED(fbc == NULL)) {
3513		func = zend_hash_find(EG(function_table), Z_STR_P(fname));
3514		if (UNEXPECTED(func == NULL)) {
3515		    SAVE_OPLINE();
3516			zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(fname));
3517			HANDLE_EXCEPTION();
3518		}
3519		fbc = Z_FUNC_P(func);
3520		CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc);
3521		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
3522			init_func_run_time_cache(&fbc->op_array);
3523		}
3524	}
3525
3526	call = zend_vm_stack_push_call_frame_ex(
3527		opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
3528		fbc, opline->extended_value, NULL, NULL);
3529	call->prev_execute_data = EX(call);
3530	EX(call) = call;
3531
3532	ZEND_VM_NEXT_OPCODE();
3533}
3534
3535ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
3536{
3537	USE_OPLINE
3538	zend_execute_data *call = EX(call);
3539	zend_function *fbc = call->func;
3540	zval *ret;
3541	zval retval;
3542
3543	SAVE_OPLINE();
3544	EX(call) = call->prev_execute_data;
3545
3546	call->prev_execute_data = execute_data;
3547	EG(current_execute_data) = call;
3548
3549	ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
3550	ZVAL_NULL(ret);
3551
3552	fbc->internal_function.handler(call, ret);
3553
3554#if ZEND_DEBUG
3555	ZEND_ASSERT(
3556		EG(exception) || !call->func ||
3557		!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
3558		zend_verify_internal_return_type(call->func, ret));
3559	ZEND_ASSERT(!Z_ISREF_P(ret));
3560#endif
3561
3562	EG(current_execute_data) = call->prev_execute_data;
3563	zend_vm_stack_free_args(call);
3564	zend_vm_stack_free_call_frame(call);
3565
3566	if (!RETURN_VALUE_USED(opline)) {
3567		zval_ptr_dtor(ret);
3568	}
3569
3570	if (UNEXPECTED(EG(exception) != NULL)) {
3571		zend_throw_exception_internal(NULL);
3572		if (RETURN_VALUE_USED(opline)) {
3573			zval_ptr_dtor(EX_VAR(opline->result.var));
3574		}
3575		HANDLE_EXCEPTION();
3576	}
3577
3578	ZEND_VM_SET_OPCODE(opline + 1);
3579	ZEND_VM_CONTINUE();
3580}
3581
3582ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
3583{
3584	USE_OPLINE
3585	zend_execute_data *call = EX(call);
3586	zend_function *fbc = call->func;
3587	zval *ret;
3588
3589	SAVE_OPLINE();
3590	EX(call) = call->prev_execute_data;
3591
3592	ret = NULL;
3593	if (RETURN_VALUE_USED(opline)) {
3594		ret = EX_VAR(opline->result.var);
3595		ZVAL_NULL(ret);
3596	}
3597
3598	call->prev_execute_data = execute_data;
3599	i_init_func_execute_data(call, &fbc->op_array, ret, 0);
3600
3601	ZEND_VM_ENTER();
3602}
3603
3604ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
3605{
3606	USE_OPLINE
3607	zend_execute_data *call = EX(call);
3608	zend_function *fbc = call->func;
3609	zval *ret;
3610
3611	SAVE_OPLINE();
3612	EX(call) = call->prev_execute_data;
3613
3614	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
3615		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
3616			if (EXPECTED(RETURN_VALUE_USED(opline))) {
3617				ret = EX_VAR(opline->result.var);
3618				zend_generator_create_zval(call, &fbc->op_array, ret);
3619			} else {
3620				zend_vm_stack_free_args(call);
3621			}
3622
3623			zend_vm_stack_free_call_frame(call);
3624		} else {
3625			ret = NULL;
3626			if (RETURN_VALUE_USED(opline)) {
3627				ret = EX_VAR(opline->result.var);
3628				ZVAL_NULL(ret);
3629			}
3630
3631			call->prev_execute_data = execute_data;
3632			i_init_func_execute_data(call, &fbc->op_array, ret, 0);
3633
3634			ZEND_VM_ENTER();
3635		}
3636	} else {
3637		zval retval;
3638		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
3639
3640		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
3641			zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
3642				fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "",
3643				fbc->common.scope ? "::" : "",
3644				ZSTR_VAL(fbc->common.function_name));
3645			if (UNEXPECTED(EG(exception) != NULL)) {
3646				HANDLE_EXCEPTION();
3647			}
3648		}
3649
3650		call->prev_execute_data = execute_data;
3651		EG(current_execute_data) = call;
3652
3653		if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
3654		 && UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
3655			zend_vm_stack_free_call_frame(call);
3656			zend_throw_exception_internal(NULL);
3657			HANDLE_EXCEPTION();
3658		}
3659
3660		ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
3661		ZVAL_NULL(ret);
3662
3663		fbc->internal_function.handler(call, ret);
3664
3665#if ZEND_DEBUG
3666		if (!EG(exception) && call->func) {
3667			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
3668				zend_verify_internal_return_type(call->func, ret));
3669			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
3670				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
3671		}
3672#endif
3673
3674		EG(current_execute_data) = call->prev_execute_data;
3675		zend_vm_stack_free_args(call);
3676		zend_vm_stack_free_call_frame(call);
3677
3678		if (!RETURN_VALUE_USED(opline)) {
3679			zval_ptr_dtor(ret);
3680		}
3681	}
3682
3683	if (UNEXPECTED(EG(exception) != NULL)) {
3684		zend_throw_exception_internal(NULL);
3685		if (RETURN_VALUE_USED(opline)) {
3686			zval_ptr_dtor(EX_VAR(opline->result.var));
3687		}
3688		HANDLE_EXCEPTION();
3689	}
3690	ZEND_VM_SET_OPCODE(opline + 1);
3691	ZEND_VM_CONTINUE();
3692}
3693
3694ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
3695{
3696	USE_OPLINE
3697	zend_execute_data *call = EX(call);
3698	zend_function *fbc = call->func;
3699	zend_object *object;
3700	zval *ret;
3701
3702	SAVE_OPLINE();
3703	EX(call) = call->prev_execute_data;
3704	if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
3705		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
3706			zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
3707			HANDLE_EXCEPTION();
3708		}
3709		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
3710			zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
3711				fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "",
3712				fbc->common.scope ? "::" : "",
3713				ZSTR_VAL(fbc->common.function_name));
3714			if (UNEXPECTED(EG(exception) != NULL)) {
3715				HANDLE_EXCEPTION();
3716			}
3717		}
3718	}
3719
3720	LOAD_OPLINE();
3721
3722	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
3723		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
3724			if (EXPECTED(RETURN_VALUE_USED(opline))) {
3725				ret = EX_VAR(opline->result.var);
3726				zend_generator_create_zval(call, &fbc->op_array, ret);
3727			} else {
3728				if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
3729					OBJ_RELEASE((zend_object*)fbc->op_array.prototype);
3730				}
3731				zend_vm_stack_free_args(call);
3732			}
3733		} else {
3734			ret = NULL;
3735			if (RETURN_VALUE_USED(opline)) {
3736				ret = EX_VAR(opline->result.var);
3737				ZVAL_NULL(ret);
3738			}
3739
3740			call->prev_execute_data = execute_data;
3741			i_init_func_execute_data(call, &fbc->op_array, ret, 1);
3742
3743			if (EXPECTED(zend_execute_ex == execute_ex)) {
3744				ZEND_VM_ENTER();
3745			} else {
3746				ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
3747				zend_execute_ex(call);
3748			}
3749		}
3750	} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
3751		zval retval;
3752
3753		call->prev_execute_data = execute_data;
3754		EG(current_execute_data) = call;
3755
3756		if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
3757		  && UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
3758			if (RETURN_VALUE_USED(opline)) {
3759				ZVAL_UNDEF(EX_VAR(opline->result.var));
3760			}
3761			ZEND_VM_C_GOTO(fcall_end);
3762		}
3763
3764		ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
3765		ZVAL_NULL(ret);
3766
3767		if (!zend_execute_internal) {
3768			/* saves one function call if zend_execute_internal is not used */
3769			fbc->internal_function.handler(call, ret);
3770		} else {
3771			zend_execute_internal(call, ret);
3772		}
3773
3774#if ZEND_DEBUG
3775		if (!EG(exception) && call->func) {
3776			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
3777				zend_verify_internal_return_type(call->func, ret));
3778			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
3779				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
3780		}
3781#endif
3782
3783		EG(current_execute_data) = call->prev_execute_data;
3784		zend_vm_stack_free_args(call);
3785
3786		if (!RETURN_VALUE_USED(opline)) {
3787			zval_ptr_dtor(ret);
3788		}
3789
3790	} else { /* ZEND_OVERLOADED_FUNCTION */
3791		zval retval;
3792
3793		ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
3794
3795		call->prev_execute_data = execute_data;
3796
3797		if (UNEXPECTED(!zend_do_fcall_overloaded(fbc, call, ret))) {
3798			HANDLE_EXCEPTION();
3799		}
3800
3801		if (!RETURN_VALUE_USED(opline)) {
3802			zval_ptr_dtor(ret);
3803		}
3804	}
3805
3806ZEND_VM_C_LABEL(fcall_end):
3807	if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
3808		object = Z_OBJ(call->This);
3809#if 0
3810		if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) {
3811#else
3812		if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) {
3813#endif
3814			GC_REFCOUNT(object)--;
3815			if (GC_REFCOUNT(object) == 1) {
3816				zend_object_store_ctor_failed(object);
3817			}
3818		}
3819		OBJ_RELEASE(object);
3820	}
3821
3822	zend_vm_stack_free_call_frame(call);
3823	if (UNEXPECTED(EG(exception) != NULL)) {
3824		zend_throw_exception_internal(NULL);
3825		if (RETURN_VALUE_USED(opline)) {
3826			zval_ptr_dtor(EX_VAR(opline->result.var));
3827		}
3828		HANDLE_EXCEPTION();
3829	}
3830
3831	ZEND_VM_SET_OPCODE(opline + 1);
3832	ZEND_VM_CONTINUE();
3833}
3834
3835ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED)
3836{
3837	USE_OPLINE
3838
3839	SAVE_OPLINE();
3840	if (OP1_TYPE == IS_UNUSED) {
3841		zend_verify_missing_return_type(EX(func), CACHE_ADDR(opline->op2.num));
3842	} else {
3843/* prevents "undefined variable opline" errors */
3844#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
3845		zval *retval_ref, *retval_ptr;
3846		zend_free_op free_op1;
3847		zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
3848
3849		retval_ref = retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3850
3851		if (OP1_TYPE == IS_CONST) {
3852			ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
3853			retval_ref = retval_ptr = EX_VAR(opline->result.var);
3854		} else if (OP1_TYPE == IS_VAR) {
3855			if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
3856				retval_ptr = Z_INDIRECT_P(retval_ptr);
3857			}
3858			ZVAL_DEREF(retval_ptr);
3859		} else if (OP1_TYPE == IS_CV) {
3860			ZVAL_DEREF(retval_ptr);
3861		}
3862
3863		if (UNEXPECTED(!ret_info->class_name
3864			&& ret_info->type_hint != IS_CALLABLE
3865			&& !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr))
3866			&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
3867			&& retval_ref != retval_ptr)
3868		) {
3869			/* A cast might happen - unwrap the reference if this is a by-value return */
3870			if (Z_REFCOUNT_P(retval_ref) == 1) {
3871				ZVAL_UNREF(retval_ref);
3872			} else {
3873				Z_DELREF_P(retval_ref);
3874				ZVAL_COPY(retval_ref, retval_ptr);
3875			}
3876			retval_ptr = retval_ref;
3877		}
3878		zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num));
3879
3880		if (UNEXPECTED(EG(exception) != NULL)) {
3881			if (OP1_TYPE == IS_CONST) {
3882				zval_ptr_dtor_nogc(retval_ptr);
3883			}
3884		}
3885#endif
3886	}
3887	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3888}
3889
3890ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
3891{
3892	USE_OPLINE
3893	zval *retval_ptr;
3894	zval *return_value;
3895	zend_free_op free_op1;
3896
3897	retval_ptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
3898	return_value = EX(return_value);
3899	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
3900		SAVE_OPLINE();
3901		retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
3902		if (return_value) {
3903			ZVAL_NULL(return_value);
3904		}
3905	} else if (!return_value) {
3906		if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
3907			if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
3908				SAVE_OPLINE();
3909				zval_dtor_func_for_ptr(Z_COUNTED_P(free_op1));
3910			}
3911		}
3912	} else {
3913		if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
3914			ZVAL_COPY_VALUE(return_value, retval_ptr);
3915			if (OP1_TYPE == IS_CONST) {
3916				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
3917					Z_ADDREF_P(return_value);
3918				}
3919			}
3920		} else if (OP1_TYPE == IS_CV) {
3921			if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
3922				if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
3923					ZVAL_COPY_VALUE(return_value, retval_ptr);
3924					if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
3925						ZVAL_NULL(retval_ptr);
3926					} else {
3927						Z_ADDREF_P(return_value);
3928					}
3929				} else {
3930					retval_ptr = Z_REFVAL_P(retval_ptr);
3931					ZVAL_COPY(return_value, retval_ptr);
3932				}
3933			} else {
3934				ZVAL_COPY_VALUE(return_value, retval_ptr);
3935			}
3936		} else /* if (OP1_TYPE == IS_VAR) */ {
3937			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
3938				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
3939
3940				retval_ptr = Z_REFVAL_P(retval_ptr);
3941				ZVAL_COPY_VALUE(return_value, retval_ptr);
3942				if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
3943					efree_size(ref, sizeof(zend_reference));
3944				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
3945					Z_ADDREF_P(retval_ptr);
3946				}
3947			} else {
3948				ZVAL_COPY_VALUE(return_value, retval_ptr);
3949			}
3950		}
3951	}
3952	ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
3953}
3954
3955ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
3956{
3957	USE_OPLINE
3958	zval *retval_ptr;
3959	zend_free_op free_op1;
3960
3961	SAVE_OPLINE();
3962
3963	do {
3964		if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR)) ||
3965		    (OP1_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
3966			/* Not supposed to happen, but we'll allow it */
3967			zend_error(E_NOTICE, "Only variable references should be returned by reference");
3968
3969			retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3970			if (!EX(return_value)) {
3971				FREE_OP1();
3972			} else {
3973				if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
3974					ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
3975					break;
3976				}
3977
3978				ZVAL_NEW_REF(EX(return_value), retval_ptr);
3979				if (OP1_TYPE == IS_CONST) {
3980					if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
3981				}
3982			}
3983			break;
3984		}
3985
3986		retval_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
3987
3988		if (OP1_TYPE == IS_VAR) {
3989			if (retval_ptr == &EG(uninitialized_zval) ||
3990			    (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr))) {
3991				zend_error(E_NOTICE, "Only variable references should be returned by reference");
3992				if (EX(return_value)) {
3993					ZVAL_NEW_REF(EX(return_value), retval_ptr);
3994				} else {
3995					FREE_OP1_VAR_PTR();
3996				}
3997				break;
3998			}
3999		}
4000
4001		if (EX(return_value)) {
4002			ZVAL_MAKE_REF(retval_ptr);
4003			Z_ADDREF_P(retval_ptr);
4004			ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
4005		}
4006
4007		FREE_OP1_VAR_PTR();
4008	} while (0);
4009
4010	ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
4011}
4012
4013ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY)
4014{
4015	USE_OPLINE
4016	zval *retval;
4017	zend_free_op free_op1;
4018
4019	zend_generator *generator = zend_get_running_generator(execute_data);
4020
4021	SAVE_OPLINE();
4022	retval = GET_OP1_ZVAL_PTR(BP_VAR_R);
4023
4024	/* Copy return value into generator->retval */
4025	if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
4026		ZVAL_COPY_VALUE(&generator->retval, retval);
4027		if (OP1_TYPE == IS_CONST) {
4028			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
4029				Z_ADDREF(generator->retval);
4030			}
4031		}
4032	} else if (OP1_TYPE == IS_CV) {
4033		ZVAL_DEREF(retval);
4034		ZVAL_COPY(&generator->retval, retval);
4035	} else /* if (OP1_TYPE == IS_VAR) */ {
4036		if (UNEXPECTED(Z_ISREF_P(retval))) {
4037			zend_refcounted *ref = Z_COUNTED_P(retval);
4038
4039			retval = Z_REFVAL_P(retval);
4040			ZVAL_COPY_VALUE(&generator->retval, retval);
4041			if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
4042				efree_size(ref, sizeof(zend_reference));
4043			} else if (Z_OPT_REFCOUNTED_P(retval)) {
4044				Z_ADDREF_P(retval);
4045			}
4046		} else {
4047			ZVAL_COPY_VALUE(&generator->retval, retval);
4048		}
4049	}
4050
4051	/* Close the generator to free up resources */
4052	zend_generator_close(generator, 1);
4053
4054	/* Pass execution back to handling code */
4055	ZEND_VM_RETURN();
4056}
4057
4058ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
4059{
4060	USE_OPLINE
4061	zval *value;
4062	zend_free_op free_op1;
4063
4064	SAVE_OPLINE();
4065	value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4066
4067	do {
4068		if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
4069			if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
4070				value = Z_REFVAL_P(value);
4071				if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
4072					break;
4073				}
4074			}
4075			if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
4076				GET_OP1_UNDEF_CV(value, BP_VAR_R);
4077				if (UNEXPECTED(EG(exception) != NULL)) {
4078					HANDLE_EXCEPTION();
4079				}
4080			}
4081			zend_throw_error(NULL, "Can only throw objects");
4082			FREE_OP1();
4083			HANDLE_EXCEPTION();
4084		}
4085	} while (0);
4086
4087	zend_exception_save();
4088	if (OP1_TYPE != IS_TMP_VAR) {
4089		if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
4090	}
4091
4092	zend_throw_exception_object(value);
4093	zend_exception_restore();
4094	FREE_OP1_IF_VAR();
4095	HANDLE_EXCEPTION();
4096}
4097
4098ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR)
4099{
4100	USE_OPLINE
4101	zend_class_entry *ce, *catch_ce;
4102	zend_object *exception;
4103
4104	SAVE_OPLINE();
4105	/* Check whether an exception has been thrown, if not, jump over code */
4106	zend_exception_restore();
4107	if (EG(exception) == NULL) {
4108		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
4109		ZEND_VM_CONTINUE();
4110	}
4111	catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
4112	if (UNEXPECTED(catch_ce == NULL)) {
4113		catch_ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD);
4114
4115		CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), catch_ce);
4116	}
4117	ce = EG(exception)->ce;
4118
4119#ifdef HAVE_DTRACE
4120	if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
4121		DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
4122	}
4123#endif /* HAVE_DTRACE */
4124
4125	if (ce != catch_ce) {
4126		if (!catch_ce || !instanceof_function(ce, catch_ce)) {
4127			if (opline->result.num) {
4128				zend_throw_exception_internal(NULL);
4129				HANDLE_EXCEPTION();
4130			}
4131			ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
4132			ZEND_VM_CONTINUE();
4133		}
4134	}
4135
4136	exception = EG(exception);
4137	zval_ptr_dtor(EX_VAR(opline->op2.var));
4138	ZVAL_OBJ(EX_VAR(opline->op2.var), EG(exception));
4139	if (UNEXPECTED(EG(exception) != exception)) {
4140		GC_REFCOUNT(EG(exception))++;
4141		HANDLE_EXCEPTION();
4142	} else {
4143		EG(exception) = NULL;
4144		ZEND_VM_NEXT_OPCODE();
4145	}
4146}
4147
4148ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, NUM)
4149{
4150	USE_OPLINE
4151	zval *value, *arg;
4152	zend_free_op free_op1;
4153
4154	value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4155	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4156	ZVAL_COPY_VALUE(arg, value);
4157	if (OP1_TYPE == IS_CONST) {
4158		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
4159			Z_ADDREF_P(arg);
4160		}
4161	}
4162	ZEND_VM_NEXT_OPCODE();
4163}
4164
4165ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, NUM, SPEC(QUICK_ARG))
4166{
4167	USE_OPLINE
4168	zval *value, *arg;
4169	zend_free_op free_op1;
4170	uint32_t arg_num = opline->op2.num;
4171
4172	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
4173		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4174			ZEND_VM_C_GOTO(send_val_by_ref);
4175		}
4176	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4177ZEND_VM_C_LABEL(send_val_by_ref):
4178		SAVE_OPLINE();
4179		zend_throw_error(NULL, "Cannot pass parameter %d by reference", arg_num);
4180		FREE_UNFETCHED_OP1();
4181		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4182		ZVAL_UNDEF(arg);
4183		HANDLE_EXCEPTION();
4184	}
4185	value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4186	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4187	ZVAL_COPY_VALUE(arg, value);
4188	if (OP1_TYPE == IS_CONST) {
4189		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
4190			Z_ADDREF_P(arg);
4191		}
4192	}
4193	ZEND_VM_NEXT_OPCODE();
4194}
4195
4196ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM)
4197{
4198	USE_OPLINE
4199	zval *varptr, *arg;
4200	zend_free_op free_op1;
4201
4202	varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4203	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
4204		SAVE_OPLINE();
4205		GET_OP1_UNDEF_CV(varptr, BP_VAR_R);
4206		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4207		ZVAL_NULL(arg);
4208		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4209	}
4210
4211	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4212
4213	if (OP1_TYPE == IS_CV) {
4214		ZVAL_OPT_DEREF(varptr);
4215		ZVAL_COPY(arg, varptr);
4216	} else /* if (OP1_TYPE == IS_VAR) */ {
4217		if (UNEXPECTED(Z_ISREF_P(varptr))) {
4218			zend_refcounted *ref = Z_COUNTED_P(varptr);
4219
4220			varptr = Z_REFVAL_P(varptr);
4221			ZVAL_COPY_VALUE(arg, varptr);
4222			if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
4223				efree_size(ref, sizeof(zend_reference));
4224			} else if (Z_OPT_REFCOUNTED_P(arg)) {
4225				Z_ADDREF_P(arg);
4226			}
4227		} else {
4228			ZVAL_COPY_VALUE(arg, varptr);
4229		}
4230	}
4231
4232	ZEND_VM_NEXT_OPCODE();
4233}
4234
4235ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM, SEND)
4236{
4237	USE_OPLINE
4238	zend_free_op free_op1;
4239	zval *varptr, *arg;
4240
4241	if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) {
4242		if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
4243			ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
4244		}
4245	}
4246
4247	varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4248
4249	if (EXPECTED(Z_ISREF_P(varptr) ||
4250	    ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
4251	     ((opline->extended_value & ZEND_ARG_SEND_SILENT) != 0) :
4252	     ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num
4253	    )))) {
4254		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4255		ZVAL_COPY_VALUE(arg, varptr);
4256
4257		ZEND_VM_NEXT_OPCODE();
4258	}
4259
4260	SAVE_OPLINE();
4261	zend_error(E_NOTICE, "Only variables should be passed by reference");
4262
4263	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4264	ZVAL_COPY_VALUE(arg, varptr);
4265
4266	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4267}
4268
4269ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, NUM)
4270{
4271	USE_OPLINE
4272	zend_free_op free_op1;
4273	zval *varptr, *arg;
4274
4275	SAVE_OPLINE();
4276	varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
4277
4278	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4279	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(varptr))) {
4280		ZVAL_NEW_REF(arg, &EG(uninitialized_zval));
4281		ZEND_VM_NEXT_OPCODE();
4282	}
4283
4284	if (Z_ISREF_P(varptr)) {
4285		Z_ADDREF_P(varptr);
4286		ZVAL_COPY_VALUE(arg, varptr);
4287	} else {
4288		ZVAL_NEW_REF(arg, varptr);
4289		Z_ADDREF_P(arg);
4290		ZVAL_REF(varptr, Z_REF_P(arg));
4291	}
4292
4293	FREE_OP1_VAR_PTR();
4294	ZEND_VM_NEXT_OPCODE();
4295}
4296
4297ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, NUM, SPEC(QUICK_ARG))
4298{
4299	USE_OPLINE
4300	zval *varptr, *arg;
4301	zend_free_op free_op1;
4302	uint32_t arg_num = opline->op2.num;
4303
4304	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
4305		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4306			ZEND_VM_C_GOTO(send_var_by_ref);
4307		}
4308	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4309ZEND_VM_C_LABEL(send_var_by_ref):
4310		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
4311	}
4312
4313	varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4314	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
4315		SAVE_OPLINE();
4316		GET_OP1_UNDEF_CV(varptr, BP_VAR_R);
4317		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4318		ZVAL_NULL(arg);
4319		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4320	}
4321
4322	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4323
4324	if (OP1_TYPE == IS_CV) {
4325		ZVAL_OPT_DEREF(varptr);
4326		ZVAL_COPY(arg, varptr);
4327	} else /* if (OP1_TYPE == IS_VAR) */ {
4328		if (UNEXPECTED(Z_ISREF_P(varptr))) {
4329			zend_refcounted *ref = Z_COUNTED_P(varptr);
4330
4331			varptr = Z_REFVAL_P(varptr);
4332			ZVAL_COPY_VALUE(arg, varptr);
4333			if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
4334				efree_size(ref, sizeof(zend_reference));
4335			} else if (Z_OPT_REFCOUNTED_P(arg)) {
4336				Z_ADDREF_P(arg);
4337			}
4338		} else {
4339			ZVAL_COPY_VALUE(arg, varptr);
4340		}
4341	}
4342
4343	ZEND_VM_NEXT_OPCODE();
4344}
4345
4346ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
4347{
4348	USE_OPLINE
4349	zend_free_op free_op1;
4350	zval *args;
4351	int arg_num;
4352
4353	SAVE_OPLINE();
4354	args = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4355	arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
4356
4357ZEND_VM_C_LABEL(send_again):
4358	if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
4359		HashTable *ht = Z_ARRVAL_P(args);
4360		zval *arg, *top;
4361		zend_string *name;
4362
4363		zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
4364
4365		if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_REFCOUNT_P(args) > 1) {
4366			uint32_t i;
4367			int separate = 0;
4368
4369			/* check if any of arguments are going to be passed by reference */
4370			for (i = 0; i < zend_hash_num_elements(ht); i++) {
4371				if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
4372					separate = 1;
4373					break;
4374				}
4375			}
4376			if (separate) {
4377				SEPARATE_ARRAY(args);
4378				ht = Z_ARRVAL_P(args);
4379			}
4380		}
4381
4382		ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
4383			if (name) {
4384				zend_throw_error(NULL, "Cannot unpack array with string keys");
4385				FREE_OP1();
4386				HANDLE_EXCEPTION();
4387			}
4388
4389			top = ZEND_CALL_ARG(EX(call), arg_num);
4390			if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4391				if (Z_REFCOUNT_P(args) == 1) {
4392					ZVAL_MAKE_REF(arg);
4393					Z_ADDREF_P(arg);
4394					ZVAL_REF(top, Z_REF_P(arg));
4395				} else {
4396					ZVAL_DUP(top, arg);
4397				}
4398			} else if (Z_ISREF_P(arg)) {
4399				ZVAL_COPY(top, Z_REFVAL_P(arg));
4400			} else {
4401				ZVAL_COPY(top, arg);
4402			}
4403
4404			ZEND_CALL_NUM_ARGS(EX(call))++;
4405			arg_num++;
4406		} ZEND_HASH_FOREACH_END();
4407
4408	} else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) {
4409		zend_class_entry *ce = Z_OBJCE_P(args);
4410		zend_object_iterator *iter;
4411
4412		if (!ce || !ce->get_iterator) {
4413			zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
4414		} else {
4415
4416			iter = ce->get_iterator(ce, args, 0);
4417			if (UNEXPECTED(!iter)) {
4418				FREE_OP1();
4419				if (!EG(exception)) {
4420					zend_throw_exception_ex(
4421						NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)
4422					);
4423				}
4424				HANDLE_EXCEPTION();
4425			}
4426
4427			if (iter->funcs->rewind) {
4428				iter->funcs->rewind(iter);
4429				if (UNEXPECTED(EG(exception) != NULL)) {
4430					ZEND_VM_C_GOTO(unpack_iter_dtor);
4431				}
4432			}
4433
4434			for (; iter->funcs->valid(iter) == SUCCESS; ++arg_num) {
4435				zval *arg, *top;
4436
4437				if (UNEXPECTED(EG(exception) != NULL)) {
4438					ZEND_VM_C_GOTO(unpack_iter_dtor);
4439				}
4440
4441				arg = iter->funcs->get_current_data(iter);
4442				if (UNEXPECTED(EG(exception) != NULL)) {
4443					ZEND_VM_C_GOTO(unpack_iter_dtor);
4444				}
4445
4446				if (iter->funcs->get_current_key) {
4447					zval key;
4448					iter->funcs->get_current_key(iter, &key);
4449					if (UNEXPECTED(EG(exception) != NULL)) {
4450						ZEND_VM_C_GOTO(unpack_iter_dtor);
4451					}
4452
4453					if (Z_TYPE(key) == IS_STRING) {
4454						zend_throw_error(NULL,
4455							"Cannot unpack Traversable with string keys");
4456						zend_string_release(Z_STR(key));
4457						ZEND_VM_C_GOTO(unpack_iter_dtor);
4458					}
4459
4460					zval_dtor(&key);
4461				}
4462
4463				if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4464					zend_error(
4465						E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
4466						" by unpacking a Traversable, passing by-value instead", arg_num,
4467						EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
4468						EX(call)->func->common.scope ? "::" : "",
4469						ZSTR_VAL(EX(call)->func->common.function_name)
4470					);
4471				}
4472
4473				if (Z_ISREF_P(arg)) {
4474					ZVAL_DUP(arg, Z_REFVAL_P(arg));
4475				} else {
4476					if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
4477				}
4478
4479				zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
4480				top = ZEND_CALL_ARG(EX(call), arg_num);
4481				ZVAL_COPY_VALUE(top, arg);
4482				ZEND_CALL_NUM_ARGS(EX(call))++;
4483
4484				iter->funcs->move_forward(iter);
4485				if (UNEXPECTED(EG(exception) != NULL)) {
4486					ZEND_VM_C_GOTO(unpack_iter_dtor);
4487				}
4488			}
4489
4490ZEND_VM_C_LABEL(unpack_iter_dtor):
4491			zend_iterator_dtor(iter);
4492		}
4493	} else if (EXPECTED(Z_ISREF_P(args))) {
4494		args = Z_REFVAL_P(args);
4495		ZEND_VM_C_GOTO(send_again);
4496	} else {
4497		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) {
4498			GET_OP1_UNDEF_CV(args, BP_VAR_R);
4499		}
4500		zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
4501	}
4502
4503	FREE_OP1();
4504	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4505}
4506
4507ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY)
4508{
4509	USE_OPLINE
4510	zend_free_op free_op1;
4511	zval *args;
4512	SAVE_OPLINE();
4513
4514	SAVE_OPLINE();
4515	args = GET_OP1_ZVAL_PTR(BP_VAR_R);
4516
4517	if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) {
4518		if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(args)) {
4519			args = Z_REFVAL_P(args);
4520			if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
4521				ZEND_VM_C_GOTO(send_array);
4522			}
4523		}
4524		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)));
4525		if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
4526			OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
4527		}
4528		if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
4529			OBJ_RELEASE(Z_OBJ(EX(call)->This));
4530		}
4531		EX(call)->func = (zend_function*)&zend_pass_function;
4532		Z_OBJ(EX(call)->This) = NULL;
4533		ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
4534	} else {
4535		uint32_t arg_num;
4536		HashTable *ht;
4537		zval *arg, *param;
4538
4539ZEND_VM_C_LABEL(send_array):
4540		ht = Z_ARRVAL_P(args);
4541		zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
4542
4543		arg_num = 1;
4544		param = ZEND_CALL_ARG(EX(call), 1);
4545		ZEND_HASH_FOREACH_VAL(ht, arg) {
4546			if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4547				if (UNEXPECTED(!Z_ISREF_P(arg))) {
4548					if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4549
4550						zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
4551							arg_num,
4552							EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
4553							EX(call)->func->common.scope ? "::" : "",
4554							ZSTR_VAL(EX(call)->func->common.function_name));
4555
4556						if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
4557							OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
4558						}
4559						if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
4560							OBJ_RELEASE(Z_OBJ(EX(call)->This));
4561						}
4562						EX(call)->func = (zend_function*)&zend_pass_function;
4563						Z_OBJ(EX(call)->This) = NULL;
4564						ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
4565						break;
4566					}
4567				}
4568			} else {
4569				if (Z_ISREF_P(arg) &&
4570				    !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
4571					/* don't separate references for __call */
4572					arg = Z_REFVAL_P(arg);
4573				}
4574			}
4575			ZVAL_COPY(param, arg);
4576			ZEND_CALL_NUM_ARGS(EX(call))++;
4577			arg_num++;
4578			param++;
4579		} ZEND_HASH_FOREACH_END();
4580	}
4581	FREE_OP1();
4582	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4583}
4584
4585ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, NUM)
4586{
4587	USE_OPLINE
4588	zval *arg, *param;
4589	zend_free_op free_op1;
4590
4591	SAVE_OPLINE();
4592	arg = GET_OP1_ZVAL_PTR(BP_VAR_R);
4593	param = ZEND_CALL_VAR(EX(call), opline->result.var);
4594
4595	if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
4596		if (UNEXPECTED(!Z_ISREF_P(arg))) {
4597			if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
4598
4599				zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
4600					opline->op2.num,
4601					EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
4602					EX(call)->func->common.scope ? "::" : "",
4603					ZSTR_VAL(EX(call)->func->common.function_name));
4604
4605				if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
4606					OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
4607				}
4608				if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
4609					OBJ_RELEASE(Z_OBJ(EX(call)->This));
4610				}
4611				ZVAL_UNDEF(param);
4612				EX(call)->func = (zend_function*)&zend_pass_function;
4613				Z_OBJ(EX(call)->This) = NULL;
4614				ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
4615
4616				FREE_OP1();
4617				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4618			}
4619		}
4620	} else {
4621		if (Z_ISREF_P(arg) &&
4622		    !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
4623			/* don't separate references for __call */
4624			arg = Z_REFVAL_P(arg);
4625		}
4626	}
4627	ZVAL_COPY(param, arg);
4628
4629	FREE_OP1();
4630	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4631}
4632
4633ZEND_VM_HANDLER(63, ZEND_RECV, NUM, ANY)
4634{
4635	USE_OPLINE
4636	uint32_t arg_num = opline->op1.num;
4637
4638	if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
4639		SAVE_OPLINE();
4640		zend_verify_missing_arg(execute_data, arg_num, CACHE_ADDR(opline->op2.num));
4641		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4642	} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
4643		zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var);
4644
4645		SAVE_OPLINE();
4646		if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) {
4647			HANDLE_EXCEPTION();
4648		}
4649	}
4650
4651	ZEND_VM_NEXT_OPCODE();
4652}
4653
4654ZEND_VM_HANDLER(64, ZEND_RECV_INIT, NUM, CONST)
4655{
4656	USE_OPLINE
4657	uint32_t arg_num;
4658	zval *param;
4659
4660	ZEND_VM_REPEATABLE_OPCODE
4661
4662	arg_num = opline->op1.num;
4663	param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var);
4664	if (arg_num > EX_NUM_ARGS()) {
4665		ZVAL_COPY(param, EX_CONSTANT(opline->op2));
4666		if (Z_OPT_CONSTANT_P(param)) {
4667			SAVE_OPLINE();
4668			if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
4669				ZVAL_UNDEF(param);
4670				HANDLE_EXCEPTION();
4671			}
4672		}
4673	}
4674
4675	if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
4676		zval *default_value = EX_CONSTANT(opline->op2);
4677
4678		SAVE_OPLINE();
4679		if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(Z_CACHE_SLOT_P(default_value))) || EG(exception))) {
4680			HANDLE_EXCEPTION();
4681		}
4682	}
4683
4684	ZEND_VM_REPEAT_OPCODE(ZEND_RECV_INIT);
4685	ZEND_VM_NEXT_OPCODE();
4686}
4687
4688ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, ANY)
4689{
4690	USE_OPLINE
4691	uint32_t arg_num = opline->op1.num;
4692	uint32_t arg_count = EX_NUM_ARGS();
4693	zval *params;
4694
4695	SAVE_OPLINE();
4696
4697	params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var);
4698
4699	if (arg_num <= arg_count) {
4700		zval *param;
4701
4702		array_init_size(params, arg_count - arg_num + 1);
4703		zend_hash_real_init(Z_ARRVAL_P(params), 1);
4704		ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
4705			param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
4706			if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
4707				do {
4708					zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num));
4709					if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
4710					ZEND_HASH_FILL_ADD(param);
4711					param++;
4712				} while (++arg_num <= arg_count);
4713			} else {
4714				do {
4715					if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
4716					ZEND_HASH_FILL_ADD(param);
4717					param++;
4718				} while (++arg_num <= arg_count);
4719			}
4720		} ZEND_HASH_FILL_END();
4721	} else {
4722		array_init(params);
4723	}
4724
4725	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4726}
4727
4728ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
4729{
4730	USE_OPLINE
4731	zval *val;
4732	zend_free_op free_op1;
4733
4734	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4735	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
4736		ZVAL_TRUE(EX_VAR(opline->result.var));
4737	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
4738		ZVAL_FALSE(EX_VAR(opline->result.var));
4739		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
4740			SAVE_OPLINE();
4741			GET_OP1_UNDEF_CV(val, BP_VAR_R);
4742			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4743		}
4744	} else {
4745		SAVE_OPLINE();
4746		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
4747		FREE_OP1();
4748		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4749	}
4750	ZEND_VM_NEXT_OPCODE();
4751}
4752
4753ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
4754{
4755	USE_OPLINE
4756	zend_free_op free_op1, free_op2;
4757	zval *op1, *op2, *result;
4758
4759	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4760	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
4761	do {
4762		int result;
4763
4764		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
4765			if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
4766				result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
4767			} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
4768				result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
4769			} else {
4770				break;
4771			}
4772		} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
4773			if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
4774				result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
4775			} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
4776				result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
4777			} else {
4778				break;
4779			}
4780		} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
4781			if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
4782				if (Z_STR_P(op1) == Z_STR_P(op2)) {
4783					result = 1;
4784				} else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
4785					if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
4786						result = 0;
4787					} else {
4788						result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
4789					}
4790				} else {
4791					result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
4792				}
4793				FREE_OP2();
4794			} else {
4795				break;
4796			}
4797		} else {
4798			break;
4799		}
4800		ZEND_VM_SMART_BRANCH(result, 0);
4801		ZVAL_BOOL(EX_VAR(opline->result.var), result);
4802		ZEND_VM_NEXT_OPCODE();
4803	} while (0);
4804
4805	SAVE_OPLINE();
4806	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
4807		op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
4808	} else if ((OP1_TYPE & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
4809		/* Don't keep lock on reference, lock the value instead */
4810		if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
4811			ZVAL_UNREF(op1);
4812		} else {
4813			Z_DELREF_P(op1);
4814			ZVAL_COPY(op1, Z_REFVAL_P(op1));
4815		}
4816	}
4817	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
4818		op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
4819	}
4820	result = EX_VAR(opline->result.var);
4821	compare_function(result, op1, op2);
4822	ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
4823	FREE_OP2();
4824	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4825}
4826
4827ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM)
4828{
4829	USE_OPLINE
4830	zval *result;
4831	zend_function *constructor;
4832	zend_class_entry *ce;
4833	zend_execute_data *call;
4834
4835	SAVE_OPLINE();
4836	if (OP1_TYPE == IS_CONST) {
4837		ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
4838		if (UNEXPECTED(ce == NULL)) {
4839			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);
4840			if (UNEXPECTED(ce == NULL)) {
4841				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4842			}
4843			CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
4844		}
4845	} else if (OP1_TYPE == IS_UNUSED) {
4846		ce = zend_fetch_class(NULL, opline->op1.num);
4847		if (UNEXPECTED(ce == NULL)) {
4848			ZEND_ASSERT(EG(exception));
4849			HANDLE_EXCEPTION();
4850		}
4851	} else {
4852		ce = Z_CE_P(EX_VAR(opline->op1.var));
4853	}
4854
4855	result = EX_VAR(opline->result.var);
4856	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
4857		HANDLE_EXCEPTION();
4858	}
4859
4860	constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
4861	if (constructor == NULL) {
4862		/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
4863		 * opcode is DO_FCALL in case EXT instructions are used. */
4864		if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
4865			ZEND_VM_NEXT_OPCODE_EX(1, 2);
4866		}
4867
4868		/* Perform a dummy function call */
4869		call = zend_vm_stack_push_call_frame(
4870			ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
4871			opline->extended_value, NULL, NULL);
4872	} else {
4873		if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) {
4874			init_func_run_time_cache(&constructor->op_array);
4875		}
4876		/* We are not handling overloaded classes right now */
4877		call = zend_vm_stack_push_call_frame(
4878			ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR,
4879			constructor,
4880			opline->extended_value,
4881			ce,
4882			Z_OBJ_P(result));
4883		Z_ADDREF_P(result);
4884	}
4885
4886	call->prev_execute_data = EX(call);
4887	EX(call) = call;
4888	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4889}
4890
4891ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
4892{
4893	USE_OPLINE
4894	zend_free_op free_op1;
4895	zval *obj;
4896	zend_class_entry *ce, *scope;
4897	zend_function *clone;
4898	zend_object_clone_obj_t clone_call;
4899
4900	SAVE_OPLINE();
4901	obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
4902
4903	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
4904		zend_throw_error(NULL, "Using $this when not in object context");
4905		HANDLE_EXCEPTION();
4906	}
4907
4908	do {
4909		if (OP1_TYPE == IS_CONST ||
4910		    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
4911		    if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
4912		    	obj = Z_REFVAL_P(obj);
4913		    	if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
4914		    		break;
4915				}
4916			}
4917			if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
4918				GET_OP1_UNDEF_CV(obj, BP_VAR_R);
4919				if (UNEXPECTED(EG(exception) != NULL)) {
4920					HANDLE_EXCEPTION();
4921				}
4922			}
4923			zend_throw_error(NULL, "__clone method called on non-object");
4924			FREE_OP1();
4925			HANDLE_EXCEPTION();
4926		}
4927	} while (0);
4928
4929	ce = Z_OBJCE_P(obj);
4930	clone = ce->clone;
4931	clone_call = Z_OBJ_HT_P(obj)->clone_obj;
4932	if (UNEXPECTED(clone_call == NULL)) {
4933		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
4934		FREE_OP1();
4935		HANDLE_EXCEPTION();
4936	}
4937
4938	if (clone) {
4939		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
4940			/* Ensure that if we're calling a private function, we're allowed to do so.
4941			 */
4942			scope = EX(func)->op_array.scope;
4943			if (UNEXPECTED(ce != scope)) {
4944				zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
4945				FREE_OP1();
4946				HANDLE_EXCEPTION();
4947			}
4948		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
4949			/* Ensure that if we're calling a protected function, we're allowed to do so.
4950			 */
4951			scope = EX(func)->op_array.scope;
4952			if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
4953				zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
4954				FREE_OP1();
4955				HANDLE_EXCEPTION();
4956			}
4957		}
4958	}
4959
4960	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
4961	if (UNEXPECTED(EG(exception) != NULL)) {
4962		OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
4963	}
4964
4965	FREE_OP1();
4966	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4967}
4968
4969ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH)
4970{
4971	USE_OPLINE
4972	zend_constant *c;
4973
4974	SAVE_OPLINE();
4975
4976	if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
4977		c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
4978	} else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) {
4979		if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
4980			char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2)));
4981			if (!actual) {
4982				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2)));
4983			} else {
4984				actual++;
4985				ZVAL_STRINGL(EX_VAR(opline->result.var),
4986						actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2))));
4987			}
4988			/* non-qualified constant - allow text substitution */
4989			zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
4990					Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var)));
4991			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4992		} else {
4993			zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
4994			HANDLE_EXCEPTION();
4995		}
4996	} else {
4997		CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c);
4998	}
4999
5000#ifdef ZTS
5001	if (c->flags & CONST_PERSISTENT) {
5002		ZVAL_DUP(EX_VAR(opline->result.var), &c->value);
5003	} else {
5004		ZVAL_COPY(EX_VAR(opline->result.var), &c->value);
5005	}
5006#else
5007	ZVAL_COPY(EX_VAR(opline->result.var), &c->value);
5008#endif
5009
5010	ZEND_VM_NEXT_OPCODE();
5011}
5012
5013ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST)
5014{
5015	zend_class_entry *ce, *scope;
5016	zend_class_constant *c;
5017	zval *value;
5018	USE_OPLINE
5019
5020	SAVE_OPLINE();
5021
5022	do {
5023		if (OP1_TYPE == IS_CONST) {
5024			if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
5025				value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
5026#ifdef ZTS
5027				ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
5028#endif
5029				break;
5030			} else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) {
5031				ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
5032			} else {
5033				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);
5034				if (UNEXPECTED(ce == NULL)) {
5035					if (EXPECTED(!EG(exception))) {
5036						zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
5037					}
5038					HANDLE_EXCEPTION();
5039				}
5040				CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
5041			}
5042		} else {
5043			if (OP1_TYPE == IS_UNUSED) {
5044				ce = zend_fetch_class(NULL, opline->op1.num);
5045				if (UNEXPECTED(ce == NULL)) {
5046					ZEND_ASSERT(EG(exception));
5047					HANDLE_EXCEPTION();
5048				}
5049			} else {
5050				ce = Z_CE_P(EX_VAR(opline->op1.var));
5051			}
5052			if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) {
5053				break;
5054			}
5055		}
5056
5057		if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) {
5058			scope = EX(func)->op_array.scope;
5059			if (!zend_verify_const_access(c, scope)) {
5060				zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2)));
5061				HANDLE_EXCEPTION();
5062			}
5063			value = &c->value;
5064			if (Z_CONSTANT_P(value)) {
5065				zval_update_constant_ex(value, ce);
5066				if (UNEXPECTED(EG(exception) != NULL)) {
5067					HANDLE_EXCEPTION();
5068				}
5069			}
5070			if (OP1_TYPE == IS_CONST) {
5071				CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value);
5072			} else {
5073				CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
5074			}
5075		} else {
5076			zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
5077			HANDLE_EXCEPTION();
5078		}
5079	} while (0);
5080
5081#ifdef ZTS
5082	if (ce->type == ZEND_INTERNAL_CLASS) {
5083		ZVAL_DUP(EX_VAR(opline->result.var), value);
5084	} else {
5085		ZVAL_COPY(EX_VAR(opline->result.var), value);
5086	}
5087#else
5088	ZVAL_COPY(EX_VAR(opline->result.var), value);
5089#endif
5090
5091	ZEND_VM_NEXT_OPCODE();
5092}
5093
5094ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, REF)
5095{
5096	USE_OPLINE
5097	zend_free_op free_op1;
5098	zval *expr_ptr, new_expr;
5099
5100	SAVE_OPLINE();
5101	if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) &&
5102	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
5103		expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
5104		ZVAL_MAKE_REF(expr_ptr);
5105		Z_ADDREF_P(expr_ptr);
5106		FREE_OP1_VAR_PTR();
5107	} else {
5108		expr_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
5109		if (OP1_TYPE == IS_TMP_VAR) {
5110			/* pass */
5111		} else if (OP1_TYPE == IS_CONST) {
5112			if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
5113				ZVAL_COPY_VALUE(&new_expr, expr_ptr);
5114				zval_copy_ctor_func(&new_expr);
5115				expr_ptr = &new_expr;
5116			}
5117		} else if (OP1_TYPE == IS_CV) {
5118			ZVAL_DEREF(expr_ptr);
5119			if (Z_REFCOUNTED_P(expr_ptr)) {
5120				Z_ADDREF_P(expr_ptr);
5121			}
5122		} else /* if (OP1_TYPE == IS_VAR) */ {
5123			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
5124				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
5125
5126				expr_ptr = Z_REFVAL_P(expr_ptr);
5127				if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
5128					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
5129					expr_ptr = &new_expr;
5130					efree_size(ref, sizeof(zend_reference));
5131				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
5132					Z_ADDREF_P(expr_ptr);
5133				}
5134			}
5135		}
5136	}
5137
5138	if (OP2_TYPE != IS_UNUSED) {
5139		zend_free_op free_op2;
5140		zval *offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
5141		zend_string *str;
5142		zend_ulong hval;
5143
5144ZEND_VM_C_LABEL(add_again):
5145		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
5146			str = Z_STR_P(offset);
5147			if (OP2_TYPE != IS_CONST) {
5148				if (ZEND_HANDLE_NUMERIC(str, hval)) {
5149					ZEND_VM_C_GOTO(num_index);
5150				}
5151			}
5152ZEND_VM_C_LABEL(str_index):
5153			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
5154		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
5155			hval = Z_LVAL_P(offset);
5156ZEND_VM_C_LABEL(num_index):
5157			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
5158		} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
5159			offset = Z_REFVAL_P(offset);
5160			ZEND_VM_C_GOTO(add_again);
5161		} else if (Z_TYPE_P(offset) == IS_NULL) {
5162			str = ZSTR_EMPTY_ALLOC();
5163			ZEND_VM_C_GOTO(str_index);
5164		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
5165			hval = zend_dval_to_lval(Z_DVAL_P(offset));
5166			ZEND_VM_C_GOTO(num_index);
5167		} else if (Z_TYPE_P(offset) == IS_FALSE) {
5168			hval = 0;
5169			ZEND_VM_C_GOTO(num_index);
5170		} else if (Z_TYPE_P(offset) == IS_TRUE) {
5171			hval = 1;
5172			ZEND_VM_C_GOTO(num_index);
5173		} else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
5174			GET_OP2_UNDEF_CV(offset, BP_VAR_R);
5175			str = ZSTR_EMPTY_ALLOC();
5176			ZEND_VM_C_GOTO(str_index);
5177		} else {
5178			zend_error(E_WARNING, "Illegal offset type");
5179			zval_ptr_dtor(expr_ptr);
5180		}
5181		FREE_OP2();
5182	} else {
5183		zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr);
5184	}
5185	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5186}
5187
5188ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF)
5189{
5190	zval *array;
5191	uint32_t size;
5192	USE_OPLINE
5193
5194	array = EX_VAR(opline->result.var);
5195	if (OP1_TYPE != IS_UNUSED) {
5196		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
5197	} else {
5198		size = 0;
5199	}
5200	ZVAL_NEW_ARR(array);
5201	zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0);
5202
5203	if (OP1_TYPE != IS_UNUSED) {
5204		/* Explicitly initialize array as not-packed if flag is set */
5205		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
5206			zend_hash_real_init(Z_ARRVAL_P(array), 0);
5207		}
5208	}
5209
5210	if (OP1_TYPE == IS_UNUSED) {
5211		ZEND_VM_NEXT_OPCODE();
5212#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
5213	} else {
5214		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
5215#endif
5216	}
5217}
5218
5219ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
5220{
5221	USE_OPLINE
5222	zend_free_op free_op1;
5223	zval *expr;
5224	zval *result = EX_VAR(opline->result.var);
5225
5226	SAVE_OPLINE();
5227	expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
5228
5229	switch (opline->extended_value) {
5230		case IS_NULL:
5231			/* This code is taken from convert_to_null. However, it does not seems very useful,
5232			 * because a conversion to null always results in the same value. This could only
5233			 * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */
5234#if 0
5235			if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
5236				ZVAL_DEREF(expr);
5237			}
5238			if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) {
5239				if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL) == SUCCESS) {
5240					break;
5241				}
5242			}
5243#endif
5244
5245			ZVAL_NULL(result);
5246			break;
5247		case _IS_BOOL:
5248			ZVAL_BOOL(result, zend_is_true(expr));
5249			break;
5250		case IS_LONG:
5251			ZVAL_LONG(result, zval_get_long(expr));
5252			break;
5253		case IS_DOUBLE:
5254			ZVAL_DOUBLE(result, zval_get_double(expr));
5255			break;
5256		case IS_STRING:
5257			ZVAL_STR(result, zval_get_string(expr));
5258			break;
5259		default:
5260			if (OP1_TYPE & (IS_VAR|IS_CV)) {
5261				ZVAL_DEREF(expr);
5262			}
5263			/* If value is already of correct type, return it directly */
5264			if (Z_TYPE_P(expr) == opline->extended_value) {
5265				ZVAL_COPY_VALUE(result, expr);
5266				if (OP1_TYPE == IS_CONST) {
5267					if (UNEXPECTED(Z_OPT_COPYABLE_P(result))) {
5268						zval_copy_ctor_func(result);
5269					}
5270				} else if (OP1_TYPE != IS_TMP_VAR) {
5271					if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
5272				}
5273
5274				FREE_OP1_IF_VAR();
5275				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5276			}
5277
5278			if (opline->extended_value == IS_ARRAY) {
5279				if (Z_TYPE_P(expr) != IS_OBJECT) {
5280					ZVAL_NEW_ARR(result);
5281					zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0);
5282					if (Z_TYPE_P(expr) != IS_NULL) {
5283						expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
5284						if (OP1_TYPE == IS_CONST) {
5285							if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
5286								zval_copy_ctor_func(expr);
5287							}
5288						} else {
5289							if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
5290						}
5291					}
5292				} else {
5293					ZVAL_COPY_VALUE(result, expr);
5294					Z_ADDREF_P(result);
5295					convert_to_array(result);
5296				}
5297			} else {
5298				if (Z_TYPE_P(expr) != IS_ARRAY) {
5299					object_init(result);
5300					if (Z_TYPE_P(expr) != IS_NULL) {
5301						expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
5302						if (OP1_TYPE == IS_CONST) {
5303							if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
5304								zval_copy_ctor_func(expr);
5305							}
5306						} else {
5307							if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
5308						}
5309					}
5310				} else {
5311					ZVAL_COPY(result, expr);
5312					convert_to_object(result);
5313				}
5314			}
5315	}
5316
5317	FREE_OP1();
5318	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5319}
5320
5321ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
5322{
5323	USE_OPLINE
5324	zend_op_array *new_op_array;
5325	zend_free_op free_op1;
5326	zval *inc_filename;
5327
5328	SAVE_OPLINE();
5329	inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R);
5330	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
5331	FREE_OP1();
5332	if (UNEXPECTED(EG(exception) != NULL)) {
5333		HANDLE_EXCEPTION();
5334	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
5335		if (RETURN_VALUE_USED(opline)) {
5336			ZVAL_TRUE(EX_VAR(opline->result.var));
5337		}
5338	} else if (EXPECTED(new_op_array != NULL)) {
5339		zval *return_value = NULL;
5340		zend_execute_data *call;
5341
5342		if (RETURN_VALUE_USED(opline)) {
5343			return_value = EX_VAR(opline->result.var);
5344		}
5345
5346		new_op_array->scope = EX(func)->op_array.scope;
5347
5348		call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
5349			(zend_function*)new_op_array, 0,
5350			Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL,
5351			Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL);
5352
5353		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
5354			call->symbol_table = EX(symbol_table);
5355		} else {
5356			call->symbol_table = zend_rebuild_symbol_table();
5357		}
5358
5359		call->prev_execute_data = execute_data;
5360		i_init_code_execute_data(call, new_op_array, return_value);
5361		if (EXPECTED(zend_execute_ex == execute_ex)) {
5362			ZEND_VM_ENTER();
5363		} else {
5364			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
5365			zend_execute_ex(call);
5366			zend_vm_stack_free_call_frame(call);
5367		}
5368
5369		destroy_op_array(new_op_array);
5370		efree_size(new_op_array, sizeof(zend_op_array));
5371		if (UNEXPECTED(EG(exception) != NULL)) {
5372			zend_throw_exception_internal(NULL);
5373			HANDLE_EXCEPTION();
5374		}
5375	} else if (RETURN_VALUE_USED(opline)) {
5376		ZVAL_FALSE(EX_VAR(opline->result.var));
5377	}
5378	ZEND_VM_SET_OPCODE(opline + 1);
5379	ZEND_VM_CONTINUE();
5380}
5381
5382ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
5383{
5384	USE_OPLINE
5385	zval tmp, *varname;
5386	HashTable *target_symbol_table;
5387	zend_free_op free_op1;
5388
5389	SAVE_OPLINE();
5390	if (OP1_TYPE == IS_CV &&
5391	    (opline->extended_value & ZEND_QUICK_SET)) {
5392		zval *var = EX_VAR(opline->op1.var);
5393
5394		if (Z_REFCOUNTED_P(var)) {
5395			zend_refcounted *garbage = Z_COUNTED_P(var);
5396
5397			if (!--GC_REFCOUNT(garbage)) {
5398				ZVAL_UNDEF(var);
5399				zval_dtor_func_for_ptr(garbage);
5400			} else {
5401				zval *z = var;
5402				ZVAL_DEREF(z);
5403				if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
5404					ZVAL_UNDEF(var);
5405					gc_possible_root(Z_COUNTED_P(z));
5406				} else {
5407					ZVAL_UNDEF(var);
5408				}
5409			}
5410		} else {
5411			ZVAL_UNDEF(var);
5412		}
5413		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5414	}
5415
5416	varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
5417
5418	ZVAL_UNDEF(&tmp);
5419	if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
5420		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
5421			varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R);
5422		}
5423		ZVAL_STR(&tmp, zval_get_string(varname));
5424		varname = &tmp;
5425	}
5426
5427	target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK);
5428	zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
5429
5430	if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
5431		zend_string_release(Z_STR(tmp));
5432	}
5433	FREE_OP1();
5434	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5435}
5436
5437ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
5438{
5439	USE_OPLINE
5440	zval tmp, *varname;
5441	zend_class_entry *ce;
5442	zend_free_op free_op1;
5443
5444	SAVE_OPLINE();
5445
5446	varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
5447
5448	ZVAL_UNDEF(&tmp);
5449	if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
5450		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
5451			varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R);
5452		}
5453		ZVAL_STR(&tmp, zval_get_string(varname));
5454		varname = &tmp;
5455	}
5456
5457	if (OP2_TYPE == IS_CONST) {
5458		ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
5459		if (UNEXPECTED(ce == NULL)) {
5460			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);
5461			if (UNEXPECTED(ce == NULL)) {
5462				if (EXPECTED(!EG(exception))) {
5463					zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
5464				}
5465				if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
5466					zend_string_release(Z_STR(tmp));
5467				}
5468				FREE_OP1();
5469				HANDLE_EXCEPTION();
5470			}
5471			CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
5472		}
5473	} else if (OP2_TYPE == IS_UNUSED) {
5474		ce = zend_fetch_class(NULL, opline->op2.num);
5475		if (UNEXPECTED(ce == NULL)) {
5476			ZEND_ASSERT(EG(exception));
5477			if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
5478				zend_string_release(Z_STR(tmp));
5479			}
5480			FREE_OP1();
5481			HANDLE_EXCEPTION();
5482		}
5483	} else {
5484		ce = Z_CE_P(EX_VAR(opline->op2.var));
5485	}
5486	zend_std_unset_static_property(ce, Z_STR_P(varname));
5487
5488	if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
5489		zend_string_release(Z_STR(tmp));
5490	}
5491	FREE_OP1();
5492	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5493}
5494
5495ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
5496{
5497	USE_OPLINE
5498	zend_free_op free_op1, free_op2;
5499	zval *container;
5500	zval *offset;
5501	zend_ulong hval;
5502	zend_string *key;
5503
5504	SAVE_OPLINE();
5505	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
5506	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
5507		zend_throw_error(NULL, "Using $this when not in object context");
5508		FREE_UNFETCHED_OP2();
5509		HANDLE_EXCEPTION();
5510	}
5511	offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
5512
5513	do {
5514		if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
5515			HashTable *ht;
5516
5517ZEND_VM_C_LABEL(unset_dim_array):
5518			SEPARATE_ARRAY(container);
5519			ht = Z_ARRVAL_P(container);
5520ZEND_VM_C_LABEL(offset_again):
5521			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
5522				key = Z_STR_P(offset);
5523				if (OP2_TYPE != IS_CONST) {
5524					if (ZEND_HANDLE_NUMERIC(key, hval)) {
5525						ZEND_VM_C_GOTO(num_index_dim);
5526					}
5527				}
5528ZEND_VM_C_LABEL(str_index_dim):
5529				if (ht == &EG(symbol_table)) {
5530					zend_delete_global_variable(key);
5531				} else {
5532					zend_hash_del(ht, key);
5533				}
5534			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
5535				hval = Z_LVAL_P(offset);
5536ZEND_VM_C_LABEL(num_index_dim):
5537				zend_hash_index_del(ht, hval);
5538			} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
5539				offset = Z_REFVAL_P(offset);
5540				ZEND_VM_C_GOTO(offset_again);
5541			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
5542				hval = zend_dval_to_lval(Z_DVAL_P(offset));
5543				ZEND_VM_C_GOTO(num_index_dim);
5544			} else if (Z_TYPE_P(offset) == IS_NULL) {
5545				key = ZSTR_EMPTY_ALLOC();
5546				ZEND_VM_C_GOTO(str_index_dim);
5547			} else if (Z_TYPE_P(offset) == IS_FALSE) {
5548				hval = 0;
5549				ZEND_VM_C_GOTO(num_index_dim);
5550			} else if (Z_TYPE_P(offset) == IS_TRUE) {
5551				hval = 1;
5552				ZEND_VM_C_GOTO(num_index_dim);
5553			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
5554				hval = Z_RES_HANDLE_P(offset);
5555				ZEND_VM_C_GOTO(num_index_dim);
5556			} else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
5557				GET_OP2_UNDEF_CV(offset, BP_VAR_R);
5558				key = ZSTR_EMPTY_ALLOC();
5559				ZEND_VM_C_GOTO(str_index_dim);
5560			} else {
5561				zend_error(E_WARNING, "Illegal offset type in unset");
5562			}
5563			break;
5564		} else if (OP1_TYPE != IS_UNUSED && Z_ISREF_P(container)) {
5565			container = Z_REFVAL_P(container);
5566			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
5567				ZEND_VM_C_GOTO(unset_dim_array);
5568			}
5569		}
5570		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
5571			container = GET_OP1_UNDEF_CV(container, BP_VAR_R);
5572		}
5573		if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
5574			offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
5575		}
5576		if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
5577			if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
5578				zend_throw_error(NULL, "Cannot use object as array");
5579			} else {
5580				Z_OBJ_HT_P(container)->unset_dimension(container, offset);
5581			}
5582		} else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
5583			zend_throw_error(NULL, "Cannot unset string offsets");
5584		}
5585	} while (0);
5586
5587	FREE_OP2();
5588	FREE_OP1_VAR_PTR();
5589	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5590}
5591
5592ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
5593{
5594	USE_OPLINE
5595	zend_free_op free_op1, free_op2;
5596	zval *container;
5597	zval *offset;
5598
5599	SAVE_OPLINE();
5600	container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
5601	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
5602		zend_throw_error(NULL, "Using $this when not in object context");
5603		FREE_UNFETCHED_OP2();
5604		HANDLE_EXCEPTION();
5605	}
5606	offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
5607
5608	do {
5609		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
5610			if (Z_ISREF_P(container)) {
5611				container = Z_REFVAL_P(container);
5612				if (Z_TYPE_P(container) != IS_OBJECT) {
5613					break;
5614				}
5615			} else {
5616				break;
5617			}
5618		}
5619		if (Z_OBJ_HT_P(container)->unset_property) {
5620			Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
5621		} else {
5622			zend_error(E_NOTICE, "Trying to unset property of non-object");
5623		}
5624	} while (0);
5625
5626	FREE_OP2();
5627	FREE_OP1_VAR_PTR();
5628	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5629}
5630
5631ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
5632{
5633	USE_OPLINE
5634	zend_free_op free_op1;
5635	zval *array_ptr, *result;
5636	HashTable *fe_ht;
5637
5638	SAVE_OPLINE();
5639
5640	array_ptr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
5641	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
5642		result = EX_VAR(opline->result.var);
5643		ZVAL_COPY_VALUE(result, array_ptr);
5644		if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
5645			Z_ADDREF_P(array_ptr);
5646		}
5647		Z_FE_POS_P(result) = 0;
5648
5649		FREE_OP1_IF_VAR();
5650		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5651	} else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
5652		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
5653			HashPosition pos = 0;
5654			Bucket *p;
5655
5656			result = EX_VAR(opline->result.var);
5657			ZVAL_COPY_VALUE(result, array_ptr);
5658			if (OP1_TYPE != IS_TMP_VAR) {
5659				Z_ADDREF_P(array_ptr);
5660			}
5661			fe_ht = Z_OBJPROP_P(array_ptr);
5662			pos = 0;
5663			p = fe_ht->arData;
5664			while (1) {
5665				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
5666					FREE_OP1_IF_VAR();
5667					Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5668					ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5669				}
5670				if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
5671				     (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
5672				      EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
5673				    (UNEXPECTED(!p->key) ||
5674				     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
5675					break;
5676				}
5677				pos++;
5678				p++;
5679			}
5680			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos);
5681
5682			FREE_OP1_IF_VAR();
5683			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5684		} else {
5685			zend_class_entry *ce = Z_OBJCE_P(array_ptr);
5686			zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
5687			zend_bool is_empty;
5688
5689			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
5690				FREE_OP1();
5691				if (!EG(exception)) {
5692					zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
5693				}
5694				zend_throw_exception_internal(NULL);
5695				HANDLE_EXCEPTION();
5696			}
5697
5698			iter->index = 0;
5699			if (iter->funcs->rewind) {
5700				iter->funcs->rewind(iter);
5701				if (UNEXPECTED(EG(exception) != NULL)) {
5702					OBJ_RELEASE(&iter->std);
5703					FREE_OP1();
5704					HANDLE_EXCEPTION();
5705				}
5706			}
5707
5708			is_empty = iter->funcs->valid(iter) != SUCCESS;
5709
5710			if (UNEXPECTED(EG(exception) != NULL)) {
5711				OBJ_RELEASE(&iter->std);
5712				FREE_OP1();
5713				HANDLE_EXCEPTION();
5714			}
5715			iter->index = -1; /* will be set to 0 before using next handler */
5716
5717			ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
5718			Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5719
5720			FREE_OP1();
5721			if (is_empty) {
5722				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5723			} else {
5724				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5725			}
5726		}
5727	} else {
5728		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
5729		ZVAL_UNDEF(EX_VAR(opline->result.var));
5730		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5731		FREE_OP1();
5732		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5733	}
5734}
5735
5736ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
5737{
5738	USE_OPLINE
5739	zend_free_op free_op1;
5740	zval *array_ptr, *array_ref;
5741	HashTable *fe_ht;
5742	HashPosition pos = 0;
5743	Bucket *p;
5744
5745	SAVE_OPLINE();
5746
5747	if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
5748		array_ref = array_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
5749		if (Z_ISREF_P(array_ref)) {
5750			array_ptr = Z_REFVAL_P(array_ref);
5751		}
5752	} else {
5753		array_ref = array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
5754	}
5755
5756	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
5757		if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
5758			if (array_ptr == array_ref) {
5759				ZVAL_NEW_REF(array_ref, array_ref);
5760				array_ptr = Z_REFVAL_P(array_ref);
5761			}
5762			Z_ADDREF_P(array_ref);
5763			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
5764		} else {
5765			array_ref = EX_VAR(opline->result.var);
5766			ZVAL_NEW_REF(array_ref, array_ptr);
5767			array_ptr = Z_REFVAL_P(array_ref);
5768		}
5769		if (OP1_TYPE == IS_CONST) {
5770			zval_copy_ctor_func(array_ptr);
5771		} else {
5772			SEPARATE_ARRAY(array_ptr);
5773		}
5774		fe_ht = Z_ARRVAL_P(array_ptr);
5775		p = fe_ht->arData;
5776		while (1) {
5777			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
5778				FREE_OP1_VAR_PTR();
5779				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5780				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5781			}
5782			if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
5783			    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
5784			     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) {
5785				break;
5786			}
5787			pos++;
5788			p++;
5789		}
5790		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos);
5791
5792		FREE_OP1_VAR_PTR();
5793		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5794	} else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
5795		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
5796			if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
5797				if (array_ptr == array_ref) {
5798					ZVAL_NEW_REF(array_ref, array_ref);
5799					array_ptr = Z_REFVAL_P(array_ref);
5800				}
5801				Z_ADDREF_P(array_ref);
5802				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
5803			} else {
5804				array_ptr = EX_VAR(opline->result.var);
5805				ZVAL_COPY_VALUE(array_ptr, array_ref);
5806			}
5807			fe_ht = Z_OBJPROP_P(array_ptr);
5808			p = fe_ht->arData;
5809			while (1) {
5810				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
5811					FREE_OP1_VAR_PTR();
5812					Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5813					ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5814				}
5815				if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
5816				     (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
5817				      EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
5818				    (UNEXPECTED(!p->key) ||
5819				     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
5820					break;
5821				}
5822				pos++;
5823				p++;
5824			}
5825			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos);
5826
5827			FREE_OP1_VAR_PTR();
5828			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5829		} else {
5830			zend_class_entry *ce = Z_OBJCE_P(array_ptr);
5831			zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
5832			zend_bool is_empty;
5833
5834			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
5835				if (OP1_TYPE == IS_VAR) {
5836					FREE_OP1_VAR_PTR();
5837				} else {
5838					FREE_OP1();
5839				}
5840				if (!EG(exception)) {
5841					zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
5842				}
5843				zend_throw_exception_internal(NULL);
5844				HANDLE_EXCEPTION();
5845			}
5846
5847			iter->index = 0;
5848			if (iter->funcs->rewind) {
5849				iter->funcs->rewind(iter);
5850				if (UNEXPECTED(EG(exception) != NULL)) {
5851					OBJ_RELEASE(&iter->std);
5852					if (OP1_TYPE == IS_VAR) {
5853						FREE_OP1_VAR_PTR();
5854					} else {
5855						FREE_OP1();
5856					}
5857					HANDLE_EXCEPTION();
5858				}
5859			}
5860
5861			is_empty = iter->funcs->valid(iter) != SUCCESS;
5862
5863			if (UNEXPECTED(EG(exception) != NULL)) {
5864				OBJ_RELEASE(&iter->std);
5865				if (OP1_TYPE == IS_VAR) {
5866					FREE_OP1_VAR_PTR();
5867				} else {
5868					FREE_OP1();
5869				}
5870				HANDLE_EXCEPTION();
5871			}
5872			iter->index = -1; /* will be set to 0 before using next handler */
5873
5874			ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
5875			Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5876
5877			if (OP1_TYPE == IS_VAR) {
5878				FREE_OP1_VAR_PTR();
5879			} else {
5880				FREE_OP1();
5881			}
5882			if (is_empty) {
5883				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5884			} else {
5885				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5886			}
5887		}
5888	} else {
5889		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
5890		ZVAL_UNDEF(EX_VAR(opline->result.var));
5891		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
5892		if (OP1_TYPE == IS_VAR) {
5893			FREE_OP1_VAR_PTR();
5894		} else {
5895			FREE_OP1();
5896		}
5897		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
5898	}
5899}
5900
5901ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
5902{
5903	USE_OPLINE
5904	zval *array;
5905	zval *value;
5906	uint32_t value_type;
5907	HashTable *fe_ht;
5908	HashPosition pos;
5909	Bucket *p;
5910
5911	array = EX_VAR(opline->op1.var);
5912	SAVE_OPLINE();
5913	if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
5914		fe_ht = Z_ARRVAL_P(array);
5915		pos = Z_FE_POS_P(array);
5916		p = fe_ht->arData + pos;
5917		while (1) {
5918			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
5919				/* reached end of iteration */
5920				ZEND_VM_C_GOTO(fe_fetch_r_exit);
5921			}
5922			value = &p->val;
5923			value_type = Z_TYPE_INFO_P(value);
5924			if (value_type == IS_UNDEF) {
5925				pos++;
5926				p++;
5927				continue;
5928			} else if (UNEXPECTED(value_type == IS_INDIRECT)) {
5929				value = Z_INDIRECT_P(value);
5930				value_type = Z_TYPE_INFO_P(value);
5931				if (UNEXPECTED(value_type == IS_UNDEF)) {
5932					pos++;
5933					p++;
5934					continue;
5935				}
5936			}
5937			break;
5938		}
5939		Z_FE_POS_P(array) = pos + 1;
5940		if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
5941			if (!p->key) {
5942				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
5943			} else {
5944				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
5945			}
5946		}
5947	} else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
5948		zend_object_iterator *iter;
5949
5950		if ((iter = zend_iterator_unwrap(array)) == NULL) {
5951			/* plain object */
5952
5953 			fe_ht = Z_OBJPROP_P(array);
5954			pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht);
5955			p = fe_ht->arData + pos;
5956			while (1) {
5957				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
5958					/* reached end of iteration */
5959					ZEND_VM_C_GOTO(fe_fetch_r_exit);
5960				}
5961
5962				value = &p->val;
5963				value_type = Z_TYPE_INFO_P(value);
5964				if (UNEXPECTED(value_type == IS_UNDEF)) {
5965					pos++;
5966					p++;
5967					continue;
5968				} else if (UNEXPECTED(value_type == IS_INDIRECT)) {
5969					value = Z_INDIRECT_P(value);
5970					value_type = Z_TYPE_INFO_P(value);
5971					if (UNEXPECTED(value_type == IS_UNDEF)) {
5972						pos++;
5973						p++;
5974						continue;
5975					}
5976				}
5977				if (UNEXPECTED(!p->key) ||
5978				    EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
5979					break;
5980				}
5981				pos++;
5982				p++;
5983			}
5984			if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
5985				if (UNEXPECTED(!p->key)) {
5986					ZVAL_LONG(EX_VAR(opline->result.var), p->h);
5987				} else if (ZSTR_VAL(p->key)[0]) {
5988					ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
5989				} else {
5990					const char *class_name, *prop_name;
5991					size_t prop_name_len;
5992					zend_unmangle_property_name_ex(
5993						p->key, &class_name, &prop_name, &prop_name_len);
5994					ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len);
5995				}
5996			}
5997			while (1) {
5998				pos++;
5999				if (pos >= fe_ht->nNumUsed) {
6000					pos = HT_INVALID_IDX;
6001					break;
6002				}
6003				p++;
6004				if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
6005				     (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
6006				      EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
6007				    (UNEXPECTED(!p->key) ||
6008				     EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS))) {
6009					break;
6010				}
6011			}
6012			EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos;
6013		} else {
6014			if (EXPECTED(++iter->index > 0)) {
6015				/* This could cause an endless loop if index becomes zero again.
6016				 * In case that ever happens we need an additional flag. */
6017				iter->funcs->move_forward(iter);
6018				if (UNEXPECTED(EG(exception) != NULL)) {
6019					HANDLE_EXCEPTION();
6020				}
6021				if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) {
6022					/* reached end of iteration */
6023					if (UNEXPECTED(EG(exception) != NULL)) {
6024						HANDLE_EXCEPTION();
6025					}
6026					ZEND_VM_C_GOTO(fe_fetch_r_exit);
6027				}
6028			}
6029			value = iter->funcs->get_current_data(iter);
6030			if (UNEXPECTED(EG(exception) != NULL)) {
6031				HANDLE_EXCEPTION();
6032			}
6033			if (!value) {
6034				/* failure in get_current_data */
6035				ZEND_VM_C_GOTO(fe_fetch_r_exit);
6036			}
6037			if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
6038				if (iter->funcs->get_current_key) {
6039					iter->funcs->get_current_key(iter, EX_VAR(opline->result.var));
6040					if (UNEXPECTED(EG(exception) != NULL)) {
6041						HANDLE_EXCEPTION();
6042					}
6043				} else {
6044					ZVAL_LONG(EX_VAR(opline->result.var), iter->index);
6045				}
6046			}
6047			value_type = Z_TYPE_INFO_P(value);
6048		}
6049	} else {
6050		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6051		if (UNEXPECTED(EG(exception))) {
6052			HANDLE_EXCEPTION();
6053		}
6054ZEND_VM_C_LABEL(fe_fetch_r_exit):
6055		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
6056		ZEND_VM_CONTINUE();
6057	}
6058
6059	if (EXPECTED(OP2_TYPE == IS_CV)) {
6060		zval *variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op2.var);
6061		zend_assign_to_variable(variable_ptr, value, IS_CV);
6062	} else {
6063		zval *res = EX_VAR(opline->op2.var);
6064		zend_refcounted *gc = Z_COUNTED_P(value);
6065
6066		ZVAL_COPY_VALUE_EX(res, value, gc, value_type);
6067		if (EXPECTED((value_type & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)) {
6068			GC_REFCOUNT(gc)++;
6069		}
6070	}
6071	ZEND_VM_NEXT_OPCODE();
6072}
6073
6074ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR)
6075{
6076	USE_OPLINE
6077	zval *array;
6078	zval *value;
6079	uint32_t value_type;
6080	HashTable *fe_ht;
6081	HashPosition pos;
6082	Bucket *p;
6083
6084	array = EX_VAR(opline->op1.var);
6085	SAVE_OPLINE();
6086
6087	ZVAL_DEREF(array);
6088	if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
6089		pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array);
6090		fe_ht = Z_ARRVAL_P(array);
6091		p = fe_ht->arData + pos;
6092		while (1) {
6093			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
6094				/* reached end of iteration */
6095				ZEND_VM_C_GOTO(fe_fetch_w_exit);
6096			}
6097			value = &p->val;
6098			value_type = Z_TYPE_INFO_P(value);
6099			if (UNEXPECTED(value_type == IS_UNDEF)) {
6100				pos++;
6101				p++;
6102				continue;
6103			} else if (UNEXPECTED(value_type == IS_INDIRECT)) {
6104				value = Z_INDIRECT_P(value);
6105				value_type = Z_TYPE_INFO_P(value);
6106				if (UNEXPECTED(value_type == IS_UNDEF)) {
6107					pos++;
6108					p++;
6109					continue;
6110				}
6111			}
6112			break;
6113		}
6114		if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
6115			if (!p->key) {
6116				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
6117			} else {
6118				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
6119			}
6120		}
6121		while (1) {
6122			pos++;
6123			if (pos >= fe_ht->nNumUsed) {
6124				pos = HT_INVALID_IDX;
6125				break;
6126			}
6127			p++;
6128			if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
6129			    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
6130			     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) {
6131				break;
6132			}
6133		}
6134		EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos;
6135	} else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
6136		zend_object_iterator *iter;
6137
6138		if ((iter = zend_iterator_unwrap(array)) == NULL) {
6139			/* plain object */
6140
6141 			fe_ht = Z_OBJPROP_P(array);
6142			pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
6143			p = fe_ht->arData + pos;
6144			while (1) {
6145				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
6146					/* reached end of iteration */
6147					ZEND_VM_C_GOTO(fe_fetch_w_exit);
6148				}
6149
6150				value = &p->val;
6151				value_type = Z_TYPE_INFO_P(value);
6152				if (UNEXPECTED(value_type == IS_UNDEF)) {
6153					pos++;
6154					p++;
6155					continue;
6156				} else if (UNEXPECTED(value_type == IS_INDIRECT)) {
6157					value = Z_INDIRECT_P(value);
6158					value_type = Z_TYPE_INFO_P(value);
6159					if (UNEXPECTED(value_type == IS_UNDEF)) {
6160						pos++;
6161						p++;
6162						continue;
6163					}
6164				}
6165				if (UNEXPECTED(!p->key) ||
6166				    EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
6167					break;
6168				}
6169				pos++;
6170				p++;
6171			}
6172			if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
6173				if (UNEXPECTED(!p->key)) {
6174					ZVAL_LONG(EX_VAR(opline->result.var), p->h);
6175				} else if (ZSTR_VAL(p->key)[0]) {
6176					ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
6177				} else {
6178					const char *class_name, *prop_name;
6179					size_t prop_name_len;
6180					zend_unmangle_property_name_ex(
6181						p->key, &class_name, &prop_name, &prop_name_len);
6182					ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len);
6183				}
6184			}
6185			while (1) {
6186				pos++;
6187				if (pos >= fe_ht->nNumUsed) {
6188					pos = HT_INVALID_IDX;
6189					break;
6190				}
6191				p++;
6192				if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
6193				     (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
6194				      EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
6195				    (UNEXPECTED(!p->key) ||
6196				     EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS))) {
6197					break;
6198				}
6199			}
6200			EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos;
6201		} else {
6202			if (++iter->index > 0) {
6203				/* This could cause an endless loop if index becomes zero again.
6204				 * In case that ever happens we need an additional flag. */
6205				iter->funcs->move_forward(iter);
6206				if (UNEXPECTED(EG(exception) != NULL)) {
6207					HANDLE_EXCEPTION();
6208				}
6209				if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) {
6210					/* reached end of iteration */
6211					if (UNEXPECTED(EG(exception) != NULL)) {
6212						HANDLE_EXCEPTION();
6213					}
6214					ZEND_VM_C_GOTO(fe_fetch_w_exit);
6215				}
6216			}
6217			value = iter->funcs->get_current_data(iter);
6218			if (UNEXPECTED(EG(exception) != NULL)) {
6219				HANDLE_EXCEPTION();
6220			}
6221			if (!value) {
6222				/* failure in get_current_data */
6223				ZEND_VM_C_GOTO(fe_fetch_w_exit);
6224			}
6225			if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
6226				if (iter->funcs->get_current_key) {
6227					iter->funcs->get_current_key(iter, EX_VAR(opline->result.var));
6228					if (UNEXPECTED(EG(exception) != NULL)) {
6229						HANDLE_EXCEPTION();
6230					}
6231				} else {
6232					ZVAL_LONG(EX_VAR(opline->result.var), iter->index);
6233				}
6234			}
6235			value_type = Z_TYPE_INFO_P(value);
6236		}
6237	} else {
6238		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6239		if (UNEXPECTED(EG(exception))) {
6240			HANDLE_EXCEPTION();
6241		}
6242ZEND_VM_C_LABEL(fe_fetch_w_exit):
6243		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
6244		ZEND_VM_CONTINUE();
6245	}
6246
6247	if (EXPECTED((value_type & Z_TYPE_MASK) != IS_REFERENCE)) {
6248		zend_refcounted *gc = Z_COUNTED_P(value);
6249		zval *ref;
6250		ZVAL_NEW_EMPTY_REF(value);
6251		ref = Z_REFVAL_P(value);
6252		ZVAL_COPY_VALUE_EX(ref, value, gc, value_type);
6253	}
6254	if (EXPECTED(OP2_TYPE == IS_CV)) {
6255		zval *variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op2.var);
6256		if (EXPECTED(variable_ptr != value)) {
6257			zend_reference *ref;
6258
6259			ref = Z_REF_P(value);
6260			GC_REFCOUNT(ref)++;
6261			zval_ptr_dtor(variable_ptr);
6262			ZVAL_REF(variable_ptr, ref);
6263		}
6264	} else {
6265		Z_ADDREF_P(value);
6266		ZVAL_REF(EX_VAR(opline->op2.var), Z_REF_P(value));
6267	}
6268	ZEND_VM_NEXT_OPCODE();
6269}
6270
6271ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
6272{
6273	USE_OPLINE
6274	zval *value;
6275	int result;
6276
6277	if (OP1_TYPE == IS_CV &&
6278	    (opline->extended_value & ZEND_QUICK_SET)) {
6279		value = EX_VAR(opline->op1.var);
6280		if (opline->extended_value & ZEND_ISSET) {
6281			result =
6282				Z_TYPE_P(value) > IS_NULL &&
6283			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
6284		} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
6285			SAVE_OPLINE();
6286			result = !i_zend_is_true(value);
6287			if (UNEXPECTED(EG(exception))) {
6288				HANDLE_EXCEPTION();
6289			}
6290		}
6291		ZEND_VM_SMART_BRANCH(result, 0);
6292		ZVAL_BOOL(EX_VAR(opline->result.var), result);
6293		ZEND_VM_SET_NEXT_OPCODE(opline + 1);
6294		ZEND_VM_CONTINUE();
6295	} else {
6296		zend_free_op free_op1;
6297		zval tmp, *varname;
6298		HashTable *target_symbol_table;
6299
6300		SAVE_OPLINE();
6301		varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
6302		ZVAL_UNDEF(&tmp);
6303		if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
6304			ZVAL_STR(&tmp, zval_get_string(varname));
6305			varname = &tmp;
6306		}
6307
6308		target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK);
6309		value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));
6310
6311		if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
6312			zend_string_release(Z_STR(tmp));
6313		}
6314		FREE_OP1();
6315
6316		if (opline->extended_value & ZEND_ISSET) {
6317			result = value && Z_TYPE_P(value) > IS_NULL &&
6318			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
6319		} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
6320			result = !value || !i_zend_is_true(value);
6321		}
6322
6323		ZEND_VM_SMART_BRANCH(result, 1);
6324		ZVAL_BOOL(EX_VAR(opline->result.var), result);
6325		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6326	}
6327}
6328
6329ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, ISSET)
6330{
6331	USE_OPLINE
6332	zval *value;
6333	int result;
6334	zend_free_op free_op1;
6335	zval tmp, *varname;
6336	zend_class_entry *ce;
6337
6338	SAVE_OPLINE();
6339	varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
6340	ZVAL_UNDEF(&tmp);
6341	if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
6342		ZVAL_STR(&tmp, zval_get_string(varname));
6343		varname = &tmp;
6344	}
6345
6346	if (OP2_TYPE == IS_CONST) {
6347		if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) {
6348			value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*));
6349
6350			/* check if static properties were destoyed */
6351			if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
6352				value = NULL;
6353			}
6354
6355			ZEND_VM_C_GOTO(is_static_prop_return);
6356		} else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) {
6357			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);
6358			if (UNEXPECTED(ce == NULL)) {
6359				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6360			}
6361			CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
6362		}
6363	} else {
6364		if (OP2_TYPE == IS_UNUSED) {
6365			ce = zend_fetch_class(NULL, opline->op2.num);
6366			if (UNEXPECTED(ce == NULL)) {
6367				ZEND_ASSERT(EG(exception));
6368				if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
6369					zend_string_release(Z_STR(tmp));
6370				}
6371				FREE_OP1();
6372				HANDLE_EXCEPTION();
6373			}
6374		} else {
6375			ce = Z_CE_P(EX_VAR(opline->op2.var));
6376		}
6377		if (OP1_TYPE == IS_CONST &&
6378		    (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) {
6379
6380			/* check if static properties were destoyed */
6381			if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
6382				value = NULL;
6383			}
6384
6385			ZEND_VM_C_GOTO(is_static_prop_return);
6386		}
6387	}
6388
6389	value = zend_std_get_static_property(ce, Z_STR_P(varname), 1);
6390
6391	if (OP1_TYPE == IS_CONST && value) {
6392		CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value);
6393	}
6394
6395	if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
6396		zend_string_release(Z_STR(tmp));
6397	}
6398	FREE_OP1();
6399
6400ZEND_VM_C_LABEL(is_static_prop_return):
6401	if (opline->extended_value & ZEND_ISSET) {
6402		result = value && Z_TYPE_P(value) > IS_NULL &&
6403		    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
6404	} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
6405		result = !value || !i_zend_is_true(value);
6406	}
6407
6408	ZEND_VM_SMART_BRANCH(result, 1);
6409	ZVAL_BOOL(EX_VAR(opline->result.var), result);
6410	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6411}
6412
6413ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET)
6414{
6415	USE_OPLINE
6416	zend_free_op free_op1, free_op2;
6417	zval *container;
6418	int result;
6419	zend_ulong hval;
6420	zval *offset;
6421
6422	SAVE_OPLINE();
6423	container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_IS);
6424
6425	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
6426		zend_throw_error(NULL, "Using $this when not in object context");
6427		FREE_UNFETCHED_OP2();
6428		HANDLE_EXCEPTION();
6429	}
6430
6431	offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
6432
6433	if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
6434		HashTable *ht;
6435		zval *value;
6436		zend_string *str;
6437
6438ZEND_VM_C_LABEL(isset_dim_obj_array):
6439		ht = Z_ARRVAL_P(container);
6440ZEND_VM_C_LABEL(isset_again):
6441		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
6442			str = Z_STR_P(offset);
6443			if (OP2_TYPE != IS_CONST) {
6444				if (ZEND_HANDLE_NUMERIC(str, hval)) {
6445					ZEND_VM_C_GOTO(num_index_prop);
6446				}
6447			}
6448ZEND_VM_C_LABEL(str_index_prop):
6449			value = zend_hash_find_ind(ht, str);
6450		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
6451			hval = Z_LVAL_P(offset);
6452ZEND_VM_C_LABEL(num_index_prop):
6453			value = zend_hash_index_find(ht, hval);
6454		} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
6455			offset = Z_REFVAL_P(offset);
6456			ZEND_VM_C_GOTO(isset_again);
6457		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
6458			hval = zend_dval_to_lval(Z_DVAL_P(offset));
6459			ZEND_VM_C_GOTO(num_index_prop);
6460		} else if (Z_TYPE_P(offset) == IS_NULL) {
6461			str = ZSTR_EMPTY_ALLOC();
6462			ZEND_VM_C_GOTO(str_index_prop);
6463		} else if (Z_TYPE_P(offset) == IS_FALSE) {
6464			hval = 0;
6465			ZEND_VM_C_GOTO(num_index_prop);
6466		} else if (Z_TYPE_P(offset) == IS_TRUE) {
6467			hval = 1;
6468			ZEND_VM_C_GOTO(num_index_prop);
6469		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
6470			hval = Z_RES_HANDLE_P(offset);
6471			ZEND_VM_C_GOTO(num_index_prop);
6472		} else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
6473			GET_OP2_UNDEF_CV(offset, BP_VAR_R);
6474			str = ZSTR_EMPTY_ALLOC();
6475			ZEND_VM_C_GOTO(str_index_prop);
6476		} else {
6477			zend_error(E_WARNING, "Illegal offset type in isset or empty");
6478			ZEND_VM_C_GOTO(isset_not_found);
6479		}
6480
6481		if (opline->extended_value & ZEND_ISSET) {
6482			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
6483			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
6484			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
6485		} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
6486			result = (value == NULL || !i_zend_is_true(value));
6487		}
6488		ZEND_VM_C_GOTO(isset_dim_obj_exit);
6489	} else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
6490		container = Z_REFVAL_P(container);
6491		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
6492			ZEND_VM_C_GOTO(isset_dim_obj_array);
6493		}
6494	}
6495
6496	if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
6497		offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
6498	}
6499
6500	if (OP1_TYPE == IS_UNUSED ||
6501	    (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
6502		if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
6503			result =
6504				((opline->extended_value & ZEND_ISSET) == 0) ^
6505				Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
6506		} else {
6507			zend_error(E_NOTICE, "Trying to check element of non-array");
6508			ZEND_VM_C_GOTO(isset_not_found);
6509		}
6510	} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
6511		zend_long lval;
6512
6513		if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
6514			lval = Z_LVAL_P(offset);
6515ZEND_VM_C_LABEL(isset_str_offset):
6516			if (UNEXPECTED(lval < 0)) { /* Handle negative offset */
6517				lval += (zend_long)Z_STRLEN_P(container);
6518			}
6519			if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
6520				if (opline->extended_value & ZEND_ISSET) {
6521					result = 1;
6522				} else {
6523					result = (Z_STRVAL_P(container)[lval] == '0');
6524				}
6525			} else {
6526				ZEND_VM_C_GOTO(isset_not_found);
6527			}
6528		} else {
6529			if (OP2_TYPE & (IS_CV|IS_VAR)) {
6530				ZVAL_DEREF(offset);
6531			}
6532			if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
6533					|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
6534						&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
6535				lval = zval_get_long(offset);
6536				ZEND_VM_C_GOTO(isset_str_offset);
6537			}
6538			ZEND_VM_C_GOTO(isset_not_found);
6539		}
6540	} else {
6541ZEND_VM_C_LABEL(isset_not_found):
6542		result = ((opline->extended_value & ZEND_ISSET) == 0);
6543	}
6544
6545ZEND_VM_C_LABEL(isset_dim_obj_exit):
6546	FREE_OP2();
6547	FREE_OP1();
6548	ZEND_VM_SMART_BRANCH(result, 1);
6549	ZVAL_BOOL(EX_VAR(opline->result.var), result);
6550	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6551}
6552
6553ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET)
6554{
6555	USE_OPLINE
6556	zend_free_op free_op1, free_op2;
6557	zval *container;
6558	int result;
6559	zval *offset;
6560
6561	SAVE_OPLINE();
6562	container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
6563
6564	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
6565		zend_throw_error(NULL, "Using $this when not in object context");
6566		FREE_UNFETCHED_OP2();
6567		HANDLE_EXCEPTION();
6568	}
6569
6570	offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
6571
6572	if (OP1_TYPE == IS_CONST ||
6573	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
6574		if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
6575			container = Z_REFVAL_P(container);
6576			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
6577				ZEND_VM_C_GOTO(isset_no_object);
6578			}
6579		} else {
6580			ZEND_VM_C_GOTO(isset_no_object);
6581		}
6582	}
6583	if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) {
6584		zend_error(E_NOTICE, "Trying to check property of non-object");
6585ZEND_VM_C_LABEL(isset_no_object):
6586		result = ((opline->extended_value & ZEND_ISSET) == 0);
6587	} else {
6588		result =
6589			((opline->extended_value & ZEND_ISSET) == 0) ^
6590			Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
6591	}
6592
6593	FREE_OP2();
6594	FREE_OP1();
6595	ZEND_VM_SMART_BRANCH(result, 1);
6596	ZVAL_BOOL(EX_VAR(opline->result.var), result);
6597	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6598}
6599
6600ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMPVAR|UNUSED|CV, ANY)
6601{
6602	USE_OPLINE
6603
6604	SAVE_OPLINE();
6605	if (OP1_TYPE != IS_UNUSED) {
6606		zend_free_op free_op1;
6607		zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
6608
6609		do {
6610			if (Z_TYPE_P(ptr) == IS_LONG) {
6611				EG(exit_status) = Z_LVAL_P(ptr);
6612			} else {
6613				if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) {
6614					ptr = Z_REFVAL_P(ptr);
6615					if (Z_TYPE_P(ptr) == IS_LONG) {
6616						EG(exit_status) = Z_LVAL_P(ptr);
6617						break;
6618					}
6619				}
6620				zend_print_variable(ptr);
6621			}
6622		} while (0);
6623		FREE_OP1();
6624	}
6625	zend_bailout();
6626	ZEND_VM_NEXT_OPCODE(); /* Never reached */
6627}
6628
6629ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
6630{
6631	USE_OPLINE
6632
6633	ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
6634
6635	if (EG(error_reporting)) {
6636		do {
6637			EG(error_reporting) = 0;
6638			if (!EG(error_reporting_ini_entry)) {
6639				zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
6640				if (p) {
6641					EG(error_reporting_ini_entry) = p;
6642				} else {
6643					break;
6644				}
6645			}
6646			if (!EG(error_reporting_ini_entry)->modified) {
6647				if (!EG(modified_ini_directives)) {
6648					ALLOC_HASHTABLE(EG(modified_ini_directives));
6649					zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
6650				}
6651				if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, EG(error_reporting_ini_entry)) != NULL)) {
6652					EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
6653					EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
6654					EG(error_reporting_ini_entry)->modified = 1;
6655				}
6656			}
6657		} while (0);
6658	}
6659	ZEND_VM_NEXT_OPCODE();
6660}
6661
6662ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
6663{
6664	USE_OPLINE
6665
6666	if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
6667		EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
6668	}
6669	ZEND_VM_NEXT_OPCODE();
6670}
6671
6672ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
6673{
6674	USE_OPLINE
6675	zend_free_op free_op1;
6676	zval *value;
6677	zval *ref = NULL;
6678
6679	SAVE_OPLINE();
6680	value = GET_OP1_ZVAL_PTR(BP_VAR_R);
6681
6682	if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
6683		if (OP1_TYPE == IS_VAR) {
6684			ref = value;
6685		}
6686		value = Z_REFVAL_P(value);
6687	}
6688	if (i_zend_is_true(value)) {
6689		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
6690		if (OP1_TYPE == IS_CONST) {
6691			if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
6692				zval_copy_ctor_func(EX_VAR(opline->result.var));
6693			}
6694		} else if (OP1_TYPE == IS_CV) {
6695			if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
6696		} else if (OP1_TYPE == IS_VAR && ref) {
6697			zend_reference *r = Z_REF_P(ref);
6698
6699			if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
6700			if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) {
6701				efree_size(r, sizeof(zend_reference));
6702			}
6703		}
6704		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6705	}
6706
6707	FREE_OP1();
6708	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6709}
6710
6711ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
6712{
6713	USE_OPLINE
6714	zend_free_op free_op1;
6715	zval *value;
6716	zval *ref = NULL;
6717
6718	SAVE_OPLINE();
6719	value = GET_OP1_ZVAL_PTR(BP_VAR_IS);
6720
6721	if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
6722		if (OP1_TYPE == IS_VAR) {
6723			ref = value;
6724		}
6725		value = Z_REFVAL_P(value);
6726	}
6727
6728	if (Z_TYPE_P(value) > IS_NULL) {
6729		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
6730		if (OP1_TYPE == IS_CONST) {
6731			if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
6732				zval_copy_ctor_func(EX_VAR(opline->result.var));
6733			}
6734		} else if (OP1_TYPE == IS_CV) {
6735			if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
6736		} else if (OP1_TYPE == IS_VAR && ref) {
6737			zend_reference *r = Z_REF_P(ref);
6738
6739			if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
6740			if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) {
6741				efree_size(r, sizeof(zend_reference));
6742			}
6743		}
6744		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6745	}
6746
6747	FREE_OP1();
6748	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6749}
6750
6751ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
6752{
6753	USE_OPLINE
6754	zend_free_op free_op1;
6755	zval *value;
6756
6757	value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
6758	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
6759		SAVE_OPLINE();
6760		GET_OP1_UNDEF_CV(value, BP_VAR_R);
6761		ZVAL_NULL(EX_VAR(opline->result.var));
6762		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6763	}
6764
6765	if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
6766		ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value));
6767		if (OP1_TYPE == IS_VAR) {
6768			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
6769				efree_size(Z_REF_P(value), sizeof(zend_reference));
6770			}
6771		}
6772	} else {
6773		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
6774		if (OP1_TYPE == IS_CONST) {
6775			if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
6776				zval_copy_ctor_func(EX_VAR(opline->result.var));
6777			}
6778		} else if (OP1_TYPE == IS_CV) {
6779			if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
6780		}
6781	}
6782	ZEND_VM_NEXT_OPCODE();
6783}
6784
6785ZEND_VM_HANDLER(101, ZEND_EXT_STMT, ANY, ANY)
6786{
6787	USE_OPLINE
6788
6789	if (!EG(no_extensions)) {
6790		SAVE_OPLINE();
6791		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(func));
6792		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6793	}
6794	ZEND_VM_NEXT_OPCODE();
6795}
6796
6797ZEND_VM_HANDLER(102, ZEND_EXT_FCALL_BEGIN, ANY, ANY)
6798{
6799	USE_OPLINE
6800
6801	if (!EG(no_extensions)) {
6802		SAVE_OPLINE();
6803		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(func));
6804		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6805	}
6806	ZEND_VM_NEXT_OPCODE();
6807}
6808
6809ZEND_VM_HANDLER(103, ZEND_EXT_FCALL_END, ANY, ANY)
6810{
6811	USE_OPLINE
6812
6813	if (!EG(no_extensions)) {
6814		SAVE_OPLINE();
6815		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(func));
6816		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6817	}
6818	ZEND_VM_NEXT_OPCODE();
6819}
6820
6821ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, ANY, ANY)
6822{
6823	USE_OPLINE
6824
6825	SAVE_OPLINE();
6826	Z_CE_P(EX_VAR(opline->result.var)) = do_bind_class(&EX(func)->op_array, opline, EG(class_table), 0);
6827	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6828}
6829
6830ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, VAR)
6831{
6832	USE_OPLINE
6833
6834	SAVE_OPLINE();
6835	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->op2.var)), 0);
6836	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6837}
6838
6839ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, VAR)
6840{
6841	USE_OPLINE
6842	zval *zce, *orig_zce;
6843
6844	SAVE_OPLINE();
6845	if ((zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)))) == NULL ||
6846	    ((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)+1))) != NULL &&
6847	     Z_CE_P(zce) != Z_CE_P(orig_zce))) {
6848		do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->op2.var)), 0);
6849	}
6850	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6851}
6852
6853ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR)
6854{
6855	zend_class_entry *ce;
6856	USE_OPLINE
6857
6858	SAVE_OPLINE();
6859	ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)));
6860	Z_CE_P(EX_VAR(opline->result.var)) = ce;
6861	ZEND_ASSERT(ce != NULL);
6862
6863	if (ce->ce_flags & ZEND_ACC_ANON_BOUND) {
6864		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
6865		ZEND_VM_CONTINUE();
6866	}
6867
6868	if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
6869		zend_verify_abstract_class(ce);
6870	}
6871	ce->ce_flags |= ZEND_ACC_ANON_BOUND;
6872	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6873}
6874
6875ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ANY, VAR, JMP_ADDR)
6876{
6877	zend_class_entry *ce;
6878	USE_OPLINE
6879
6880	SAVE_OPLINE();
6881	ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)));
6882	Z_CE_P(EX_VAR(opline->result.var)) = ce;
6883	ZEND_ASSERT(ce != NULL);
6884
6885	if (ce->ce_flags & ZEND_ACC_ANON_BOUND) {
6886		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
6887		ZEND_VM_CONTINUE();
6888	}
6889
6890	zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->op2.var)));
6891	ce->ce_flags |= ZEND_ACC_ANON_BOUND;
6892	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6893}
6894
6895ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY)
6896{
6897	USE_OPLINE
6898
6899	SAVE_OPLINE();
6900	do_bind_function(&EX(func)->op_array, opline, EG(function_table), 0);
6901	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6902}
6903
6904ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM)
6905{
6906	USE_OPLINE
6907
6908	if ((uint32_t)++EG(ticks_count) >= opline->extended_value) {
6909		EG(ticks_count) = 0;
6910		if (zend_ticks_function) {
6911			SAVE_OPLINE();
6912			zend_ticks_function(opline->extended_value);
6913			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6914		}
6915	}
6916	ZEND_VM_NEXT_OPCODE();
6917}
6918
6919ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
6920{
6921	USE_OPLINE
6922	zend_free_op free_op1;
6923	zval *expr;
6924	zend_bool result;
6925
6926	SAVE_OPLINE();
6927	expr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
6928
6929ZEND_VM_C_LABEL(try_instanceof):
6930	if (Z_TYPE_P(expr) == IS_OBJECT) {
6931		zend_class_entry *ce;
6932
6933		if (OP2_TYPE == IS_CONST) {
6934			ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
6935			if (UNEXPECTED(ce == NULL)) {
6936				ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD);
6937				if (UNEXPECTED(ce == NULL)) {
6938					ZVAL_FALSE(EX_VAR(opline->result.var));
6939					FREE_OP1();
6940					ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6941				}
6942				CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
6943			}
6944		} else if (OP2_TYPE == IS_UNUSED) {
6945			ce = zend_fetch_class(NULL, opline->op2.num);
6946			if (UNEXPECTED(ce == NULL)) {
6947				ZEND_ASSERT(EG(exception));
6948				FREE_OP1();
6949				HANDLE_EXCEPTION();
6950			}
6951		} else {
6952			ce = Z_CE_P(EX_VAR(opline->op2.var));
6953		}
6954		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
6955	} else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
6956		expr = Z_REFVAL_P(expr);
6957		ZEND_VM_C_GOTO(try_instanceof);
6958	} else {
6959		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
6960			GET_OP1_UNDEF_CV(expr, BP_VAR_R);
6961		}
6962		result = 0;
6963	}
6964	FREE_OP1();
6965	ZEND_VM_SMART_BRANCH(result, 1);
6966	ZVAL_BOOL(EX_VAR(opline->result.var), result);
6967	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6968}
6969
6970ZEND_VM_HANDLER(104, ZEND_EXT_NOP, ANY, ANY)
6971{
6972	USE_OPLINE
6973
6974	ZEND_VM_NEXT_OPCODE();
6975}
6976
6977ZEND_VM_HANDLER(0, ZEND_NOP, ANY, ANY)
6978{
6979	USE_OPLINE
6980
6981	ZEND_VM_NEXT_OPCODE();
6982}
6983
6984ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST)
6985{
6986	USE_OPLINE
6987	zend_class_entry *ce = Z_CE_P(EX_VAR(opline->op1.var));
6988	zend_class_entry *iface;
6989
6990	SAVE_OPLINE();
6991	iface = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
6992	if (UNEXPECTED(iface == NULL)) {
6993		iface = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE);
6994		if (UNEXPECTED(iface == NULL)) {
6995			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6996		}
6997		CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), iface);
6998	}
6999
7000	if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) {
7001		zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name));
7002	}
7003	zend_do_implement_interface(ce, iface);
7004
7005	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7006}
7007
7008ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY)
7009{
7010	USE_OPLINE
7011	zend_class_entry *ce = Z_CE_P(EX_VAR(opline->op1.var));
7012	zend_class_entry *trait;
7013
7014	SAVE_OPLINE();
7015	trait = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
7016	if (UNEXPECTED(trait == NULL)) {
7017		trait = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)),
7018		                                 EX_CONSTANT(opline->op2) + 1,
7019		                                 ZEND_FETCH_CLASS_TRAIT);
7020		if (UNEXPECTED(trait == NULL)) {
7021			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7022		}
7023		if (!(trait->ce_flags & ZEND_ACC_TRAIT)) {
7024			zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name));
7025		}
7026		CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), trait);
7027	}
7028
7029	zend_do_implement_trait(ce, trait);
7030
7031	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7032}
7033
7034ZEND_VM_HANDLER(155, ZEND_BIND_TRAITS, ANY, ANY)
7035{
7036	USE_OPLINE
7037	zend_class_entry *ce = Z_CE_P(EX_VAR(opline->op1.var));
7038
7039	SAVE_OPLINE();
7040	zend_do_bind_traits(ce);
7041	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7042}
7043
7044ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
7045{
7046	uint32_t op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
7047	int i;
7048	uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
7049	int in_finally = 0;
7050
7051	{
7052		const zend_op *exc_opline = EG(opline_before_exception);
7053		if ((exc_opline->opcode == ZEND_FREE || exc_opline->opcode == ZEND_FE_FREE)
7054			&& exc_opline->extended_value & ZEND_FREE_ON_RETURN) {
7055			/* exceptions thrown because of loop var destruction on return/break/...
7056			 * are logically thrown at the end of the foreach loop, so adjust the
7057			 * op_num.
7058			 */
7059			op_num = EX(func)->op_array.live_range[exc_opline->op2.num].end;
7060		}
7061	}
7062
7063	for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
7064		if (EX(func)->op_array.try_catch_array[i].try_op > op_num) {
7065			/* further blocks will not be relevant... */
7066			break;
7067		}
7068		in_finally = 0;
7069		if (op_num < EX(func)->op_array.try_catch_array[i].catch_op) {
7070			catch_op_num = EX(func)->op_array.try_catch_array[i].catch_op;
7071		}
7072		if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) {
7073			finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op;
7074			finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
7075		}
7076		if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
7077				op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
7078			finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
7079			in_finally = 1;
7080		}
7081	}
7082
7083	cleanup_unfinished_calls(execute_data, op_num);
7084
7085	if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
7086		zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
7087
7088		cleanup_live_vars(execute_data, op_num, finally_op_num);
7089		if (in_finally && Z_OBJ_P(fast_call)) {
7090			zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call));
7091		}
7092		Z_OBJ_P(fast_call) = EG(exception);
7093		EG(exception) = NULL;
7094		fast_call->u2.lineno = (uint32_t)-1;
7095		ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]);
7096		ZEND_VM_CONTINUE();
7097	} else {
7098		cleanup_live_vars(execute_data, op_num, catch_op_num);
7099		if (in_finally) {
7100			/* we are going out of current finally scope */
7101			zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
7102
7103			if (Z_OBJ_P(fast_call)) {
7104				zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call));
7105				Z_OBJ_P(fast_call) = NULL;
7106			}
7107		}
7108		if (catch_op_num) {
7109			ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
7110			ZEND_VM_CONTINUE();
7111		} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
7112			zend_generator *generator = zend_get_running_generator(execute_data);
7113			zend_generator_close(generator, 1);
7114			ZEND_VM_RETURN();
7115		} else {
7116			ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
7117		}
7118	}
7119}
7120
7121ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
7122{
7123	USE_OPLINE
7124
7125	SAVE_OPLINE();
7126	zend_verify_abstract_class(Z_CE_P(EX_VAR(opline->op1.var)));
7127	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7128}
7129
7130ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
7131{
7132	USE_OPLINE
7133	int ret;
7134
7135	SAVE_OPLINE();
7136	ret = zend_user_opcode_handlers[opline->opcode](execute_data);
7137	opline = EX(opline);
7138
7139	switch (ret) {
7140		case ZEND_USER_OPCODE_CONTINUE:
7141			ZEND_VM_CONTINUE();
7142		case ZEND_USER_OPCODE_RETURN:
7143			if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
7144				zend_generator *generator = zend_get_running_generator(execute_data);
7145				zend_generator_close(generator, 1);
7146				ZEND_VM_RETURN();
7147			} else {
7148				ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
7149			}
7150		case ZEND_USER_OPCODE_ENTER:
7151			ZEND_VM_ENTER();
7152		case ZEND_USER_OPCODE_LEAVE:
7153			ZEND_VM_LEAVE();
7154		case ZEND_USER_OPCODE_DISPATCH:
7155			ZEND_VM_DISPATCH(opline->opcode, opline);
7156		default:
7157			ZEND_VM_DISPATCH((zend_uchar)(ret & 0xff), opline);
7158	}
7159}
7160
7161ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
7162{