1 /*
2    +----------------------------------------------------------------------+
3    | Zend Engine                                                          |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 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@php.net>                                 |
16    |          Zeev Suraski <zeev@php.net>                                 |
17    |          Dmitry Stogov <dmitry@php.net>                              |
18    +----------------------------------------------------------------------+
19 */
20 
21 /* If you change this file, please regenerate the zend_vm_execute.h and
22  * zend_vm_opcodes.h files by running:
23  * php zend_vm_gen.php
24  */
25 
ZEND_VM_HELPER(zend_add_helper, ANY, ANY, zval *op_1, zval *op_2)26 ZEND_VM_HELPER(zend_add_helper, ANY, ANY, zval *op_1, zval *op_2)
27 {
28 	USE_OPLINE
29 
30 	SAVE_OPLINE();
31 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
32 		op_1 = ZVAL_UNDEFINED_OP1();
33 	}
34 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
35 		op_2 = ZVAL_UNDEFINED_OP2();
36 	}
37 	add_function(EX_VAR(opline->result.var), op_1, op_2);
38 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
39 		zval_ptr_dtor_nogc(op_1);
40 	}
41 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
42 		zval_ptr_dtor_nogc(op_2);
43 	}
44 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
45 }
46 
47 ZEND_VM_HOT_NOCONSTCONST_HANDLER(1, ZEND_ADD, CONST|TMPVARCV, CONST|TMPVARCV)
48 {
49 	USE_OPLINE
50 	zend_free_op free_op1, free_op2;
51 	zval *op1, *op2, *result;
52 	double d1, d2;
53 
54 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
55 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
56 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
57 		/* pass */
58 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
59 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
60 			result = EX_VAR(opline->result.var);
61 			fast_long_add_function(result, op1, op2);
62 			ZEND_VM_NEXT_OPCODE();
63 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
64 			d1 = (double)Z_LVAL_P(op1);
65 			d2 = Z_DVAL_P(op2);
66 			ZEND_VM_C_GOTO(add_double);
67 		}
68 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
69 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
70 			d1 = Z_DVAL_P(op1);
71 			d2 = Z_DVAL_P(op2);
72 ZEND_VM_C_LABEL(add_double):
73 			result = EX_VAR(opline->result.var);
74 			ZVAL_DOUBLE(result, d1 + d2);
75 			ZEND_VM_NEXT_OPCODE();
76 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
77 			d1 = Z_DVAL_P(op1);
78 			d2 = (double)Z_LVAL_P(op2);
79 			ZEND_VM_C_GOTO(add_double);
80 		}
81 	}
82 
83 	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper, op_1, op1, op_2, op2);
84 }
85 
ZEND_VM_HELPER(zend_sub_helper, ANY, ANY, zval *op_1, zval *op_2)86 ZEND_VM_HELPER(zend_sub_helper, ANY, ANY, zval *op_1, zval *op_2)
87 {
88 	USE_OPLINE
89 
90 	SAVE_OPLINE();
91 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
92 		op_1 = ZVAL_UNDEFINED_OP1();
93 	}
94 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
95 		op_2 = ZVAL_UNDEFINED_OP2();
96 	}
97 	sub_function(EX_VAR(opline->result.var), op_1, op_2);
98 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
99 		zval_ptr_dtor_nogc(op_1);
100 	}
101 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
102 		zval_ptr_dtor_nogc(op_2);
103 	}
104 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
105 }
106 
107 ZEND_VM_HOT_NOCONSTCONST_HANDLER(2, ZEND_SUB, CONST|TMPVARCV, CONST|TMPVARCV)
108 {
109 	USE_OPLINE
110 	zend_free_op free_op1, free_op2;
111 	zval *op1, *op2, *result;
112 	double d1, d2;
113 
114 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
115 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
116 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
117 		/* pass */
118 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
119 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
120 			result = EX_VAR(opline->result.var);
121 			fast_long_sub_function(result, op1, op2);
122 			ZEND_VM_NEXT_OPCODE();
123 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
124 			d1 = (double)Z_LVAL_P(op1);
125 			d2 = Z_DVAL_P(op2);
126 			ZEND_VM_C_GOTO(sub_double);
127 		}
128 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
129 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
130 			d1 = Z_DVAL_P(op1);
131 			d2 = Z_DVAL_P(op2);
132 ZEND_VM_C_LABEL(sub_double):
133 			result = EX_VAR(opline->result.var);
134 			ZVAL_DOUBLE(result, d1 - d2);
135 			ZEND_VM_NEXT_OPCODE();
136 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
137 			d1 = Z_DVAL_P(op1);
138 			d2 = (double)Z_LVAL_P(op2);
139 			ZEND_VM_C_GOTO(sub_double);
140 		}
141 	}
142 
143 	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper, op_1, op1, op_2, op2);
144 }
145 
ZEND_VM_HELPER(zend_mul_helper, ANY, ANY, zval *op_1, zval *op_2)146 ZEND_VM_HELPER(zend_mul_helper, ANY, ANY, zval *op_1, zval *op_2)
147 {
148 	USE_OPLINE
149 
150 	SAVE_OPLINE();
151 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
152 		op_1 = ZVAL_UNDEFINED_OP1();
153 	}
154 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
155 		op_2 = ZVAL_UNDEFINED_OP2();
156 	}
157 	mul_function(EX_VAR(opline->result.var), op_1, op_2);
158 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
159 		zval_ptr_dtor_nogc(op_1);
160 	}
161 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
162 		zval_ptr_dtor_nogc(op_2);
163 	}
164 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
165 }
166 
167 ZEND_VM_COLD_CONSTCONST_HANDLER(3, ZEND_MUL, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
168 {
169 	USE_OPLINE
170 	zend_free_op free_op1, free_op2;
171 	zval *op1, *op2, *result;
172 	double d1, d2;
173 
174 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
175 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
176 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
177 		/* pass */
178 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
179 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
180 			zend_long overflow;
181 
182 			result = EX_VAR(opline->result.var);
183 			ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
184 			Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
185 			ZEND_VM_NEXT_OPCODE();
186 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
187 			d1 = (double)Z_LVAL_P(op1);
188 			d2 = Z_DVAL_P(op2);
189 			ZEND_VM_C_GOTO(mul_double);
190 		}
191 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
192 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
193 			d1 = Z_DVAL_P(op1);
194 			d2 = Z_DVAL_P(op2);
195 ZEND_VM_C_LABEL(mul_double):
196 			result = EX_VAR(opline->result.var);
197 			ZVAL_DOUBLE(result, d1 * d2);
198 			ZEND_VM_NEXT_OPCODE();
199 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
200 			d1 = Z_DVAL_P(op1);
201 			d2 = (double)Z_LVAL_P(op2);
202 			ZEND_VM_C_GOTO(mul_double);
203 		}
204 	}
205 
206 	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper, op_1, op1, op_2, op2);
207 }
208 
209 ZEND_VM_COLD_CONSTCONST_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
210 {
211 	USE_OPLINE
212 	zend_free_op free_op1, free_op2;
213 	zval *op1, *op2;
214 
215 	SAVE_OPLINE();
216 	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
217 	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
218 	fast_div_function(EX_VAR(opline->result.var), op1, op2);
219 	FREE_OP1();
220 	FREE_OP2();
221 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
222 }
223 
ZEND_VM_COLD_HELPER(zend_mod_by_zero_helper, ANY, ANY)224 ZEND_VM_COLD_HELPER(zend_mod_by_zero_helper, ANY, ANY)
225 {
226 	USE_OPLINE
227 
228 	SAVE_OPLINE();
229 	zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
230 	ZVAL_UNDEF(EX_VAR(opline->result.var));
231 	HANDLE_EXCEPTION();
232 }
233 
ZEND_VM_HELPER(zend_mod_helper, ANY, ANY, zval *op_1, zval *op_2)234 ZEND_VM_HELPER(zend_mod_helper, ANY, ANY, zval *op_1, zval *op_2)
235 {
236 	USE_OPLINE
237 
238 	SAVE_OPLINE();
239 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
240 		op_1 = ZVAL_UNDEFINED_OP1();
241 	}
242 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
243 		op_2 = ZVAL_UNDEFINED_OP2();
244 	}
245 	mod_function(EX_VAR(opline->result.var), op_1, op_2);
246 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
247 		zval_ptr_dtor_nogc(op_1);
248 	}
249 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
250 		zval_ptr_dtor_nogc(op_2);
251 	}
252 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
253 }
254 
255 ZEND_VM_COLD_CONSTCONST_HANDLER(5, ZEND_MOD, CONST|TMPVARCV, CONST|TMPVARCV)
256 {
257 	USE_OPLINE
258 	zend_free_op free_op1, free_op2;
259 	zval *op1, *op2, *result;
260 
261 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
262 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
263 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
264 		/* pass */
265 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
266 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
267 			result = EX_VAR(opline->result.var);
268 			if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
269 				ZEND_VM_DISPATCH_TO_HELPER(zend_mod_by_zero_helper);
270 			} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
271 				/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
272 				ZVAL_LONG(result, 0);
273 			} else {
274 				ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
275 			}
276 			ZEND_VM_NEXT_OPCODE();
277 		}
278 	}
279 
280 	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper, op_1, op1, op_2, op2);
281 }
282 
ZEND_VM_HELPER(zend_shift_left_helper, ANY, ANY, zval *op_1, zval *op_2)283 ZEND_VM_HELPER(zend_shift_left_helper, ANY, ANY, zval *op_1, zval *op_2)
284 {
285 	USE_OPLINE
286 
287 	SAVE_OPLINE();
288 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
289 		op_1 = ZVAL_UNDEFINED_OP1();
290 	}
291 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
292 		op_2 = ZVAL_UNDEFINED_OP2();
293 	}
294 	shift_left_function(EX_VAR(opline->result.var), op_1, op_2);
295 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
296 		zval_ptr_dtor_nogc(op_1);
297 	}
298 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
299 		zval_ptr_dtor_nogc(op_2);
300 	}
301 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
302 }
303 
304 ZEND_VM_COLD_CONSTCONST_HANDLER(6, ZEND_SL, CONST|TMPVARCV, CONST|TMPVARCV)
305 {
306 	USE_OPLINE
307 	zend_free_op free_op1, free_op2;
308 	zval *op1, *op2;
309 
310 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
311 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
312 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
313 		/* pass */
314 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
315 			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
316 			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
317 		/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
318 		ZVAL_LONG(EX_VAR(opline->result.var),
319 			(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
320 		ZEND_VM_NEXT_OPCODE();
321 	}
322 
323 	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper, op_1, op1, op_2, op2);
324 }
325 
ZEND_VM_HELPER(zend_shift_right_helper, ANY, ANY, zval *op_1, zval *op_2)326 ZEND_VM_HELPER(zend_shift_right_helper, ANY, ANY, zval *op_1, zval *op_2)
327 {
328 	USE_OPLINE
329 
330 	SAVE_OPLINE();
331 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
332 		op_1 = ZVAL_UNDEFINED_OP1();
333 	}
334 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
335 		op_2 = ZVAL_UNDEFINED_OP2();
336 	}
337 	shift_right_function(EX_VAR(opline->result.var), op_1, op_2);
338 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
339 		zval_ptr_dtor_nogc(op_1);
340 	}
341 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
342 		zval_ptr_dtor_nogc(op_2);
343 	}
344 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
345 }
346 
347 ZEND_VM_COLD_CONSTCONST_HANDLER(7, ZEND_SR, CONST|TMPVARCV, CONST|TMPVARCV)
348 {
349 	USE_OPLINE
350 	zend_free_op free_op1, free_op2;
351 	zval *op1, *op2;
352 
353 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
354 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
355 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
356 		/* pass */
357 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
358 			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
359 			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
360 		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2));
361 		ZEND_VM_NEXT_OPCODE();
362 	}
363 
364 	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper, op_1, op1, op_2, op2);
365 }
366 
367 ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
368 {
369 	USE_OPLINE
370 	zend_free_op free_op1, free_op2;
371 	zval *op1, *op2;
372 
373 	SAVE_OPLINE();
374 	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
375 	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
376 	pow_function(EX_VAR(opline->result.var), op1, op2);
377 	FREE_OP1();
378 	FREE_OP2();
379 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
380 }
381 
382 ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_CONST))
383 {
384 	USE_OPLINE
385 	zend_free_op free_op1, free_op2;
386 	zval *op1, *op2;
387 
388 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
389 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
390 
391 	if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
392 	    (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
393 		zend_string *op1_str = Z_STR_P(op1);
394 		zend_string *op2_str = Z_STR_P(op2);
395 		zend_string *str;
396 
397 		if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
398 			if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) {
399 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
400 			} else {
401 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
402 			}
403 			if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
404 				zend_string_release_ex(op1_str, 0);
405 			}
406 		} else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
407 			if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) {
408 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
409 			} else {
410 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
411 			}
412 			if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
413 				zend_string_release_ex(op2_str, 0);
414 			}
415 		} else if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV &&
416 		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
417 		    size_t len = ZSTR_LEN(op1_str);
418 
419 			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
420 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
421 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
422 			if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
423 				zend_string_release_ex(op2_str, 0);
424 			}
425 		} else {
426 			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
427 			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
428 			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
429 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
430 			if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
431 				zend_string_release_ex(op1_str, 0);
432 			}
433 			if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
434 				zend_string_release_ex(op2_str, 0);
435 			}
436 		}
437 		ZEND_VM_NEXT_OPCODE();
438 	} else {
439 		SAVE_OPLINE();
440 
441 		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
442 			op1 = ZVAL_UNDEFINED_OP1();
443 		}
444 		if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
445 			op2 = ZVAL_UNDEFINED_OP2();
446 		}
447 		concat_function(EX_VAR(opline->result.var), op1, op2);
448 		FREE_OP1();
449 		FREE_OP2();
450 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
451 	}
452 }
453 
454 ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
455 {
456 	USE_OPLINE
457 	zend_free_op free_op1, free_op2;
458 	zval *op1, *op2;
459 	zend_bool result;
460 
461 	SAVE_OPLINE();
462 	op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
463 	op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
464 	result = fast_is_identical_function(op1, op2);
465 	FREE_OP1();
466 	FREE_OP2();
467 	ZEND_VM_SMART_BRANCH(result, 1);
468 	ZVAL_BOOL(EX_VAR(opline->result.var), result);
469 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
470 }
471 
472 ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
473 {
474 	USE_OPLINE
475 	zend_free_op free_op1, free_op2;
476 	zval *op1, *op2;
477 	zend_bool result;
478 
479 	SAVE_OPLINE();
480 	op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
481 	op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
482 	result = fast_is_not_identical_function(op1, op2);
483 	FREE_OP1();
484 	FREE_OP2();
485 	ZEND_VM_SMART_BRANCH(result, 1);
486 	ZVAL_BOOL(EX_VAR(opline->result.var), result);
487 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
488 }
489 
ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)490 ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
491 {
492 	USE_OPLINE
493 
494 	SAVE_OPLINE();
495 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
496 		op_1 = ZVAL_UNDEFINED_OP1();
497 	}
498 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
499 		op_2 = ZVAL_UNDEFINED_OP2();
500 	}
501 	compare_function(EX_VAR(opline->result.var), op_1, op_2);
502 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
503 		zval_ptr_dtor_nogc(op_1);
504 	}
505 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
506 		zval_ptr_dtor_nogc(op_2);
507 	}
508 	if (UNEXPECTED(EG(exception))) {
509 		HANDLE_EXCEPTION();
510 	}
511 	if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
512 		ZEND_VM_SMART_BRANCH_TRUE();
513 		ZVAL_TRUE(EX_VAR(opline->result.var));
514 		ZEND_VM_NEXT_OPCODE();
515 	} else {
516 		ZEND_VM_SMART_BRANCH_FALSE();
517 		ZVAL_FALSE(EX_VAR(opline->result.var));
518 		ZEND_VM_NEXT_OPCODE();
519 	}
520 }
521 
522 ZEND_VM_COLD_CONSTCONST_HANDLER(18, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
523 {
524 	USE_OPLINE
525 	zend_free_op free_op1, free_op2;
526 	zval *op1, *op2;
527 	double d1, d2;
528 
529 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
530 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
531 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
532 		/* pass */
533 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
534 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
535 			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
536 ZEND_VM_C_LABEL(is_equal_true):
537 				ZEND_VM_SMART_BRANCH_TRUE();
538 				ZVAL_TRUE(EX_VAR(opline->result.var));
539 				ZEND_VM_NEXT_OPCODE();
540 			} else {
541 ZEND_VM_C_LABEL(is_equal_false):
542 				ZEND_VM_SMART_BRANCH_FALSE();
543 				ZVAL_FALSE(EX_VAR(opline->result.var));
544 				ZEND_VM_NEXT_OPCODE();
545 			}
546 		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
547 			d1 = (double)Z_LVAL_P(op1);
548 			d2 = Z_DVAL_P(op2);
549 			ZEND_VM_C_GOTO(is_equal_double);
550 		}
551 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
552 		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
553 			d1 = Z_DVAL_P(op1);
554 			d2 = Z_DVAL_P(op2);
ZEND_VM_C_LABEL(is_equal_double)555 ZEND_VM_C_LABEL(is_equal_double):
556 			if (d1 == d2) {
557 				ZEND_VM_C_GOTO(is_equal_true);
558 			} else {
559 				ZEND_VM_C_GOTO(is_equal_false);
560 			}
561 		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
562 			d1 = Z_DVAL_P(op1);
563 			d2 = (double)Z_LVAL_P(op2);
564 			ZEND_VM_C_GOTO(is_equal_double);
565 		}
566 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
567 		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
568 			int result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
569 			if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
570 				zval_ptr_dtor_str(op1);
571 			}
572 			if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
573 				zval_ptr_dtor_str(op2);
574 			}
575 			if (result) {
576 				ZEND_VM_C_GOTO(is_equal_true);
577 			} else {
578 				ZEND_VM_C_GOTO(is_equal_false);
579 			}
580 		}
581 	}
582 	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper, op_1, op1, op_2, op2);
583 }
584 
ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)585 ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
586 {
587 	USE_OPLINE
588 
589 	SAVE_OPLINE();
590 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
591 		op_1 = ZVAL_UNDEFINED_OP1();
592 	}
593 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
594 		op_2 = ZVAL_UNDEFINED_OP2();
595 	}
596 	compare_function(EX_VAR(opline->result.var), op_1, op_2);
597 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
598 		zval_ptr_dtor_nogc(op_1);
599 	}
600 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
601 		zval_ptr_dtor_nogc(op_2);
602 	}
603 	if (UNEXPECTED(EG(exception))) {
604 		HANDLE_EXCEPTION();
605 	}
606 	if (Z_LVAL_P(EX_VAR(opline->result.var)) != 0) {
607 		ZEND_VM_SMART_BRANCH_TRUE();
608 		ZVAL_TRUE(EX_VAR(opline->result.var));
609 		ZEND_VM_NEXT_OPCODE();
610 	} else {
611 		ZEND_VM_SMART_BRANCH_FALSE();
612 		ZVAL_FALSE(EX_VAR(opline->result.var));
613 		ZEND_VM_NEXT_OPCODE();
614 	}
615 }
616 
617 ZEND_VM_COLD_CONSTCONST_HANDLER(19, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
618 {
619 	USE_OPLINE
620 	zend_free_op free_op1, free_op2;
621 	zval *op1, *op2;
622 	double d1, d2;
623 
624 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
625 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
626 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
627 		/* pass */
628 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
629 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
630 			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
631 ZEND_VM_C_LABEL(is_not_equal_true):
632 				ZEND_VM_SMART_BRANCH_TRUE();
633 				ZVAL_TRUE(EX_VAR(opline->result.var));
634 				ZEND_VM_NEXT_OPCODE();
635 			} else {
636 ZEND_VM_C_LABEL(is_not_equal_false):
637 				ZEND_VM_SMART_BRANCH_FALSE();
638 				ZVAL_FALSE(EX_VAR(opline->result.var));
639 				ZEND_VM_NEXT_OPCODE();
640 			}
641 		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
642 			d1 = (double)Z_LVAL_P(op1);
643 			d2 = Z_DVAL_P(op2);
644 			ZEND_VM_C_GOTO(is_not_equal_double);
645 		}
646 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
647 		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
648 			d1 = Z_DVAL_P(op1);
649 			d2 = Z_DVAL_P(op2);
ZEND_VM_C_LABEL(is_not_equal_double)650 ZEND_VM_C_LABEL(is_not_equal_double):
651 			if (d1 != d2) {
652 				ZEND_VM_C_GOTO(is_not_equal_true);
653 			} else {
654 				ZEND_VM_C_GOTO(is_not_equal_false);
655 			}
656 		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
657 			d1 = Z_DVAL_P(op1);
658 			d2 = (double)Z_LVAL_P(op2);
659 			ZEND_VM_C_GOTO(is_not_equal_double);
660 		}
661 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
662 		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
663 			int result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
664 			if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
665 				zval_ptr_dtor_str(op1);
666 			}
667 			if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
668 				zval_ptr_dtor_str(op2);
669 			}
670 			if (!result) {
671 				ZEND_VM_C_GOTO(is_not_equal_true);
672 			} else {
673 				ZEND_VM_C_GOTO(is_not_equal_false);
674 			}
675 		}
676 	}
677 	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper, op_1, op1, op_2, op2);
678 }
679 
ZEND_VM_HELPER(zend_is_smaller_helper, ANY, ANY, zval *op_1, zval *op_2)680 ZEND_VM_HELPER(zend_is_smaller_helper, ANY, ANY, zval *op_1, zval *op_2)
681 {
682 	USE_OPLINE
683 
684 	SAVE_OPLINE();
685 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
686 		op_1 = ZVAL_UNDEFINED_OP1();
687 	}
688 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
689 		op_2 = ZVAL_UNDEFINED_OP2();
690 	}
691 	compare_function(EX_VAR(opline->result.var), op_1, op_2);
692 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
693 		zval_ptr_dtor_nogc(op_1);
694 	}
695 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
696 		zval_ptr_dtor_nogc(op_2);
697 	}
698 	if (UNEXPECTED(EG(exception))) {
699 		HANDLE_EXCEPTION();
700 	}
701 	if (Z_LVAL_P(EX_VAR(opline->result.var)) < 0) {
702 		ZEND_VM_SMART_BRANCH_TRUE();
703 		ZVAL_TRUE(EX_VAR(opline->result.var));
704 		ZEND_VM_NEXT_OPCODE();
705 	} else {
706 		ZEND_VM_SMART_BRANCH_FALSE();
707 		ZVAL_FALSE(EX_VAR(opline->result.var));
708 		ZEND_VM_NEXT_OPCODE();
709 	}
710 }
711 
712 ZEND_VM_HOT_NOCONSTCONST_HANDLER(20, ZEND_IS_SMALLER, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH))
713 {
714 	USE_OPLINE
715 	zend_free_op free_op1, free_op2;
716 	zval *op1, *op2;
717 	double d1, d2;
718 
719 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
720 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
721 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
722 		/* pass */
723 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
724 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
725 			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
726 ZEND_VM_C_LABEL(is_smaller_true):
727 				ZEND_VM_SMART_BRANCH_TRUE();
728 				ZVAL_TRUE(EX_VAR(opline->result.var));
729 				ZEND_VM_NEXT_OPCODE();
730 			} else {
731 ZEND_VM_C_LABEL(is_smaller_false):
732 				ZEND_VM_SMART_BRANCH_FALSE();
733 				ZVAL_FALSE(EX_VAR(opline->result.var));
734 				ZEND_VM_NEXT_OPCODE();
735 			}
736 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
737 			d1 = (double)Z_LVAL_P(op1);
738 			d2 = Z_DVAL_P(op2);
739 			ZEND_VM_C_GOTO(is_smaller_double);
740 		}
741 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
742 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
743 			d1 = Z_DVAL_P(op1);
744 			d2 = Z_DVAL_P(op2);
ZEND_VM_C_LABEL(is_smaller_double)745 ZEND_VM_C_LABEL(is_smaller_double):
746 			if (d1 < d2) {
747 				ZEND_VM_C_GOTO(is_smaller_true);
748 			} else {
749 				ZEND_VM_C_GOTO(is_smaller_false);
750 			}
751 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
752 			d1 = Z_DVAL_P(op1);
753 			d2 = (double)Z_LVAL_P(op2);
754 			ZEND_VM_C_GOTO(is_smaller_double);
755 		}
756 	}
757 	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper, op_1, op1, op_2, op2);
758 }
759 
ZEND_VM_HELPER(zend_is_smaller_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2)760 ZEND_VM_HELPER(zend_is_smaller_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
761 {
762 	USE_OPLINE
763 
764 	SAVE_OPLINE();
765 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
766 		op_1 = ZVAL_UNDEFINED_OP1();
767 	}
768 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
769 		op_2 = ZVAL_UNDEFINED_OP2();
770 	}
771 	compare_function(EX_VAR(opline->result.var), op_1, op_2);
772 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
773 		zval_ptr_dtor_nogc(op_1);
774 	}
775 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
776 		zval_ptr_dtor_nogc(op_2);
777 	}
778 	if (UNEXPECTED(EG(exception))) {
779 		HANDLE_EXCEPTION();
780 	}
781 	if (Z_LVAL_P(EX_VAR(opline->result.var)) <= 0) {
782 		ZEND_VM_SMART_BRANCH_TRUE();
783 		ZVAL_TRUE(EX_VAR(opline->result.var));
784 		ZEND_VM_NEXT_OPCODE();
785 	} else {
786 		ZEND_VM_SMART_BRANCH_FALSE();
787 		ZVAL_FALSE(EX_VAR(opline->result.var));
788 		ZEND_VM_NEXT_OPCODE();
789 	}
790 }
791 
792 ZEND_VM_HOT_NOCONSTCONST_HANDLER(21, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH))
793 {
794 	USE_OPLINE
795 	zend_free_op free_op1, free_op2;
796 	zval *op1, *op2;
797 	double d1, d2;
798 
799 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
800 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
801 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
802 		/* pass */
803 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
804 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
805 			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
806 ZEND_VM_C_LABEL(is_smaller_or_equal_true):
807 				ZEND_VM_SMART_BRANCH_TRUE();
808 				ZVAL_TRUE(EX_VAR(opline->result.var));
809 				ZEND_VM_NEXT_OPCODE();
810 			} else {
811 ZEND_VM_C_LABEL(is_smaller_or_equal_false):
812 				ZEND_VM_SMART_BRANCH_FALSE();
813 				ZVAL_FALSE(EX_VAR(opline->result.var));
814 				ZEND_VM_NEXT_OPCODE();
815 			}
816 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
817 			d1 = (double)Z_LVAL_P(op1);
818 			d2 = Z_DVAL_P(op2);
819 			ZEND_VM_C_GOTO(is_smaller_or_equal_double);
820 		}
821 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
822 		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
823 			d1 = Z_DVAL_P(op1);
824 			d2 = Z_DVAL_P(op2);
ZEND_VM_C_LABEL(is_smaller_or_equal_double)825 ZEND_VM_C_LABEL(is_smaller_or_equal_double):
826 			if (d1 <= d2) {
827 				ZEND_VM_C_GOTO(is_smaller_or_equal_true);
828 			} else {
829 				ZEND_VM_C_GOTO(is_smaller_or_equal_false);
830 			}
831 		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
832 			d1 = Z_DVAL_P(op1);
833 			d2 = (double)Z_LVAL_P(op2);
834 			ZEND_VM_C_GOTO(is_smaller_or_equal_double);
835 		}
836 	}
837 	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper, op_1, op1, op_2, op2);
838 }
839 
840 ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
841 {
842 	USE_OPLINE
843 	zend_free_op free_op1, free_op2;
844 	zval *op1, *op2;
845 
846 	SAVE_OPLINE();
847 	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
848 	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
849 	compare_function(EX_VAR(opline->result.var), op1, op2);
850 	FREE_OP1();
851 	FREE_OP2();
852 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
853 }
854 
ZEND_VM_HELPER(zend_bw_or_helper, ANY, ANY, zval *op_1, zval *op_2)855 ZEND_VM_HELPER(zend_bw_or_helper, ANY, ANY, zval *op_1, zval *op_2)
856 {
857 	USE_OPLINE
858 
859 	SAVE_OPLINE();
860 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
861 		op_1 = ZVAL_UNDEFINED_OP1();
862 	}
863 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
864 		op_2 = ZVAL_UNDEFINED_OP2();
865 	}
866 	bitwise_or_function(EX_VAR(opline->result.var), op_1, op_2);
867 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
868 		zval_ptr_dtor_nogc(op_1);
869 	}
870 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
871 		zval_ptr_dtor_nogc(op_2);
872 	}
873 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
874 }
875 
876 ZEND_VM_COLD_CONSTCONST_HANDLER(9, ZEND_BW_OR, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
877 {
878 	USE_OPLINE
879 	zend_free_op free_op1, free_op2;
880 	zval *op1, *op2;
881 
882 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
883 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
884 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
885 		/* pass */
886 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
887 			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
888 		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2));
889 		ZEND_VM_NEXT_OPCODE();
890 	}
891 
892 	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper, op_1, op1, op_2, op2);
893 }
894 
ZEND_VM_HELPER(zend_bw_and_helper, ANY, ANY, zval *op_1, zval *op_2)895 ZEND_VM_HELPER(zend_bw_and_helper, ANY, ANY, zval *op_1, zval *op_2)
896 {
897 	USE_OPLINE
898 
899 	SAVE_OPLINE();
900 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
901 		op_1 = ZVAL_UNDEFINED_OP1();
902 	}
903 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
904 		op_2 = ZVAL_UNDEFINED_OP2();
905 	}
906 	bitwise_and_function(EX_VAR(opline->result.var), op_1, op_2);
907 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
908 		zval_ptr_dtor_nogc(op_1);
909 	}
910 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
911 		zval_ptr_dtor_nogc(op_2);
912 	}
913 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
914 }
915 
916 ZEND_VM_COLD_CONSTCONST_HANDLER(10, ZEND_BW_AND, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
917 {
918 	USE_OPLINE
919 	zend_free_op free_op1, free_op2;
920 	zval *op1, *op2;
921 
922 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
923 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
924 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
925 		/* pass */
926 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
927 			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
928 		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2));
929 		ZEND_VM_NEXT_OPCODE();
930 	}
931 
932 	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper, op_1, op1, op_2, op2);
933 }
934 
ZEND_VM_HELPER(zend_bw_xor_helper, ANY, ANY, zval *op_1, zval *op_2)935 ZEND_VM_HELPER(zend_bw_xor_helper, ANY, ANY, zval *op_1, zval *op_2)
936 {
937 	USE_OPLINE
938 
939 	SAVE_OPLINE();
940 	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
941 		op_1 = ZVAL_UNDEFINED_OP1();
942 	}
943 	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
944 		op_2 = ZVAL_UNDEFINED_OP2();
945 	}
946 	bitwise_xor_function(EX_VAR(opline->result.var), op_1, op_2);
947 	if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
948 		zval_ptr_dtor_nogc(op_1);
949 	}
950 	if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
951 		zval_ptr_dtor_nogc(op_2);
952 	}
953 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
954 }
955 
956 ZEND_VM_COLD_CONSTCONST_HANDLER(11, ZEND_BW_XOR, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
957 {
958 	USE_OPLINE
959 	zend_free_op free_op1, free_op2;
960 	zval *op1, *op2;
961 
962 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
963 	op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
964 	if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
965 		/* pass */
966 	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
967 			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
968 		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
969 		ZEND_VM_NEXT_OPCODE();
970 	}
971 
972 	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper, op_1, op1, op_2, op2);
973 }
974 
975 ZEND_VM_COLD_CONSTCONST_HANDLER(15, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE))
976 {
977 	USE_OPLINE
978 	zend_free_op free_op1, free_op2;
979 	zval *op1, *op2;
980 
981 	SAVE_OPLINE();
982 	op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
983 	op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
984 	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
985 	FREE_OP1();
986 	FREE_OP2();
987 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
988 }
989 
990 ZEND_VM_COLD_CONST_HANDLER(13, ZEND_BW_NOT, CONST|TMPVAR|CV, ANY)
991 {
992 	USE_OPLINE
993 	zend_free_op free_op1;
994 	zval *op1;
995 
996 	op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
997 	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
998 		ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1));
999 		ZEND_VM_NEXT_OPCODE();
1000 	}
1001 
1002 	SAVE_OPLINE();
1003 	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
1004 		op1 = ZVAL_UNDEFINED_OP1();
1005 	}
1006 	bitwise_not_function(EX_VAR(opline->result.var), op1);
1007 	FREE_OP1();
1008 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1009 }
1010 
1011 ZEND_VM_COLD_CONST_HANDLER(14, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
1012 {
1013 	USE_OPLINE
1014 	zval *val;
1015 	zend_free_op free_op1;
1016 
1017 	val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1018 	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
1019 		ZVAL_FALSE(EX_VAR(opline->result.var));
1020 	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
1021 		/* The result and op1 can be the same cv zval */
1022 		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
1023 		ZVAL_TRUE(EX_VAR(opline->result.var));
1024 		if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
1025 			SAVE_OPLINE();
1026 			ZVAL_UNDEFINED_OP1();
1027 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1028 		}
1029 	} else {
1030 		SAVE_OPLINE();
1031 		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
1032 		FREE_OP1();
1033 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1034 	}
1035 	ZEND_VM_NEXT_OPCODE();
1036 }
1037 
ZEND_VM_COLD_HELPER(zend_this_not_in_object_context_helper, ANY, ANY)1038 ZEND_VM_COLD_HELPER(zend_this_not_in_object_context_helper, ANY, ANY)
1039 {
1040 	USE_OPLINE
1041 
1042 	SAVE_OPLINE();
1043 	zend_throw_error(NULL, "Using $this when not in object context");
1044 	if ((opline+1)->opcode == ZEND_OP_DATA) {
1045 		FREE_UNFETCHED_OP_DATA();
1046 	}
1047 	FREE_UNFETCHED_OP2();
1048 	UNDEF_RESULT();
1049 	HANDLE_EXCEPTION();
1050 }
1051 
ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY)1052 ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY)
1053 {
1054 	USE_OPLINE
1055 	zval *function_name;
1056 
1057 	SAVE_OPLINE();
1058 	function_name = RT_CONSTANT(opline, opline->op2);
1059 	zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name));
1060 	HANDLE_EXCEPTION();
1061 }
1062 
1063 ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, OP)
1064 {
1065 	USE_OPLINE
1066 	zend_free_op free_op1, free_op2, free_op_data;
1067 	zval *object;
1068 	zval *property;
1069 	zval *value;
1070 	zval *zptr;
1071 	void **cache_slot;
1072 	zend_property_info *prop_info;
1073 
1074 	SAVE_OPLINE();
1075 	object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1076 
1077 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1078 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
1079 	}
1080 
1081 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1082 
1083 	do {
1084 		value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
1085 
1086 		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1087 			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
1088 				object = Z_REFVAL_P(object);
1089 				ZEND_VM_C_GOTO(assign_op_object);
1090 			}
1091 			if (OP1_TYPE == IS_CV
1092 			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1093 				ZVAL_UNDEFINED_OP1();
1094 			}
1095 			object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
1096 			if (UNEXPECTED(!object)) {
1097 				break;
1098 			}
1099 		}
1100 
1101 ZEND_VM_C_LABEL(assign_op_object):
1102 		/* here we are sure we are dealing with an object */
1103 		cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL;
1104 		if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
1105 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1106 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1107 					ZVAL_NULL(EX_VAR(opline->result.var));
1108 				}
1109 			} else {
1110 				zval *orig_zptr = zptr;
1111 				zend_reference *ref;
1112 
1113 				do {
1114 					if (UNEXPECTED(Z_ISREF_P(zptr))) {
1115 						ref = Z_REF_P(zptr);
1116 						zptr = Z_REFVAL_P(zptr);
1117 						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1118 							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1119 							break;
1120 						}
1121 					}
1122 
1123 					if (OP2_TYPE == IS_CONST) {
1124 						prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
1125 					} else {
1126 						prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr);
1127 					}
1128 					if (UNEXPECTED(prop_info)) {
1129 						/* special case for typed properties */
1130 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
1131 					} else {
1132 						zend_binary_op(zptr, zptr, value OPLINE_CC);
1133 					}
1134 				} while (0);
1135 
1136 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1137 					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
1138 				}
1139 			}
1140 		} else {
1141 			zend_assign_op_overloaded_property(object, property, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
1142 		}
1143 	} while (0);
1144 
1145 	FREE_OP_DATA();
1146 	FREE_OP2();
1147 	FREE_OP1_VAR_PTR();
1148 	/* assign_obj has two opcodes! */
1149 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
1150 }
1151 
1152 /* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
1153 ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
1154 {
1155 	/* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
1156 
1157 	USE_OPLINE
1158 	zend_free_op free_op_data;
1159 	zval *prop, *value;
1160 	zend_property_info *prop_info;
1161 	zend_reference *ref;
1162 
1163 	SAVE_OPLINE();
1164 
1165 	if (UNEXPECTED(zend_fetch_static_property_address(&prop, &prop_info, (opline+1)->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS)) {
1166 		ZEND_ASSERT(EG(exception));
1167 		UNDEF_RESULT();
1168 		FREE_UNFETCHED_OP_DATA();
1169 		HANDLE_EXCEPTION();
1170 	}
1171 
1172 	value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
1173 
1174 	do {
1175 		if (UNEXPECTED(Z_ISREF_P(prop))) {
1176 			ref = Z_REF_P(prop);
1177 			prop = Z_REFVAL_P(prop);
1178 			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1179 				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1180 				break;
1181 			}
1182 		}
1183 
1184 		if (UNEXPECTED(prop_info->type)) {
1185 			/* special case for typed properties */
1186 			zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC);
1187 		} else {
1188 			zend_binary_op(prop, prop, value OPLINE_CC);
1189 		}
1190 	} while (0);
1191 
1192 	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1193 		ZVAL_COPY(EX_VAR(opline->result.var), prop);
1194 	}
1195 
1196 	FREE_OP_DATA();
1197 	/* assign_static_prop has two opcodes! */
1198 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
1199 }
1200 
1201 ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP)
1202 {
1203 	USE_OPLINE
1204 	zend_free_op free_op1, free_op2, free_op_data1;
1205 	zval *var_ptr;
1206 	zval *value, *container, *dim;
1207 
1208 	SAVE_OPLINE();
1209 	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1210 
1211 	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1212 ZEND_VM_C_LABEL(assign_dim_op_array):
1213 		SEPARATE_ARRAY(container);
1214 ZEND_VM_C_LABEL(assign_dim_op_new_array):
1215 		dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1216 		if (OP2_TYPE == IS_UNUSED) {
1217 			var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
1218 			if (UNEXPECTED(!var_ptr)) {
1219 				zend_cannot_add_element();
1220 				ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1221 			}
1222 		} else {
1223 			if (OP2_TYPE == IS_CONST) {
1224 				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
1225 			} else {
1226 				var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
1227 			}
1228 			if (UNEXPECTED(!var_ptr)) {
1229 				ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1230 			}
1231 		}
1232 
1233 		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
1234 
1235 		do {
1236 			if (OP2_TYPE != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
1237 				zend_reference *ref = Z_REF_P(var_ptr);
1238 				var_ptr = Z_REFVAL_P(var_ptr);
1239 				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1240 					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1241 					break;
1242 				}
1243 			}
1244 			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
1245 		} while (0);
1246 
1247 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1248 			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1249 		}
1250 		FREE_OP(free_op_data1);
1251 	} else {
1252 		if (EXPECTED(Z_ISREF_P(container))) {
1253 			container = Z_REFVAL_P(container);
1254 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1255 				ZEND_VM_C_GOTO(assign_dim_op_array);
1256 			}
1257 		}
1258 
1259 		dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
1260 
1261 		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
1262 			if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1263 				dim++;
1264 			}
1265 			zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
1266 		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
1267 			if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
1268 				ZVAL_UNDEFINED_OP1();
1269 			}
1270 			ZVAL_ARR(container, zend_new_array(8));
1271 			ZEND_VM_C_GOTO(assign_dim_op_new_array);
1272 		} else {
1273 			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
1274 ZEND_VM_C_LABEL(assign_dim_op_ret_null):
1275 			FREE_UNFETCHED_OP_DATA();
1276 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1277 				ZVAL_NULL(EX_VAR(opline->result.var));
1278 			}
1279 		}
1280 	}
1281 
1282 	FREE_OP2();
1283 	FREE_OP1_VAR_PTR();
1284 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
1285 }
1286 
1287 ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
1288 {
1289 	USE_OPLINE
1290 	zend_free_op free_op1, free_op2;
1291 	zval *var_ptr;
1292 	zval *value;
1293 
1294 	SAVE_OPLINE();
1295 	value = GET_OP2_ZVAL_PTR(BP_VAR_R);
1296 	var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
1297 
1298 	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1299 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1300 			ZVAL_NULL(EX_VAR(opline->result.var));
1301 		}
1302 	} else {
1303 		do {
1304 			if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1305 				zend_reference *ref = Z_REF_P(var_ptr);
1306 				var_ptr = Z_REFVAL_P(var_ptr);
1307 				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1308 					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1309 					break;
1310 				}
1311 			}
1312 			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
1313 		} while (0);
1314 
1315 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1316 			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1317 		}
1318 	}
1319 
1320 	FREE_OP2();
1321 	FREE_OP1_VAR_PTR();
1322 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1323 }
1324 
1325 ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1326 {
1327 	USE_OPLINE
1328 	zend_free_op free_op1, free_op2;
1329 	zval *object;
1330 	zval *property;
1331 	zval *zptr;
1332 	void **cache_slot;
1333 	zend_property_info *prop_info;
1334 
1335 	SAVE_OPLINE();
1336 	object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1337 
1338 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1339 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
1340 	}
1341 
1342 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1343 
1344 	do {
1345 		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1346 			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
1347 				object = Z_REFVAL_P(object);
1348 				ZEND_VM_C_GOTO(pre_incdec_object);
1349 			}
1350 			if (OP1_TYPE == IS_CV
1351 			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1352 				ZVAL_UNDEFINED_OP1();
1353 			}
1354 			object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
1355 			if (UNEXPECTED(!object)) {
1356 				break;
1357 			}
1358 		}
1359 
1360 ZEND_VM_C_LABEL(pre_incdec_object):
1361 		/* here we are sure we are dealing with an object */
1362 		cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL;
1363 		if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
1364 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1365 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1366 					ZVAL_NULL(EX_VAR(opline->result.var));
1367 				}
1368 			} else {
1369 				if (OP2_TYPE == IS_CONST) {
1370 					prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
1371 				} else {
1372 					prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr);
1373 				}
1374 				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
1375 			}
1376 		} else {
1377 			zend_pre_incdec_overloaded_property(object, property, cache_slot OPLINE_CC EXECUTE_DATA_CC);
1378 		}
1379 	} while (0);
1380 
1381 	FREE_OP2();
1382 	FREE_OP1_VAR_PTR();
1383 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1384 }
1385 
1386 ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1387 {
1388 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_OBJ);
1389 }
1390 
1391 ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1392 {
1393 	USE_OPLINE
1394 	zend_free_op free_op1, free_op2;
1395 	zval *object;
1396 	zval *property;
1397 	zval *zptr;
1398 	void **cache_slot;
1399 	zend_property_info *prop_info;
1400 
1401 	SAVE_OPLINE();
1402 	object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1403 
1404 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1405 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
1406 	}
1407 
1408 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1409 
1410 	do {
1411 		if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1412 			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
1413 				object = Z_REFVAL_P(object);
1414 				ZEND_VM_C_GOTO(post_incdec_object);
1415 			}
1416 			if (OP1_TYPE == IS_CV
1417 			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1418 				ZVAL_UNDEFINED_OP1();
1419 			}
1420 			object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
1421 			if (UNEXPECTED(!object)) {
1422 				break;
1423 			}
1424 		}
1425 
1426 ZEND_VM_C_LABEL(post_incdec_object):
1427 		/* here we are sure we are dealing with an object */
1428 		cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL;
1429 		if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
1430 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1431 				ZVAL_NULL(EX_VAR(opline->result.var));
1432 			} else {
1433 				if (OP2_TYPE == IS_CONST) {
1434 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
1435 				} else {
1436 					prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr);
1437 				}
1438 
1439 				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
1440 			}
1441 		} else {
1442 			zend_post_incdec_overloaded_property(object, property, cache_slot OPLINE_CC EXECUTE_DATA_CC);
1443 		}
1444 	} while (0);
1445 
1446 	FREE_OP2();
1447 	FREE_OP1_VAR_PTR();
1448 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1449 }
1450 
1451 ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1452 {
1453 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_OBJ);
1454 }
1455 
1456 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1457 ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1458 {
1459 	USE_OPLINE
1460 	zval *prop;
1461 	zend_property_info *prop_info;
1462 
1463 	SAVE_OPLINE();
1464 
1465 	if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
1466 		UNDEF_RESULT();
1467 		HANDLE_EXCEPTION();
1468 	}
1469 
1470 	zend_pre_incdec_property_zval(prop, prop_info->type ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
1471 
1472 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1473 }
1474 
1475 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1476 ZEND_VM_HANDLER(39, ZEND_PRE_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1477 {
1478 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_STATIC_PROP);
1479 }
1480 
1481 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1482 ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1483 {
1484 	USE_OPLINE
1485 	zval *prop;
1486 	zend_property_info *prop_info;
1487 
1488 	SAVE_OPLINE();
1489 
1490 	if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
1491 		UNDEF_RESULT();
1492 		HANDLE_EXCEPTION();
1493 	}
1494 
1495 	zend_post_incdec_property_zval(prop, prop_info->type ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
1496 
1497 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1498 }
1499 
1500 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1501 ZEND_VM_HANDLER(41, ZEND_POST_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1502 {
1503 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_STATIC_PROP);
1504 }
1505 
ZEND_VM_HELPER(zend_pre_inc_helper, VAR|CV, ANY)1506 ZEND_VM_HELPER(zend_pre_inc_helper, VAR|CV, ANY)
1507 {
1508 	USE_OPLINE
1509 	zend_free_op free_op1;
1510 	zval *var_ptr;
1511 
1512 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1513 
1514 	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1515 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1516 			ZVAL_NULL(EX_VAR(opline->result.var));
1517 		}
1518 		ZEND_VM_NEXT_OPCODE();
1519 	}
1520 
1521 	SAVE_OPLINE();
1522 	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1523 		ZVAL_NULL(var_ptr);
1524 		ZVAL_UNDEFINED_OP1();
1525 	}
1526 
1527 	do {
1528 		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1529 			zend_reference *ref = Z_REF_P(var_ptr);
1530 			var_ptr = Z_REFVAL_P(var_ptr);
1531 			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1532 				zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
1533 				break;
1534 			}
1535 		}
1536 		increment_function(var_ptr);
1537 	} while (0);
1538 
1539 	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1540 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1541 	}
1542 
1543 	FREE_OP1_VAR_PTR();
1544 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1545 }
1546 
1547 ZEND_VM_HOT_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY, SPEC(RETVAL))
1548 {
1549 	USE_OPLINE
1550 	zend_free_op free_op1;
1551 	zval *var_ptr;
1552 
1553 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1554 
1555 	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1556 		fast_long_increment_function(var_ptr);
1557 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1558 			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1559 		}
1560 		ZEND_VM_NEXT_OPCODE();
1561 	}
1562 
1563 	ZEND_VM_DISPATCH_TO_HELPER(zend_pre_inc_helper);
1564 }
1565 
ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)1566 ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)
1567 {
1568 	USE_OPLINE
1569 	zend_free_op free_op1;
1570 	zval *var_ptr;
1571 
1572 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1573 
1574 	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1575 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1576 			ZVAL_NULL(EX_VAR(opline->result.var));
1577 		}
1578 		ZEND_VM_NEXT_OPCODE();
1579 	}
1580 
1581 	SAVE_OPLINE();
1582 	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1583 		ZVAL_NULL(var_ptr);
1584 		ZVAL_UNDEFINED_OP1();
1585 	}
1586 
1587 	do {
1588 		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1589 			zend_reference *ref = Z_REF_P(var_ptr);
1590 			var_ptr = Z_REFVAL_P(var_ptr);
1591 
1592 			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1593 				zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
1594 				break;
1595 			}
1596 		}
1597 		decrement_function(var_ptr);
1598 	} while (0);
1599 
1600 	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1601 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1602 	}
1603 
1604 	FREE_OP1_VAR_PTR();
1605 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1606 }
1607 
1608 ZEND_VM_HOT_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY, SPEC(RETVAL))
1609 {
1610 	USE_OPLINE
1611 	zend_free_op free_op1;
1612 	zval *var_ptr;
1613 
1614 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1615 
1616 	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1617 		fast_long_decrement_function(var_ptr);
1618 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1619 			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1620 		}
1621 		ZEND_VM_NEXT_OPCODE();
1622 	}
1623 
1624 	ZEND_VM_DISPATCH_TO_HELPER(zend_pre_dec_helper);
1625 }
1626 
ZEND_VM_HELPER(zend_post_inc_helper, VAR|CV, ANY)1627 ZEND_VM_HELPER(zend_post_inc_helper, VAR|CV, ANY)
1628 {
1629 	USE_OPLINE
1630 	zend_free_op free_op1;
1631 	zval *var_ptr;
1632 
1633 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1634 
1635 	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1636 		ZVAL_NULL(EX_VAR(opline->result.var));
1637 		ZEND_VM_NEXT_OPCODE();
1638 	}
1639 
1640 	SAVE_OPLINE();
1641 	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1642 		ZVAL_NULL(var_ptr);
1643 		ZVAL_UNDEFINED_OP1();
1644 	}
1645 
1646 	do {
1647 		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1648 			zend_reference *ref = Z_REF_P(var_ptr);
1649 			var_ptr = Z_REFVAL_P(var_ptr);
1650 
1651 			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1652 				zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
1653 				break;
1654 			}
1655 		}
1656 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1657 
1658 		increment_function(var_ptr);
1659 	} while (0);
1660 
1661 	FREE_OP1_VAR_PTR();
1662 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1663 }
1664 
1665 ZEND_VM_HOT_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
1666 {
1667 	USE_OPLINE
1668 	zend_free_op free_op1;
1669 	zval *var_ptr;
1670 
1671 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1672 
1673 	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1674 		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
1675 		fast_long_increment_function(var_ptr);
1676 		ZEND_VM_NEXT_OPCODE();
1677 	}
1678 
1679 	ZEND_VM_DISPATCH_TO_HELPER(zend_post_inc_helper);
1680 }
1681 
ZEND_VM_HELPER(zend_post_dec_helper, VAR|CV, ANY)1682 ZEND_VM_HELPER(zend_post_dec_helper, VAR|CV, ANY)
1683 {
1684 	USE_OPLINE
1685 	zend_free_op free_op1;
1686 	zval *var_ptr;
1687 
1688 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1689 
1690 	if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1691 		ZVAL_NULL(EX_VAR(opline->result.var));
1692 		ZEND_VM_NEXT_OPCODE();
1693 	}
1694 
1695 	SAVE_OPLINE();
1696 	if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1697 		ZVAL_NULL(var_ptr);
1698 		ZVAL_UNDEFINED_OP1();
1699 	}
1700 
1701 	do {
1702 		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1703 			zend_reference *ref = Z_REF_P(var_ptr);
1704 			var_ptr = Z_REFVAL_P(var_ptr);
1705 
1706 			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1707 				zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
1708 				break;
1709 			}
1710 		}
1711 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1712 
1713 		decrement_function(var_ptr);
1714 	} while (0);
1715 
1716 	FREE_OP1_VAR_PTR();
1717 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1718 }
1719 
1720 ZEND_VM_HOT_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
1721 {
1722 	USE_OPLINE
1723 	zend_free_op free_op1;
1724 	zval *var_ptr;
1725 
1726 	var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1727 
1728 	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1729 		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
1730 		fast_long_decrement_function(var_ptr);
1731 		ZEND_VM_NEXT_OPCODE();
1732 	}
1733 
1734 	ZEND_VM_DISPATCH_TO_HELPER(zend_post_dec_helper);
1735 }
1736 
1737 ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
1738 {
1739 	USE_OPLINE
1740 	zend_free_op free_op1;
1741 	zval *z;
1742 
1743 	SAVE_OPLINE();
1744 	z = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1745 
1746 	if (Z_TYPE_P(z) == IS_STRING) {
1747 		zend_string *str = Z_STR_P(z);
1748 
1749 		if (ZSTR_LEN(str) != 0) {
1750 			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
1751 		}
1752 	} else {
1753 		zend_string *str = zval_get_string_func(z);
1754 
1755 		if (ZSTR_LEN(str) != 0) {
1756 			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
1757 		} else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
1758 			ZVAL_UNDEFINED_OP1();
1759 		}
1760 		zend_string_release_ex(str, 0);
1761 	}
1762 
1763 	FREE_OP1();
1764 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1765 }
1766 
ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)1767 ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
1768 {
1769 	USE_OPLINE
1770 	zend_free_op free_op1;
1771 	zval *varname;
1772 	zval *retval;
1773 	zend_string *name, *tmp_name;
1774 	HashTable *target_symbol_table;
1775 
1776 	SAVE_OPLINE();
1777 	varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1778 
1779 	if (OP1_TYPE == IS_CONST) {
1780 		name = Z_STR_P(varname);
1781 	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
1782 		name = Z_STR_P(varname);
1783 		tmp_name = NULL;
1784 	} else {
1785 		if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
1786 			ZVAL_UNDEFINED_OP1();
1787 		}
1788 		name = zval_try_get_tmp_string(varname, &tmp_name);
1789 		if (UNEXPECTED(!name)) {
1790 			FREE_OP1();
1791 			ZVAL_UNDEF(EX_VAR(opline->result.var));
1792 			HANDLE_EXCEPTION();
1793 		}
1794 	}
1795 
1796 	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
1797 	retval = zend_hash_find_ex(target_symbol_table, name, OP1_TYPE == IS_CONST);
1798 	if (retval == NULL) {
1799 		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
1800 ZEND_VM_C_LABEL(fetch_this):
1801 			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
1802 			if (OP1_TYPE != IS_CONST) {
1803 				zend_tmp_string_release(tmp_name);
1804 			}
1805 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1806 		}
1807 		if (type == BP_VAR_W) {
1808 			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
1809 		} else if (type == BP_VAR_IS) {
1810 			retval = &EG(uninitialized_zval);
1811 		} else {
1812 			zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1813 			if (type == BP_VAR_RW) {
1814 				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
1815 			} else {
1816 				retval = &EG(uninitialized_zval);
1817 			}
1818 		}
1819 	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
1820 	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
1821 		retval = Z_INDIRECT_P(retval);
1822 		if (Z_TYPE_P(retval) == IS_UNDEF) {
1823 			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
1824 				ZEND_VM_C_GOTO(fetch_this);
1825 			}
1826 			if (type == BP_VAR_W) {
1827 				ZVAL_NULL(retval);
1828 			} else if (type == BP_VAR_IS) {
1829 				retval = &EG(uninitialized_zval);
1830 			} else {
1831 				zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1832 				if (type == BP_VAR_RW) {
1833 					ZVAL_NULL(retval);
1834 				} else {
1835 					retval = &EG(uninitialized_zval);
1836 				}
1837 			}
1838 		}
1839 	}
1840 
1841 	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
1842 		FREE_OP1();
1843 	}
1844 
1845 	if (OP1_TYPE != IS_CONST) {
1846 		zend_tmp_string_release(tmp_name);
1847 	}
1848 
1849 	ZEND_ASSERT(retval != NULL);
1850 	if (type == BP_VAR_R || type == BP_VAR_IS) {
1851 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
1852 	} else {
1853 		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
1854 	}
1855 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1856 }
1857 
1858 ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1859 {
1860 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
1861 }
1862 
1863 ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1864 {
1865 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
1866 }
1867 
1868 ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1869 {
1870 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
1871 }
1872 
1873 ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1874 {
1875 	int fetch_type =
1876 		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
1877 			BP_VAR_W : BP_VAR_R;
1878 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, fetch_type);
1879 }
1880 
1881 ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1882 {
1883 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
1884 }
1885 
1886 ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1887 {
1888 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS);
1889 }
1890 
1891 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)1892 ZEND_VM_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
1893 {
1894 	USE_OPLINE
1895 	zval *prop;
1896 
1897 	SAVE_OPLINE();
1898 
1899 	if (UNEXPECTED(zend_fetch_static_property_address(&prop, NULL, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type, opline->extended_value & ZEND_FETCH_OBJ_FLAGS OPLINE_CC EXECUTE_DATA_CC) != SUCCESS)) {
1900 		ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
1901 		prop = &EG(uninitialized_zval);
1902 	}
1903 
1904 	if (type == BP_VAR_R || type == BP_VAR_IS) {
1905 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), prop);
1906 	} else {
1907 		ZVAL_INDIRECT(EX_VAR(opline->result.var), prop);
1908 	}
1909 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1910 }
1911 
1912 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1913 ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, ANY, CLASS_FETCH, CACHE_SLOT)
1914 {
1915 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
1916 }
1917 
1918 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1919 ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, ANY, CLASS_FETCH, FETCH_REF|DIM_OBJ_WRITE|CACHE_SLOT)
1920 {
1921 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
1922 }
1923 
1924 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1925 ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, ANY, CLASS_FETCH, CACHE_SLOT)
1926 {
1927 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
1928 }
1929 
1930 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1931 ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, ANY, CLASS_FETCH, FETCH_REF|CACHE_SLOT)
1932 {
1933 	int fetch_type =
1934 		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
1935 			BP_VAR_W : BP_VAR_R;
1936 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, fetch_type);
1937 }
1938 
1939 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1940 ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, ANY, CLASS_FETCH, CACHE_SLOT)
1941 {
1942 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
1943 }
1944 
1945 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1946 ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, ANY, CLASS_FETCH, CACHE_SLOT)
1947 {
1948 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS);
1949 }
1950 
1951 ZEND_VM_COLD_CONSTCONST_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
1952 {
1953 	USE_OPLINE
1954 	zend_free_op free_op1, free_op2;
1955 	zval *container, *dim, *value;
1956 
1957 	SAVE_OPLINE();
1958 	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1959 	dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1960 	if (OP1_TYPE != IS_CONST) {
1961 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1962 ZEND_VM_C_LABEL(fetch_dim_r_array):
1963 			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, OP2_TYPE, BP_VAR_R EXECUTE_DATA_CC);
1964 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
1965 		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
1966 			container = Z_REFVAL_P(container);
1967 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1968 				ZEND_VM_C_GOTO(fetch_dim_r_array);
1969 			} else {
1970 				ZEND_VM_C_GOTO(fetch_dim_r_slow);
1971 			}
1972 		} else {
ZEND_VM_C_LABEL(fetch_dim_r_slow)1973 ZEND_VM_C_LABEL(fetch_dim_r_slow):
1974 			if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1975 				dim++;
1976 			}
1977 			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
1978 		}
1979 	} else {
1980 		zend_fetch_dimension_address_read_R(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
1981 	}
1982 	FREE_OP2();
1983 	FREE_OP1();
1984 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1985 }
1986 
1987 ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
1988 {
1989 	USE_OPLINE
1990 	zend_free_op free_op1, free_op2;
1991 	zval *container;
1992 
1993 	SAVE_OPLINE();
1994 	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1995 	zend_fetch_dimension_address_W(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
1996 	FREE_OP2();
1997 	if (OP1_TYPE == IS_VAR) {
1998 		zval *result = EX_VAR(opline->result.var);
1999 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2000 	}
2001 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2002 }
2003 
2004 ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
2005 {
2006 	USE_OPLINE
2007 	zend_free_op free_op1, free_op2;
2008 	zval *container;
2009 
2010 	SAVE_OPLINE();
2011 	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
2012 	zend_fetch_dimension_address_RW(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2013 	FREE_OP2();
2014 	if (OP1_TYPE == IS_VAR) {
2015 		zval *result = EX_VAR(opline->result.var);
2016 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2017 	}
2018 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2019 }
2020 
2021 ZEND_VM_COLD_CONSTCONST_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
2022 {
2023 	USE_OPLINE
2024 	zend_free_op free_op1, free_op2;
2025 	zval *container;
2026 
2027 	SAVE_OPLINE();
2028 	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_IS);
2029 	zend_fetch_dimension_address_read_IS(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2030 	FREE_OP2();
2031 	FREE_OP1();
2032 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2033 }
2034 
ZEND_VM_COLD_HELPER(zend_use_tmp_in_write_context_helper, ANY, ANY)2035 ZEND_VM_COLD_HELPER(zend_use_tmp_in_write_context_helper, ANY, ANY)
2036 {
2037 	USE_OPLINE
2038 
2039 	SAVE_OPLINE();
2040 	zend_throw_error(NULL, "Cannot use temporary expression in write context");
2041 	FREE_UNFETCHED_OP2();
2042 	FREE_UNFETCHED_OP1();
2043 	ZVAL_UNDEF(EX_VAR(opline->result.var));
2044 	HANDLE_EXCEPTION();
2045 }
2046 
ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY)2047 ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY)
2048 {
2049 	USE_OPLINE
2050 
2051 	SAVE_OPLINE();
2052 	zend_throw_error(NULL, "Cannot use [] for reading");
2053 	FREE_UNFETCHED_OP2();
2054 	FREE_UNFETCHED_OP1();
2055 	ZVAL_UNDEF(EX_VAR(opline->result.var));
2056 	HANDLE_EXCEPTION();
2057 }
2058 
2059 ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
2060 {
2061 #if !ZEND_VM_SPEC
2062 	USE_OPLINE
2063 #endif
2064 
2065 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
2066         if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
2067 			ZEND_VM_DISPATCH_TO_HELPER(zend_use_tmp_in_write_context_helper);
2068         }
2069 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_W);
2070 	} else {
2071 		if (OP2_TYPE == IS_UNUSED) {
2072 			ZEND_VM_DISPATCH_TO_HELPER(zend_use_undef_in_read_context_helper);
2073 		}
2074 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_R);
2075 	}
2076 }
2077 
2078 ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
2079 {
2080 	USE_OPLINE
2081 	zend_free_op free_op1, free_op2;
2082 	zval *container;
2083 
2084 	SAVE_OPLINE();
2085 	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
2086 	zend_fetch_dimension_address_UNSET(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2087 	FREE_OP2();
2088 	if (OP1_TYPE == IS_VAR) {
2089 		zval *result = EX_VAR(opline->result.var);
2090 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2091 	}
2092 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2093 }
2094 
2095 ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2096 {
2097 	USE_OPLINE
2098 	zend_free_op free_op1;
2099 	zval *container;
2100 	zend_free_op free_op2;
2101 	zval *offset;
2102 	void **cache_slot = NULL;
2103 
2104 	SAVE_OPLINE();
2105 	container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
2106 
2107 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2108 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2109 	}
2110 
2111 	offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2112 
2113 	if (OP1_TYPE == IS_CONST ||
2114 	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
2115 	    do {
2116 			if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
2117 				container = Z_REFVAL_P(container);
2118 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
2119 					break;
2120 				}
2121 			}
2122 			if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2123 				ZVAL_UNDEFINED_OP1();
2124 			}
2125 			if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
2126 				ZVAL_UNDEFINED_OP2();
2127 			}
2128 			zend_wrong_property_read(offset);
2129 			ZVAL_NULL(EX_VAR(opline->result.var));
2130 			ZEND_VM_C_GOTO(fetch_obj_r_finish);
2131 		} while (0);
2132 	}
2133 
2134 	/* here we are sure we are dealing with an object */
2135 	do {
2136 		zend_object *zobj = Z_OBJ_P(container);
2137 		zval *retval;
2138 
2139 		if (OP2_TYPE == IS_CONST) {
2140 			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
2141 
2142 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
2143 				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
2144 
2145 				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2146 					retval = OBJ_PROP(zobj, prop_offset);
2147 					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
2148 						if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2149 							ZEND_VM_C_GOTO(fetch_obj_r_copy);
2150 						} else {
2151 ZEND_VM_C_LABEL(fetch_obj_r_fast_copy):
2152 							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2153 							ZEND_VM_NEXT_OPCODE();
2154 						}
2155 					}
2156 				} else if (EXPECTED(zobj->properties != NULL)) {
2157 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
2158 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
2159 
2160 						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
2161 							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
2162 
2163 							if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
2164 						        (EXPECTED(p->key == Z_STR_P(offset)) ||
2165 						         (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) &&
2166 						          EXPECTED(p->key != NULL) &&
2167 						          EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) {
2168 								retval = &p->val;
2169 								if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2170 									ZEND_VM_C_GOTO(fetch_obj_r_copy);
2171 								} else {
2172 									ZEND_VM_C_GOTO(fetch_obj_r_fast_copy);
2173 								}
2174 							}
2175 						}
2176 						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
2177 					}
2178 					retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1);
2179 					if (EXPECTED(retval)) {
2180 						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
2181 						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
2182 						if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2183 							ZEND_VM_C_GOTO(fetch_obj_r_copy);
2184 						} else {
2185 							ZEND_VM_C_GOTO(fetch_obj_r_fast_copy);
2186 						}
2187 					}
2188 				}
2189 			}
2190 		} else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) {
2191 			ZVAL_UNDEFINED_OP2();
2192 		}
2193 
2194 		retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
2195 
2196 		if (retval != EX_VAR(opline->result.var)) {
2197 ZEND_VM_C_LABEL(fetch_obj_r_copy):
2198 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2199 		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
2200 			zend_unwrap_reference(retval);
2201 		}
2202 	} while (0);
2203 
2204 ZEND_VM_C_LABEL(fetch_obj_r_finish):
2205 	FREE_OP2();
2206 	FREE_OP1();
2207 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2208 }
2209 
2210 ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|DIM_OBJ_WRITE|CACHE_SLOT)
2211 {
2212 	USE_OPLINE
2213 	zend_free_op free_op1, free_op2;
2214 	zval *property, *container, *result;
2215 
2216 	SAVE_OPLINE();
2217 
2218 	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2219 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2220 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2221 	}
2222 
2223 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2224 	result = EX_VAR(opline->result.var);
2225 	zend_fetch_property_address(
2226 		result, container, OP1_TYPE, property, OP2_TYPE,
2227 		((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
2228 		BP_VAR_W, opline->extended_value & ZEND_FETCH_OBJ_FLAGS, 1 OPLINE_CC EXECUTE_DATA_CC);
2229 	FREE_OP2();
2230 	if (OP1_TYPE == IS_VAR) {
2231 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2232 	}
2233 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2234 }
2235 
2236 ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2237 {
2238 	USE_OPLINE
2239 	zend_free_op free_op1, free_op2;
2240 	zval *property, *container, *result;
2241 
2242 	SAVE_OPLINE();
2243 	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
2244 
2245 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2246 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2247 	}
2248 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2249 	result = EX_VAR(opline->result.var);
2250 	zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
2251 	FREE_OP2();
2252 	if (OP1_TYPE == IS_VAR) {
2253 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2254 	}
2255 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2256 }
2257 
2258 ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2259 {
2260 	USE_OPLINE
2261 	zend_free_op free_op1;
2262 	zval *container;
2263 	zend_free_op free_op2;
2264 	zval *offset;
2265 	void **cache_slot = NULL;
2266 
2267 	SAVE_OPLINE();
2268 	container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
2269 
2270 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2271 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2272 	}
2273 
2274 	offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
2275 
2276 	if (OP1_TYPE == IS_CONST ||
2277 	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
2278 		do {
2279 			if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
2280 				container = Z_REFVAL_P(container);
2281 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
2282 					break;
2283 				}
2284 			}
2285 			ZVAL_NULL(EX_VAR(opline->result.var));
2286 			ZEND_VM_C_GOTO(fetch_obj_is_finish);
2287 		} while (0);
2288 	}
2289 
2290 	/* here we are sure we are dealing with an object */
2291 	do {
2292 		zend_object *zobj = Z_OBJ_P(container);
2293 		zval *retval;
2294 
2295 		if (OP2_TYPE == IS_CONST) {
2296 			cache_slot = CACHE_ADDR(opline->extended_value);
2297 
2298 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
2299 				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
2300 
2301 				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2302 					retval = OBJ_PROP(zobj, prop_offset);
2303 					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
2304 						if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2305 							ZEND_VM_C_GOTO(fetch_obj_is_copy);
2306 						} else {
2307 ZEND_VM_C_LABEL(fetch_obj_is_fast_copy):
2308 							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2309 							ZEND_VM_NEXT_OPCODE();
2310 						}
2311 					}
2312 				} else if (EXPECTED(zobj->properties != NULL)) {
2313 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
2314 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
2315 
2316 						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
2317 							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
2318 
2319 							if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
2320 						        (EXPECTED(p->key == Z_STR_P(offset)) ||
2321 						         (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) &&
2322 						          EXPECTED(p->key != NULL) &&
2323 						          EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) {
2324 								retval = &p->val;
2325 								if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2326 									ZEND_VM_C_GOTO(fetch_obj_is_copy);
2327 								} else {
2328 									ZEND_VM_C_GOTO(fetch_obj_is_fast_copy);
2329 								}
2330 							}
2331 						}
2332 						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
2333 					}
2334 					retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1);
2335 					if (EXPECTED(retval)) {
2336 						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
2337 						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
2338 						if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2339 							ZEND_VM_C_GOTO(fetch_obj_is_copy);
2340 						} else {
2341 							ZEND_VM_C_GOTO(fetch_obj_is_fast_copy);
2342 						}
2343 					}
2344 				}
2345 			}
2346 		}
2347 
2348 		retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
2349 
2350 		if (retval != EX_VAR(opline->result.var)) {
2351 ZEND_VM_C_LABEL(fetch_obj_is_copy):
2352 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2353 		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
2354 			zend_unwrap_reference(retval);
2355 		}
2356 	} while (0);
2357 
2358 ZEND_VM_C_LABEL(fetch_obj_is_finish):
2359 	FREE_OP2();
2360 	FREE_OP1();
2361 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2362 }
2363 
2364 ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|CACHE_SLOT)
2365 {
2366 #if !ZEND_VM_SPEC
2367 	USE_OPLINE
2368 #endif
2369 
2370 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
2371 		/* Behave like FETCH_OBJ_W */
2372 		if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
2373 			ZEND_VM_DISPATCH_TO_HELPER(zend_use_tmp_in_write_context_helper);
2374 		}
2375 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_W);
2376 	} else {
2377 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
2378 	}
2379 }
2380 
2381 ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2382 {
2383 	USE_OPLINE
2384 	zend_free_op free_op1, free_op2;
2385 	zval *container, *property, *result;
2386 
2387 	SAVE_OPLINE();
2388 	container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
2389 
2390 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2391 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2392 	}
2393 
2394 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2395 	result = EX_VAR(opline->result.var);
2396 	zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
2397 	FREE_OP2();
2398 	if (OP1_TYPE == IS_VAR) {
2399 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2400 	}
2401 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2402 }
2403 
2404 ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
2405 {
2406 	USE_OPLINE
2407 	zend_free_op free_op1, free_op2;
2408 	zval *container;
2409 
2410 	SAVE_OPLINE();
2411 	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2412 	zend_fetch_dimension_address_LIST_r(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2413 	FREE_OP2();
2414 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2415 }
2416 
2417 ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
2418 {
2419 	USE_OPLINE
2420 	zend_free_op free_op1, free_op2;
2421 	zval *container, *dim;
2422 
2423 	SAVE_OPLINE();
2424 	container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2425 	dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2426 
2427 	if (OP1_TYPE == IS_VAR
2428 		&& Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT
2429 		&& UNEXPECTED(!Z_ISREF_P(container))
2430 	) {
2431 		zend_error(E_NOTICE, "Attempting to set reference to non referenceable value");
2432 		zend_fetch_dimension_address_LIST_r(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2433 	} else {
2434 		zend_fetch_dimension_address_W(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2435 	}
2436 
2437 	FREE_OP2();
2438 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2439 }
2440 
2441 ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2442 {
2443 	USE_OPLINE
2444 	zend_free_op free_op1, free_op2, free_op_data;
2445 	zval *object, *property, *value, tmp;
2446 
2447 	SAVE_OPLINE();
2448 	object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2449 
2450 	if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
2451 		ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2452 	}
2453 
2454 	property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2455 	value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2456 
2457 	if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
2458 		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
2459 			object = Z_REFVAL_P(object);
2460 			ZEND_VM_C_GOTO(assign_object);
2461 		}
2462 		object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
2463 		if (UNEXPECTED(!object)) {
2464 			value = &EG(uninitialized_zval);
2465 			ZEND_VM_C_GOTO(free_and_exit_assign_obj);
2466 		}
2467 	}
2468 
ZEND_VM_C_LABEL(assign_object)2469 ZEND_VM_C_LABEL(assign_object):
2470 	if (OP2_TYPE == IS_CONST &&
2471 	    EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) {
2472 		void **cache_slot = CACHE_ADDR(opline->extended_value);
2473 		uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
2474 		zend_object *zobj = Z_OBJ_P(object);
2475 		zval *property_val;
2476 
2477 		if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2478 			property_val = OBJ_PROP(zobj, prop_offset);
2479 			if (Z_TYPE_P(property_val) != IS_UNDEF) {
2480 				zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
2481 
2482 				if (UNEXPECTED(prop_info != NULL)) {
2483 					zend_uchar orig_type = IS_UNDEF;
2484 
2485 					if (OP_DATA_TYPE == IS_CONST) {
2486 						orig_type = Z_TYPE_P(value);
2487 					}
2488 
2489 					value = zend_assign_to_typed_prop(prop_info, property_val, value EXECUTE_DATA_CC);
2490 
2491 					/* will remain valid, thus no need to check prop_info in future here */
2492 					if (OP_DATA_TYPE == IS_CONST && Z_TYPE_P(value) == orig_type) {
2493 						CACHE_PTR_EX(cache_slot + 2, NULL);
2494 					}
2495 					ZEND_VM_C_GOTO(free_and_exit_assign_obj);
2496 				} else {
2497 ZEND_VM_C_LABEL(fast_assign_obj):
2498 					value = zend_assign_to_variable(property_val, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2499 					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2500 						ZVAL_COPY(EX_VAR(opline->result.var), value);
2501 					}
2502 					ZEND_VM_C_GOTO(exit_assign_obj);
2503 				}
2504 			}
2505 		} else {
2506 			if (EXPECTED(zobj->properties != NULL)) {
2507 				if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
2508 					if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
2509 						GC_DELREF(zobj->properties);
2510 					}
2511 					zobj->properties = zend_array_dup(zobj->properties);
2512 				}
2513 				property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1);
2514 				if (property_val) {
2515 					ZEND_VM_C_GOTO(fast_assign_obj);
2516 				}
2517 			}
2518 
2519 			if (!zobj->ce->__set) {
2520 
2521 				if (EXPECTED(zobj->properties == NULL)) {
2522 					rebuild_object_properties(zobj);
2523 				}
2524 				if (OP_DATA_TYPE == IS_CONST) {
2525 					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
2526 						Z_ADDREF_P(value);
2527 					}
2528 				} else if (OP_DATA_TYPE != IS_TMP_VAR) {
2529 					if (Z_ISREF_P(value)) {
2530 						if (OP_DATA_TYPE == IS_VAR) {
2531 							zend_reference *ref = Z_REF_P(value);
2532 							if (GC_DELREF(ref) == 0) {
2533 								ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
2534 								efree_size(ref, sizeof(zend_reference));
2535 								value = &tmp;
2536 							} else {
2537 								value = Z_REFVAL_P(value);
2538 								Z_TRY_ADDREF_P(value);
2539 							}
2540 						} else {
2541 							value = Z_REFVAL_P(value);
2542 							Z_TRY_ADDREF_P(value);
2543 						}
2544 					} else if (OP_DATA_TYPE == IS_CV) {
2545 						Z_TRY_ADDREF_P(value);
2546 					}
2547 				}
2548 				zend_hash_add_new(zobj->properties, Z_STR_P(property), value);
2549 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2550 					ZVAL_COPY(EX_VAR(opline->result.var), value);
2551 				}
2552 				ZEND_VM_C_GOTO(exit_assign_obj);
2553 			}
2554 		}
2555 	}
2556 
2557 	if (OP_DATA_TYPE == IS_CV || OP_DATA_TYPE == IS_VAR) {
2558 		ZVAL_DEREF(value);
2559 	}
2560 
2561 	value = Z_OBJ_HT_P(object)->write_property(object, property, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
2562 
ZEND_VM_C_LABEL(free_and_exit_assign_obj)2563 ZEND_VM_C_LABEL(free_and_exit_assign_obj):
2564 	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2565 		ZVAL_COPY(EX_VAR(opline->result.var), value);
2566 	}
2567 	FREE_OP_DATA();
2568 ZEND_VM_C_LABEL(exit_assign_obj):
2569 	FREE_OP2();
2570 	FREE_OP1_VAR_PTR();
2571 	/* assign_obj has two opcodes! */
2572 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
2573 }
2574 
2575 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
2576 ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2577 {
2578 	USE_OPLINE
2579 	zend_free_op free_op_data;
2580 	zval *prop, *value;
2581 	zend_property_info