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