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