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