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