1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andi Gutmans <andi@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 | Dmitry Stogov <dmitry@php.net> |
18 +----------------------------------------------------------------------+
19 */
20
21 /* If you change this file, please regenerate the zend_vm_execute.h and
22 * zend_vm_opcodes.h files by running:
23 * php zend_vm_gen.php
24 */
25
ZEND_VM_HELPER(zend_add_helper,ANY,ANY,zval * op_1,zval * op_2)26 ZEND_VM_HELPER(zend_add_helper, ANY, ANY, zval *op_1, zval *op_2)
27 {
28 USE_OPLINE
29
30 SAVE_OPLINE();
31 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
32 op_1 = ZVAL_UNDEFINED_OP1();
33 }
34 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
35 op_2 = ZVAL_UNDEFINED_OP2();
36 }
37 add_function(EX_VAR(opline->result.var), op_1, op_2);
38 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
39 zval_ptr_dtor_nogc(op_1);
40 }
41 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
42 zval_ptr_dtor_nogc(op_2);
43 }
44 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
45 }
46
47 ZEND_VM_HOT_NOCONSTCONST_HANDLER(1, ZEND_ADD, CONST|TMPVARCV, CONST|TMPVARCV)
48 {
49 USE_OPLINE
50 zend_free_op free_op1, free_op2;
51 zval *op1, *op2, *result;
52 double d1, d2;
53
54 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
55 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
56 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
57 /* pass */
58 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
59 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
60 result = EX_VAR(opline->result.var);
61 fast_long_add_function(result, op1, op2);
62 ZEND_VM_NEXT_OPCODE();
63 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
64 d1 = (double)Z_LVAL_P(op1);
65 d2 = Z_DVAL_P(op2);
66 ZEND_VM_C_GOTO(add_double);
67 }
68 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
69 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
70 d1 = Z_DVAL_P(op1);
71 d2 = Z_DVAL_P(op2);
72 ZEND_VM_C_LABEL(add_double):
73 result = EX_VAR(opline->result.var);
74 ZVAL_DOUBLE(result, d1 + d2);
75 ZEND_VM_NEXT_OPCODE();
76 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
77 d1 = Z_DVAL_P(op1);
78 d2 = (double)Z_LVAL_P(op2);
79 ZEND_VM_C_GOTO(add_double);
80 }
81 }
82
83 ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper, op_1, op1, op_2, op2);
84 }
85
ZEND_VM_HELPER(zend_sub_helper,ANY,ANY,zval * op_1,zval * op_2)86 ZEND_VM_HELPER(zend_sub_helper, ANY, ANY, zval *op_1, zval *op_2)
87 {
88 USE_OPLINE
89
90 SAVE_OPLINE();
91 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
92 op_1 = ZVAL_UNDEFINED_OP1();
93 }
94 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
95 op_2 = ZVAL_UNDEFINED_OP2();
96 }
97 sub_function(EX_VAR(opline->result.var), op_1, op_2);
98 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
99 zval_ptr_dtor_nogc(op_1);
100 }
101 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
102 zval_ptr_dtor_nogc(op_2);
103 }
104 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
105 }
106
107 ZEND_VM_HOT_NOCONSTCONST_HANDLER(2, ZEND_SUB, CONST|TMPVARCV, CONST|TMPVARCV)
108 {
109 USE_OPLINE
110 zend_free_op free_op1, free_op2;
111 zval *op1, *op2, *result;
112 double d1, d2;
113
114 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
115 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
116 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
117 /* pass */
118 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
119 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
120 result = EX_VAR(opline->result.var);
121 fast_long_sub_function(result, op1, op2);
122 ZEND_VM_NEXT_OPCODE();
123 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
124 d1 = (double)Z_LVAL_P(op1);
125 d2 = Z_DVAL_P(op2);
126 ZEND_VM_C_GOTO(sub_double);
127 }
128 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
129 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
130 d1 = Z_DVAL_P(op1);
131 d2 = Z_DVAL_P(op2);
132 ZEND_VM_C_LABEL(sub_double):
133 result = EX_VAR(opline->result.var);
134 ZVAL_DOUBLE(result, d1 - d2);
135 ZEND_VM_NEXT_OPCODE();
136 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
137 d1 = Z_DVAL_P(op1);
138 d2 = (double)Z_LVAL_P(op2);
139 ZEND_VM_C_GOTO(sub_double);
140 }
141 }
142
143 ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper, op_1, op1, op_2, op2);
144 }
145
ZEND_VM_HELPER(zend_mul_helper,ANY,ANY,zval * op_1,zval * op_2)146 ZEND_VM_HELPER(zend_mul_helper, ANY, ANY, zval *op_1, zval *op_2)
147 {
148 USE_OPLINE
149
150 SAVE_OPLINE();
151 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
152 op_1 = ZVAL_UNDEFINED_OP1();
153 }
154 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
155 op_2 = ZVAL_UNDEFINED_OP2();
156 }
157 mul_function(EX_VAR(opline->result.var), op_1, op_2);
158 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
159 zval_ptr_dtor_nogc(op_1);
160 }
161 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
162 zval_ptr_dtor_nogc(op_2);
163 }
164 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
165 }
166
167 ZEND_VM_COLD_CONSTCONST_HANDLER(3, ZEND_MUL, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
168 {
169 USE_OPLINE
170 zend_free_op free_op1, free_op2;
171 zval *op1, *op2, *result;
172 double d1, d2;
173
174 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
175 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
176 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
177 /* pass */
178 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
179 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
180 zend_long overflow;
181
182 result = EX_VAR(opline->result.var);
183 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
184 Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
185 ZEND_VM_NEXT_OPCODE();
186 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
187 d1 = (double)Z_LVAL_P(op1);
188 d2 = Z_DVAL_P(op2);
189 ZEND_VM_C_GOTO(mul_double);
190 }
191 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
192 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
193 d1 = Z_DVAL_P(op1);
194 d2 = Z_DVAL_P(op2);
195 ZEND_VM_C_LABEL(mul_double):
196 result = EX_VAR(opline->result.var);
197 ZVAL_DOUBLE(result, d1 * d2);
198 ZEND_VM_NEXT_OPCODE();
199 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
200 d1 = Z_DVAL_P(op1);
201 d2 = (double)Z_LVAL_P(op2);
202 ZEND_VM_C_GOTO(mul_double);
203 }
204 }
205
206 ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper, op_1, op1, op_2, op2);
207 }
208
209 ZEND_VM_COLD_CONSTCONST_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
210 {
211 USE_OPLINE
212 zend_free_op free_op1, free_op2;
213 zval *op1, *op2;
214
215 SAVE_OPLINE();
216 op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
217 op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
218 fast_div_function(EX_VAR(opline->result.var), op1, op2);
219 FREE_OP1();
220 FREE_OP2();
221 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
222 }
223
ZEND_VM_COLD_HELPER(zend_mod_by_zero_helper,ANY,ANY)224 ZEND_VM_COLD_HELPER(zend_mod_by_zero_helper, ANY, ANY)
225 {
226 USE_OPLINE
227
228 SAVE_OPLINE();
229 zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
230 ZVAL_UNDEF(EX_VAR(opline->result.var));
231 HANDLE_EXCEPTION();
232 }
233
ZEND_VM_HELPER(zend_mod_helper,ANY,ANY,zval * op_1,zval * op_2)234 ZEND_VM_HELPER(zend_mod_helper, ANY, ANY, zval *op_1, zval *op_2)
235 {
236 USE_OPLINE
237
238 SAVE_OPLINE();
239 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
240 op_1 = ZVAL_UNDEFINED_OP1();
241 }
242 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
243 op_2 = ZVAL_UNDEFINED_OP2();
244 }
245 mod_function(EX_VAR(opline->result.var), op_1, op_2);
246 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
247 zval_ptr_dtor_nogc(op_1);
248 }
249 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
250 zval_ptr_dtor_nogc(op_2);
251 }
252 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
253 }
254
255 ZEND_VM_COLD_CONSTCONST_HANDLER(5, ZEND_MOD, CONST|TMPVARCV, CONST|TMPVARCV)
256 {
257 USE_OPLINE
258 zend_free_op free_op1, free_op2;
259 zval *op1, *op2, *result;
260
261 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
262 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
263 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
264 /* pass */
265 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
266 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
267 result = EX_VAR(opline->result.var);
268 if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
269 ZEND_VM_DISPATCH_TO_HELPER(zend_mod_by_zero_helper);
270 } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
271 /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
272 ZVAL_LONG(result, 0);
273 } else {
274 ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
275 }
276 ZEND_VM_NEXT_OPCODE();
277 }
278 }
279
280 ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper, op_1, op1, op_2, op2);
281 }
282
ZEND_VM_HELPER(zend_shift_left_helper,ANY,ANY,zval * op_1,zval * op_2)283 ZEND_VM_HELPER(zend_shift_left_helper, ANY, ANY, zval *op_1, zval *op_2)
284 {
285 USE_OPLINE
286
287 SAVE_OPLINE();
288 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
289 op_1 = ZVAL_UNDEFINED_OP1();
290 }
291 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
292 op_2 = ZVAL_UNDEFINED_OP2();
293 }
294 shift_left_function(EX_VAR(opline->result.var), op_1, op_2);
295 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
296 zval_ptr_dtor_nogc(op_1);
297 }
298 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
299 zval_ptr_dtor_nogc(op_2);
300 }
301 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
302 }
303
304 ZEND_VM_COLD_CONSTCONST_HANDLER(6, ZEND_SL, CONST|TMPVARCV, CONST|TMPVARCV)
305 {
306 USE_OPLINE
307 zend_free_op free_op1, free_op2;
308 zval *op1, *op2;
309
310 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
311 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
312 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
313 /* pass */
314 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
315 && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
316 && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
317 /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
318 ZVAL_LONG(EX_VAR(opline->result.var),
319 (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
320 ZEND_VM_NEXT_OPCODE();
321 }
322
323 ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper, op_1, op1, op_2, op2);
324 }
325
ZEND_VM_HELPER(zend_shift_right_helper,ANY,ANY,zval * op_1,zval * op_2)326 ZEND_VM_HELPER(zend_shift_right_helper, ANY, ANY, zval *op_1, zval *op_2)
327 {
328 USE_OPLINE
329
330 SAVE_OPLINE();
331 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
332 op_1 = ZVAL_UNDEFINED_OP1();
333 }
334 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
335 op_2 = ZVAL_UNDEFINED_OP2();
336 }
337 shift_right_function(EX_VAR(opline->result.var), op_1, op_2);
338 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
339 zval_ptr_dtor_nogc(op_1);
340 }
341 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
342 zval_ptr_dtor_nogc(op_2);
343 }
344 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
345 }
346
347 ZEND_VM_COLD_CONSTCONST_HANDLER(7, ZEND_SR, CONST|TMPVARCV, CONST|TMPVARCV)
348 {
349 USE_OPLINE
350 zend_free_op free_op1, free_op2;
351 zval *op1, *op2;
352
353 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
354 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
355 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
356 /* pass */
357 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
358 && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
359 && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
360 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2));
361 ZEND_VM_NEXT_OPCODE();
362 }
363
364 ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper, op_1, op1, op_2, op2);
365 }
366
367 ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
368 {
369 USE_OPLINE
370 zend_free_op free_op1, free_op2;
371 zval *op1, *op2;
372
373 SAVE_OPLINE();
374 op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
375 op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
376 pow_function(EX_VAR(opline->result.var), op1, op2);
377 FREE_OP1();
378 FREE_OP2();
379 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
380 }
381
382 ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_CONST))
383 {
384 USE_OPLINE
385 zend_free_op free_op1, free_op2;
386 zval *op1, *op2;
387
388 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
389 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
390
391 if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
392 (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
393 zend_string *op1_str = Z_STR_P(op1);
394 zend_string *op2_str = Z_STR_P(op2);
395 zend_string *str;
396
397 if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
398 if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) {
399 ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
400 } else {
401 ZVAL_STR(EX_VAR(opline->result.var), op2_str);
402 }
403 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
404 zend_string_release_ex(op1_str, 0);
405 }
406 } else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
407 if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) {
408 ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
409 } else {
410 ZVAL_STR(EX_VAR(opline->result.var), op1_str);
411 }
412 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
413 zend_string_release_ex(op2_str, 0);
414 }
415 } else if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV &&
416 !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
417 size_t len = ZSTR_LEN(op1_str);
418
419 if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
420 zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
421 }
422 str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
423 memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
424 ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
425 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
426 zend_string_release_ex(op2_str, 0);
427 }
428 } else {
429 str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
430 memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
431 memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
432 ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
433 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
434 zend_string_release_ex(op1_str, 0);
435 }
436 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
437 zend_string_release_ex(op2_str, 0);
438 }
439 }
440 ZEND_VM_NEXT_OPCODE();
441 } else {
442 SAVE_OPLINE();
443
444 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
445 op1 = ZVAL_UNDEFINED_OP1();
446 }
447 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
448 op2 = ZVAL_UNDEFINED_OP2();
449 }
450 concat_function(EX_VAR(opline->result.var), op1, op2);
451 FREE_OP1();
452 FREE_OP2();
453 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
454 }
455 }
456
457 ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
458 {
459 USE_OPLINE
460 zend_free_op free_op1, free_op2;
461 zval *op1, *op2;
462 zend_bool result;
463
464 SAVE_OPLINE();
465 op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
466 op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
467 result = fast_is_identical_function(op1, op2);
468 FREE_OP1();
469 FREE_OP2();
470 ZEND_VM_SMART_BRANCH(result, 1);
471 ZVAL_BOOL(EX_VAR(opline->result.var), result);
472 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
473 }
474
475 ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
476 {
477 USE_OPLINE
478 zend_free_op free_op1, free_op2;
479 zval *op1, *op2;
480 zend_bool result;
481
482 SAVE_OPLINE();
483 op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
484 op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
485 result = fast_is_not_identical_function(op1, op2);
486 FREE_OP1();
487 FREE_OP2();
488 ZEND_VM_SMART_BRANCH(result, 1);
489 ZVAL_BOOL(EX_VAR(opline->result.var), result);
490 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
491 }
492
ZEND_VM_HELPER(zend_is_equal_helper,ANY,ANY,zval * op_1,zval * op_2)493 ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
494 {
495 USE_OPLINE
496
497 SAVE_OPLINE();
498 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
499 op_1 = ZVAL_UNDEFINED_OP1();
500 }
501 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
502 op_2 = ZVAL_UNDEFINED_OP2();
503 }
504 compare_function(EX_VAR(opline->result.var), op_1, op_2);
505 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
506 zval_ptr_dtor_nogc(op_1);
507 }
508 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
509 zval_ptr_dtor_nogc(op_2);
510 }
511 if (UNEXPECTED(EG(exception))) {
512 HANDLE_EXCEPTION();
513 }
514 if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
515 ZEND_VM_SMART_BRANCH_TRUE();
516 ZVAL_TRUE(EX_VAR(opline->result.var));
517 ZEND_VM_NEXT_OPCODE();
518 } else {
519 ZEND_VM_SMART_BRANCH_FALSE();
520 ZVAL_FALSE(EX_VAR(opline->result.var));
521 ZEND_VM_NEXT_OPCODE();
522 }
523 }
524
525 ZEND_VM_COLD_CONSTCONST_HANDLER(18, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
526 {
527 USE_OPLINE
528 zend_free_op free_op1, free_op2;
529 zval *op1, *op2;
530 double d1, d2;
531
532 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
533 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
534 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
535 /* pass */
536 } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
537 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
538 if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
539 ZEND_VM_C_LABEL(is_equal_true):
540 ZEND_VM_SMART_BRANCH_TRUE();
541 ZVAL_TRUE(EX_VAR(opline->result.var));
542 ZEND_VM_NEXT_OPCODE();
543 } else {
544 ZEND_VM_C_LABEL(is_equal_false):
545 ZEND_VM_SMART_BRANCH_FALSE();
546 ZVAL_FALSE(EX_VAR(opline->result.var));
547 ZEND_VM_NEXT_OPCODE();
548 }
549 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
550 d1 = (double)Z_LVAL_P(op1);
551 d2 = Z_DVAL_P(op2);
552 ZEND_VM_C_GOTO(is_equal_double);
553 }
554 } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
555 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
556 d1 = Z_DVAL_P(op1);
557 d2 = Z_DVAL_P(op2);
558 ZEND_VM_C_LABEL(is_equal_double):
559 if (d1 == d2) {
560 ZEND_VM_C_GOTO(is_equal_true);
561 } else {
562 ZEND_VM_C_GOTO(is_equal_false);
563 }
564 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
565 d1 = Z_DVAL_P(op1);
566 d2 = (double)Z_LVAL_P(op2);
567 ZEND_VM_C_GOTO(is_equal_double);
568 }
569 } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
570 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
571 int result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
572 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
573 zval_ptr_dtor_str(op1);
574 }
575 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
576 zval_ptr_dtor_str(op2);
577 }
578 if (result) {
579 ZEND_VM_C_GOTO(is_equal_true);
580 } else {
581 ZEND_VM_C_GOTO(is_equal_false);
582 }
583 }
584 }
585 ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper, op_1, op1, op_2, op2);
586 }
587
ZEND_VM_HELPER(zend_is_not_equal_helper,ANY,ANY,zval * op_1,zval * op_2)588 ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
589 {
590 USE_OPLINE
591
592 SAVE_OPLINE();
593 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
594 op_1 = ZVAL_UNDEFINED_OP1();
595 }
596 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
597 op_2 = ZVAL_UNDEFINED_OP2();
598 }
599 compare_function(EX_VAR(opline->result.var), op_1, op_2);
600 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
601 zval_ptr_dtor_nogc(op_1);
602 }
603 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
604 zval_ptr_dtor_nogc(op_2);
605 }
606 if (UNEXPECTED(EG(exception))) {
607 HANDLE_EXCEPTION();
608 }
609 if (Z_LVAL_P(EX_VAR(opline->result.var)) != 0) {
610 ZEND_VM_SMART_BRANCH_TRUE();
611 ZVAL_TRUE(EX_VAR(opline->result.var));
612 ZEND_VM_NEXT_OPCODE();
613 } else {
614 ZEND_VM_SMART_BRANCH_FALSE();
615 ZVAL_FALSE(EX_VAR(opline->result.var));
616 ZEND_VM_NEXT_OPCODE();
617 }
618 }
619
620 ZEND_VM_COLD_CONSTCONST_HANDLER(19, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
621 {
622 USE_OPLINE
623 zend_free_op free_op1, free_op2;
624 zval *op1, *op2;
625 double d1, d2;
626
627 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
628 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
629 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
630 /* pass */
631 } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
632 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
633 if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
634 ZEND_VM_C_LABEL(is_not_equal_true):
635 ZEND_VM_SMART_BRANCH_TRUE();
636 ZVAL_TRUE(EX_VAR(opline->result.var));
637 ZEND_VM_NEXT_OPCODE();
638 } else {
639 ZEND_VM_C_LABEL(is_not_equal_false):
640 ZEND_VM_SMART_BRANCH_FALSE();
641 ZVAL_FALSE(EX_VAR(opline->result.var));
642 ZEND_VM_NEXT_OPCODE();
643 }
644 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
645 d1 = (double)Z_LVAL_P(op1);
646 d2 = Z_DVAL_P(op2);
647 ZEND_VM_C_GOTO(is_not_equal_double);
648 }
649 } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
650 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
651 d1 = Z_DVAL_P(op1);
652 d2 = Z_DVAL_P(op2);
653 ZEND_VM_C_LABEL(is_not_equal_double):
654 if (d1 != d2) {
655 ZEND_VM_C_GOTO(is_not_equal_true);
656 } else {
657 ZEND_VM_C_GOTO(is_not_equal_false);
658 }
659 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
660 d1 = Z_DVAL_P(op1);
661 d2 = (double)Z_LVAL_P(op2);
662 ZEND_VM_C_GOTO(is_not_equal_double);
663 }
664 } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
665 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
666 int result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
667 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
668 zval_ptr_dtor_str(op1);
669 }
670 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
671 zval_ptr_dtor_str(op2);
672 }
673 if (!result) {
674 ZEND_VM_C_GOTO(is_not_equal_true);
675 } else {
676 ZEND_VM_C_GOTO(is_not_equal_false);
677 }
678 }
679 }
680 ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper, op_1, op1, op_2, op2);
681 }
682
ZEND_VM_HELPER(zend_is_smaller_helper,ANY,ANY,zval * op_1,zval * op_2)683 ZEND_VM_HELPER(zend_is_smaller_helper, ANY, ANY, zval *op_1, zval *op_2)
684 {
685 USE_OPLINE
686
687 SAVE_OPLINE();
688 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
689 op_1 = ZVAL_UNDEFINED_OP1();
690 }
691 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
692 op_2 = ZVAL_UNDEFINED_OP2();
693 }
694 compare_function(EX_VAR(opline->result.var), op_1, op_2);
695 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
696 zval_ptr_dtor_nogc(op_1);
697 }
698 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
699 zval_ptr_dtor_nogc(op_2);
700 }
701 if (UNEXPECTED(EG(exception))) {
702 HANDLE_EXCEPTION();
703 }
704 if (Z_LVAL_P(EX_VAR(opline->result.var)) < 0) {
705 ZEND_VM_SMART_BRANCH_TRUE();
706 ZVAL_TRUE(EX_VAR(opline->result.var));
707 ZEND_VM_NEXT_OPCODE();
708 } else {
709 ZEND_VM_SMART_BRANCH_FALSE();
710 ZVAL_FALSE(EX_VAR(opline->result.var));
711 ZEND_VM_NEXT_OPCODE();
712 }
713 }
714
715 ZEND_VM_HOT_NOCONSTCONST_HANDLER(20, ZEND_IS_SMALLER, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH))
716 {
717 USE_OPLINE
718 zend_free_op free_op1, free_op2;
719 zval *op1, *op2;
720 double d1, d2;
721
722 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
723 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
724 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
725 /* pass */
726 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
727 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
728 if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
729 ZEND_VM_C_LABEL(is_smaller_true):
730 ZEND_VM_SMART_BRANCH_TRUE();
731 ZVAL_TRUE(EX_VAR(opline->result.var));
732 ZEND_VM_NEXT_OPCODE();
733 } else {
734 ZEND_VM_C_LABEL(is_smaller_false):
735 ZEND_VM_SMART_BRANCH_FALSE();
736 ZVAL_FALSE(EX_VAR(opline->result.var));
737 ZEND_VM_NEXT_OPCODE();
738 }
739 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
740 d1 = (double)Z_LVAL_P(op1);
741 d2 = Z_DVAL_P(op2);
742 ZEND_VM_C_GOTO(is_smaller_double);
743 }
744 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
745 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
746 d1 = Z_DVAL_P(op1);
747 d2 = Z_DVAL_P(op2);
748 ZEND_VM_C_LABEL(is_smaller_double):
749 if (d1 < d2) {
750 ZEND_VM_C_GOTO(is_smaller_true);
751 } else {
752 ZEND_VM_C_GOTO(is_smaller_false);
753 }
754 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
755 d1 = Z_DVAL_P(op1);
756 d2 = (double)Z_LVAL_P(op2);
757 ZEND_VM_C_GOTO(is_smaller_double);
758 }
759 }
760 ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper, op_1, op1, op_2, op2);
761 }
762
ZEND_VM_HELPER(zend_is_smaller_or_equal_helper,ANY,ANY,zval * op_1,zval * op_2)763 ZEND_VM_HELPER(zend_is_smaller_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
764 {
765 USE_OPLINE
766
767 SAVE_OPLINE();
768 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
769 op_1 = ZVAL_UNDEFINED_OP1();
770 }
771 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
772 op_2 = ZVAL_UNDEFINED_OP2();
773 }
774 compare_function(EX_VAR(opline->result.var), op_1, op_2);
775 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
776 zval_ptr_dtor_nogc(op_1);
777 }
778 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
779 zval_ptr_dtor_nogc(op_2);
780 }
781 if (UNEXPECTED(EG(exception))) {
782 HANDLE_EXCEPTION();
783 }
784 if (Z_LVAL_P(EX_VAR(opline->result.var)) <= 0) {
785 ZEND_VM_SMART_BRANCH_TRUE();
786 ZVAL_TRUE(EX_VAR(opline->result.var));
787 ZEND_VM_NEXT_OPCODE();
788 } else {
789 ZEND_VM_SMART_BRANCH_FALSE();
790 ZVAL_FALSE(EX_VAR(opline->result.var));
791 ZEND_VM_NEXT_OPCODE();
792 }
793 }
794
795 ZEND_VM_HOT_NOCONSTCONST_HANDLER(21, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH))
796 {
797 USE_OPLINE
798 zend_free_op free_op1, free_op2;
799 zval *op1, *op2;
800 double d1, d2;
801
802 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
803 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
804 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
805 /* pass */
806 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
807 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
808 if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
809 ZEND_VM_C_LABEL(is_smaller_or_equal_true):
810 ZEND_VM_SMART_BRANCH_TRUE();
811 ZVAL_TRUE(EX_VAR(opline->result.var));
812 ZEND_VM_NEXT_OPCODE();
813 } else {
814 ZEND_VM_C_LABEL(is_smaller_or_equal_false):
815 ZEND_VM_SMART_BRANCH_FALSE();
816 ZVAL_FALSE(EX_VAR(opline->result.var));
817 ZEND_VM_NEXT_OPCODE();
818 }
819 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
820 d1 = (double)Z_LVAL_P(op1);
821 d2 = Z_DVAL_P(op2);
822 ZEND_VM_C_GOTO(is_smaller_or_equal_double);
823 }
824 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
825 if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
826 d1 = Z_DVAL_P(op1);
827 d2 = Z_DVAL_P(op2);
828 ZEND_VM_C_LABEL(is_smaller_or_equal_double):
829 if (d1 <= d2) {
830 ZEND_VM_C_GOTO(is_smaller_or_equal_true);
831 } else {
832 ZEND_VM_C_GOTO(is_smaller_or_equal_false);
833 }
834 } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
835 d1 = Z_DVAL_P(op1);
836 d2 = (double)Z_LVAL_P(op2);
837 ZEND_VM_C_GOTO(is_smaller_or_equal_double);
838 }
839 }
840 ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper, op_1, op1, op_2, op2);
841 }
842
843 ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
844 {
845 USE_OPLINE
846 zend_free_op free_op1, free_op2;
847 zval *op1, *op2;
848
849 SAVE_OPLINE();
850 op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
851 op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
852 compare_function(EX_VAR(opline->result.var), op1, op2);
853 FREE_OP1();
854 FREE_OP2();
855 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
856 }
857
ZEND_VM_HELPER(zend_bw_or_helper,ANY,ANY,zval * op_1,zval * op_2)858 ZEND_VM_HELPER(zend_bw_or_helper, ANY, ANY, zval *op_1, zval *op_2)
859 {
860 USE_OPLINE
861
862 SAVE_OPLINE();
863 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
864 op_1 = ZVAL_UNDEFINED_OP1();
865 }
866 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
867 op_2 = ZVAL_UNDEFINED_OP2();
868 }
869 bitwise_or_function(EX_VAR(opline->result.var), op_1, op_2);
870 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
871 zval_ptr_dtor_nogc(op_1);
872 }
873 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
874 zval_ptr_dtor_nogc(op_2);
875 }
876 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
877 }
878
879 ZEND_VM_COLD_CONSTCONST_HANDLER(9, ZEND_BW_OR, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
880 {
881 USE_OPLINE
882 zend_free_op free_op1, free_op2;
883 zval *op1, *op2;
884
885 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
886 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
887 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
888 /* pass */
889 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
890 && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
891 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2));
892 ZEND_VM_NEXT_OPCODE();
893 }
894
895 ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper, op_1, op1, op_2, op2);
896 }
897
ZEND_VM_HELPER(zend_bw_and_helper,ANY,ANY,zval * op_1,zval * op_2)898 ZEND_VM_HELPER(zend_bw_and_helper, ANY, ANY, zval *op_1, zval *op_2)
899 {
900 USE_OPLINE
901
902 SAVE_OPLINE();
903 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
904 op_1 = ZVAL_UNDEFINED_OP1();
905 }
906 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
907 op_2 = ZVAL_UNDEFINED_OP2();
908 }
909 bitwise_and_function(EX_VAR(opline->result.var), op_1, op_2);
910 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
911 zval_ptr_dtor_nogc(op_1);
912 }
913 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
914 zval_ptr_dtor_nogc(op_2);
915 }
916 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
917 }
918
919 ZEND_VM_COLD_CONSTCONST_HANDLER(10, ZEND_BW_AND, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
920 {
921 USE_OPLINE
922 zend_free_op free_op1, free_op2;
923 zval *op1, *op2;
924
925 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
926 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
927 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
928 /* pass */
929 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
930 && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
931 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2));
932 ZEND_VM_NEXT_OPCODE();
933 }
934
935 ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper, op_1, op1, op_2, op2);
936 }
937
ZEND_VM_HELPER(zend_bw_xor_helper,ANY,ANY,zval * op_1,zval * op_2)938 ZEND_VM_HELPER(zend_bw_xor_helper, ANY, ANY, zval *op_1, zval *op_2)
939 {
940 USE_OPLINE
941
942 SAVE_OPLINE();
943 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
944 op_1 = ZVAL_UNDEFINED_OP1();
945 }
946 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
947 op_2 = ZVAL_UNDEFINED_OP2();
948 }
949 bitwise_xor_function(EX_VAR(opline->result.var), op_1, op_2);
950 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
951 zval_ptr_dtor_nogc(op_1);
952 }
953 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
954 zval_ptr_dtor_nogc(op_2);
955 }
956 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
957 }
958
959 ZEND_VM_COLD_CONSTCONST_HANDLER(11, ZEND_BW_XOR, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(COMMUTATIVE))
960 {
961 USE_OPLINE
962 zend_free_op free_op1, free_op2;
963 zval *op1, *op2;
964
965 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
966 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
967 if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
968 /* pass */
969 } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
970 && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
971 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
972 ZEND_VM_NEXT_OPCODE();
973 }
974
975 ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper, op_1, op1, op_2, op2);
976 }
977
978 ZEND_VM_COLD_CONSTCONST_HANDLER(15, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE))
979 {
980 USE_OPLINE
981 zend_free_op free_op1, free_op2;
982 zval *op1, *op2;
983
984 SAVE_OPLINE();
985 op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
986 op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
987 boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
988 FREE_OP1();
989 FREE_OP2();
990 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
991 }
992
993 ZEND_VM_COLD_CONST_HANDLER(13, ZEND_BW_NOT, CONST|TMPVAR|CV, ANY)
994 {
995 USE_OPLINE
996 zend_free_op free_op1;
997 zval *op1;
998
999 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1000 if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
1001 ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1));
1002 ZEND_VM_NEXT_OPCODE();
1003 }
1004
1005 SAVE_OPLINE();
1006 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
1007 op1 = ZVAL_UNDEFINED_OP1();
1008 }
1009 bitwise_not_function(EX_VAR(opline->result.var), op1);
1010 FREE_OP1();
1011 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1012 }
1013
1014 ZEND_VM_COLD_CONST_HANDLER(14, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
1015 {
1016 USE_OPLINE
1017 zval *val;
1018 zend_free_op free_op1;
1019
1020 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1021 if (Z_TYPE_INFO_P(val) == IS_TRUE) {
1022 ZVAL_FALSE(EX_VAR(opline->result.var));
1023 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
1024 /* The result and op1 can be the same cv zval */
1025 const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
1026 ZVAL_TRUE(EX_VAR(opline->result.var));
1027 if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
1028 SAVE_OPLINE();
1029 ZVAL_UNDEFINED_OP1();
1030 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1031 }
1032 } else {
1033 SAVE_OPLINE();
1034 ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
1035 FREE_OP1();
1036 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1037 }
1038 ZEND_VM_NEXT_OPCODE();
1039 }
1040
ZEND_VM_COLD_HELPER(zend_this_not_in_object_context_helper,ANY,ANY)1041 ZEND_VM_COLD_HELPER(zend_this_not_in_object_context_helper, ANY, ANY)
1042 {
1043 USE_OPLINE
1044
1045 SAVE_OPLINE();
1046 zend_throw_error(NULL, "Using $this when not in object context");
1047 if ((opline+1)->opcode == ZEND_OP_DATA) {
1048 FREE_UNFETCHED_OP_DATA();
1049 }
1050 FREE_UNFETCHED_OP2();
1051 UNDEF_RESULT();
1052 HANDLE_EXCEPTION();
1053 }
1054
ZEND_VM_COLD_HELPER(zend_undefined_function_helper,ANY,ANY)1055 ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY)
1056 {
1057 USE_OPLINE
1058 zval *function_name;
1059
1060 SAVE_OPLINE();
1061 function_name = RT_CONSTANT(opline, opline->op2);
1062 zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name));
1063 HANDLE_EXCEPTION();
1064 }
1065
1066 ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, OP)
1067 {
1068 USE_OPLINE
1069 zend_free_op free_op1, free_op2, free_op_data;
1070 zval *object;
1071 zval *property;
1072 zval *value;
1073 zval *zptr;
1074 void **cache_slot;
1075 zend_property_info *prop_info;
1076
1077 SAVE_OPLINE();
1078 object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1079
1080 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1081 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
1082 }
1083
1084 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1085
1086 do {
1087 value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
1088
1089 if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1090 if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
1091 object = Z_REFVAL_P(object);
1092 ZEND_VM_C_GOTO(assign_op_object);
1093 }
1094 if (OP1_TYPE == IS_CV
1095 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1096 ZVAL_UNDEFINED_OP1();
1097 }
1098 object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
1099 if (UNEXPECTED(!object)) {
1100 break;
1101 }
1102 }
1103
1104 ZEND_VM_C_LABEL(assign_op_object):
1105 /* here we are sure we are dealing with an object */
1106 cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL;
1107 if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
1108 if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1109 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1110 ZVAL_NULL(EX_VAR(opline->result.var));
1111 }
1112 } else {
1113 zval *orig_zptr = zptr;
1114 zend_reference *ref;
1115
1116 do {
1117 if (UNEXPECTED(Z_ISREF_P(zptr))) {
1118 ref = Z_REF_P(zptr);
1119 zptr = Z_REFVAL_P(zptr);
1120 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1121 zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1122 break;
1123 }
1124 }
1125
1126 if (OP2_TYPE == IS_CONST) {
1127 prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
1128 } else {
1129 prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr);
1130 }
1131 if (UNEXPECTED(prop_info)) {
1132 /* special case for typed properties */
1133 zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
1134 } else {
1135 zend_binary_op(zptr, zptr, value OPLINE_CC);
1136 }
1137 } while (0);
1138
1139 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1140 ZVAL_COPY(EX_VAR(opline->result.var), zptr);
1141 }
1142 }
1143 } else {
1144 zend_assign_op_overloaded_property(object, property, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
1145 }
1146 } while (0);
1147
1148 FREE_OP_DATA();
1149 FREE_OP2();
1150 FREE_OP1_VAR_PTR();
1151 /* assign_obj has two opcodes! */
1152 ZEND_VM_NEXT_OPCODE_EX(1, 2);
1153 }
1154
1155 /* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
1156 ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
1157 {
1158 /* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
1159
1160 USE_OPLINE
1161 zend_free_op free_op_data;
1162 zval *prop, *value;
1163 zend_property_info *prop_info;
1164 zend_reference *ref;
1165
1166 SAVE_OPLINE();
1167
1168 if (UNEXPECTED(zend_fetch_static_property_address(&prop, &prop_info, (opline+1)->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS)) {
1169 ZEND_ASSERT(EG(exception));
1170 UNDEF_RESULT();
1171 FREE_UNFETCHED_OP_DATA();
1172 HANDLE_EXCEPTION();
1173 }
1174
1175 value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
1176
1177 do {
1178 if (UNEXPECTED(Z_ISREF_P(prop))) {
1179 ref = Z_REF_P(prop);
1180 prop = Z_REFVAL_P(prop);
1181 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1182 zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1183 break;
1184 }
1185 }
1186
1187 if (UNEXPECTED(prop_info->type)) {
1188 /* special case for typed properties */
1189 zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC);
1190 } else {
1191 zend_binary_op(prop, prop, value OPLINE_CC);
1192 }
1193 } while (0);
1194
1195 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1196 ZVAL_COPY(EX_VAR(opline->result.var), prop);
1197 }
1198
1199 FREE_OP_DATA();
1200 /* assign_static_prop has two opcodes! */
1201 ZEND_VM_NEXT_OPCODE_EX(1, 2);
1202 }
1203
1204 ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP)
1205 {
1206 USE_OPLINE
1207 zend_free_op free_op1, free_op2, free_op_data1;
1208 zval *var_ptr;
1209 zval *value, *container, *dim;
1210
1211 SAVE_OPLINE();
1212 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1213
1214 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1215 ZEND_VM_C_LABEL(assign_dim_op_array):
1216 SEPARATE_ARRAY(container);
1217 ZEND_VM_C_LABEL(assign_dim_op_new_array):
1218 dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1219 if (OP2_TYPE == IS_UNUSED) {
1220 var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
1221 if (UNEXPECTED(!var_ptr)) {
1222 zend_cannot_add_element();
1223 ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1224 }
1225 } else {
1226 if (OP2_TYPE == IS_CONST) {
1227 var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
1228 } else {
1229 var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
1230 }
1231 if (UNEXPECTED(!var_ptr)) {
1232 ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1233 }
1234 }
1235
1236 value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
1237
1238 do {
1239 if (OP2_TYPE != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
1240 zend_reference *ref = Z_REF_P(var_ptr);
1241 var_ptr = Z_REFVAL_P(var_ptr);
1242 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1243 zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1244 break;
1245 }
1246 }
1247 zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
1248 } while (0);
1249
1250 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1251 ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1252 }
1253 FREE_OP(free_op_data1);
1254 } else {
1255 if (EXPECTED(Z_ISREF_P(container))) {
1256 container = Z_REFVAL_P(container);
1257 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1258 ZEND_VM_C_GOTO(assign_dim_op_array);
1259 }
1260 }
1261
1262 dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
1263
1264 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
1265 if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1266 dim++;
1267 }
1268 zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
1269 } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
1270 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
1271 ZVAL_UNDEFINED_OP1();
1272 }
1273 ZVAL_ARR(container, zend_new_array(8));
1274 ZEND_VM_C_GOTO(assign_dim_op_new_array);
1275 } else {
1276 zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
1277 ZEND_VM_C_LABEL(assign_dim_op_ret_null):
1278 FREE_UNFETCHED_OP_DATA();
1279 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1280 ZVAL_NULL(EX_VAR(opline->result.var));
1281 }
1282 }
1283 }
1284
1285 FREE_OP2();
1286 FREE_OP1_VAR_PTR();
1287 ZEND_VM_NEXT_OPCODE_EX(1, 2);
1288 }
1289
1290 ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
1291 {
1292 USE_OPLINE
1293 zend_free_op free_op1, free_op2;
1294 zval *var_ptr;
1295 zval *value;
1296
1297 SAVE_OPLINE();
1298 value = GET_OP2_ZVAL_PTR(BP_VAR_R);
1299 var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
1300
1301 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1302 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1303 ZVAL_NULL(EX_VAR(opline->result.var));
1304 }
1305 } else {
1306 do {
1307 if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1308 zend_reference *ref = Z_REF_P(var_ptr);
1309 var_ptr = Z_REFVAL_P(var_ptr);
1310 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1311 zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
1312 break;
1313 }
1314 }
1315 zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
1316 } while (0);
1317
1318 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1319 ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1320 }
1321 }
1322
1323 FREE_OP2();
1324 FREE_OP1_VAR_PTR();
1325 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1326 }
1327
1328 ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1329 {
1330 USE_OPLINE
1331 zend_free_op free_op1, free_op2;
1332 zval *object;
1333 zval *property;
1334 zval *zptr;
1335 void **cache_slot;
1336 zend_property_info *prop_info;
1337
1338 SAVE_OPLINE();
1339 object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1340
1341 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1342 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
1343 }
1344
1345 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1346
1347 do {
1348 if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1349 if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
1350 object = Z_REFVAL_P(object);
1351 ZEND_VM_C_GOTO(pre_incdec_object);
1352 }
1353 if (OP1_TYPE == IS_CV
1354 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1355 ZVAL_UNDEFINED_OP1();
1356 }
1357 object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
1358 if (UNEXPECTED(!object)) {
1359 break;
1360 }
1361 }
1362
1363 ZEND_VM_C_LABEL(pre_incdec_object):
1364 /* here we are sure we are dealing with an object */
1365 cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL;
1366 if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
1367 if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1368 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1369 ZVAL_NULL(EX_VAR(opline->result.var));
1370 }
1371 } else {
1372 if (OP2_TYPE == IS_CONST) {
1373 prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
1374 } else {
1375 prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr);
1376 }
1377 zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
1378 }
1379 } else {
1380 zend_pre_incdec_overloaded_property(object, property, cache_slot OPLINE_CC EXECUTE_DATA_CC);
1381 }
1382 } while (0);
1383
1384 FREE_OP2();
1385 FREE_OP1_VAR_PTR();
1386 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1387 }
1388
1389 ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1390 {
1391 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_OBJ);
1392 }
1393
1394 ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1395 {
1396 USE_OPLINE
1397 zend_free_op free_op1, free_op2;
1398 zval *object;
1399 zval *property;
1400 zval *zptr;
1401 void **cache_slot;
1402 zend_property_info *prop_info;
1403
1404 SAVE_OPLINE();
1405 object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1406
1407 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1408 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
1409 }
1410
1411 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1412
1413 do {
1414 if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
1415 if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
1416 object = Z_REFVAL_P(object);
1417 ZEND_VM_C_GOTO(post_incdec_object);
1418 }
1419 if (OP1_TYPE == IS_CV
1420 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
1421 ZVAL_UNDEFINED_OP1();
1422 }
1423 object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
1424 if (UNEXPECTED(!object)) {
1425 break;
1426 }
1427 }
1428
1429 ZEND_VM_C_LABEL(post_incdec_object):
1430 /* here we are sure we are dealing with an object */
1431 cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL;
1432 if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
1433 if (UNEXPECTED(Z_ISERROR_P(zptr))) {
1434 ZVAL_NULL(EX_VAR(opline->result.var));
1435 } else {
1436 if (OP2_TYPE == IS_CONST) {
1437 prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
1438 } else {
1439 prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr);
1440 }
1441
1442 zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
1443 }
1444 } else {
1445 zend_post_incdec_overloaded_property(object, property, cache_slot OPLINE_CC EXECUTE_DATA_CC);
1446 }
1447 } while (0);
1448
1449 FREE_OP2();
1450 FREE_OP1_VAR_PTR();
1451 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1452 }
1453
1454 ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
1455 {
1456 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_OBJ);
1457 }
1458
1459 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1460 ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1461 {
1462 USE_OPLINE
1463 zval *prop;
1464 zend_property_info *prop_info;
1465
1466 SAVE_OPLINE();
1467
1468 if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
1469 UNDEF_RESULT();
1470 HANDLE_EXCEPTION();
1471 }
1472
1473 zend_pre_incdec_property_zval(prop, prop_info->type ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
1474
1475 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1476 }
1477
1478 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1479 ZEND_VM_HANDLER(39, ZEND_PRE_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1480 {
1481 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_STATIC_PROP);
1482 }
1483
1484 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1485 ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1486 {
1487 USE_OPLINE
1488 zval *prop;
1489 zend_property_info *prop_info;
1490
1491 SAVE_OPLINE();
1492
1493 if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
1494 UNDEF_RESULT();
1495 HANDLE_EXCEPTION();
1496 }
1497
1498 zend_post_incdec_property_zval(prop, prop_info->type ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
1499
1500 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1501 }
1502
1503 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
1504 ZEND_VM_HANDLER(41, ZEND_POST_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
1505 {
1506 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_STATIC_PROP);
1507 }
1508
1509 ZEND_VM_HELPER(zend_pre_inc_helper, VAR|CV, ANY)
1510 {
1511 USE_OPLINE
1512 zend_free_op free_op1;
1513 zval *var_ptr;
1514
1515 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1516
1517 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1518 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1519 ZVAL_NULL(EX_VAR(opline->result.var));
1520 }
1521 ZEND_VM_NEXT_OPCODE();
1522 }
1523
1524 SAVE_OPLINE();
1525 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1526 ZVAL_NULL(var_ptr);
1527 ZVAL_UNDEFINED_OP1();
1528 }
1529
1530 do {
1531 if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1532 zend_reference *ref = Z_REF_P(var_ptr);
1533 var_ptr = Z_REFVAL_P(var_ptr);
1534 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1535 zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
1536 break;
1537 }
1538 }
1539 increment_function(var_ptr);
1540 } while (0);
1541
1542 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1543 ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1544 }
1545
1546 FREE_OP1_VAR_PTR();
1547 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1548 }
1549
1550 ZEND_VM_HOT_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY, SPEC(RETVAL))
1551 {
1552 USE_OPLINE
1553 zend_free_op free_op1;
1554 zval *var_ptr;
1555
1556 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1557
1558 if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1559 fast_long_increment_function(var_ptr);
1560 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1561 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1562 }
1563 ZEND_VM_NEXT_OPCODE();
1564 }
1565
1566 ZEND_VM_DISPATCH_TO_HELPER(zend_pre_inc_helper);
1567 }
1568
1569 ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)
1570 {
1571 USE_OPLINE
1572 zend_free_op free_op1;
1573 zval *var_ptr;
1574
1575 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1576
1577 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1578 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1579 ZVAL_NULL(EX_VAR(opline->result.var));
1580 }
1581 ZEND_VM_NEXT_OPCODE();
1582 }
1583
1584 SAVE_OPLINE();
1585 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1586 ZVAL_NULL(var_ptr);
1587 ZVAL_UNDEFINED_OP1();
1588 }
1589
1590 do {
1591 if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1592 zend_reference *ref = Z_REF_P(var_ptr);
1593 var_ptr = Z_REFVAL_P(var_ptr);
1594
1595 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1596 zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
1597 break;
1598 }
1599 }
1600 decrement_function(var_ptr);
1601 } while (0);
1602
1603 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1604 ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1605 }
1606
1607 FREE_OP1_VAR_PTR();
1608 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1609 }
1610
1611 ZEND_VM_HOT_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY, SPEC(RETVAL))
1612 {
1613 USE_OPLINE
1614 zend_free_op free_op1;
1615 zval *var_ptr;
1616
1617 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1618
1619 if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1620 fast_long_decrement_function(var_ptr);
1621 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1622 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
1623 }
1624 ZEND_VM_NEXT_OPCODE();
1625 }
1626
1627 ZEND_VM_DISPATCH_TO_HELPER(zend_pre_dec_helper);
1628 }
1629
1630 ZEND_VM_HELPER(zend_post_inc_helper, VAR|CV, ANY)
1631 {
1632 USE_OPLINE
1633 zend_free_op free_op1;
1634 zval *var_ptr;
1635
1636 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1637
1638 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1639 ZVAL_NULL(EX_VAR(opline->result.var));
1640 ZEND_VM_NEXT_OPCODE();
1641 }
1642
1643 SAVE_OPLINE();
1644 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1645 ZVAL_NULL(var_ptr);
1646 ZVAL_UNDEFINED_OP1();
1647 }
1648
1649 do {
1650 if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1651 zend_reference *ref = Z_REF_P(var_ptr);
1652 var_ptr = Z_REFVAL_P(var_ptr);
1653
1654 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1655 zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
1656 break;
1657 }
1658 }
1659 ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1660
1661 increment_function(var_ptr);
1662 } while (0);
1663
1664 FREE_OP1_VAR_PTR();
1665 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1666 }
1667
1668 ZEND_VM_HOT_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
1669 {
1670 USE_OPLINE
1671 zend_free_op free_op1;
1672 zval *var_ptr;
1673
1674 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1675
1676 if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1677 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
1678 fast_long_increment_function(var_ptr);
1679 ZEND_VM_NEXT_OPCODE();
1680 }
1681
1682 ZEND_VM_DISPATCH_TO_HELPER(zend_post_inc_helper);
1683 }
1684
1685 ZEND_VM_HELPER(zend_post_dec_helper, VAR|CV, ANY)
1686 {
1687 USE_OPLINE
1688 zend_free_op free_op1;
1689 zval *var_ptr;
1690
1691 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1692
1693 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
1694 ZVAL_NULL(EX_VAR(opline->result.var));
1695 ZEND_VM_NEXT_OPCODE();
1696 }
1697
1698 SAVE_OPLINE();
1699 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
1700 ZVAL_NULL(var_ptr);
1701 ZVAL_UNDEFINED_OP1();
1702 }
1703
1704 do {
1705 if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
1706 zend_reference *ref = Z_REF_P(var_ptr);
1707 var_ptr = Z_REFVAL_P(var_ptr);
1708
1709 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1710 zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
1711 break;
1712 }
1713 }
1714 ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
1715
1716 decrement_function(var_ptr);
1717 } while (0);
1718
1719 FREE_OP1_VAR_PTR();
1720 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1721 }
1722
1723 ZEND_VM_HOT_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
1724 {
1725 USE_OPLINE
1726 zend_free_op free_op1;
1727 zval *var_ptr;
1728
1729 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
1730
1731 if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
1732 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
1733 fast_long_decrement_function(var_ptr);
1734 ZEND_VM_NEXT_OPCODE();
1735 }
1736
1737 ZEND_VM_DISPATCH_TO_HELPER(zend_post_dec_helper);
1738 }
1739
1740 ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
1741 {
1742 USE_OPLINE
1743 zend_free_op free_op1;
1744 zval *z;
1745
1746 SAVE_OPLINE();
1747 z = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1748
1749 if (Z_TYPE_P(z) == IS_STRING) {
1750 zend_string *str = Z_STR_P(z);
1751
1752 if (ZSTR_LEN(str) != 0) {
1753 zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
1754 }
1755 } else {
1756 zend_string *str = zval_get_string_func(z);
1757
1758 if (ZSTR_LEN(str) != 0) {
1759 zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
1760 } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
1761 ZVAL_UNDEFINED_OP1();
1762 }
1763 zend_string_release_ex(str, 0);
1764 }
1765
1766 FREE_OP1();
1767 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1768 }
1769
1770 ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
1771 {
1772 USE_OPLINE
1773 zend_free_op free_op1;
1774 zval *varname;
1775 zval *retval;
1776 zend_string *name, *tmp_name;
1777 HashTable *target_symbol_table;
1778
1779 SAVE_OPLINE();
1780 varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1781
1782 if (OP1_TYPE == IS_CONST) {
1783 name = Z_STR_P(varname);
1784 } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
1785 name = Z_STR_P(varname);
1786 tmp_name = NULL;
1787 } else {
1788 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
1789 ZVAL_UNDEFINED_OP1();
1790 }
1791 name = zval_try_get_tmp_string(varname, &tmp_name);
1792 if (UNEXPECTED(!name)) {
1793 FREE_OP1();
1794 ZVAL_UNDEF(EX_VAR(opline->result.var));
1795 HANDLE_EXCEPTION();
1796 }
1797 }
1798
1799 target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
1800 retval = zend_hash_find_ex(target_symbol_table, name, OP1_TYPE == IS_CONST);
1801 if (retval == NULL) {
1802 if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
1803 ZEND_VM_C_LABEL(fetch_this):
1804 zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
1805 if (OP1_TYPE != IS_CONST) {
1806 zend_tmp_string_release(tmp_name);
1807 }
1808 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1809 }
1810 if (type == BP_VAR_W) {
1811 retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
1812 } else if (type == BP_VAR_IS) {
1813 retval = &EG(uninitialized_zval);
1814 } else {
1815 zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1816 if (type == BP_VAR_RW) {
1817 retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
1818 } else {
1819 retval = &EG(uninitialized_zval);
1820 }
1821 }
1822 /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
1823 } else if (Z_TYPE_P(retval) == IS_INDIRECT) {
1824 retval = Z_INDIRECT_P(retval);
1825 if (Z_TYPE_P(retval) == IS_UNDEF) {
1826 if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
1827 ZEND_VM_C_GOTO(fetch_this);
1828 }
1829 if (type == BP_VAR_W) {
1830 ZVAL_NULL(retval);
1831 } else if (type == BP_VAR_IS) {
1832 retval = &EG(uninitialized_zval);
1833 } else {
1834 zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
1835 if (type == BP_VAR_RW) {
1836 ZVAL_NULL(retval);
1837 } else {
1838 retval = &EG(uninitialized_zval);
1839 }
1840 }
1841 }
1842 }
1843
1844 if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
1845 FREE_OP1();
1846 }
1847
1848 if (OP1_TYPE != IS_CONST) {
1849 zend_tmp_string_release(tmp_name);
1850 }
1851
1852 ZEND_ASSERT(retval != NULL);
1853 if (type == BP_VAR_R || type == BP_VAR_IS) {
1854 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
1855 } else {
1856 ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
1857 }
1858 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1859 }
1860
1861 ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1862 {
1863 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
1864 }
1865
1866 ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1867 {
1868 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
1869 }
1870
1871 ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1872 {
1873 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
1874 }
1875
1876 ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1877 {
1878 int fetch_type =
1879 (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
1880 BP_VAR_W : BP_VAR_R;
1881 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, fetch_type);
1882 }
1883
1884 ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1885 {
1886 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
1887 }
1888
1889 ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
1890 {
1891 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS);
1892 }
1893
1894 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HELPER(zend_fetch_static_prop_helper,ANY,ANY,int type)1895 ZEND_VM_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
1896 {
1897 USE_OPLINE
1898 zval *prop;
1899
1900 SAVE_OPLINE();
1901
1902 if (UNEXPECTED(zend_fetch_static_property_address(&prop, NULL, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type, opline->extended_value & ZEND_FETCH_OBJ_FLAGS OPLINE_CC EXECUTE_DATA_CC) != SUCCESS)) {
1903 ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
1904 prop = &EG(uninitialized_zval);
1905 }
1906
1907 if (type == BP_VAR_R || type == BP_VAR_IS) {
1908 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), prop);
1909 } else {
1910 ZVAL_INDIRECT(EX_VAR(opline->result.var), prop);
1911 }
1912 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1913 }
1914
1915 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1916 ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, ANY, CLASS_FETCH, CACHE_SLOT)
1917 {
1918 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
1919 }
1920
1921 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1922 ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, ANY, CLASS_FETCH, FETCH_REF|DIM_OBJ_WRITE|CACHE_SLOT)
1923 {
1924 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
1925 }
1926
1927 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1928 ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, ANY, CLASS_FETCH, CACHE_SLOT)
1929 {
1930 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
1931 }
1932
1933 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1934 ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, ANY, CLASS_FETCH, FETCH_REF|CACHE_SLOT)
1935 {
1936 int fetch_type =
1937 (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
1938 BP_VAR_W : BP_VAR_R;
1939 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, fetch_type);
1940 }
1941
1942 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1943 ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, ANY, CLASS_FETCH, CACHE_SLOT)
1944 {
1945 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
1946 }
1947
1948 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
1949 ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, ANY, CLASS_FETCH, CACHE_SLOT)
1950 {
1951 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS);
1952 }
1953
1954 ZEND_VM_COLD_CONSTCONST_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
1955 {
1956 USE_OPLINE
1957 zend_free_op free_op1, free_op2;
1958 zval *container, *dim, *value;
1959
1960 SAVE_OPLINE();
1961 container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1962 dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1963 if (OP1_TYPE != IS_CONST) {
1964 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1965 ZEND_VM_C_LABEL(fetch_dim_r_array):
1966 value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, OP2_TYPE, BP_VAR_R EXECUTE_DATA_CC);
1967 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
1968 } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
1969 container = Z_REFVAL_P(container);
1970 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1971 ZEND_VM_C_GOTO(fetch_dim_r_array);
1972 } else {
1973 ZEND_VM_C_GOTO(fetch_dim_r_slow);
1974 }
1975 } else {
1976 ZEND_VM_C_LABEL(fetch_dim_r_slow):
1977 if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1978 dim++;
1979 }
1980 zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
1981 }
1982 } else {
1983 zend_fetch_dimension_address_read_R(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
1984 }
1985 FREE_OP2();
1986 FREE_OP1();
1987 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1988 }
1989
1990 ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
1991 {
1992 USE_OPLINE
1993 zend_free_op free_op1, free_op2;
1994 zval *container;
1995
1996 SAVE_OPLINE();
1997 container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
1998 zend_fetch_dimension_address_W(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
1999 FREE_OP2();
2000 if (OP1_TYPE == IS_VAR) {
2001 zval *result = EX_VAR(opline->result.var);
2002 FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2003 }
2004 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2005 }
2006
2007 ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
2008 {
2009 USE_OPLINE
2010 zend_free_op free_op1, free_op2;
2011 zval *container;
2012
2013 SAVE_OPLINE();
2014 container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
2015 zend_fetch_dimension_address_RW(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2016 FREE_OP2();
2017 if (OP1_TYPE == IS_VAR) {
2018 zval *result = EX_VAR(opline->result.var);
2019 FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2020 }
2021 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2022 }
2023
2024 ZEND_VM_COLD_CONSTCONST_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
2025 {
2026 USE_OPLINE
2027 zend_free_op free_op1, free_op2;
2028 zval *container;
2029
2030 SAVE_OPLINE();
2031 container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_IS);
2032 zend_fetch_dimension_address_read_IS(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2033 FREE_OP2();
2034 FREE_OP1();
2035 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2036 }
2037
ZEND_VM_COLD_HELPER(zend_use_tmp_in_write_context_helper,ANY,ANY)2038 ZEND_VM_COLD_HELPER(zend_use_tmp_in_write_context_helper, ANY, ANY)
2039 {
2040 USE_OPLINE
2041
2042 SAVE_OPLINE();
2043 zend_throw_error(NULL, "Cannot use temporary expression in write context");
2044 FREE_UNFETCHED_OP2();
2045 FREE_UNFETCHED_OP1();
2046 ZVAL_UNDEF(EX_VAR(opline->result.var));
2047 HANDLE_EXCEPTION();
2048 }
2049
ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper,ANY,ANY)2050 ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY)
2051 {
2052 USE_OPLINE
2053
2054 SAVE_OPLINE();
2055 zend_throw_error(NULL, "Cannot use [] for reading");
2056 FREE_UNFETCHED_OP2();
2057 FREE_UNFETCHED_OP1();
2058 ZVAL_UNDEF(EX_VAR(opline->result.var));
2059 HANDLE_EXCEPTION();
2060 }
2061
2062 ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
2063 {
2064 #if !ZEND_VM_SPEC
2065 USE_OPLINE
2066 #endif
2067
2068 if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
2069 if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
2070 ZEND_VM_DISPATCH_TO_HELPER(zend_use_tmp_in_write_context_helper);
2071 }
2072 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_W);
2073 } else {
2074 if (OP2_TYPE == IS_UNUSED) {
2075 ZEND_VM_DISPATCH_TO_HELPER(zend_use_undef_in_read_context_helper);
2076 }
2077 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_R);
2078 }
2079 }
2080
2081 ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
2082 {
2083 USE_OPLINE
2084 zend_free_op free_op1, free_op2;
2085 zval *container;
2086
2087 SAVE_OPLINE();
2088 container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
2089 zend_fetch_dimension_address_UNSET(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2090 FREE_OP2();
2091 if (OP1_TYPE == IS_VAR) {
2092 zval *result = EX_VAR(opline->result.var);
2093 FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2094 }
2095 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2096 }
2097
2098 ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2099 {
2100 USE_OPLINE
2101 zend_free_op free_op1;
2102 zval *container;
2103 zend_free_op free_op2;
2104 zval *offset;
2105 void **cache_slot = NULL;
2106
2107 SAVE_OPLINE();
2108 container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
2109
2110 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2111 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2112 }
2113
2114 offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2115
2116 if (OP1_TYPE == IS_CONST ||
2117 (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
2118 do {
2119 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
2120 container = Z_REFVAL_P(container);
2121 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
2122 break;
2123 }
2124 }
2125 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2126 ZVAL_UNDEFINED_OP1();
2127 }
2128 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
2129 ZVAL_UNDEFINED_OP2();
2130 }
2131 zend_wrong_property_read(offset);
2132 ZVAL_NULL(EX_VAR(opline->result.var));
2133 ZEND_VM_C_GOTO(fetch_obj_r_finish);
2134 } while (0);
2135 }
2136
2137 /* here we are sure we are dealing with an object */
2138 do {
2139 zend_object *zobj = Z_OBJ_P(container);
2140 zval *retval;
2141
2142 if (OP2_TYPE == IS_CONST) {
2143 cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
2144
2145 if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
2146 uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
2147
2148 if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2149 retval = OBJ_PROP(zobj, prop_offset);
2150 if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
2151 if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2152 ZEND_VM_C_GOTO(fetch_obj_r_copy);
2153 } else {
2154 ZEND_VM_C_LABEL(fetch_obj_r_fast_copy):
2155 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2156 ZEND_VM_NEXT_OPCODE();
2157 }
2158 }
2159 } else if (EXPECTED(zobj->properties != NULL)) {
2160 if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
2161 uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
2162
2163 if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
2164 Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
2165
2166 if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
2167 (EXPECTED(p->key == Z_STR_P(offset)) ||
2168 (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) &&
2169 EXPECTED(p->key != NULL) &&
2170 EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) {
2171 retval = &p->val;
2172 if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2173 ZEND_VM_C_GOTO(fetch_obj_r_copy);
2174 } else {
2175 ZEND_VM_C_GOTO(fetch_obj_r_fast_copy);
2176 }
2177 }
2178 }
2179 CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
2180 }
2181 retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1);
2182 if (EXPECTED(retval)) {
2183 uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
2184 CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
2185 if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2186 ZEND_VM_C_GOTO(fetch_obj_r_copy);
2187 } else {
2188 ZEND_VM_C_GOTO(fetch_obj_r_fast_copy);
2189 }
2190 }
2191 }
2192 }
2193 } else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) {
2194 ZVAL_UNDEFINED_OP2();
2195 }
2196
2197 retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
2198
2199 if (retval != EX_VAR(opline->result.var)) {
2200 ZEND_VM_C_LABEL(fetch_obj_r_copy):
2201 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2202 } else if (UNEXPECTED(Z_ISREF_P(retval))) {
2203 zend_unwrap_reference(retval);
2204 }
2205 } while (0);
2206
2207 ZEND_VM_C_LABEL(fetch_obj_r_finish):
2208 FREE_OP2();
2209 FREE_OP1();
2210 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2211 }
2212
2213 ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|DIM_OBJ_WRITE|CACHE_SLOT)
2214 {
2215 USE_OPLINE
2216 zend_free_op free_op1, free_op2;
2217 zval *property, *container, *result;
2218
2219 SAVE_OPLINE();
2220
2221 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2222 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2223 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2224 }
2225
2226 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2227 result = EX_VAR(opline->result.var);
2228 zend_fetch_property_address(
2229 result, container, OP1_TYPE, property, OP2_TYPE,
2230 ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
2231 BP_VAR_W, opline->extended_value & ZEND_FETCH_OBJ_FLAGS, 1 OPLINE_CC EXECUTE_DATA_CC);
2232 FREE_OP2();
2233 if (OP1_TYPE == IS_VAR) {
2234 FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2235 }
2236 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2237 }
2238
2239 ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2240 {
2241 USE_OPLINE
2242 zend_free_op free_op1, free_op2;
2243 zval *property, *container, *result;
2244
2245 SAVE_OPLINE();
2246 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
2247
2248 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2249 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2250 }
2251 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2252 result = EX_VAR(opline->result.var);
2253 zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
2254 FREE_OP2();
2255 if (OP1_TYPE == IS_VAR) {
2256 FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2257 }
2258 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2259 }
2260
2261 ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2262 {
2263 USE_OPLINE
2264 zend_free_op free_op1;
2265 zval *container;
2266 zend_free_op free_op2;
2267 zval *offset;
2268 void **cache_slot = NULL;
2269
2270 SAVE_OPLINE();
2271 container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
2272
2273 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2274 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2275 }
2276
2277 offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
2278
2279 if (OP1_TYPE == IS_CONST ||
2280 (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
2281 do {
2282 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
2283 container = Z_REFVAL_P(container);
2284 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
2285 break;
2286 }
2287 }
2288 ZVAL_NULL(EX_VAR(opline->result.var));
2289 ZEND_VM_C_GOTO(fetch_obj_is_finish);
2290 } while (0);
2291 }
2292
2293 /* here we are sure we are dealing with an object */
2294 do {
2295 zend_object *zobj = Z_OBJ_P(container);
2296 zval *retval;
2297
2298 if (OP2_TYPE == IS_CONST) {
2299 cache_slot = CACHE_ADDR(opline->extended_value);
2300
2301 if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
2302 uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
2303
2304 if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2305 retval = OBJ_PROP(zobj, prop_offset);
2306 if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
2307 if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2308 ZEND_VM_C_GOTO(fetch_obj_is_copy);
2309 } else {
2310 ZEND_VM_C_LABEL(fetch_obj_is_fast_copy):
2311 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2312 ZEND_VM_NEXT_OPCODE();
2313 }
2314 }
2315 } else if (EXPECTED(zobj->properties != NULL)) {
2316 if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
2317 uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
2318
2319 if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
2320 Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
2321
2322 if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
2323 (EXPECTED(p->key == Z_STR_P(offset)) ||
2324 (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) &&
2325 EXPECTED(p->key != NULL) &&
2326 EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) {
2327 retval = &p->val;
2328 if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2329 ZEND_VM_C_GOTO(fetch_obj_is_copy);
2330 } else {
2331 ZEND_VM_C_GOTO(fetch_obj_is_fast_copy);
2332 }
2333 }
2334 }
2335 CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
2336 }
2337 retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1);
2338 if (EXPECTED(retval)) {
2339 uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
2340 CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
2341 if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
2342 ZEND_VM_C_GOTO(fetch_obj_is_copy);
2343 } else {
2344 ZEND_VM_C_GOTO(fetch_obj_is_fast_copy);
2345 }
2346 }
2347 }
2348 }
2349 }
2350
2351 retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
2352
2353 if (retval != EX_VAR(opline->result.var)) {
2354 ZEND_VM_C_LABEL(fetch_obj_is_copy):
2355 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
2356 } else if (UNEXPECTED(Z_ISREF_P(retval))) {
2357 zend_unwrap_reference(retval);
2358 }
2359 } while (0);
2360
2361 ZEND_VM_C_LABEL(fetch_obj_is_finish):
2362 FREE_OP2();
2363 FREE_OP1();
2364 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2365 }
2366
2367 ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|CACHE_SLOT)
2368 {
2369 #if !ZEND_VM_SPEC
2370 USE_OPLINE
2371 #endif
2372
2373 if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
2374 /* Behave like FETCH_OBJ_W */
2375 if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
2376 ZEND_VM_DISPATCH_TO_HELPER(zend_use_tmp_in_write_context_helper);
2377 }
2378 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_W);
2379 } else {
2380 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
2381 }
2382 }
2383
2384 ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
2385 {
2386 USE_OPLINE
2387 zend_free_op free_op1, free_op2;
2388 zval *container, *property, *result;
2389
2390 SAVE_OPLINE();
2391 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
2392
2393 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2394 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2395 }
2396
2397 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2398 result = EX_VAR(opline->result.var);
2399 zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
2400 FREE_OP2();
2401 if (OP1_TYPE == IS_VAR) {
2402 FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result);
2403 }
2404 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2405 }
2406
2407 ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
2408 {
2409 USE_OPLINE
2410 zend_free_op free_op1, free_op2;
2411 zval *container;
2412
2413 SAVE_OPLINE();
2414 container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2415 zend_fetch_dimension_address_LIST_r(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2416 FREE_OP2();
2417 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2418 }
2419
2420 ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
2421 {
2422 USE_OPLINE
2423 zend_free_op free_op1, free_op2;
2424 zval *container, *dim;
2425
2426 SAVE_OPLINE();
2427 container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2428 dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2429
2430 if (OP1_TYPE == IS_VAR
2431 && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT
2432 && UNEXPECTED(!Z_ISREF_P(container))
2433 ) {
2434 zend_error(E_NOTICE, "Attempting to set reference to non referenceable value");
2435 zend_fetch_dimension_address_LIST_r(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2436 } else {
2437 zend_fetch_dimension_address_W(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
2438 }
2439
2440 FREE_OP2();
2441 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2442 }
2443
2444 ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2445 {
2446 USE_OPLINE
2447 zend_free_op free_op1, free_op2, free_op_data;
2448 zval *object, *property, *value, tmp;
2449
2450 SAVE_OPLINE();
2451 object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2452
2453 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
2454 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2455 }
2456
2457 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2458 value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2459
2460 if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
2461 if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
2462 object = Z_REFVAL_P(object);
2463 ZEND_VM_C_GOTO(assign_object);
2464 }
2465 object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
2466 if (UNEXPECTED(!object)) {
2467 value = &EG(uninitialized_zval);
2468 ZEND_VM_C_GOTO(free_and_exit_assign_obj);
2469 }
2470 }
2471
2472 ZEND_VM_C_LABEL(assign_object):
2473 if (OP2_TYPE == IS_CONST &&
2474 EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) {
2475 void **cache_slot = CACHE_ADDR(opline->extended_value);
2476 uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
2477 zend_object *zobj = Z_OBJ_P(object);
2478 zval *property_val;
2479
2480 if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2481 property_val = OBJ_PROP(zobj, prop_offset);
2482 if (Z_TYPE_P(property_val) != IS_UNDEF) {
2483 zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
2484
2485 if (UNEXPECTED(prop_info != NULL)) {
2486 value = zend_assign_to_typed_prop(prop_info, property_val, value EXECUTE_DATA_CC);
2487 ZEND_VM_C_GOTO(free_and_exit_assign_obj);
2488 } else {
2489 ZEND_VM_C_LABEL(fast_assign_obj):
2490 value = zend_assign_to_variable(property_val, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2491 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2492 ZVAL_COPY(EX_VAR(opline->result.var), value);
2493 }
2494 ZEND_VM_C_GOTO(exit_assign_obj);
2495 }
2496 }
2497 } else {
2498 if (EXPECTED(zobj->properties != NULL)) {
2499 if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
2500 if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
2501 GC_DELREF(zobj->properties);
2502 }
2503 zobj->properties = zend_array_dup(zobj->properties);
2504 }
2505 property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1);
2506 if (property_val) {
2507 ZEND_VM_C_GOTO(fast_assign_obj);
2508 }
2509 }
2510
2511 if (!zobj->ce->__set) {
2512
2513 if (EXPECTED(zobj->properties == NULL)) {
2514 rebuild_object_properties(zobj);
2515 }
2516 if (OP_DATA_TYPE == IS_CONST) {
2517 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
2518 Z_ADDREF_P(value);
2519 }
2520 } else if (OP_DATA_TYPE != IS_TMP_VAR) {
2521 if (Z_ISREF_P(value)) {
2522 if (OP_DATA_TYPE == IS_VAR) {
2523 zend_reference *ref = Z_REF_P(value);
2524 if (GC_DELREF(ref) == 0) {
2525 ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
2526 efree_size(ref, sizeof(zend_reference));
2527 value = &tmp;
2528 } else {
2529 value = Z_REFVAL_P(value);
2530 Z_TRY_ADDREF_P(value);
2531 }
2532 } else {
2533 value = Z_REFVAL_P(value);
2534 Z_TRY_ADDREF_P(value);
2535 }
2536 } else if (OP_DATA_TYPE == IS_CV) {
2537 Z_TRY_ADDREF_P(value);
2538 }
2539 }
2540 zend_hash_add_new(zobj->properties, Z_STR_P(property), value);
2541 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2542 ZVAL_COPY(EX_VAR(opline->result.var), value);
2543 }
2544 ZEND_VM_C_GOTO(exit_assign_obj);
2545 }
2546 }
2547 }
2548
2549 if (OP_DATA_TYPE == IS_CV || OP_DATA_TYPE == IS_VAR) {
2550 ZVAL_DEREF(value);
2551 }
2552
2553 value = Z_OBJ_HT_P(object)->write_property(object, property, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
2554
2555 ZEND_VM_C_LABEL(free_and_exit_assign_obj):
2556 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2557 ZVAL_COPY(EX_VAR(opline->result.var), value);
2558 }
2559 FREE_OP_DATA();
2560 ZEND_VM_C_LABEL(exit_assign_obj):
2561 FREE_OP2();
2562 FREE_OP1_VAR_PTR();
2563 /* assign_obj has two opcodes! */
2564 ZEND_VM_NEXT_OPCODE_EX(1, 2);
2565 }
2566
2567 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
2568 ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2569 {
2570 USE_OPLINE
2571 zend_free_op free_op_data;
2572 zval *prop, *value;
2573 zend_property_info *prop_info;
2574
2575 SAVE_OPLINE();
2576
2577 if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
2578 FREE_UNFETCHED_OP_DATA();
2579 UNDEF_RESULT();
2580 HANDLE_EXCEPTION();
2581 }
2582
2583 value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2584
2585 if (UNEXPECTED(prop_info->type)) {
2586 value = zend_assign_to_typed_prop(prop_info, prop, value EXECUTE_DATA_CC);
2587 FREE_OP_DATA();
2588 } else {
2589 value = zend_assign_to_variable(prop, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2590 }
2591
2592 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2593 ZVAL_COPY(EX_VAR(opline->result.var), value);
2594 }
2595
2596 /* assign_static_prop has two opcodes! */
2597 ZEND_VM_NEXT_OPCODE_EX(1, 2);
2598 }
2599
2600 ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
2601 {
2602 USE_OPLINE
2603 zend_free_op free_op1;
2604 zval *object_ptr, *orig_object_ptr;
2605 zend_free_op free_op2, free_op_data;
2606 zval *value;
2607 zval *variable_ptr;
2608 zval *dim;
2609
2610 SAVE_OPLINE();
2611 orig_object_ptr = object_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2612
2613 if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
2614 ZEND_VM_C_LABEL(try_assign_dim_array):
2615 value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2616 SEPARATE_ARRAY(object_ptr);
2617 if (OP2_TYPE == IS_UNUSED) {
2618 if (OP_DATA_TYPE == IS_CV || OP_DATA_TYPE == IS_VAR) {
2619 ZVAL_DEREF(value);
2620 }
2621 variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
2622 if (UNEXPECTED(variable_ptr == NULL)) {
2623 zend_cannot_add_element();
2624 ZEND_VM_C_GOTO(assign_dim_error);
2625 } else if (OP_DATA_TYPE == IS_CV) {
2626 if (Z_REFCOUNTED_P(value)) {
2627 Z_ADDREF_P(value);
2628 }
2629 } else if (OP_DATA_TYPE == IS_VAR) {
2630 if (value != free_op_data) {
2631 if (Z_REFCOUNTED_P(value)) {
2632 Z_ADDREF_P(value);
2633 }
2634 FREE_OP_DATA();
2635 }
2636 } else if (OP_DATA_TYPE == IS_CONST) {
2637 if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
2638 Z_ADDREF_P(value);
2639 }
2640 }
2641 } else {
2642 dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2643 if (OP2_TYPE == IS_CONST) {
2644 variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
2645 } else {
2646 variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
2647 }
2648 if (UNEXPECTED(variable_ptr == NULL)) {
2649 ZEND_VM_C_GOTO(assign_dim_error);
2650 }
2651 value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2652 }
2653 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2654 ZVAL_COPY(EX_VAR(opline->result.var), value);
2655 }
2656 } else {
2657 if (EXPECTED(Z_ISREF_P(object_ptr))) {
2658 object_ptr = Z_REFVAL_P(object_ptr);
2659 if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
2660 ZEND_VM_C_GOTO(try_assign_dim_array);
2661 }
2662 }
2663 if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
2664 dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2665 value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
2666
2667 if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
2668 dim++;
2669 }
2670 zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
2671
2672 FREE_OP_DATA();
2673 } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
2674 if (OP2_TYPE == IS_UNUSED) {
2675 zend_use_new_element_for_string();
2676 FREE_UNFETCHED_OP_DATA();
2677 UNDEF_RESULT();
2678 } else {
2679 dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2680 value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
2681 zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
2682 FREE_OP_DATA();
2683 }
2684 } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
2685 if (Z_ISREF_P(orig_object_ptr)
2686 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
2687 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
2688 dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2689 FREE_UNFETCHED_OP_DATA();
2690 UNDEF_RESULT();
2691 } else {
2692 ZVAL_ARR(object_ptr, zend_new_array(8));
2693 ZEND_VM_C_GOTO(try_assign_dim_array);
2694 }
2695 } else {
2696 if (OP1_TYPE != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) {
2697 zend_use_scalar_as_array();
2698 }
2699 dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2700 ZEND_VM_C_LABEL(assign_dim_error):
2701 FREE_UNFETCHED_OP_DATA();
2702 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2703 ZVAL_NULL(EX_VAR(opline->result.var));
2704 }
2705 }
2706 }
2707 if (OP2_TYPE != IS_UNUSED) {
2708 FREE_OP2();
2709 }
2710 FREE_OP1_VAR_PTR();
2711 /* assign_dim has two opcodes! */
2712 ZEND_VM_NEXT_OPCODE_EX(1, 2);
2713 }
2714
2715 ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
2716 {
2717 USE_OPLINE
2718 zend_free_op free_op1, free_op2;
2719 zval *value;
2720 zval *variable_ptr;
2721
2722 SAVE_OPLINE();
2723 value = GET_OP2_ZVAL_PTR(BP_VAR_R);
2724 variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2725
2726 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) {
2727 FREE_OP2();
2728 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2729 ZVAL_NULL(EX_VAR(opline->result.var));
2730 }
2731 } else {
2732 value = zend_assign_to_variable(variable_ptr, value, OP2_TYPE, EX_USES_STRICT_TYPES());
2733 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2734 ZVAL_COPY(EX_VAR(opline->result.var), value);
2735 }
2736 FREE_OP1_VAR_PTR();
2737 /* zend_assign_to_variable() always takes care of op2, never free it! */
2738 }
2739
2740 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2741 }
2742
2743 ZEND_VM_HANDLER(30, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
2744 {
2745 USE_OPLINE
2746 zend_free_op free_op1, free_op2;
2747 zval *variable_ptr;
2748 zval *value_ptr;
2749
2750 SAVE_OPLINE();
2751 value_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);
2752 variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2753
2754 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) {
2755 variable_ptr = &EG(uninitialized_zval);
2756 } else if (OP1_TYPE == IS_VAR &&
2757 UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
2758
2759 zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
2760 variable_ptr = &EG(uninitialized_zval);
2761 } else if (OP2_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) {
2762 variable_ptr = &EG(uninitialized_zval);
2763 } else if (OP2_TYPE == IS_VAR &&
2764 opline->extended_value == ZEND_RETURNS_FUNCTION &&
2765 UNEXPECTED(!Z_ISREF_P(value_ptr))) {
2766
2767 variable_ptr = zend_wrong_assign_to_variable_reference(
2768 variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC);
2769 } else {
2770 zend_assign_to_variable_reference(variable_ptr, value_ptr);
2771 }
2772
2773 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2774 ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
2775 }
2776
2777 FREE_OP2_VAR_PTR();
2778 FREE_OP1_VAR_PTR();
2779 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2780 }
2781
2782 ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
2783 {
2784 USE_OPLINE
2785 zend_free_op free_op1, free_op2, free_op_data;
2786 zval *property, *container, *value_ptr;
2787
2788 SAVE_OPLINE();
2789
2790 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
2791
2792 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
2793 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
2794 }
2795
2796 property = GET_OP2_ZVAL_PTR(BP_VAR_R);
2797
2798 value_ptr = GET_OP_DATA_ZVAL_PTR_PTR(BP_VAR_W);
2799
2800 if (ZEND_VM_SPEC) {
2801 if (OP1_TYPE == IS_UNUSED) {
2802 if (OP2_TYPE == IS_CONST) {
2803 zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
2804 } else {
2805 zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
2806 }
2807 } else {
2808 if (OP2_TYPE == IS_CONST) {
2809 zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
2810 } else {
2811 zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
2812 }
2813 }
2814 } else {
2815 zend_assign_to_property_reference(container, OP1_TYPE, property, OP2_TYPE, value_ptr OPLINE_CC EXECUTE_DATA_CC);
2816 }
2817
2818 FREE_OP1_VAR_PTR();
2819 FREE_OP2();
2820 FREE_OP_DATA_VAR_PTR();
2821 ZEND_VM_NEXT_OPCODE_EX(1, 2);
2822 }
2823
2824 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
2825 ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
2826 {
2827 USE_OPLINE
2828 zend_free_op free_op_data;
2829 zval *prop, *value_ptr;
2830 zend_property_info *prop_info;
2831
2832 SAVE_OPLINE();
2833
2834 if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value & ~ZEND_RETURNS_FUNCTION, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
2835 FREE_UNFETCHED_OP_DATA();
2836 UNDEF_RESULT();
2837 HANDLE_EXCEPTION();
2838 }
2839
2840 value_ptr = GET_OP_DATA_ZVAL_PTR_PTR(BP_VAR_W);
2841
2842 if (OP_DATA_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) {
2843 prop = &EG(uninitialized_zval);
2844 } else if (OP_DATA_TYPE == IS_VAR && (opline->extended_value & ZEND_RETURNS_FUNCTION) && UNEXPECTED(!Z_ISREF_P(value_ptr))) {
2845 if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(prop, value_ptr OPLINE_CC EXECUTE_DATA_CC))) {
2846 prop = &EG(uninitialized_zval);
2847 }
2848 } else if (UNEXPECTED(prop_info->type)) {
2849 prop = zend_assign_to_typed_property_reference(prop_info, prop, value_ptr EXECUTE_DATA_CC);
2850 } else {
2851 zend_assign_to_variable_reference(prop, value_ptr);
2852 }
2853
2854 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2855 ZVAL_COPY(EX_VAR(opline->result.var), prop);
2856 }
2857
2858 FREE_OP_DATA_VAR_PTR();
2859 ZEND_VM_NEXT_OPCODE_EX(1, 2);
2860 }
2861
ZEND_VM_HOT_HELPER(zend_leave_helper,ANY,ANY)2862 ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
2863 {
2864 zend_execute_data *old_execute_data;
2865 uint32_t call_info = EX_CALL_INFO();
2866 SAVE_OPLINE();
2867
2868 if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
2869 EG(current_execute_data) = EX(prev_execute_data);
2870 i_free_compiled_variables(execute_data);
2871
2872 #ifdef ZEND_PREFER_RELOAD
2873 call_info = EX_CALL_INFO();
2874 #endif
2875 if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
2876 OBJ_RELEASE(Z_OBJ(execute_data->This));
2877 } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
2878 OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
2879 }
2880 EG(vm_stack_top) = (zval*)execute_data;
2881 execute_data = EX(prev_execute_data);
2882
2883 if (UNEXPECTED(EG(exception) != NULL)) {
2884 zend_rethrow_exception(execute_data);
2885 HANDLE_EXCEPTION_LEAVE();
2886 }
2887
2888 LOAD_NEXT_OPLINE();
2889 ZEND_VM_LEAVE();
2890 } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
2891 EG(current_execute_data) = EX(prev_execute_data);
2892 i_free_compiled_variables(execute_data);
2893
2894 #ifdef ZEND_PREFER_RELOAD
2895 call_info = EX_CALL_INFO();
2896 #endif
2897 if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2898 zend_clean_and_cache_symbol_table(EX(symbol_table));
2899 }
2900
2901 /* Free extra args before releasing the closure,
2902 * as that may free the op_array. */
2903 zend_vm_stack_free_extra_args_ex(call_info, execute_data);
2904
2905 if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
2906 OBJ_RELEASE(Z_OBJ(execute_data->This));
2907 } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
2908 OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
2909 }
2910
2911 old_execute_data = execute_data;
2912 execute_data = EX(prev_execute_data);
2913 zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
2914
2915 if (UNEXPECTED(EG(exception) != NULL)) {
2916 zend_rethrow_exception(execute_data);
2917 HANDLE_EXCEPTION_LEAVE();
2918 }
2919
2920 LOAD_NEXT_OPLINE();
2921 ZEND_VM_LEAVE();
2922 } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
2923 zend_detach_symbol_table(execute_data);
2924 destroy_op_array(&EX(func)->op_array);
2925 efree_size(EX(func), sizeof(zend_op_array));
2926 #ifdef ZEND_PREFER_RELOAD
2927 call_info = EX_CALL_INFO();
2928 #endif
2929 old_execute_data = execute_data;
2930 execute_data = EG(current_execute_data) = EX(prev_execute_data);
2931 zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
2932
2933 zend_attach_symbol_table(execute_data);
2934 if (UNEXPECTED(EG(exception) != NULL)) {
2935 zend_rethrow_exception(execute_data);
2936 HANDLE_EXCEPTION_LEAVE();
2937 }
2938
2939 LOAD_NEXT_OPLINE();
2940 ZEND_VM_LEAVE();
2941 } else {
2942 if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
2943 EG(current_execute_data) = EX(prev_execute_data);
2944 i_free_compiled_variables(execute_data);
2945 #ifdef ZEND_PREFER_RELOAD
2946 call_info = EX_CALL_INFO();
2947 #endif
2948 if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
2949 if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2950 zend_clean_and_cache_symbol_table(EX(symbol_table));
2951 }
2952 zend_vm_stack_free_extra_args_ex(call_info, execute_data);
2953 }
2954 if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
2955 OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
2956 }
2957 ZEND_VM_RETURN();
2958 } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
2959 zend_array *symbol_table = EX(symbol_table);
2960
2961 zend_detach_symbol_table(execute_data);
2962 old_execute_data = EX(prev_execute_data);
2963 while (old_execute_data) {
2964 if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2965 if (old_execute_data->symbol_table == symbol_table) {
2966 zend_attach_symbol_table(old_execute_data);
2967 }
2968 break;
2969 }
2970 old_execute_data = old_execute_data->prev_execute_data;
2971 }
2972 EG(current_execute_data) = EX(prev_execute_data);
2973 ZEND_VM_RETURN();
2974 }
2975 }
2976 }
2977
2978 ZEND_VM_HOT_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
2979 {
2980 USE_OPLINE
2981
2982 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
2983 }
2984
2985 ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
2986 {
2987 USE_OPLINE
2988 zend_free_op free_op1;
2989 zval *val;
2990
2991 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2992
2993 if (Z_TYPE_INFO_P(val) == IS_TRUE) {
2994 ZEND_VM_NEXT_OPCODE();
2995 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2996 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2997 SAVE_OPLINE();
2998 ZVAL_UNDEFINED_OP1();
2999 if (UNEXPECTED(EG(exception))) {
3000 HANDLE_EXCEPTION();
3001 }
3002 }
3003 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
3004 }
3005
3006 SAVE_OPLINE();
3007 if (i_zend_is_true(val)) {
3008 opline++;
3009 } else {
3010 opline = OP_JMP_ADDR(opline, opline->op2);
3011 }
3012 FREE_OP1();
3013 ZEND_VM_JMP(opline);
3014 }
3015
3016 ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
3017 {
3018 USE_OPLINE
3019 zend_free_op free_op1;
3020 zval *val;
3021
3022 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
3023
3024 if (Z_TYPE_INFO_P(val) == IS_TRUE) {
3025 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
3026 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
3027 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
3028 SAVE_OPLINE();
3029 ZVAL_UNDEFINED_OP1();
3030 if (UNEXPECTED(EG(exception))) {
3031 HANDLE_EXCEPTION();
3032 }
3033 }
3034 ZEND_VM_NEXT_OPCODE();
3035 }
3036
3037 SAVE_OPLINE();
3038 if (i_zend_is_true(val)) {
3039 opline = OP_JMP_ADDR(opline, opline->op2);
3040 } else {
3041 opline++;
3042 }
3043 FREE_OP1();
3044 ZEND_VM_JMP(opline);
3045 }
3046
3047 ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR)
3048 {
3049 USE_OPLINE
3050 zend_free_op free_op1;
3051 zval *val;
3052
3053 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
3054
3055 if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) {
3056 ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
3057 ZEND_VM_CONTINUE();
3058 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
3059 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
3060 SAVE_OPLINE();
3061 ZVAL_UNDEFINED_OP1();
3062 if (UNEXPECTED(EG(exception))) {
3063 HANDLE_EXCEPTION();
3064 }
3065 }
3066 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
3067 }
3068
3069 SAVE_OPLINE();
3070 if (i_zend_is_true(val)) {
3071 opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
3072 } else {
3073 opline = OP_JMP_ADDR(opline, opline->op2);
3074 }
3075 FREE_OP1();
3076 ZEND_VM_JMP(opline);
3077 }
3078
3079 ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
3080 {
3081 USE_OPLINE
3082 zend_free_op free_op1;
3083 zval *val;
3084 int ret;
3085
3086 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
3087
3088 if (Z_TYPE_INFO_P(val) == IS_TRUE) {
3089 ZVAL_TRUE(EX_VAR(opline->result.var));
3090 ZEND_VM_NEXT_OPCODE();
3091 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
3092 ZVAL_FALSE(EX_VAR(opline->result.var));
3093 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
3094 SAVE_OPLINE();
3095 ZVAL_UNDEFINED_OP1();
3096 if (UNEXPECTED(EG(exception))) {
3097 HANDLE_EXCEPTION();
3098 }
3099 }
3100 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
3101 }
3102
3103 SAVE_OPLINE();
3104 ret = i_zend_is_true(val);
3105 FREE_OP1();
3106 if (ret) {
3107 ZVAL_TRUE(EX_VAR(opline->result.var));
3108 opline++;
3109 } else {
3110 ZVAL_FALSE(EX_VAR(opline->result.var));
3111 opline = OP_JMP_ADDR(opline, opline->op2);
3112 }
3113 ZEND_VM_JMP(opline);
3114 }
3115
3116 ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
3117 {
3118 USE_OPLINE
3119 zend_free_op free_op1;
3120 zval *val;
3121 int ret;
3122
3123 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
3124
3125 if (Z_TYPE_INFO_P(val) == IS_TRUE) {
3126 ZVAL_TRUE(EX_VAR(opline->result.var));
3127 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
3128 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
3129 ZVAL_FALSE(EX_VAR(opline->result.var));
3130 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
3131 SAVE_OPLINE();
3132 ZVAL_UNDEFINED_OP1();
3133 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3134 } else {
3135 ZEND_VM_NEXT_OPCODE();
3136 }
3137 }
3138
3139 SAVE_OPLINE();
3140 ret = i_zend_is_true(val);
3141 FREE_OP1();
3142 if (ret) {
3143 ZVAL_TRUE(EX_VAR(opline->result.var));
3144 opline = OP_JMP_ADDR(opline, opline->op2);
3145 } else {
3146 ZVAL_FALSE(EX_VAR(opline->result.var));
3147 opline++;
3148 }
3149 ZEND_VM_JMP(opline);
3150 }
3151
3152 ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY)
3153 {
3154 USE_OPLINE
3155
3156 SAVE_OPLINE();
3157 zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
3158 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3159 }
3160
3161 ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY)
3162 {
3163 zval *var;
3164 USE_OPLINE
3165
3166 SAVE_OPLINE();
3167 var = EX_VAR(opline->op1.var);
3168 if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
3169 zend_hash_iterator_del(Z_FE_ITER_P(var));
3170 }
3171 zval_ptr_dtor_nogc(var);
3172 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3173 }
3174
3175 ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
3176 {
3177 USE_OPLINE
3178 zend_free_op free_op1, free_op2;
3179 zval *op1, *op2;
3180 zend_string *op1_str, *op2_str, *str;
3181
3182
3183 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
3184 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3185 if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
3186 (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
3187 zend_string *op1_str = Z_STR_P(op1);
3188 zend_string *op2_str = Z_STR_P(op2);
3189 zend_string *str;
3190
3191 if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
3192 if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) {
3193 ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
3194 } else {
3195 ZVAL_STR(EX_VAR(opline->result.var), op2_str);
3196 }
3197 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
3198 zend_string_release_ex(op1_str, 0);
3199 }
3200 } else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
3201 if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) {
3202 ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
3203 } else {
3204 ZVAL_STR(EX_VAR(opline->result.var), op1_str);
3205 }
3206 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
3207 zend_string_release_ex(op2_str, 0);
3208 }
3209 } else if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV &&
3210 !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
3211 size_t len = ZSTR_LEN(op1_str);
3212
3213 str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
3214 memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
3215 ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
3216 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
3217 zend_string_release_ex(op2_str, 0);
3218 }
3219 } else {
3220 str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
3221 memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
3222 memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
3223 ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
3224 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
3225 zend_string_release_ex(op1_str, 0);
3226 }
3227 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
3228 zend_string_release_ex(op2_str, 0);
3229 }
3230 }
3231 ZEND_VM_NEXT_OPCODE();
3232 }
3233
3234 SAVE_OPLINE();
3235 if (OP1_TYPE == IS_CONST) {
3236 op1_str = Z_STR_P(op1);
3237 } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
3238 op1_str = zend_string_copy(Z_STR_P(op1));
3239 } else {
3240 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
3241 ZVAL_UNDEFINED_OP1();
3242 }
3243 op1_str = zval_get_string_func(op1);
3244 }
3245 if (OP2_TYPE == IS_CONST) {
3246 op2_str = Z_STR_P(op2);
3247 } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
3248 op2_str = zend_string_copy(Z_STR_P(op2));
3249 } else {
3250 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
3251 ZVAL_UNDEFINED_OP2();
3252 }
3253 op2_str = zval_get_string_func(op2);
3254 }
3255 do {
3256 if (OP1_TYPE != IS_CONST) {
3257 if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
3258 if (OP2_TYPE == IS_CONST) {
3259 if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
3260 GC_ADDREF(op2_str);
3261 }
3262 }
3263 ZVAL_STR(EX_VAR(opline->result.var), op2_str);
3264 zend_string_release_ex(op1_str, 0);
3265 break;
3266 }
3267 }
3268 if (OP2_TYPE != IS_CONST) {
3269 if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
3270 if (OP1_TYPE == IS_CONST) {
3271 if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
3272 GC_ADDREF(op1_str);
3273 }
3274 }
3275 ZVAL_STR(EX_VAR(opline->result.var), op1_str);
3276 zend_string_release_ex(op2_str, 0);
3277 break;
3278 }
3279 }
3280 str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
3281 memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
3282 memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
3283 ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
3284 if (OP1_TYPE != IS_CONST) {
3285 zend_string_release_ex(op1_str, 0);
3286 }
3287 if (OP2_TYPE != IS_CONST) {
3288 zend_string_release_ex(op2_str, 0);
3289 }
3290 } while (0);
3291 FREE_OP1();
3292 FREE_OP2();
3293 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3294 }
3295
3296 ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM)
3297 {
3298 USE_OPLINE
3299 zend_free_op free_op2;
3300 zend_string **rope;
3301 zval *var;
3302
3303 /* Compiler allocates the necessary number of zval slots to keep the rope */
3304 rope = (zend_string**)EX_VAR(opline->result.var);
3305 if (OP2_TYPE == IS_CONST) {
3306 var = GET_OP2_ZVAL_PTR(BP_VAR_R);
3307 rope[0] = Z_STR_P(var);
3308 if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
3309 Z_ADDREF_P(var);
3310 }
3311 } else {
3312 var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3313 if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
3314 if (OP2_TYPE == IS_CV) {
3315 rope[0] = zend_string_copy(Z_STR_P(var));
3316 } else {
3317 rope[0] = Z_STR_P(var);
3318 }
3319 } else {
3320 SAVE_OPLINE();
3321 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
3322 ZVAL_UNDEFINED_OP2();
3323 }
3324 rope[0] = zval_get_string_func(var);
3325 FREE_OP2();
3326 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3327 }
3328 }
3329 ZEND_VM_NEXT_OPCODE();
3330 }
3331
3332 ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM)
3333 {
3334 USE_OPLINE
3335 zend_free_op free_op2;
3336 zend_string **rope;
3337 zval *var;
3338
3339 /* op1 and result are the same */
3340 rope = (zend_string**)EX_VAR(opline->op1.var);
3341 if (OP2_TYPE == IS_CONST) {
3342 var = GET_OP2_ZVAL_PTR(BP_VAR_R);
3343 rope[opline->extended_value] = Z_STR_P(var);
3344 if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
3345 Z_ADDREF_P(var);
3346 }
3347 } else {
3348 var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3349 if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
3350 if (OP2_TYPE == IS_CV) {
3351 rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
3352 } else {
3353 rope[opline->extended_value] = Z_STR_P(var);
3354 }
3355 } else {
3356 SAVE_OPLINE();
3357 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
3358 ZVAL_UNDEFINED_OP2();
3359 }
3360 rope[opline->extended_value] = zval_get_string_func(var);
3361 FREE_OP2();
3362 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3363 }
3364 }
3365 ZEND_VM_NEXT_OPCODE();
3366 }
3367
3368 ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
3369 {
3370 USE_OPLINE
3371 zend_free_op free_op2;
3372 zend_string **rope;
3373 zval *var, *ret;
3374 uint32_t i;
3375 size_t len = 0;
3376 char *target;
3377
3378 rope = (zend_string**)EX_VAR(opline->op1.var);
3379 if (OP2_TYPE == IS_CONST) {
3380 var = GET_OP2_ZVAL_PTR(BP_VAR_R);
3381 rope[opline->extended_value] = Z_STR_P(var);
3382 if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
3383 Z_ADDREF_P(var);
3384 }
3385 } else {
3386 var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3387 if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
3388 if (OP2_TYPE == IS_CV) {
3389 rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
3390 } else {
3391 rope[opline->extended_value] = Z_STR_P(var);
3392 }
3393 } else {
3394 SAVE_OPLINE();
3395 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
3396 ZVAL_UNDEFINED_OP2();
3397 }
3398 rope[opline->extended_value] = zval_get_string_func(var);
3399 FREE_OP2();
3400 if (UNEXPECTED(EG(exception))) {
3401 for (i = 0; i <= opline->extended_value; i++) {
3402 zend_string_release_ex(rope[i], 0);
3403 }
3404 ZVAL_UNDEF(EX_VAR(opline->result.var));
3405 HANDLE_EXCEPTION();
3406 }
3407 }
3408 }
3409 for (i = 0; i <= opline->extended_value; i++) {
3410 len += ZSTR_LEN(rope[i]);
3411 }
3412 ret = EX_VAR(opline->result.var);
3413 ZVAL_STR(ret, zend_string_alloc(len, 0));
3414 target = Z_STRVAL_P(ret);
3415 for (i = 0; i <= opline->extended_value; i++) {
3416 memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
3417 target += ZSTR_LEN(rope[i]);
3418 zend_string_release_ex(rope[i], 0);
3419 }
3420 *target = '\0';
3421
3422 ZEND_VM_NEXT_OPCODE();
3423 }
3424
3425 ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|CV, CACHE_SLOT)
3426 {
3427 zend_free_op free_op2;
3428 zval *class_name;
3429 USE_OPLINE
3430
3431 SAVE_OPLINE();
3432 if (OP2_TYPE == IS_UNUSED) {
3433 Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
3434 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3435 } else if (OP2_TYPE == IS_CONST) {
3436 zend_class_entry *ce = CACHED_PTR(opline->extended_value);
3437
3438 if (UNEXPECTED(ce == NULL)) {
3439 class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3440 ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num);
3441 CACHE_PTR(opline->extended_value, ce);
3442 }
3443 Z_CE_P(EX_VAR(opline->result.var)) = ce;
3444 } else {
3445 class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3446 ZEND_VM_C_LABEL(try_class_name):
3447 if (Z_TYPE_P(class_name) == IS_OBJECT) {
3448 Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
3449 } else if (Z_TYPE_P(class_name) == IS_STRING) {
3450 Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
3451 } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
3452 class_name = Z_REFVAL_P(class_name);
3453 ZEND_VM_C_GOTO(try_class_name);
3454 } else {
3455 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
3456 ZVAL_UNDEFINED_OP2();
3457 if (UNEXPECTED(EG(exception) != NULL)) {
3458 HANDLE_EXCEPTION();
3459 }
3460 }
3461 zend_throw_error(NULL, "Class name must be a valid object or a string");
3462 }
3463 }
3464
3465 FREE_OP2();
3466 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3467 }
3468
3469 ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM|CACHE_SLOT)
3470 {
3471 USE_OPLINE
3472 zval *function_name;
3473 zend_free_op free_op1, free_op2;
3474 zval *object;
3475 zend_function *fbc;
3476 zend_class_entry *called_scope;
3477 zend_object *obj;
3478 zend_execute_data *call;
3479 uint32_t call_info;
3480
3481 SAVE_OPLINE();
3482
3483 object = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
3484
3485 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
3486 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
3487 }
3488
3489 if (OP2_TYPE != IS_CONST) {
3490 function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3491 }
3492
3493 if (OP2_TYPE != IS_CONST &&
3494 UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
3495 do {
3496 if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
3497 function_name = Z_REFVAL_P(function_name);
3498 if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
3499 break;
3500 }
3501 } else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
3502 ZVAL_UNDEFINED_OP2();
3503 if (UNEXPECTED(EG(exception) != NULL)) {
3504 FREE_OP1();
3505 HANDLE_EXCEPTION();
3506 }
3507 }
3508 zend_throw_error(NULL, "Method name must be a string");
3509 FREE_OP2();
3510 FREE_OP1();
3511 HANDLE_EXCEPTION();
3512 } while (0);
3513 }
3514
3515 if (OP1_TYPE != IS_UNUSED) {
3516 do {
3517 if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
3518 if ((OP1_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
3519 object = Z_REFVAL_P(object);
3520 if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
3521 break;
3522 }
3523 }
3524 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
3525 object = ZVAL_UNDEFINED_OP1();
3526 if (UNEXPECTED(EG(exception) != NULL)) {
3527 if (OP2_TYPE != IS_CONST) {
3528 FREE_OP2();
3529 }
3530 HANDLE_EXCEPTION();
3531 }
3532 }
3533 if (OP2_TYPE == IS_CONST) {
3534 function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3535 }
3536 zend_invalid_method_call(object, function_name);
3537 FREE_OP2();
3538 FREE_OP1();
3539 HANDLE_EXCEPTION();
3540 }
3541 } while (0);
3542 }
3543
3544 obj = Z_OBJ_P(object);
3545 called_scope = obj->ce;
3546
3547 if (OP2_TYPE == IS_CONST &&
3548 EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
3549 fbc = CACHED_PTR(opline->result.num + sizeof(void*));
3550 } else {
3551 zend_object *orig_obj = obj;
3552
3553 if (OP2_TYPE == IS_CONST) {
3554 function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3555 }
3556
3557 /* First, locate the function. */
3558 fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
3559 if (UNEXPECTED(fbc == NULL)) {
3560 if (EXPECTED(!EG(exception))) {
3561 zend_undefined_method(obj->ce, Z_STR_P(function_name));
3562 }
3563 FREE_OP2();
3564 FREE_OP1();
3565 HANDLE_EXCEPTION();
3566 }
3567 if (OP2_TYPE == IS_CONST &&
3568 EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
3569 EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
3570 EXPECTED(obj == orig_obj)) {
3571 CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
3572 }
3573 if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
3574 /* Reset "object" to trigger reference counting */
3575 object = NULL;
3576 }
3577 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
3578 init_func_run_time_cache(&fbc->op_array);
3579 }
3580 }
3581
3582 if (OP2_TYPE != IS_CONST) {
3583 FREE_OP2();
3584 }
3585
3586 call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
3587 if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
3588 FREE_OP1();
3589
3590 if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
3591 HANDLE_EXCEPTION();
3592 }
3593 /* call static method */
3594 obj = (zend_object*)called_scope;
3595 call_info = ZEND_CALL_NESTED_FUNCTION;
3596 } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) {
3597 if (OP1_TYPE == IS_CV) {
3598 GC_ADDREF(obj); /* For $this pointer */
3599 } else if (free_op1 != object) {
3600 GC_ADDREF(obj); /* For $this pointer */
3601 FREE_OP1();
3602 }
3603 /* CV may be changed indirectly (e.g. when it's a reference) */
3604 call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
3605 }
3606
3607 call = zend_vm_stack_push_call_frame(call_info,
3608 fbc, opline->extended_value, obj);
3609 call->prev_execute_data = EX(call);
3610 EX(call) = call;
3611
3612 ZEND_VM_NEXT_OPCODE();
3613 }
3614
3615 ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM|CACHE_SLOT)
3616 {
3617 USE_OPLINE
3618 zval *function_name;
3619 zend_class_entry *ce;
3620 uint32_t call_info;
3621 zend_function *fbc;
3622 zend_execute_data *call;
3623
3624 SAVE_OPLINE();
3625
3626 if (OP1_TYPE == IS_CONST) {
3627 /* no function found. try a static method in class */
3628 ce = CACHED_PTR(opline->result.num);
3629 if (UNEXPECTED(ce == NULL)) {
3630 ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
3631 if (UNEXPECTED(ce == NULL)) {
3632 ZEND_ASSERT(EG(exception));
3633 FREE_UNFETCHED_OP2();
3634 HANDLE_EXCEPTION();
3635 }
3636 if (OP2_TYPE != IS_CONST) {
3637 CACHE_PTR(opline->result.num, ce);
3638 }
3639 }
3640 } else if (OP1_TYPE == IS_UNUSED) {
3641 ce = zend_fetch_class(NULL, opline->op1.num);
3642 if (UNEXPECTED(ce == NULL)) {
3643 ZEND_ASSERT(EG(exception));
3644 FREE_UNFETCHED_OP2();
3645 HANDLE_EXCEPTION();
3646 }
3647 } else {
3648 ce = Z_CE_P(EX_VAR(opline->op1.var));
3649 }
3650
3651 if (OP1_TYPE == IS_CONST &&
3652 OP2_TYPE == IS_CONST &&
3653 EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
3654 /* nothing to do */
3655 } else if (OP1_TYPE != IS_CONST &&
3656 OP2_TYPE == IS_CONST &&
3657 EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
3658 fbc = CACHED_PTR(opline->result.num + sizeof(void*));
3659 } else if (OP2_TYPE != IS_UNUSED) {
3660 zend_free_op free_op2;
3661
3662 function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3663 if (OP2_TYPE != IS_CONST) {
3664 if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
3665 do {
3666 if (OP2_TYPE & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
3667 function_name = Z_REFVAL_P(function_name);
3668 if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
3669 break;
3670 }
3671 } else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
3672 ZVAL_UNDEFINED_OP2();
3673 if (UNEXPECTED(EG(exception) != NULL)) {
3674 HANDLE_EXCEPTION();
3675 }
3676 }
3677 zend_throw_error(NULL, "Function name must be a string");
3678 FREE_OP2();
3679 HANDLE_EXCEPTION();
3680 } while (0);
3681 }
3682 }
3683
3684 if (ce->get_static_method) {
3685 fbc = ce->get_static_method(ce, Z_STR_P(function_name));
3686 } else {
3687 fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
3688 }
3689 if (UNEXPECTED(fbc == NULL)) {
3690 if (EXPECTED(!EG(exception))) {
3691 zend_undefined_method(ce, Z_STR_P(function_name));
3692 }
3693 FREE_OP2();
3694 HANDLE_EXCEPTION();
3695 }
3696 if (OP2_TYPE == IS_CONST &&
3697 EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
3698 EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
3699 CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
3700 }
3701 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
3702 init_func_run_time_cache(&fbc->op_array);
3703 }
3704 if (OP2_TYPE != IS_CONST) {
3705 FREE_OP2();
3706 }
3707 } else {
3708 if (UNEXPECTED(ce->constructor == NULL)) {
3709 zend_throw_error(NULL, "Cannot call constructor");
3710 HANDLE_EXCEPTION();
3711 }
3712 if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
3713 zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
3714 HANDLE_EXCEPTION();
3715 }
3716 fbc = ce->constructor;
3717 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
3718 init_func_run_time_cache(&fbc->op_array);
3719 }
3720 }
3721
3722 if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
3723 if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
3724 ce = (zend_class_entry*)Z_OBJ(EX(This));
3725 call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
3726 } else {
3727 zend_non_static_method_call(fbc);
3728 if (UNEXPECTED(EG(exception) != NULL)) {
3729 HANDLE_EXCEPTION();
3730 }
3731 ZEND_VM_C_GOTO(check_parent_and_self);
3732 }
3733 } else {
3734 ZEND_VM_C_LABEL(check_parent_and_self):
3735 /* previous opcode is ZEND_FETCH_CLASS */
3736 if (OP1_TYPE == IS_UNUSED
3737 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
3738 (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
3739 if (Z_TYPE(EX(This)) == IS_OBJECT) {
3740 ce = Z_OBJCE(EX(This));
3741 } else {
3742 ce = Z_CE(EX(This));
3743 }
3744 }
3745 call_info = ZEND_CALL_NESTED_FUNCTION;
3746 }
3747
3748 call = zend_vm_stack_push_call_frame(call_info,
3749 fbc, opline->extended_value, ce);
3750 call->prev_execute_data = EX(call);
3751 EX(call) = call;
3752
3753 ZEND_VM_NEXT_OPCODE();
3754 }
3755
3756 ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
3757 {
3758 USE_OPLINE
3759 zend_function *fbc;
3760 zval *function_name, *func;
3761 zend_execute_data *call;
3762
3763 fbc = CACHED_PTR(opline->result.num);
3764 if (UNEXPECTED(fbc == NULL)) {
3765 function_name = (zval*)RT_CONSTANT(opline, opline->op2);
3766 func = zend_hash_find_ex(EG(function_table), Z_STR_P(function_name+1), 1);
3767 if (UNEXPECTED(func == NULL)) {
3768 ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
3769 }
3770 fbc = Z_FUNC_P(func);
3771 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
3772 init_func_run_time_cache(&fbc->op_array);
3773 }
3774 CACHE_PTR(opline->result.num, fbc);
3775 }
3776 call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3777 fbc, opline->extended_value, NULL);
3778 call->prev_execute_data = EX(call);
3779 EX(call) = call;
3780
3781 ZEND_VM_NEXT_OPCODE();
3782 }
3783
3784 ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV, NUM)
3785 {
3786 USE_OPLINE
3787 zend_free_op free_op2;
3788 zval *function_name;
3789 zend_execute_data *call;
3790
3791 SAVE_OPLINE();
3792 function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
3793
3794 ZEND_VM_C_LABEL(try_function_name):
3795 if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
3796 call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value);
3797 } else if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
3798 call = zend_init_dynamic_call_object(function_name, opline->extended_value);
3799 } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) {
3800 call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value);
3801 } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
3802 function_name = Z_REFVAL_P(function_name);
3803 ZEND_VM_C_GOTO(try_function_name);
3804 } else {
3805 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
3806 ZVAL_UNDEFINED_OP2();
3807 if (UNEXPECTED(EG(exception) != NULL)) {
3808 HANDLE_EXCEPTION();
3809 }
3810 }
3811 zend_throw_error(NULL, "Function name must be a string");
3812 call = NULL;
3813 }
3814
3815 FREE_OP2();
3816 if (UNEXPECTED(!call)) {
3817 HANDLE_EXCEPTION();
3818 }
3819
3820 if (OP2_TYPE & (IS_VAR|IS_TMP_VAR)) {
3821 if (UNEXPECTED(EG(exception))) {
3822 if (call) {
3823 if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
3824 zend_string_release_ex(call->func->common.function_name, 0);
3825 zend_free_trampoline(call->func);
3826 }
3827 zend_vm_stack_free_call_frame(call);
3828 }
3829 HANDLE_EXCEPTION();
3830 }
3831 }
3832
3833 call->prev_execute_data = EX(call);
3834 EX(call) = call;
3835
3836 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3837 }
3838
3839 ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
3840 {
3841 USE_OPLINE
3842 zend_free_op free_op2;
3843 zval *function_name;
3844 zend_fcall_info_cache fcc;
3845 char *error = NULL;
3846 zend_function *func;
3847 void *object_or_called_scope;
3848 zend_execute_data *call;
3849 uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
3850
3851 SAVE_OPLINE();
3852 function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
3853 if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
3854 func = fcc.function_handler;
3855 if (error) {
3856 efree(error);
3857 /* This is the only soft error is_callable() can generate */
3858 zend_non_static_method_call(func);
3859 if (UNEXPECTED(EG(exception) != NULL)) {
3860 FREE_OP2();
3861 HANDLE_EXCEPTION();
3862 }
3863 }
3864 object_or_called_scope = fcc.called_scope;
3865 if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
3866 /* Delay closure destruction until its invocation */
3867 GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
3868 call_info |= ZEND_CALL_CLOSURE;
3869 if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
3870 call_info |= ZEND_CALL_FAKE_CLOSURE;
3871 }
3872 if (fcc.object) {
3873 object_or_called_scope = fcc.object;
3874 call_info |= ZEND_CALL_HAS_THIS;
3875 }
3876 } else if (fcc.object) {
3877 GC_ADDREF(fcc.object); /* For $this pointer */
3878 object_or_called_scope = fcc.object;
3879 call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
3880 }
3881
3882 FREE_OP2();
3883 if ((OP2_TYPE & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
3884 if (call_info & ZEND_CALL_CLOSURE) {
3885 zend_object_release(ZEND_CLOSURE_OBJECT(func));
3886 } else if (call_info & ZEND_CALL_RELEASE_THIS) {
3887 zend_object_release(fcc.object);
3888 }
3889 HANDLE_EXCEPTION();
3890 }
3891
3892 if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
3893 init_func_run_time_cache(&func->op_array);
3894 }
3895 } else {
3896 zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error);
3897 efree(error);
3898 FREE_OP2();
3899 if (UNEXPECTED(EG(exception))) {
3900 HANDLE_EXCEPTION();
3901 }
3902 func = (zend_function*)&zend_pass_function;
3903 object_or_called_scope = NULL;
3904 }
3905
3906 call = zend_vm_stack_push_call_frame(call_info,
3907 func, opline->extended_value, object_or_called_scope);
3908 call->prev_execute_data = EX(call);
3909 EX(call) = call;
3910
3911 ZEND_VM_NEXT_OPCODE();
3912 }
3913
3914 ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
3915 {
3916 USE_OPLINE
3917 zval *func_name;
3918 zval *func;
3919 zend_function *fbc;
3920 zend_execute_data *call;
3921
3922 fbc = CACHED_PTR(opline->result.num);
3923 if (UNEXPECTED(fbc == NULL)) {
3924 func_name = (zval *)RT_CONSTANT(opline, opline->op2);
3925 func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name + 1), 1);
3926 if (func == NULL) {
3927 func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name + 2), 1);
3928 if (UNEXPECTED(func == NULL)) {
3929 ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
3930 }
3931 }
3932 fbc = Z_FUNC_P(func);
3933 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
3934 init_func_run_time_cache(&fbc->op_array);
3935 }
3936 CACHE_PTR(opline->result.num, fbc);
3937 }
3938
3939 call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3940 fbc, opline->extended_value, NULL);
3941 call->prev_execute_data = EX(call);
3942 EX(call) = call;
3943
3944 ZEND_VM_NEXT_OPCODE();
3945 }
3946
3947 ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT)
3948 {
3949 USE_OPLINE
3950 zval *fname;
3951 zval *func;
3952 zend_function *fbc;
3953 zend_execute_data *call;
3954
3955 fbc = CACHED_PTR(opline->result.num);
3956 if (UNEXPECTED(fbc == NULL)) {
3957 fname = (zval*)RT_CONSTANT(opline, opline->op2);
3958 func = zend_hash_find_ex(EG(function_table), Z_STR_P(fname), 1);
3959 if (UNEXPECTED(func == NULL)) {
3960 ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
3961 }
3962 fbc = Z_FUNC_P(func);
3963 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
3964 init_func_run_time_cache(&fbc->op_array);
3965 }
3966 CACHE_PTR(opline->result.num, fbc);
3967 }
3968
3969 call = _zend_vm_stack_push_call_frame_ex(
3970 opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
3971 fbc, opline->extended_value, NULL);
3972 call->prev_execute_data = EX(call);
3973 EX(call) = call;
3974
3975 ZEND_VM_NEXT_OPCODE();
3976 }
3977
3978 ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
3979 {
3980 USE_OPLINE
3981 zend_execute_data *call = EX(call);
3982 zend_function *fbc = call->func;
3983 zval *ret;
3984 zval retval;
3985
3986 SAVE_OPLINE();
3987 EX(call) = call->prev_execute_data;
3988
3989 call->prev_execute_data = execute_data;
3990 EG(current_execute_data) = call;
3991
3992 ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
3993 ZVAL_NULL(ret);
3994
3995 fbc->internal_function.handler(call, ret);
3996
3997 #if ZEND_DEBUG
3998 if (!EG(exception) && call->func) {
3999 ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
4000 zend_verify_internal_return_type(call->func, ret));
4001 ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
4002 ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
4003 }
4004 #endif
4005
4006 EG(current_execute_data) = execute_data;
4007 zend_vm_stack_free_args(call);
4008 zend_vm_stack_free_call_frame(call);
4009
4010 if (!RETURN_VALUE_USED(opline)) {
4011 i_zval_ptr_dtor(ret);
4012 }
4013
4014 if (UNEXPECTED(EG(exception) != NULL)) {
4015 zend_rethrow_exception(execute_data);
4016 HANDLE_EXCEPTION();
4017 }
4018
4019 ZEND_VM_SET_OPCODE(opline + 1);
4020 ZEND_VM_CONTINUE();
4021 }
4022
4023 ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
4024 {
4025 USE_OPLINE
4026 zend_execute_data *call = EX(call);
4027 zend_function *fbc = call->func;
4028 zval *ret;
4029
4030 SAVE_OPLINE();
4031 EX(call) = call->prev_execute_data;
4032
4033 ret = NULL;
4034 if (RETURN_VALUE_USED(opline)) {
4035 ret = EX_VAR(opline->result.var);
4036 }
4037
4038 call->prev_execute_data = execute_data;
4039 execute_data = call;
4040 i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
4041 LOAD_OPLINE_EX();
4042
4043 ZEND_VM_ENTER_EX();
4044 }
4045
4046 ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
4047 {
4048 USE_OPLINE
4049 zend_execute_data *call = EX(call);
4050 zend_function *fbc = call->func;
4051 zval *ret;
4052
4053 SAVE_OPLINE();
4054 EX(call) = call->prev_execute_data;
4055
4056 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
4057 ret = NULL;
4058 if (RETURN_VALUE_USED(opline)) {
4059 ret = EX_VAR(opline->result.var);
4060 }
4061
4062 call->prev_execute_data = execute_data;
4063 execute_data = call;
4064 i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
4065 LOAD_OPLINE_EX();
4066
4067 ZEND_VM_ENTER_EX();
4068 } else {
4069 zval retval;
4070 ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
4071
4072 if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
4073 zend_deprecated_function(fbc);
4074 if (UNEXPECTED(EG(exception) != NULL)) {
4075 UNDEF_RESULT();
4076 if (!RETURN_VALUE_USED(opline)) {
4077 ret = &retval;
4078 ZVAL_UNDEF(ret);
4079 }
4080 ZEND_VM_C_GOTO(fcall_by_name_end);
4081 }
4082 }
4083
4084 call->prev_execute_data = execute_data;
4085 EG(current_execute_data) = call;
4086
4087 if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
4088 && UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
4089 UNDEF_RESULT();
4090 if (!RETURN_VALUE_USED(opline)) {
4091 ret = &retval;
4092 ZVAL_UNDEF(ret);
4093 }
4094 ZEND_VM_C_GOTO(fcall_by_name_end);
4095 }
4096
4097 ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
4098 ZVAL_NULL(ret);
4099
4100 fbc->internal_function.handler(call, ret);
4101
4102 #if ZEND_DEBUG
4103 if (!EG(exception) && call->func) {
4104 ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
4105 zend_verify_internal_return_type(call->func, ret));
4106 ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
4107 ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
4108 }
4109 #endif
4110
4111 EG(current_execute_data) = execute_data;
4112
4113 ZEND_VM_C_LABEL(fcall_by_name_end):
4114 zend_vm_stack_free_args(call);
4115 zend_vm_stack_free_call_frame(call);
4116
4117 if (!RETURN_VALUE_USED(opline)) {
4118 i_zval_ptr_dtor(ret);
4119 }
4120 }
4121
4122 if (UNEXPECTED(EG(exception) != NULL)) {
4123 zend_rethrow_exception(execute_data);
4124 HANDLE_EXCEPTION();
4125 }
4126 ZEND_VM_SET_OPCODE(opline + 1);
4127 ZEND_VM_CONTINUE();
4128 }
4129
4130 ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
4131 {
4132 USE_OPLINE
4133 zend_execute_data *call = EX(call);
4134 zend_function *fbc = call->func;
4135 zval *ret;
4136 zval retval;
4137
4138 SAVE_OPLINE();
4139 EX(call) = call->prev_execute_data;
4140 if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
4141 if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
4142 zend_abstract_method(fbc);
4143 ZEND_VM_C_LABEL(fcall_except):
4144 UNDEF_RESULT();
4145 if (!RETURN_VALUE_USED(opline)) {
4146 ret = &retval;
4147 ZVAL_UNDEF(ret);
4148 }
4149 ZEND_VM_C_GOTO(fcall_end);
4150 } else {
4151 zend_deprecated_function(fbc);
4152 if (UNEXPECTED(EG(exception) != NULL)) {
4153 ZEND_VM_C_GOTO(fcall_except);
4154 }
4155 }
4156 }
4157
4158 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
4159 ret = NULL;
4160 if (RETURN_VALUE_USED(opline)) {
4161 ret = EX_VAR(opline->result.var);
4162 }
4163
4164 call->prev_execute_data = execute_data;
4165 execute_data = call;
4166 i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
4167
4168 if (EXPECTED(zend_execute_ex == execute_ex)) {
4169 LOAD_OPLINE_EX();
4170 ZEND_VM_ENTER_EX();
4171 } else {
4172 SAVE_OPLINE_EX();
4173 execute_data = EX(prev_execute_data);
4174 LOAD_OPLINE();
4175 ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
4176 zend_execute_ex(call);
4177 }
4178 } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
4179 call->prev_execute_data = execute_data;
4180 EG(current_execute_data) = call;
4181
4182 if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
4183 && UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
4184 ZEND_VM_C_GOTO(fcall_except);
4185 }
4186
4187 ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
4188 ZVAL_NULL(ret);
4189
4190 if (!zend_execute_internal) {
4191 /* saves one function call if zend_execute_internal is not used */
4192 fbc->internal_function.handler(call, ret);
4193 } else {
4194 zend_execute_internal(call, ret);
4195 }
4196
4197 #if ZEND_DEBUG
4198 if (!EG(exception) && call->func) {
4199 ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
4200 zend_verify_internal_return_type(call->func, ret));
4201 ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
4202 ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
4203 }
4204 #endif
4205
4206 EG(current_execute_data) = execute_data;
4207
4208 ZEND_VM_C_LABEL(fcall_end):
4209 zend_vm_stack_free_args(call);
4210 if (!RETURN_VALUE_USED(opline)) {
4211 i_zval_ptr_dtor(ret);
4212 }
4213 } else { /* ZEND_OVERLOADED_FUNCTION */
4214 ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
4215
4216 call->prev_execute_data = execute_data;
4217
4218 if (UNEXPECTED(!zend_do_fcall_overloaded(call, ret))) {
4219 UNDEF_RESULT();
4220 HANDLE_EXCEPTION();
4221 }
4222
4223 if (!RETURN_VALUE_USED(opline)) {
4224 zval_ptr_dtor(ret);
4225 }
4226 }
4227
4228 if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
4229 OBJ_RELEASE(Z_OBJ(call->This));
4230 }
4231
4232 zend_vm_stack_free_call_frame(call);
4233 if (UNEXPECTED(EG(exception) != NULL)) {
4234 zend_rethrow_exception(execute_data);
4235 HANDLE_EXCEPTION();
4236 }
4237
4238 ZEND_VM_SET_OPCODE(opline + 1);
4239 ZEND_VM_CONTINUE();
4240 }
4241
4242 ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED|CACHE_SLOT)
4243 {
4244 USE_OPLINE
4245
4246 SAVE_OPLINE();
4247 if (OP1_TYPE == IS_UNUSED) {
4248 zend_verify_missing_return_type(EX(func), CACHE_ADDR(opline->op2.num));
4249 } else {
4250 /* prevents "undefined variable opline" errors */
4251 #if !ZEND_VM_SPEC || (OP1_TYPE != IS_UNUSED)
4252 zval *retval_ref, *retval_ptr;
4253 zend_free_op free_op1;
4254 zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
4255
4256 retval_ref = retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4257
4258 if (OP1_TYPE == IS_CONST) {
4259 ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
4260 retval_ref = retval_ptr = EX_VAR(opline->result.var);
4261 } else if (OP1_TYPE == IS_VAR) {
4262 if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
4263 retval_ptr = Z_INDIRECT_P(retval_ptr);
4264 }
4265 ZVAL_DEREF(retval_ptr);
4266 } else if (OP1_TYPE == IS_CV) {
4267 ZVAL_DEREF(retval_ptr);
4268 }
4269
4270 if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
4271 && ZEND_TYPE_CODE(ret_info->type) != IS_CALLABLE
4272 && ZEND_TYPE_CODE(ret_info->type) != IS_ITERABLE
4273 && !ZEND_SAME_FAKE_TYPE(ZEND_TYPE_CODE(ret_info->type), Z_TYPE_P(retval_ptr))
4274 && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
4275 && retval_ref != retval_ptr)
4276 ) {
4277 /* A cast might happen - unwrap the reference if this is a by-value return */
4278 if (Z_REFCOUNT_P(retval_ref) == 1) {
4279 ZVAL_UNREF(retval_ref);
4280 } else {
4281 Z_DELREF_P(retval_ref);
4282 ZVAL_COPY(retval_ref, retval_ptr);
4283 }
4284 retval_ptr = retval_ref;
4285 }
4286 zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num));
4287 #endif
4288 }
4289 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4290 }
4291
4292 ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
4293 {
4294 USE_OPLINE
4295 zval *retval_ptr;
4296 zval *return_value;
4297 zend_free_op free_op1;
4298
4299 retval_ptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4300 return_value = EX(return_value);
4301 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
4302 SAVE_OPLINE();
4303 retval_ptr = ZVAL_UNDEFINED_OP1();
4304 if (return_value) {
4305 ZVAL_NULL(return_value);
4306 }
4307 } else if (!return_value) {
4308 if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
4309 if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
4310 SAVE_OPLINE();
4311 rc_dtor_func(Z_COUNTED_P(free_op1));
4312 }
4313 }
4314 } else {
4315 if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
4316 ZVAL_COPY_VALUE(return_value, retval_ptr);
4317 if (OP1_TYPE == IS_CONST) {
4318 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
4319 Z_ADDREF_P(return_value);
4320 }
4321 }
4322 } else if (OP1_TYPE == IS_CV) {
4323 do {
4324 if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
4325 if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
4326 if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
4327 zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
4328 ZVAL_COPY_VALUE(return_value, retval_ptr);
4329 if (GC_MAY_LEAK(ref)) {
4330 gc_possible_root(ref);
4331 }
4332 ZVAL_NULL(retval_ptr);
4333 break;
4334 } else {
4335 Z_ADDREF_P(retval_ptr);
4336 }
4337 } else {
4338 retval_ptr = Z_REFVAL_P(retval_ptr);
4339 if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
4340 Z_ADDREF_P(retval_ptr);
4341 }
4342 }
4343 }
4344 ZVAL_COPY_VALUE(return_value, retval_ptr);
4345 } while (0);
4346 } else /* if (OP1_TYPE == IS_VAR) */ {
4347 if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
4348 zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
4349
4350 retval_ptr = Z_REFVAL_P(retval_ptr);
4351 ZVAL_COPY_VALUE(return_value, retval_ptr);
4352 if (UNEXPECTED(GC_DELREF(ref) == 0)) {
4353 efree_size(ref, sizeof(zend_reference));
4354 } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
4355 Z_ADDREF_P(retval_ptr);
4356 }
4357 } else {
4358 ZVAL_COPY_VALUE(return_value, retval_ptr);
4359 }
4360 }
4361 }
4362 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
4363 }
4364
4365 ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
4366 {
4367 USE_OPLINE
4368 zval *retval_ptr;
4369 zend_free_op free_op1;
4370
4371 SAVE_OPLINE();
4372
4373 do {
4374 if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR)) ||
4375 (OP1_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
4376 /* Not supposed to happen, but we'll allow it */
4377 zend_error(E_NOTICE, "Only variable references should be returned by reference");
4378
4379 retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4380 if (!EX(return_value)) {
4381 FREE_OP1();
4382 } else {
4383 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
4384 ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
4385 break;
4386 }
4387
4388 ZVAL_NEW_REF(EX(return_value), retval_ptr);
4389 if (OP1_TYPE == IS_CONST) {
4390 Z_TRY_ADDREF_P(retval_ptr);
4391 }
4392 }
4393 break;
4394 }
4395
4396 retval_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
4397
4398 if (OP1_TYPE == IS_VAR) {
4399 ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
4400 if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
4401 zend_error(E_NOTICE, "Only variable references should be returned by reference");
4402 if (EX(return_value)) {
4403 ZVAL_NEW_REF(EX(return_value), retval_ptr);
4404 } else {
4405 FREE_OP1_VAR_PTR();
4406 }
4407 break;
4408 }
4409 }
4410
4411 if (EX(return_value)) {
4412 if (Z_ISREF_P(retval_ptr)) {
4413 Z_ADDREF_P(retval_ptr);
4414 } else {
4415 ZVAL_MAKE_REF_EX(retval_ptr, 2);
4416 }
4417 ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
4418 }
4419
4420 FREE_OP1_VAR_PTR();
4421 } while (0);
4422
4423 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
4424 }
4425
4426 ZEND_VM_HANDLER(139, ZEND_GENERATOR_CREATE, ANY, ANY)
4427 {
4428 zval *return_value = EX(return_value);
4429
4430 if (EXPECTED(return_value)) {
4431 USE_OPLINE
4432 zend_generator *generator;
4433 zend_execute_data *gen_execute_data;
4434 uint32_t num_args, used_stack, call_info;
4435
4436 object_init_ex(return_value, zend_ce_generator);
4437
4438 /*
4439 * Normally the execute_data is allocated on the VM stack (because it does
4440 * not actually do any allocation and thus is faster). For generators
4441 * though this behavior would be suboptimal, because the (rather large)
4442 * structure would have to be copied back and forth every time execution is
4443 * suspended or resumed. That's why for generators the execution context
4444 * is allocated on heap.
4445 */
4446 num_args = EX_NUM_ARGS();
4447 if (EXPECTED(num_args <= EX(func)->op_array.num_args)) {
4448 used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var + EX(func)->op_array.T) * sizeof(zval);
4449 gen_execute_data = (zend_execute_data*)emalloc(used_stack);
4450 used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var) * sizeof(zval);
4451 } else {
4452 used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - EX(func)->op_array.num_args) * sizeof(zval);
4453 gen_execute_data = (zend_execute_data*)emalloc(used_stack);
4454 }
4455 memcpy(gen_execute_data, execute_data, used_stack);
4456
4457 /* Save execution context in generator object. */
4458 generator = (zend_generator *) Z_OBJ_P(EX(return_value));
4459 generator->execute_data = gen_execute_data;
4460 generator->frozen_call_stack = NULL;
4461 generator->execute_fake.opline = NULL;
4462 generator->execute_fake.func = NULL;
4463 generator->execute_fake.prev_execute_data = NULL;
4464 ZVAL_OBJ(&generator->execute_fake.This, (zend_object *) generator);
4465
4466 gen_execute_data->opline = opline + 1;
4467 /* EX(return_value) keeps pointer to zend_object (not a real zval) */
4468 gen_execute_data->return_value = (zval*)generator;
4469 call_info = Z_TYPE_INFO(EX(This));
4470 if ((call_info & Z_TYPE_MASK) == IS_OBJECT
4471 && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS))
4472 /* Bug #72523 */
4473 || UNEXPECTED(zend_execute_ex != execute_ex))) {
4474 ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS);
4475 Z_ADDREF(gen_execute_data->This);
4476 }
4477 ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR));
4478 Z_TYPE_INFO(gen_execute_data->This) = call_info;
4479 gen_execute_data->prev_execute_data = NULL;
4480
4481 call_info = EX_CALL_INFO();
4482 EG(current_execute_data) = EX(prev_execute_data);
4483 if (EXPECTED(!(call_info & (ZEND_CALL_TOP|ZEND_CALL_ALLOCATED)))) {
4484 EG(vm_stack_top) = (zval*)execute_data;
4485 execute_data = EX(prev_execute_data);
4486 LOAD_NEXT_OPLINE();
4487 ZEND_VM_LEAVE();
4488 } else if (EXPECTED(!(call_info & ZEND_CALL_TOP))) {
4489 zend_execute_data *old_execute_data = execute_data;
4490 execute_data = EX(prev_execute_data);
4491 zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
4492 LOAD_NEXT_OPLINE();
4493 ZEND_VM_LEAVE();
4494 } else {
4495 ZEND_VM_RETURN();
4496 }
4497 } else {
4498 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
4499 }
4500 }
4501
4502 ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY)
4503 {
4504 USE_OPLINE
4505 zval *retval;
4506 zend_free_op free_op1;
4507
4508 zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
4509
4510 SAVE_OPLINE();
4511 retval = GET_OP1_ZVAL_PTR(BP_VAR_R);
4512
4513 /* Copy return value into generator->retval */
4514 if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
4515 ZVAL_COPY_VALUE(&generator->retval, retval);
4516 if (OP1_TYPE == IS_CONST) {
4517 if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
4518 Z_ADDREF(generator->retval);
4519 }
4520 }
4521 } else if (OP1_TYPE == IS_CV) {
4522 ZVAL_COPY_DEREF(&generator->retval, retval);
4523 } else /* if (OP1_TYPE == IS_VAR) */ {
4524 if (UNEXPECTED(Z_ISREF_P(retval))) {
4525 zend_refcounted *ref = Z_COUNTED_P(retval);
4526
4527 retval = Z_REFVAL_P(retval);
4528 ZVAL_COPY_VALUE(&generator->retval, retval);
4529 if (UNEXPECTED(GC_DELREF(ref) == 0)) {
4530 efree_size(ref, sizeof(zend_reference));
4531 } else if (Z_OPT_REFCOUNTED_P(retval)) {
4532 Z_ADDREF_P(retval);
4533 }
4534 } else {
4535 ZVAL_COPY_VALUE(&generator->retval, retval);
4536 }
4537 }
4538
4539 /* Close the generator to free up resources */
4540 zend_generator_close(generator, 1);
4541
4542 /* Pass execution back to handling code */
4543 ZEND_VM_RETURN();
4544 }
4545
4546 ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
4547 {
4548 USE_OPLINE
4549 zval *value;
4550 zend_free_op free_op1;
4551
4552 SAVE_OPLINE();
4553 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4554
4555 do {
4556 if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
4557 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
4558 value = Z_REFVAL_P(value);
4559 if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
4560 break;
4561 }
4562 }
4563 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
4564 ZVAL_UNDEFINED_OP1();
4565 if (UNEXPECTED(EG(exception) != NULL)) {
4566 HANDLE_EXCEPTION();
4567 }
4568 }
4569 zend_throw_error(NULL, "Can only throw objects");
4570 FREE_OP1();
4571 HANDLE_EXCEPTION();
4572 }
4573 } while (0);
4574
4575 zend_exception_save();
4576 if (OP1_TYPE != IS_TMP_VAR) {
4577 Z_TRY_ADDREF_P(value);
4578 }
4579
4580 zend_throw_exception_object(value);
4581 zend_exception_restore();
4582 FREE_OP1_IF_VAR();
4583 HANDLE_EXCEPTION();
4584 }
4585
4586 ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
4587 {
4588 USE_OPLINE
4589 zend_class_entry *ce, *catch_ce;
4590 zend_object *exception;
4591 zval *ex;
4592
4593 SAVE_OPLINE();
4594 /* Check whether an exception has been thrown, if not, jump over code */
4595 zend_exception_restore();
4596 if (EG(exception) == NULL) {
4597 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
4598 }
4599 catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
4600 if (UNEXPECTED(catch_ce == NULL)) {
4601 catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
4602
4603 CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
4604 }
4605 ce = EG(exception)->ce;
4606
4607 #ifdef HAVE_DTRACE
4608 if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
4609 DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
4610 }
4611 #endif /* HAVE_DTRACE */
4612
4613 if (ce != catch_ce) {
4614 if (!catch_ce || !instanceof_function(ce, catch_ce)) {
4615 if (opline->extended_value & ZEND_LAST_CATCH) {
4616 zend_rethrow_exception(execute_data);
4617 HANDLE_EXCEPTION();
4618 }
4619 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
4620 }
4621 }
4622
4623 exception = EG(exception);
4624 ex = EX_VAR(opline->result.var);
4625 {
4626 /* Always perform a strict assignment. There is a reasonable expectation that if you
4627 * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such,
4628 * we should not permit coercion to string here. */
4629 zval tmp;
4630 ZVAL_OBJ(&tmp, exception);
4631 EG(exception) = NULL;
4632 zend_assign_to_variable(ex, &tmp, IS_TMP_VAR, /* strict */ 1);
4633 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4634 }
4635 }
4636
4637 ZEND_VM_HOT_HANDLER(65, ZEND_SEND_VAL, CONST|TMPVAR, NUM)
4638 {
4639 USE_OPLINE
4640 zval *value, *arg;
4641 zend_free_op free_op1;
4642
4643 value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4644 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4645 ZVAL_COPY_VALUE(arg, value);
4646 if (OP1_TYPE == IS_CONST) {
4647 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
4648 Z_ADDREF_P(arg);
4649 }
4650 }
4651 ZEND_VM_NEXT_OPCODE();
4652 }
4653
ZEND_VM_COLD_HELPER(zend_cannot_pass_by_ref_helper,ANY,ANY)4654 ZEND_VM_COLD_HELPER(zend_cannot_pass_by_ref_helper, ANY, ANY)
4655 {
4656 USE_OPLINE
4657 zval *arg;
4658 uint32_t arg_num = opline->op2.num;
4659
4660 SAVE_OPLINE();
4661 zend_throw_error(NULL, "Cannot pass parameter %d by reference", arg_num);
4662 FREE_UNFETCHED_OP1();
4663 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4664 ZVAL_UNDEF(arg);
4665 HANDLE_EXCEPTION();
4666 }
4667
4668 ZEND_VM_HOT_SEND_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, NUM, SPEC(QUICK_ARG))
4669 {
4670 USE_OPLINE
4671 zval *value, *arg;
4672 zend_free_op free_op1;
4673 uint32_t arg_num = opline->op2.num;
4674
4675 if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
4676 if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4677 ZEND_VM_C_GOTO(send_val_by_ref);
4678 }
4679 } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4680 ZEND_VM_C_LABEL(send_val_by_ref):
4681 ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper);
4682 }
4683 value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4684 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4685 ZVAL_COPY_VALUE(arg, value);
4686 if (OP1_TYPE == IS_CONST) {
4687 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
4688 Z_ADDREF_P(arg);
4689 }
4690 }
4691 ZEND_VM_NEXT_OPCODE();
4692 }
4693
4694 ZEND_VM_HOT_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM)
4695 {
4696 USE_OPLINE
4697 zval *varptr, *arg;
4698 zend_free_op free_op1;
4699
4700 varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4701 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
4702 SAVE_OPLINE();
4703 ZVAL_UNDEFINED_OP1();
4704 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4705 ZVAL_NULL(arg);
4706 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4707 }
4708
4709 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4710
4711 if (OP1_TYPE == IS_CV) {
4712 ZVAL_COPY_DEREF(arg, varptr);
4713 } else /* if (OP1_TYPE == IS_VAR) */ {
4714 if (UNEXPECTED(Z_ISREF_P(varptr))) {
4715 zend_refcounted *ref = Z_COUNTED_P(varptr);
4716
4717 varptr = Z_REFVAL_P(varptr);
4718 ZVAL_COPY_VALUE(arg, varptr);
4719 if (UNEXPECTED(GC_DELREF(ref) == 0)) {
4720 efree_size(ref, sizeof(zend_reference));
4721 } else if (Z_OPT_REFCOUNTED_P(arg)) {
4722 Z_ADDREF_P(arg);
4723 }
4724 } else {
4725 ZVAL_COPY_VALUE(arg, varptr);
4726 }
4727 }
4728
4729 ZEND_VM_NEXT_OPCODE();
4730 }
4731
4732 ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM)
4733 {
4734 USE_OPLINE
4735 zend_free_op free_op1;
4736 zval *varptr, *arg;
4737
4738 varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4739 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4740 ZVAL_COPY_VALUE(arg, varptr);
4741
4742 if (EXPECTED(Z_ISREF_P(varptr))) {
4743 ZEND_VM_NEXT_OPCODE();
4744 }
4745
4746 SAVE_OPLINE();
4747 ZVAL_NEW_REF(arg, arg);
4748 zend_error(E_NOTICE, "Only variables should be passed by reference");
4749 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4750 }
4751
4752 ZEND_VM_HOT_SEND_HANDLER(50, ZEND_SEND_VAR_NO_REF_EX, VAR, NUM, SPEC(QUICK_ARG))
4753 {
4754 USE_OPLINE
4755 zend_free_op free_op1;
4756 zval *varptr, *arg;
4757 uint32_t arg_num = opline->op2.num;
4758
4759 if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
4760 if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4761 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
4762 }
4763
4764 varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4765 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4766 ZVAL_COPY_VALUE(arg, varptr);
4767
4768 if (EXPECTED(Z_ISREF_P(varptr) ||
4769 QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
4770 ZEND_VM_NEXT_OPCODE();
4771 }
4772 } else {
4773 if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4774 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
4775 }
4776
4777 varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4778 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4779 ZVAL_COPY_VALUE(arg, varptr);
4780
4781 if (EXPECTED(Z_ISREF_P(varptr) ||
4782 ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
4783 ZEND_VM_NEXT_OPCODE();
4784 }
4785 }
4786
4787 SAVE_OPLINE();
4788 ZVAL_NEW_REF(arg, arg);
4789 zend_error(E_NOTICE, "Only variables should be passed by reference");
4790 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4791 }
4792
4793 ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, NUM)
4794 {
4795 USE_OPLINE
4796 zend_free_op free_op1;
4797 zval *varptr, *arg;
4798
4799 SAVE_OPLINE();
4800 varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
4801
4802 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4803 if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(varptr))) {
4804 ZVAL_NEW_EMPTY_REF(arg);
4805 ZVAL_NULL(Z_REFVAL_P(arg));
4806 ZEND_VM_NEXT_OPCODE();
4807 }
4808
4809 if (Z_ISREF_P(varptr)) {
4810 Z_ADDREF_P(varptr);
4811 } else {
4812 ZVAL_MAKE_REF_EX(varptr, 2);
4813 }
4814 ZVAL_REF(arg, Z_REF_P(varptr));
4815
4816 FREE_OP1_VAR_PTR();
4817 ZEND_VM_NEXT_OPCODE();
4818 }
4819
4820 ZEND_VM_HOT_SEND_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, NUM, SPEC(QUICK_ARG))
4821 {
4822 USE_OPLINE
4823 zval *varptr, *arg;
4824 zend_free_op free_op1;
4825 uint32_t arg_num = opline->op2.num;
4826
4827 if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
4828 if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4829 ZEND_VM_C_GOTO(send_var_by_ref);
4830 }
4831 } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4832 ZEND_VM_C_LABEL(send_var_by_ref):
4833 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
4834 }
4835
4836 varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4837 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
4838 SAVE_OPLINE();
4839 ZVAL_UNDEFINED_OP1();
4840 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4841 ZVAL_NULL(arg);
4842 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4843 }
4844
4845 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4846
4847 if (OP1_TYPE == IS_CV) {
4848 ZVAL_COPY_DEREF(arg, varptr);
4849 } else /* if (OP1_TYPE == IS_VAR) */ {
4850 if (UNEXPECTED(Z_ISREF_P(varptr))) {
4851 zend_refcounted *ref = Z_COUNTED_P(varptr);
4852
4853 varptr = Z_REFVAL_P(varptr);
4854 ZVAL_COPY_VALUE(arg, varptr);
4855 if (UNEXPECTED(GC_DELREF(ref) == 0)) {
4856 efree_size(ref, sizeof(zend_reference));
4857 } else if (Z_OPT_REFCOUNTED_P(arg)) {
4858 Z_ADDREF_P(arg);
4859 }
4860 } else {
4861 ZVAL_COPY_VALUE(arg, varptr);
4862 }
4863 }
4864
4865 ZEND_VM_NEXT_OPCODE();
4866 }
4867
4868 ZEND_VM_HOT_SEND_HANDLER(100, ZEND_CHECK_FUNC_ARG, UNUSED, NUM, SPEC(QUICK_ARG))
4869 {
4870 USE_OPLINE
4871 uint32_t arg_num = opline->op2.num;
4872
4873 if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
4874 if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4875 ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
4876 } else {
4877 ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
4878 }
4879 } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4880 ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
4881 } else {
4882 ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
4883 }
4884 ZEND_VM_NEXT_OPCODE();
4885 }
4886
4887 ZEND_VM_HOT_HANDLER(185, ZEND_SEND_FUNC_ARG, VAR, NUM)
4888 {
4889 USE_OPLINE
4890 zval *varptr, *arg;
4891 zend_free_op free_op1;
4892
4893 if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
4894 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
4895 }
4896
4897 varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4898 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4899
4900 if (UNEXPECTED(Z_ISREF_P(varptr))) {
4901 zend_refcounted *ref = Z_COUNTED_P(varptr);
4902
4903 varptr = Z_REFVAL_P(varptr);
4904 ZVAL_COPY_VALUE(arg, varptr);
4905 if (UNEXPECTED(GC_DELREF(ref) == 0)) {
4906 efree_size(ref, sizeof(zend_reference));
4907 } else if (Z_OPT_REFCOUNTED_P(arg)) {
4908 Z_ADDREF_P(arg);
4909 }
4910 } else {
4911 ZVAL_COPY_VALUE(arg, varptr);
4912 }
4913
4914 ZEND_VM_NEXT_OPCODE();
4915 }
4916
4917 ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
4918 {
4919 USE_OPLINE
4920 zend_free_op free_op1;
4921 zval *args;
4922 int arg_num;
4923
4924 SAVE_OPLINE();
4925 args = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
4926 arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
4927
4928 ZEND_VM_C_LABEL(send_again):
4929 if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
4930 HashTable *ht = Z_ARRVAL_P(args);
4931 zval *arg, *top;
4932 zend_string *name;
4933
4934 zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
4935
4936 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_REFCOUNT_P(args) > 1) {
4937 uint32_t i;
4938 int separate = 0;
4939
4940 /* check if any of arguments are going to be passed by reference */
4941 for (i = 0; i < zend_hash_num_elements(ht); i++) {
4942 if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
4943 separate = 1;
4944 break;
4945 }
4946 }
4947 if (separate) {
4948 SEPARATE_ARRAY(args);
4949 ht = Z_ARRVAL_P(args);
4950 }
4951 }
4952
ZEND_HASH_FOREACH_STR_KEY_VAL(ht,name,arg)4953 ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
4954 if (name) {
4955 zend_throw_error(NULL, "Cannot unpack array with string keys");
4956 FREE_OP1();
4957 HANDLE_EXCEPTION();
4958 }
4959
4960 top = ZEND_CALL_ARG(EX(call), arg_num);
4961 if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4962 if (Z_ISREF_P(arg)) {
4963 Z_ADDREF_P(arg);
4964 ZVAL_REF(top, Z_REF_P(arg));
4965 } else if (OP1_TYPE & (IS_VAR|IS_CV)) {
4966 /* array is already separated above */
4967 ZVAL_MAKE_REF_EX(arg, 2);
4968 ZVAL_REF(top, Z_REF_P(arg));
4969 } else {
4970 Z_TRY_ADDREF_P(arg);
4971 ZVAL_NEW_REF(top, arg);
4972 }
4973 } else {
4974 ZVAL_COPY_DEREF(top, arg);
4975 }
4976
4977 ZEND_CALL_NUM_ARGS(EX(call))++;
4978 arg_num++;
4979 } ZEND_HASH_FOREACH_END();
4980
4981 } else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) {
4982 zend_class_entry *ce = Z_OBJCE_P(args);
4983 zend_object_iterator *iter;
4984
4985 if (!ce || !ce->get_iterator) {
4986 zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
4987 } else {
4988
4989 iter = ce->get_iterator(ce, args, 0);
4990 if (UNEXPECTED(!iter)) {
4991 FREE_OP1();
4992 if (!EG(exception)) {
4993 zend_throw_exception_ex(
4994 NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)
4995 );
4996 }
4997 HANDLE_EXCEPTION();
4998 }
4999
5000 if (iter->funcs->rewind) {
5001 iter->funcs->rewind(iter);
5002 }
5003
5004 for (; iter->funcs->valid(iter) == SUCCESS; ++arg_num) {
5005 zval *arg, *top;
5006
5007 if (UNEXPECTED(EG(exception) != NULL)) {
5008 break;
5009 }
5010
5011 arg = iter->funcs->get_current_data(iter);
5012 if (UNEXPECTED(EG(exception) != NULL)) {
5013 break;
5014 }
5015
5016 if (iter->funcs->get_current_key) {
5017 zval key;
5018 iter->funcs->get_current_key(iter, &key);
5019 if (UNEXPECTED(EG(exception) != NULL)) {
5020 break;
5021 }
5022
5023 if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) {
5024 zend_throw_error(NULL,
5025 (Z_TYPE(key) == IS_STRING) ?
5026 "Cannot unpack Traversable with string keys" :
5027 "Cannot unpack Traversable with non-integer keys");
5028 zval_ptr_dtor(&key);
5029 break;
5030 }
5031 }
5032
5033 if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
5034 zend_error(
5035 E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
5036 " by unpacking a Traversable, passing by-value instead", arg_num,
5037 EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
5038 EX(call)->func->common.scope ? "::" : "",
5039 ZSTR_VAL(EX(call)->func->common.function_name)
5040 );
5041 }
5042
5043 ZVAL_DEREF(arg);
5044 Z_TRY_ADDREF_P(arg);
5045
5046 zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
5047 top = ZEND_CALL_ARG(EX(call), arg_num);
5048 ZVAL_COPY_VALUE(top, arg);
5049 ZEND_CALL_NUM_ARGS(EX(call))++;
5050
5051 iter->funcs->move_forward(iter);
5052 }
5053
5054 zend_iterator_dtor(iter);
5055 }
5056 } else if (EXPECTED(Z_ISREF_P(args))) {
5057 args = Z_REFVAL_P(args);
5058 ZEND_VM_C_GOTO(send_again);
5059 } else {
5060 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) {
5061 ZVAL_UNDEFINED_OP1();
5062 }
5063 zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
5064 }
5065
5066 FREE_OP1();
5067 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5068 }
5069
5070 ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY, NUM)
5071 {
5072 USE_OPLINE
5073 zend_free_op free_op1;
5074 zval *args;
5075
5076 SAVE_OPLINE();
5077 args = GET_OP1_ZVAL_PTR(BP_VAR_R);
5078
5079 if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) {
5080 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(args)) {
5081 args = Z_REFVAL_P(args);
5082 if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
5083 ZEND_VM_C_GOTO(send_array);
5084 }
5085 }
5086 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)));
5087 if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
5088 OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(call)->func));
5089 } else if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_RELEASE_THIS) {
5090 OBJ_RELEASE(Z_OBJ(EX(call)->This));
5091 }
5092 EX(call)->func = (zend_function*)&zend_pass_function;
5093 Z_OBJ(EX(call)->This) = NULL;
5094 ZEND_CALL_INFO(EX(call)) &= ~(ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS);
5095 FREE_UNFETCHED_OP2();
5096 } else {
5097 uint32_t arg_num;
5098 HashTable *ht;
5099 zval *arg, *param;
5100
5101
5102 ZEND_VM_C_LABEL(send_array):
5103 ht = Z_ARRVAL_P(args);
5104 if (OP2_TYPE != IS_UNUSED) {
5105 zend_free_op free_op2;
5106 zval *op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
5107 uint32_t skip = opline->extended_value;
5108 uint32_t count = zend_hash_num_elements(ht);
5109 zend_long len = zval_get_long(op2);
5110
5111 if (len < 0) {
5112 len += (zend_long)(count - skip);
5113 }
5114 if (skip < count && len > 0) {
5115 if (len > (zend_long)(count - skip)) {
5116 len = (zend_long)(count - skip);
5117 }
5118 zend_vm_stack_extend_call_frame(&EX(call), 0, len);
5119 arg_num = 1;
5120 param = ZEND_CALL_ARG(EX(call), 1);
ZEND_HASH_FOREACH_VAL(ht,arg)5121 ZEND_HASH_FOREACH_VAL(ht, arg) {
5122 zend_bool must_wrap = 0;
5123 if (skip > 0) {
5124 skip--;
5125 continue;
5126 } else if ((zend_long)(arg_num - 1) >= len) {
5127 break;
5128 } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
5129 if (UNEXPECTED(!Z_ISREF_P(arg))) {
5130 if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
5131 /* By-value send is not allowed -- emit a warning,
5132 * but still perform the call. */
5133 zend_param_must_be_ref(EX(call)->func, arg_num);
5134 must_wrap = 1;
5135 }
5136 }
5137 } else {
5138 if (Z_ISREF_P(arg) &&
5139 !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
5140 /* don't separate references for __call */
5141 arg = Z_REFVAL_P(arg);
5142 }
5143 }
5144 if (EXPECTED(!must_wrap)) {
5145 ZVAL_COPY(param, arg);
5146 } else {
5147 Z_TRY_ADDREF_P(arg);
5148 ZVAL_NEW_REF(param, arg);
5149 }
5150 ZEND_CALL_NUM_ARGS(EX(call))++;
5151 arg_num++;
5152 param++;
5153 } ZEND_HASH_FOREACH_END();
5154 }
5155 FREE_OP2();
5156 } else {
5157 zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
5158 arg_num = 1;
5159 param = ZEND_CALL_ARG(EX(call), 1);
ZEND_HASH_FOREACH_VAL(ht,arg)5160 ZEND_HASH_FOREACH_VAL(ht, arg) {
5161 zend_bool must_wrap = 0;
5162 if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
5163 if (UNEXPECTED(!Z_ISREF_P(arg))) {
5164 if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
5165 /* By-value send is not allowed -- emit a warning,
5166 * but still perform the call. */
5167 zend_param_must_be_ref(EX(call)->func, arg_num);
5168 must_wrap = 1;
5169 }
5170 }
5171 } else {
5172 if (Z_ISREF_P(arg) &&
5173 !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
5174 /* don't separate references for __call */
5175 arg = Z_REFVAL_P(arg);
5176 }
5177 }
5178 if (EXPECTED(!must_wrap)) {
5179 ZVAL_COPY(param, arg);
5180 } else {
5181 Z_TRY_ADDREF_P(arg);
5182 ZVAL_NEW_REF(param, arg);
5183 }
5184 ZEND_CALL_NUM_ARGS(EX(call))++;
5185 arg_num++;
5186 param++;
5187 } ZEND_HASH_FOREACH_END();
5188 }
5189 }
5190 FREE_OP1();
5191 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5192 }
5193
5194 ZEND_VM_HANDLER(120, ZEND_SEND_USER, CONST|TMP|VAR|CV, NUM)
5195 {
5196 USE_OPLINE
5197 zval *arg, *param;
5198 zend_free_op free_op1;
5199
5200 SAVE_OPLINE();
5201
5202 if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
5203 zend_param_must_be_ref(EX(call)->func, opline->op2.num);
5204 }
5205
5206 arg = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
5207 param = ZEND_CALL_VAR(EX(call), opline->result.var);
5208 ZVAL_COPY(param, arg);
5209 FREE_OP1();
5210 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5211 }
5212
5213 ZEND_VM_HOT_HANDLER(63, ZEND_RECV, NUM, UNUSED|CACHE_SLOT)
5214 {
5215 USE_OPLINE
5216 uint32_t arg_num = opline->op1.num;
5217
5218 if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
5219 SAVE_OPLINE();
5220 zend_missing_arg_error(execute_data);
5221 HANDLE_EXCEPTION();
5222 } else {
5223 zval *param = EX_VAR(opline->result.var);
5224
5225 SAVE_OPLINE();
5226 if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)))) {
5227 HANDLE_EXCEPTION();
5228 }
5229 }
5230
5231 ZEND_VM_NEXT_OPCODE();
5232 }
5233
5234 ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT)
5235 {
5236 USE_OPLINE
5237 uint32_t arg_num;
5238 zval *param;
5239
5240 ZEND_VM_REPEATABLE_OPCODE
5241
5242 arg_num = opline->op1.num;
5243 param = EX_VAR(opline->result.var);
5244 if (arg_num > EX_NUM_ARGS()) {
5245 zval *default_value = RT_CONSTANT(opline, opline->op2);
5246
5247 if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) {
5248 zval *cache_val = (zval*)CACHE_ADDR(Z_CACHE_SLOT_P(default_value));
5249
5250 /* we keep in cache only not refcounted values */
5251 if (Z_TYPE_P(cache_val) != IS_UNDEF) {
5252 ZVAL_COPY_VALUE(param, cache_val);
5253 } else {
5254 SAVE_OPLINE();
5255 ZVAL_COPY(param, default_value);
5256 if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
5257 zval_ptr_dtor_nogc(param);
5258 ZVAL_UNDEF(param);
5259 HANDLE_EXCEPTION();
5260 }
5261 if (!Z_REFCOUNTED_P(param)) {
5262 ZVAL_COPY_VALUE(cache_val, param);
5263 }
5264 }
5265 ZEND_VM_C_GOTO(recv_init_check_type);
5266 } else {
5267 ZVAL_COPY(param, default_value);
5268 }
5269 } else {
5270 ZEND_VM_C_LABEL(recv_init_check_type):
5271 if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
5272 zval *default_value = RT_CONSTANT(opline, opline->op2);
5273
5274 SAVE_OPLINE();
5275 if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) {
5276 HANDLE_EXCEPTION();
5277 }
5278 }
5279 }
5280
5281 ZEND_VM_REPEAT_OPCODE(ZEND_RECV_INIT);
5282 ZEND_VM_NEXT_OPCODE();
5283 }
5284
5285 ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED|CACHE_SLOT)
5286 {
5287 USE_OPLINE
5288 uint32_t arg_num = opline->op1.num;
5289 uint32_t arg_count = EX_NUM_ARGS();
5290 zval *params;
5291
5292 SAVE_OPLINE();
5293
5294 params = EX_VAR(opline->result.var);
5295
5296 if (arg_num <= arg_count) {
5297 zval *param;
5298
5299 array_init_size(params, arg_count - arg_num + 1);
5300 zend_hash_real_init_packed(Z_ARRVAL_P(params));
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P (params))5301 ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
5302 param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
5303 if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
5304 ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS);
5305 do {
5306 zend_verify_variadic_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num));
5307 if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
5308 ZEND_HASH_FILL_ADD(param);
5309 param++;
5310 } while (++arg_num <= arg_count);
5311 } else {
5312 do {
5313 if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
5314 ZEND_HASH_FILL_ADD(param);
5315 param++;
5316 } while (++arg_num <= arg_count);
5317 }
5318 } ZEND_HASH_FILL_END();
5319 } else {
5320 ZVAL_EMPTY_ARRAY(params);
5321 }
5322
5323 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5324 }
5325
5326 ZEND_VM_COLD_CONST_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
5327 {
5328 USE_OPLINE
5329 zval *val;
5330 zend_free_op free_op1;
5331
5332 val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
5333 if (Z_TYPE_INFO_P(val) == IS_TRUE) {
5334 ZVAL_TRUE(EX_VAR(opline->result.var));
5335 } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
5336 /* The result and op1 can be the same cv zval */
5337 const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
5338 ZVAL_FALSE(EX_VAR(opline->result.var));
5339 if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
5340 SAVE_OPLINE();
5341 ZVAL_UNDEFINED_OP1();
5342 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5343 }
5344 } else {
5345 SAVE_OPLINE();
5346 ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
5347 FREE_OP1();
5348 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5349 }
5350 ZEND_VM_NEXT_OPCODE();
5351 }
5352
ZEND_VM_HELPER(zend_case_helper,ANY,ANY,zval * op_1,zval * op_2)5353 ZEND_VM_HELPER(zend_case_helper, ANY, ANY, zval *op_1, zval *op_2)
5354 {
5355 USE_OPLINE
5356
5357 SAVE_OPLINE();
5358 if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
5359 op_1 = ZVAL_UNDEFINED_OP1();
5360 }
5361 if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
5362 op_2 = ZVAL_UNDEFINED_OP2();
5363 }
5364 compare_function(EX_VAR(opline->result.var), op_1, op_2);
5365 if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
5366 zval_ptr_dtor_nogc(op_2);
5367 }
5368 if (UNEXPECTED(EG(exception))) {
5369 HANDLE_EXCEPTION();
5370 }
5371 if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
5372 ZEND_VM_SMART_BRANCH_TRUE();
5373 ZVAL_TRUE(EX_VAR(opline->result.var));
5374 ZEND_VM_NEXT_OPCODE();
5375 } else {
5376 ZEND_VM_SMART_BRANCH_FALSE();
5377 ZVAL_FALSE(EX_VAR(opline->result.var));
5378 ZEND_VM_NEXT_OPCODE();
5379 }
5380 }
5381
5382 ZEND_VM_HANDLER(48, ZEND_CASE, TMPVAR, CONST|TMPVAR|CV)
5383 {
5384 USE_OPLINE
5385 zend_free_op free_op1, free_op2;
5386 zval *op1, *op2;
5387 double d1, d2;
5388
5389 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
5390 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
5391 if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
5392 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
5393 if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
5394 ZEND_VM_C_LABEL(case_true):
5395 ZEND_VM_SMART_BRANCH_TRUE();
5396 ZVAL_TRUE(EX_VAR(opline->result.var));
5397 ZEND_VM_NEXT_OPCODE();
5398 } else {
5399 ZEND_VM_C_LABEL(case_false):
5400 ZEND_VM_SMART_BRANCH_FALSE();
5401 ZVAL_FALSE(EX_VAR(opline->result.var));
5402 ZEND_VM_NEXT_OPCODE();
5403 }
5404 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
5405 d1 = (double)Z_LVAL_P(op1);
5406 d2 = Z_DVAL_P(op2);
5407 ZEND_VM_C_GOTO(case_double);
5408 }
5409 } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
5410 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
5411 d1 = Z_DVAL_P(op1);
5412 d2 = Z_DVAL_P(op2);
5413 ZEND_VM_C_LABEL(case_double):
5414 if (d1 == d2) {
5415 ZEND_VM_C_GOTO(case_true);
5416 } else {
5417 ZEND_VM_C_GOTO(case_false);
5418 }
5419 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
5420 d1 = Z_DVAL_P(op1);
5421 d2 = (double)Z_LVAL_P(op2);
5422 ZEND_VM_C_GOTO(case_double);
5423 }
5424 } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
5425 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
5426 int result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
5427 FREE_OP2();
5428 if (result) {
5429 ZEND_VM_C_GOTO(case_true);
5430 } else {
5431 ZEND_VM_C_GOTO(case_false);
5432 }
5433 }
5434 }
5435 ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper, op_1, op1, op_2, op2);
5436 }
5437
5438 ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, NUM)
5439 {
5440 USE_OPLINE
5441 zval *result;
5442 zend_function *constructor;
5443 zend_class_entry *ce;
5444 zend_execute_data *call;
5445
5446 SAVE_OPLINE();
5447 if (OP1_TYPE == IS_CONST) {
5448 ce = CACHED_PTR(opline->op2.num);
5449 if (UNEXPECTED(ce == NULL)) {
5450 ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
5451 if (UNEXPECTED(ce == NULL)) {
5452 ZEND_ASSERT(EG(exception));
5453 ZVAL_UNDEF(EX_VAR(opline->result.var));
5454 HANDLE_EXCEPTION();
5455 }
5456 CACHE_PTR(opline->op2.num, ce);
5457 }
5458 } else if (OP1_TYPE == IS_UNUSED) {
5459 ce = zend_fetch_class(NULL, opline->op1.num);
5460 if (UNEXPECTED(ce == NULL)) {
5461 ZEND_ASSERT(EG(exception));
5462 ZVAL_UNDEF(EX_VAR(opline->result.var));
5463 HANDLE_EXCEPTION();
5464 }
5465 } else {
5466 ce = Z_CE_P(EX_VAR(opline->op1.var));
5467 }
5468
5469 result = EX_VAR(opline->result.var);
5470 if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
5471 ZVAL_UNDEF(result);
5472 HANDLE_EXCEPTION();
5473 }
5474
5475 constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
5476 if (constructor == NULL) {
5477 if (UNEXPECTED(EG(exception))) {
5478 HANDLE_EXCEPTION();
5479 }
5480
5481 /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
5482 * opcode is DO_FCALL in case EXT instructions are used. */
5483 if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
5484 ZEND_VM_NEXT_OPCODE_EX(1, 2);
5485 }
5486
5487 /* Perform a dummy function call */
5488 call = zend_vm_stack_push_call_frame(
5489 ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
5490 opline->extended_value, NULL);
5491 } else {
5492 if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
5493 init_func_run_time_cache(&constructor->op_array);
5494 }
5495 /* We are not handling overloaded classes right now */
5496 call = zend_vm_stack_push_call_frame(
5497 ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
5498 constructor,
5499 opline->extended_value,
5500 Z_OBJ_P(result));
5501 Z_ADDREF_P(result);
5502 }
5503
5504 call->prev_execute_data = EX(call);
5505 EX(call) = call;
5506 ZEND_VM_NEXT_OPCODE();
5507 }
5508
5509 ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
5510 {
5511 USE_OPLINE
5512 zend_free_op free_op1;
5513 zval *obj;
5514 zend_class_entry *ce, *scope;
5515 zend_function *clone;
5516 zend_object_clone_obj_t clone_call;
5517
5518 SAVE_OPLINE();
5519 obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
5520
5521 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
5522 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
5523 }
5524
5525 do {
5526 if (OP1_TYPE == IS_CONST ||
5527 (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
5528 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
5529 obj = Z_REFVAL_P(obj);
5530 if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
5531 break;
5532 }
5533 }
5534 ZVAL_UNDEF(EX_VAR(opline->result.var));
5535 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
5536 ZVAL_UNDEFINED_OP1();
5537 if (UNEXPECTED(EG(exception) != NULL)) {
5538 HANDLE_EXCEPTION();
5539 }
5540 }
5541 zend_throw_error(NULL, "__clone method called on non-object");
5542 FREE_OP1();
5543 HANDLE_EXCEPTION();
5544 }
5545 } while (0);
5546
5547 ce = Z_OBJCE_P(obj);
5548 clone = ce->clone;
5549 clone_call = Z_OBJ_HT_P(obj)->clone_obj;
5550 if (UNEXPECTED(clone_call == NULL)) {
5551 zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
5552 FREE_OP1();
5553 ZVAL_UNDEF(EX_VAR(opline->result.var));
5554 HANDLE_EXCEPTION();
5555 }
5556
5557 if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
5558 scope = EX(func)->op_array.scope;
5559 if (clone->common.scope != scope) {
5560 if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
5561 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
5562 zend_wrong_clone_call(clone, scope);
5563 FREE_OP1();
5564 ZVAL_UNDEF(EX_VAR(opline->result.var));
5565 HANDLE_EXCEPTION();
5566 }
5567 }
5568 }
5569
5570 ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
5571
5572 FREE_OP1();
5573 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5574 }
5575
5576 ZEND_VM_HOT_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SLOT)
5577 {
5578 USE_OPLINE
5579 zend_constant *c;
5580
5581 c = CACHED_PTR(opline->extended_value);
5582 if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
5583 ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
5584 ZEND_VM_NEXT_OPCODE();
5585 }
5586
5587 SAVE_OPLINE();
5588 zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC);
5589 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5590 }
5591
5592 ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST, CACHE_SLOT)
5593 {
5594 zend_class_entry *ce, *scope;
5595 zend_class_constant *c;
5596 zval *value, *zv;
5597 USE_OPLINE
5598
5599 SAVE_OPLINE();
5600
5601 do {
5602 if (OP1_TYPE == IS_CONST) {
5603 if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
5604 value = CACHED_PTR(opline->extended_value + sizeof(void*));
5605 break;
5606 } else if (EXPECTED(CACHED_PTR(opline->extended_value))) {
5607 ce = CACHED_PTR(opline->extended_value);
5608 } else {
5609 ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
5610 if (UNEXPECTED(ce == NULL)) {
5611 ZEND_ASSERT(EG(exception));
5612 ZVAL_UNDEF(EX_VAR(opline->result.var));
5613 HANDLE_EXCEPTION();
5614 }
5615 }
5616 } else {
5617 if (OP1_TYPE == IS_UNUSED) {
5618 ce = zend_fetch_class(NULL, opline->op1.num);
5619 if (UNEXPECTED(ce == NULL)) {
5620 ZEND_ASSERT(EG(exception));
5621 ZVAL_UNDEF(EX_VAR(opline->result.var));
5622 HANDLE_EXCEPTION();
5623 }
5624 } else {
5625 ce = Z_CE_P(EX_VAR(opline->op1.var));
5626 }
5627 if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
5628 value = CACHED_PTR(opline->extended_value + sizeof(void*));
5629 break;
5630 }
5631 }
5632
5633 zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1);
5634 if (EXPECTED(zv != NULL)) {
5635 c = Z_PTR_P(zv);
5636 scope = EX(func)->op_array.scope;
5637 if (!zend_verify_const_access(c, scope)) {
5638 zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
5639 ZVAL_UNDEF(EX_VAR(opline->result.var));
5640 HANDLE_EXCEPTION();
5641 }
5642 value = &c->value;
5643 if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
5644 zval_update_constant_ex(value, c->ce);
5645 if (UNEXPECTED(EG(exception) != NULL)) {
5646 ZVAL_UNDEF(EX_VAR(opline->result.var));
5647 HANDLE_EXCEPTION();
5648 }
5649 }
5650 CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
5651 } else {
5652 zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
5653 ZVAL_UNDEF(EX_VAR(opline->result.var));
5654 HANDLE_EXCEPTION();
5655 }
5656 } while (0);
5657
5658 ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
5659
5660 ZEND_VM_NEXT_OPCODE();
5661 }
5662
5663 ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, REF)
5664 {
5665 USE_OPLINE
5666 zend_free_op free_op1;
5667 zval *expr_ptr, new_expr;
5668
5669 SAVE_OPLINE();
5670 if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) &&
5671 UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
5672 expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
5673 if (Z_ISREF_P(expr_ptr)) {
5674 Z_ADDREF_P(expr_ptr);
5675 } else {
5676 ZVAL_MAKE_REF_EX(expr_ptr, 2);
5677 }
5678 FREE_OP1_VAR_PTR();
5679 } else {
5680 expr_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
5681 if (OP1_TYPE == IS_TMP_VAR) {
5682 /* pass */
5683 } else if (OP1_TYPE == IS_CONST) {
5684 Z_TRY_ADDREF_P(expr_ptr);
5685 } else if (OP1_TYPE == IS_CV) {
5686 ZVAL_DEREF(expr_ptr);
5687 Z_TRY_ADDREF_P(expr_ptr);
5688 } else /* if (OP1_TYPE == IS_VAR) */ {
5689 if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
5690 zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
5691
5692 expr_ptr = Z_REFVAL_P(expr_ptr);
5693 if (UNEXPECTED(GC_DELREF(ref) == 0)) {
5694 ZVAL_COPY_VALUE(&new_expr, expr_ptr);
5695 expr_ptr = &new_expr;
5696 efree_size(ref, sizeof(zend_reference));
5697 } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
5698 Z_ADDREF_P(expr_ptr);
5699 }
5700 }
5701 }
5702 }
5703
5704 if (OP2_TYPE != IS_UNUSED) {
5705 zend_free_op free_op2;
5706 zval *offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
5707 zend_string *str;
5708 zend_ulong hval;
5709
5710 ZEND_VM_C_LABEL(add_again):
5711 if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
5712 str = Z_STR_P(offset);
5713 if (OP2_TYPE != IS_CONST) {
5714 if (ZEND_HANDLE_NUMERIC(str, hval)) {
5715 ZEND_VM_C_GOTO(num_index);
5716 }
5717 }
5718 ZEND_VM_C_LABEL(str_index):
5719 zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
5720 } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
5721 hval = Z_LVAL_P(offset);
5722 ZEND_VM_C_LABEL(num_index):
5723 zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
5724 } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
5725 offset = Z_REFVAL_P(offset);
5726 ZEND_VM_C_GOTO(add_again);
5727 } else if (Z_TYPE_P(offset) == IS_NULL) {
5728 str = ZSTR_EMPTY_ALLOC();
5729 ZEND_VM_C_GOTO(str_index);
5730 } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
5731 hval = zend_dval_to_lval(Z_DVAL_P(offset));
5732 ZEND_VM_C_GOTO(num_index);
5733 } else if (Z_TYPE_P(offset) == IS_FALSE) {
5734 hval = 0;
5735 ZEND_VM_C_GOTO(num_index);
5736 } else if (Z_TYPE_P(offset) == IS_TRUE) {
5737 hval = 1;
5738 ZEND_VM_C_GOTO(num_index);
5739 } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
5740 zend_use_resource_as_offset(offset);
5741 hval = Z_RES_HANDLE_P(offset);
5742 ZEND_VM_C_GOTO(num_index);
5743 } else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
5744 ZVAL_UNDEFINED_OP2();
5745 str = ZSTR_EMPTY_ALLOC();
5746 ZEND_VM_C_GOTO(str_index);
5747 } else {
5748 zend_illegal_offset();
5749 zval_ptr_dtor_nogc(expr_ptr);
5750 }
5751 FREE_OP2();
5752 } else {
5753 if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
5754 zend_cannot_add_element();
5755 zval_ptr_dtor_nogc(expr_ptr);
5756 }
5757 }
5758 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5759 }
5760
5761 ZEND_VM_HANDLER(147, ZEND_ADD_ARRAY_UNPACK, ANY, ANY)
5762 {
5763 USE_OPLINE
5764 zend_free_op free_op1;
5765 zval *op1;
5766
5767 SAVE_OPLINE();
5768 op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
5769
5770 ZEND_VM_C_LABEL(add_unpack_again):
5771 if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) {
5772 HashTable *ht = Z_ARRVAL_P(op1);
5773 zval *val;
5774 zend_string *key;
5775
ZEND_HASH_FOREACH_STR_KEY_VAL(ht,key,val)5776 ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
5777 if (key) {
5778 zend_throw_error(NULL, "Cannot unpack array with string keys");
5779 FREE_OP1();
5780 HANDLE_EXCEPTION();
5781 } else {
5782 if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
5783 val = Z_REFVAL_P(val);
5784 }
5785 Z_TRY_ADDREF_P(val);
5786 if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) {
5787 zend_cannot_add_element();
5788 zval_ptr_dtor_nogc(val);
5789 break;
5790 }
5791 }
5792 } ZEND_HASH_FOREACH_END();
5793 } else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) {
5794 zend_class_entry *ce = Z_OBJCE_P(op1);
5795 zend_object_iterator *iter;
5796
5797 if (!ce || !ce->get_iterator) {
5798 zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
5799 } else {
5800 iter = ce->get_iterator(ce, op1, 0);
5801 if (UNEXPECTED(!iter)) {
5802 FREE_OP1();
5803 if (!EG(exception)) {
5804 zend_throw_exception_ex(
5805 NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)
5806 );
5807 }
5808 HANDLE_EXCEPTION();
5809 }
5810
5811 if (iter->funcs->rewind) {
5812 iter->funcs->rewind(iter);
5813 }
5814
5815 for (; iter->funcs->valid(iter) == SUCCESS; ) {
5816 zval *val;
5817
5818 if (UNEXPECTED(EG(exception) != NULL)) {
5819 break;
5820 }
5821
5822 val = iter->funcs->get_current_data(iter);
5823 if (UNEXPECTED(EG(exception) != NULL)) {
5824 break;
5825 }
5826
5827 if (iter->funcs->get_current_key) {
5828 zval key;
5829 iter->funcs->get_current_key(iter, &key);
5830 if (UNEXPECTED(EG(exception) != NULL)) {
5831 break;
5832 }
5833
5834 if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) {
5835 zend_throw_error(NULL,
5836 (Z_TYPE(key) == IS_STRING) ?
5837 "Cannot unpack Traversable with string keys" :
5838 "Cannot unpack Traversable with non-integer keys");
5839 zval_ptr_dtor(&key);
5840 break;
5841 }
5842 }
5843
5844 ZVAL_DEREF(val);
5845 Z_TRY_ADDREF_P(val);
5846
5847 if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) {
5848 zend_cannot_add_element();
5849 zval_ptr_dtor_nogc(val);
5850 }
5851
5852 iter->funcs->move_forward(iter);
5853 }
5854
5855 zend_iterator_dtor(iter);
5856 }
5857 } else if (EXPECTED(Z_ISREF_P(op1))) {
5858 op1 = Z_REFVAL_P(op1);
5859 ZEND_VM_C_GOTO(add_unpack_again);
5860 } else {
5861 zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
5862 }
5863
5864 FREE_OP1();
5865 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5866 }
5867
5868 ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF)
5869 {
5870 zval *array;
5871 uint32_t size;
5872 USE_OPLINE
5873
5874 array = EX_VAR(opline->result.var);
5875 if (OP1_TYPE != IS_UNUSED) {
5876 size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
5877 ZVAL_ARR(array, zend_new_array(size));
5878 /* Explicitly initialize array as not-packed if flag is set */
5879 if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
5880 zend_hash_real_init_mixed(Z_ARRVAL_P(array));
5881 }
5882 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
5883 } else {
5884 ZVAL_ARR(array, zend_new_array(0));
5885 ZEND_VM_NEXT_OPCODE();
5886 }
5887 }
5888
5889 ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
5890 {
5891 USE_OPLINE
5892 zend_free_op free_op1;
5893 zval *expr;
5894 zval *result = EX_VAR(opline->result.var);
5895 HashTable *ht;
5896
5897 SAVE_OPLINE();
5898 expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
5899
5900 switch (opline->extended_value) {
5901 case IS_NULL:
5902 ZVAL_NULL(result);
5903 break;
5904 case _IS_BOOL:
5905 ZVAL_BOOL(result, zend_is_true(expr));
5906 break;
5907 case IS_LONG:
5908 ZVAL_LONG(result, zval_get_long(expr));
5909 break;
5910 case IS_DOUBLE:
5911 ZVAL_DOUBLE(result, zval_get_double(expr));
5912 break;
5913 case IS_STRING:
5914 ZVAL_STR(result, zval_get_string(expr));
5915 break;
5916 default:
5917 if (OP1_TYPE & (IS_VAR|IS_CV)) {
5918 ZVAL_DEREF(expr);
5919 }
5920 /* If value is already of correct type, return it directly */
5921 if (Z_TYPE_P(expr) == opline->extended_value) {
5922 ZVAL_COPY_VALUE(result, expr);
5923 if (OP1_TYPE == IS_CONST) {
5924 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
5925 } else if (OP1_TYPE != IS_TMP_VAR) {
5926 if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
5927 }
5928
5929 FREE_OP1_IF_VAR();
5930 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5931 }
5932
5933 if (opline->extended_value == IS_ARRAY) {
5934 if (OP1_TYPE == IS_CONST || Z_TYPE_P(expr) != IS_OBJECT || Z_OBJCE_P(expr) == zend_ce_closure) {
5935 if (Z_TYPE_P(expr) != IS_NULL) {
5936 ZVAL_ARR(result, zend_new_array(1));
5937 expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
5938 if (OP1_TYPE == IS_CONST) {
5939 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
5940 } else {
5941 if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
5942 }
5943 } else {
5944 ZVAL_EMPTY_ARRAY(result);
5945 }
5946 } else {
5947 HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST);
5948 if (obj_ht) {
5949 /* fast copy */
5950 ZVAL_ARR(result, zend_proptable_to_symtable(obj_ht,
5951 (Z_OBJCE_P(expr)->default_properties_count ||
5952 Z_OBJ_P(expr)->handlers != &std_object_handlers ||
5953 GC_IS_RECURSIVE(obj_ht))));
5954 zend_release_properties(obj_ht);
5955 } else {
5956 ZVAL_EMPTY_ARRAY(result);
5957 }
5958 }
5959 } else {
5960 ZVAL_OBJ(result, zend_objects_new(zend_standard_class_def));
5961 if (Z_TYPE_P(expr) == IS_ARRAY) {
5962 ht = zend_symtable_to_proptable(Z_ARR_P(expr));
5963 if (GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) {
5964 /* TODO: try not to duplicate immutable arrays as well ??? */
5965 ht = zend_array_dup(ht);
5966 }
5967 Z_OBJ_P(result)->properties = ht;
5968 } else if (Z_TYPE_P(expr) != IS_NULL) {
5969 Z_OBJ_P(result)->properties = ht = zend_new_array(1);
5970 expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
5971 if (OP1_TYPE == IS_CONST) {
5972 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
5973 } else {
5974 if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
5975 }
5976 }
5977 }
5978 }
5979
5980 FREE_OP1();
5981 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
5982 }
5983
5984 ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
5985 {
5986 USE_OPLINE
5987 zend_op_array *new_op_array;
5988 zend_free_op free_op1;
5989 zval *inc_filename;
5990
5991 SAVE_OPLINE();
5992 inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R);
5993 new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
5994 FREE_OP1();
5995 if (UNEXPECTED(EG(exception) != NULL)) {
5996 if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
5997 destroy_op_array(new_op_array);
5998 efree_size(new_op_array, sizeof(zend_op_array));
5999 }
6000 UNDEF_RESULT();
6001 HANDLE_EXCEPTION();
6002 } else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
6003 if (RETURN_VALUE_USED(opline)) {
6004 ZVAL_TRUE(EX_VAR(opline->result.var));
6005 }
6006 } else if (EXPECTED(new_op_array != NULL)) {
6007 zval *return_value = NULL;
6008 zend_execute_data *call;
6009
6010 if (RETURN_VALUE_USED(opline)) {
6011 return_value = EX_VAR(opline->result.var);
6012 }
6013
6014 new_op_array->scope = EX(func)->op_array.scope;
6015
6016 call = zend_vm_stack_push_call_frame(
6017 (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
6018 (zend_function*)new_op_array, 0,
6019 Z_PTR(EX(This)));
6020
6021 if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
6022 call->symbol_table = EX(symbol_table);
6023 } else {
6024 call->symbol_table = zend_rebuild_symbol_table();
6025 }
6026
6027 call->prev_execute_data = execute_data;
6028 i_init_code_execute_data(call, new_op_array, return_value);
6029 if (EXPECTED(zend_execute_ex == execute_ex)) {
6030 ZEND_VM_ENTER();
6031 } else {
6032 ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
6033 zend_execute_ex(call);
6034 zend_vm_stack_free_call_frame(call);
6035 }
6036
6037 destroy_op_array(new_op_array);
6038 efree_size(new_op_array, sizeof(zend_op_array));
6039 if (UNEXPECTED(EG(exception) != NULL)) {
6040 zend_rethrow_exception(execute_data);
6041 UNDEF_RESULT();
6042 HANDLE_EXCEPTION();
6043 }
6044 } else if (RETURN_VALUE_USED(opline)) {
6045 ZVAL_FALSE(EX_VAR(opline->result.var));
6046 }
6047 ZEND_VM_NEXT_OPCODE();
6048 }
6049
6050 ZEND_VM_HANDLER(153, ZEND_UNSET_CV, CV, UNUSED)
6051 {
6052 USE_OPLINE
6053 zval *var = EX_VAR(opline->op1.var);
6054
6055 if (Z_REFCOUNTED_P(var)) {
6056 zend_refcounted *garbage = Z_COUNTED_P(var);
6057
6058 ZVAL_UNDEF(var);
6059 SAVE_OPLINE();
6060 if (!GC_DELREF(garbage)) {
6061 rc_dtor_func(garbage);
6062 } else {
6063 gc_check_possible_root(garbage);
6064 }
6065 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6066 } else {
6067 ZVAL_UNDEF(var);
6068 }
6069 ZEND_VM_NEXT_OPCODE();
6070 }
6071
6072 ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
6073 {
6074 USE_OPLINE
6075 zval *varname;
6076 zend_string *name, *tmp_name;
6077 HashTable *target_symbol_table;
6078 zend_free_op free_op1;
6079
6080 SAVE_OPLINE();
6081
6082 varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
6083
6084 if (OP1_TYPE == IS_CONST) {
6085 name = Z_STR_P(varname);
6086 } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
6087 name = Z_STR_P(varname);
6088 tmp_name = NULL;
6089 } else {
6090 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
6091 varname = ZVAL_UNDEFINED_OP1();
6092 }
6093 name = zval_try_get_tmp_string(varname, &tmp_name);
6094 if (UNEXPECTED(!name)) {
6095 FREE_OP1();
6096 HANDLE_EXCEPTION();
6097 }
6098 }
6099
6100 target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
6101 zend_hash_del_ind(target_symbol_table, name);
6102
6103 if (OP1_TYPE != IS_CONST) {
6104 zend_tmp_string_release(tmp_name);
6105 }
6106 FREE_OP1();
6107 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6108 }
6109
6110 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
6111 ZEND_VM_COLD_HANDLER(179, ZEND_UNSET_STATIC_PROP, ANY, ANY, CACHE_SLOT)
6112 {
6113 USE_OPLINE
6114 zval *varname;
6115 zend_string *name, *tmp_name = NULL;
6116 zend_class_entry *ce;
6117 zend_free_op free_op1;
6118
6119 SAVE_OPLINE();
6120
6121 if (OP2_TYPE == IS_CONST) {
6122 ce = CACHED_PTR(opline->extended_value);
6123 if (UNEXPECTED(ce == NULL)) {
6124 ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
6125 if (UNEXPECTED(ce == NULL)) {
6126 ZEND_ASSERT(EG(exception));
6127 FREE_UNFETCHED_OP1();
6128 HANDLE_EXCEPTION();
6129 }
6130 /*CACHE_PTR(opline->extended_value, ce);*/
6131 }
6132 } else if (OP2_TYPE == IS_UNUSED) {
6133 ce = zend_fetch_class(NULL, opline->op2.num);
6134 if (UNEXPECTED(ce == NULL)) {
6135 ZEND_ASSERT(EG(exception));
6136 FREE_UNFETCHED_OP1();
6137 HANDLE_EXCEPTION();
6138 }
6139 } else {
6140 ce = Z_CE_P(EX_VAR(opline->op2.var));
6141 }
6142
6143 varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
6144 if (OP1_TYPE == IS_CONST) {
6145 name = Z_STR_P(varname);
6146 } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
6147 name = Z_STR_P(varname);
6148 } else {
6149 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
6150 varname = ZVAL_UNDEFINED_OP1();
6151 }
6152 name = zval_get_tmp_string(varname, &tmp_name);
6153 }
6154
6155 zend_std_unset_static_property(ce, name);
6156
6157 zend_tmp_string_release(tmp_name);
6158 FREE_OP1();
6159 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6160 }
6161
6162 ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|CV, CONST|TMPVAR|CV)
6163 {
6164 USE_OPLINE
6165 zend_free_op free_op1, free_op2;
6166 zval *container;
6167 zval *offset;
6168 zend_ulong hval;
6169 zend_string *key;
6170
6171 SAVE_OPLINE();
6172 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
6173 offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
6174
6175 do {
6176 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
6177 HashTable *ht;
6178
6179 ZEND_VM_C_LABEL(unset_dim_array):
6180 SEPARATE_ARRAY(container);
6181 ht = Z_ARRVAL_P(container);
6182 ZEND_VM_C_LABEL(offset_again):
6183 if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
6184 key = Z_STR_P(offset);
6185 if (OP2_TYPE != IS_CONST) {
6186 if (ZEND_HANDLE_NUMERIC(key, hval)) {
6187 ZEND_VM_C_GOTO(num_index_dim);
6188 }
6189 }
6190 ZEND_VM_C_LABEL(str_index_dim):
6191 if (ht == &EG(symbol_table)) {
6192 zend_delete_global_variable(key);
6193 } else {
6194 zend_hash_del(ht, key);
6195 }
6196 } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
6197 hval = Z_LVAL_P(offset);
6198 ZEND_VM_C_LABEL(num_index_dim):
6199 zend_hash_index_del(ht, hval);
6200 } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
6201 offset = Z_REFVAL_P(offset);
6202 ZEND_VM_C_GOTO(offset_again);
6203 } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
6204 hval = zend_dval_to_lval(Z_DVAL_P(offset));
6205 ZEND_VM_C_GOTO(num_index_dim);
6206 } else if (Z_TYPE_P(offset) == IS_NULL) {
6207 key = ZSTR_EMPTY_ALLOC();
6208 ZEND_VM_C_GOTO(str_index_dim);
6209 } else if (Z_TYPE_P(offset) == IS_FALSE) {
6210 hval = 0;
6211 ZEND_VM_C_GOTO(num_index_dim);
6212 } else if (Z_TYPE_P(offset) == IS_TRUE) {
6213 hval = 1;
6214 ZEND_VM_C_GOTO(num_index_dim);
6215 } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
6216 hval = Z_RES_HANDLE_P(offset);
6217 ZEND_VM_C_GOTO(num_index_dim);
6218 } else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
6219 ZVAL_UNDEFINED_OP2();
6220 key = ZSTR_EMPTY_ALLOC();
6221 ZEND_VM_C_GOTO(str_index_dim);
6222 } else {
6223 zend_error(E_WARNING, "Illegal offset type in unset");
6224 }
6225 break;
6226 } else if (Z_ISREF_P(container)) {
6227 container = Z_REFVAL_P(container);
6228 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
6229 ZEND_VM_C_GOTO(unset_dim_array);
6230 }
6231 }
6232 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
6233 container = ZVAL_UNDEFINED_OP1();
6234 }
6235 if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
6236 offset = ZVAL_UNDEFINED_OP2();
6237 }
6238 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
6239 if (OP2_TYPE == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
6240 offset++;
6241 }
6242 Z_OBJ_HT_P(container)->unset_dimension(container, offset);
6243 } else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
6244 zend_throw_error(NULL, "Cannot unset string offsets");
6245 }
6246 } while (0);
6247
6248 FREE_OP2();
6249 FREE_OP1_VAR_PTR();
6250 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6251 }
6252
6253 ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
6254 {
6255 USE_OPLINE
6256 zend_free_op free_op1, free_op2;
6257 zval *container;
6258 zval *offset;
6259
6260 SAVE_OPLINE();
6261 container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
6262 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
6263 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
6264 }
6265 offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
6266
6267 do {
6268 if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
6269 if (Z_ISREF_P(container)) {
6270 container = Z_REFVAL_P(container);
6271 if (Z_TYPE_P(container) != IS_OBJECT) {
6272 if (OP1_TYPE == IS_CV
6273 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
6274 ZVAL_UNDEFINED_OP1();
6275 }
6276 break;
6277 }
6278 } else {
6279 break;
6280 }
6281 }
6282 Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
6283 } while (0);
6284
6285 FREE_OP2();
6286 FREE_OP1_VAR_PTR();
6287 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6288 }
6289
6290 ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
6291 {
6292 USE_OPLINE
6293 zend_free_op free_op1;
6294 zval *array_ptr, *result;
6295
6296 SAVE_OPLINE();
6297
6298 array_ptr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
6299 if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
6300 result = EX_VAR(opline->result.var);
6301 ZVAL_COPY_VALUE(result, array_ptr);
6302 if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
6303 Z_ADDREF_P(array_ptr);
6304 }
6305 Z_FE_POS_P(result) = 0;
6306
6307 FREE_OP1_IF_VAR();
6308 ZEND_VM_NEXT_OPCODE();
6309 } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
6310 if (!Z_OBJCE_P(array_ptr)->get_iterator) {
6311 HashTable *properties;
6312 if (Z_OBJ_P(array_ptr)->properties
6313 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
6314 if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
6315 GC_DELREF(Z_OBJ_P(array_ptr)->properties);
6316 }
6317 Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
6318 }
6319
6320 properties = Z_OBJPROP_P(array_ptr);
6321 result = EX_VAR(opline->result.var);
6322 ZVAL_COPY_VALUE(result, array_ptr);
6323 if (OP1_TYPE != IS_TMP_VAR) {
6324 Z_ADDREF_P(array_ptr);
6325 }
6326
6327 if (zend_hash_num_elements(properties) == 0) {
6328 Z_FE_ITER_P(result) = (uint32_t) -1;
6329 FREE_OP1_IF_VAR();
6330 ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6331 }
6332
6333 Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
6334 FREE_OP1_IF_VAR();
6335 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6336 } else {
6337 zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
6338
6339 FREE_OP1();
6340 if (UNEXPECTED(EG(exception))) {
6341 HANDLE_EXCEPTION();
6342 } else if (is_empty) {
6343 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
6344 } else {
6345 ZEND_VM_NEXT_OPCODE();
6346 }
6347 }
6348 } else {
6349 zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6350 ZVAL_UNDEF(EX_VAR(opline->result.var));
6351 Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
6352 FREE_OP1();
6353 ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6354 }
6355 }
6356
6357 ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
6358 {
6359 USE_OPLINE
6360 zend_free_op free_op1;
6361 zval *array_ptr, *array_ref;
6362
6363 SAVE_OPLINE();
6364
6365 if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
6366 array_ref = array_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
6367 if (Z_ISREF_P(array_ref)) {
6368 array_ptr = Z_REFVAL_P(array_ref);
6369 }
6370 } else {
6371 array_ref = array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
6372 }
6373
6374 if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
6375 if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
6376 if (array_ptr == array_ref) {
6377 ZVAL_NEW_REF(array_ref, array_ref);
6378 array_ptr = Z_REFVAL_P(array_ref);
6379 }
6380 Z_ADDREF_P(array_ref);
6381 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
6382 } else {
6383 array_ref = EX_VAR(opline->result.var);
6384 ZVAL_NEW_REF(array_ref, array_ptr);
6385 array_ptr = Z_REFVAL_P(array_ref);
6386 }
6387 if (OP1_TYPE == IS_CONST) {
6388 ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
6389 } else {
6390 SEPARATE_ARRAY(array_ptr);
6391 }
6392 Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
6393
6394 if (OP1_TYPE == IS_VAR) {
6395 FREE_OP1_VAR_PTR();
6396 }
6397 ZEND_VM_NEXT_OPCODE();
6398 } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
6399 if (!Z_OBJCE_P(array_ptr)->get_iterator) {
6400 HashTable *properties;
6401 if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
6402 if (array_ptr == array_ref) {
6403 ZVAL_NEW_REF(array_ref, array_ref);
6404 array_ptr = Z_REFVAL_P(array_ref);
6405 }
6406 Z_ADDREF_P(array_ref);
6407 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
6408 } else {
6409 array_ptr = EX_VAR(opline->result.var);
6410 ZVAL_COPY_VALUE(array_ptr, array_ref);
6411 }
6412 if (Z_OBJ_P(array_ptr)->properties
6413 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
6414 if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
6415 GC_DELREF(Z_OBJ_P(array_ptr)->properties);
6416 }
6417 Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
6418 }
6419
6420 properties = Z_OBJPROP_P(array_ptr);
6421 if (zend_hash_num_elements(properties) == 0) {
6422 Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
6423 FREE_OP1_VAR_PTR();
6424 ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6425 }
6426
6427 Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
6428 FREE_OP1_VAR_PTR();
6429 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6430 } else {
6431 zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
6432
6433 if (OP1_TYPE == IS_VAR) {
6434 FREE_OP1_VAR_PTR();
6435 } else {
6436 FREE_OP1();
6437 }
6438 if (UNEXPECTED(EG(exception))) {
6439 HANDLE_EXCEPTION();
6440 } else if (is_empty) {
6441 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
6442 } else {
6443 ZEND_VM_NEXT_OPCODE();
6444 }
6445 }
6446 } else {
6447 zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6448 ZVAL_UNDEF(EX_VAR(opline->result.var));
6449 Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
6450 if (OP1_TYPE == IS_VAR) {
6451 FREE_OP1_VAR_PTR();
6452 } else {
6453 FREE_OP1();
6454 }
6455 ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6456 }
6457 }
6458
6459 ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
6460 {
6461 USE_OPLINE
6462 zval *array;
6463 zval *value;
6464 uint32_t value_type;
6465 HashTable *fe_ht;
6466 HashPosition pos;
6467 Bucket *p;
6468
6469 array = EX_VAR(opline->op1.var);
6470 SAVE_OPLINE();
6471 if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
6472 fe_ht = Z_ARRVAL_P(array);
6473 pos = Z_FE_POS_P(array);
6474 p = fe_ht->arData + pos;
6475 while (1) {
6476 if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
6477 /* reached end of iteration */
6478 ZEND_VM_C_LABEL(fe_fetch_r_exit):
6479 ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
6480 ZEND_VM_CONTINUE();
6481 }
6482 value = &p->val;
6483 value_type = Z_TYPE_INFO_P(value);
6484 if (EXPECTED(value_type != IS_UNDEF)) {
6485 if (UNEXPECTED(value_type == IS_INDIRECT)) {
6486 value = Z_INDIRECT_P(value);
6487 value_type = Z_TYPE_INFO_P(value);
6488 if (EXPECTED(value_type != IS_UNDEF)) {
6489 break;
6490 }
6491 } else {
6492 break;
6493 }
6494 }
6495 pos++;
6496 p++;
6497 }
6498 Z_FE_POS_P(array) = pos + 1;
6499 if (RETURN_VALUE_USED(opline)) {
6500 if (!p->key) {
6501 ZVAL_LONG(EX_VAR(opline->result.var), p->h);
6502 } else {
6503 ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
6504 }
6505 }
6506 } else {
6507 zend_object_iterator *iter;
6508
6509 ZEND_ASSERT(Z_TYPE_P(array) == IS_OBJECT);
6510 if ((iter = zend_iterator_unwrap(array)) == NULL) {
6511 /* plain object */
6512
6513 fe_ht = Z_OBJPROP_P(array);
6514 pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht);
6515 p = fe_ht->arData + pos;
6516 while (1) {
6517 if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
6518 /* reached end of iteration */
6519 ZEND_VM_C_GOTO(fe_fetch_r_exit);
6520 }
6521
6522 value = &p->val;
6523 value_type = Z_TYPE_INFO_P(value);
6524 if (EXPECTED(value_type != IS_UNDEF)) {
6525 if (UNEXPECTED(value_type == IS_INDIRECT)) {
6526 value = Z_INDIRECT_P(value);
6527 value_type = Z_TYPE_INFO_P(value);
6528 if (EXPECTED(value_type != IS_UNDEF)
6529 && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) {
6530 break;
6531 }
6532 } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
6533 || !p->key
6534 || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) {
6535 break;
6536 }
6537 }
6538 pos++;
6539 p++;
6540 }
6541 if (RETURN_VALUE_USED(opline)) {
6542 if (UNEXPECTED(!p->key)) {
6543 ZVAL_LONG(EX_VAR(opline->result.var), p->h);
6544 } else if (ZSTR_VAL(p->key)[0]) {
6545 ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
6546 } else {
6547 const char *class_name, *prop_name;
6548 size_t prop_name_len;
6549 zend_unmangle_property_name_ex(
6550 p->key, &class_name, &prop_name, &prop_name_len);
6551 ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len);
6552 }
6553 }
6554 EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos + 1;
6555 } else {
6556 if (EXPECTED(++iter->index > 0)) {
6557 /* This could cause an endless loop if index becomes zero again.
6558 * In case that ever happens we need an additional flag. */
6559 iter->funcs->move_forward(iter);
6560 if (UNEXPECTED(EG(exception) != NULL)) {
6561 UNDEF_RESULT();
6562 HANDLE_EXCEPTION();
6563 }
6564 if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) {
6565 /* reached end of iteration */
6566 if (UNEXPECTED(EG(exception) != NULL)) {
6567 UNDEF_RESULT();
6568 HANDLE_EXCEPTION();
6569 }
6570 ZEND_VM_C_GOTO(fe_fetch_r_exit);
6571 }
6572 }
6573 value = iter->funcs->get_current_data(iter);
6574 if (UNEXPECTED(EG(exception) != NULL)) {
6575 UNDEF_RESULT();
6576 HANDLE_EXCEPTION();
6577 }
6578 if (!value) {
6579 /* failure in get_current_data */
6580 ZEND_VM_C_GOTO(fe_fetch_r_exit);
6581 }
6582 if (RETURN_VALUE_USED(opline)) {
6583 if (iter->funcs->get_current_key) {
6584 iter->funcs->get_current_key(iter, EX_VAR(opline->result.var));
6585 if (UNEXPECTED(EG(exception) != NULL)) {
6586 UNDEF_RESULT();
6587 HANDLE_EXCEPTION();
6588 }
6589 } else {
6590 ZVAL_LONG(EX_VAR(opline->result.var), iter->index);
6591 }
6592 }
6593 value_type = Z_TYPE_INFO_P(value);
6594 }
6595 }
6596
6597 if (EXPECTED(OP2_TYPE == IS_CV)) {
6598 zval *variable_ptr = EX_VAR(opline->op2.var);
6599 zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
6600 } else {
6601 zval *res = EX_VAR(opline->op2.var);
6602 zend_refcounted *gc = Z_COUNTED_P(value);
6603
6604 ZVAL_COPY_VALUE_EX(res, value, gc, value_type);
6605 if (Z_TYPE_INFO_REFCOUNTED(value_type)) {
6606 GC_ADDREF(gc);
6607 }
6608 }
6609 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6610 }
6611
6612 ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR)
6613 {
6614 USE_OPLINE
6615 zval *array;
6616 zval *value;
6617 uint32_t value_type;
6618 HashTable *fe_ht;
6619 HashPosition pos;
6620 Bucket *p;
6621
6622 array = EX_VAR(opline->op1.var);
6623 SAVE_OPLINE();
6624
6625 ZVAL_DEREF(array);
6626 if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
6627 pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array);
6628 fe_ht = Z_ARRVAL_P(array);
6629 p = fe_ht->arData + pos;
6630 while (1) {
6631 if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
6632 /* reached end of iteration */
6633 ZEND_VM_C_GOTO(fe_fetch_w_exit);
6634 }
6635 value = &p->val;
6636 value_type = Z_TYPE_INFO_P(value);
6637 if (EXPECTED(value_type != IS_UNDEF)) {
6638 if (UNEXPECTED(value_type == IS_INDIRECT)) {
6639 value = Z_INDIRECT_P(value);
6640 value_type = Z_TYPE_INFO_P(value);
6641 if (EXPECTED(value_type != IS_UNDEF)) {
6642 break;
6643 }
6644 } else {
6645 break;
6646 }
6647 }
6648 pos++;
6649 p++;
6650 }
6651 if (RETURN_VALUE_USED(opline)) {
6652 if (!p->key) {
6653 ZVAL_LONG(EX_VAR(opline->result.var), p->h);
6654 } else {
6655 ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
6656 }
6657 }
6658 EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1;
6659 } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
6660 zend_object_iterator *iter;
6661
6662 if ((iter = zend_iterator_unwrap(array)) == NULL) {
6663 /* plain object */
6664
6665 fe_ht = Z_OBJPROP_P(array);
6666 pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
6667 p = fe_ht->arData + pos;
6668 while (1) {
6669 if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
6670 /* reached end of iteration */
6671 ZEND_VM_C_GOTO(fe_fetch_w_exit);
6672 }
6673
6674 value = &p->val;
6675 value_type = Z_TYPE_INFO_P(value);
6676 if (EXPECTED(value_type != IS_UNDEF)) {
6677 if (UNEXPECTED(value_type == IS_INDIRECT)) {
6678 value = Z_INDIRECT_P(value);
6679 value_type = Z_TYPE_INFO_P(value);
6680 if (EXPECTED(value_type != IS_UNDEF)
6681 && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) {
6682 if ((value_type & Z_TYPE_MASK) != IS_REFERENCE) {
6683 zend_property_info *prop_info =
6684 zend_get_typed_property_info_for_slot(Z_OBJ_P(array), value);
6685 if (UNEXPECTED(prop_info)) {
6686 ZVAL_NEW_REF(value, value);
6687 ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(value), prop_info);
6688 value_type = IS_REFERENCE_EX;
6689 }
6690 }
6691 break;
6692 }
6693 } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
6694 || !p->key
6695 || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) {
6696 break;
6697 }
6698 }
6699 pos++;
6700 p++;
6701 }
6702 if (RETURN_VALUE_USED(opline)) {
6703 if (UNEXPECTED(!p->key)) {
6704 ZVAL_LONG(EX_VAR(opline->result.var), p->h);
6705 } else if (ZSTR_VAL(p->key)[0]) {
6706 ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
6707 } else {
6708 const char *class_name, *prop_name;
6709 size_t prop_name_len;
6710 zend_unmangle_property_name_ex(
6711 p->key, &class_name, &prop_name, &prop_name_len);
6712 ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len);
6713 }
6714 }
6715 EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1;
6716 } else {
6717 if (++iter->index > 0) {
6718 /* This could cause an endless loop if index becomes zero again.
6719 * In case that ever happens we need an additional flag. */
6720 iter->funcs->move_forward(iter);
6721 if (UNEXPECTED(EG(exception) != NULL)) {
6722 UNDEF_RESULT();
6723 HANDLE_EXCEPTION();
6724 }
6725 if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) {
6726 /* reached end of iteration */
6727 if (UNEXPECTED(EG(exception) != NULL)) {
6728 UNDEF_RESULT();
6729 HANDLE_EXCEPTION();
6730 }
6731 ZEND_VM_C_GOTO(fe_fetch_w_exit);
6732 }
6733 }
6734 value = iter->funcs->get_current_data(iter);
6735 if (UNEXPECTED(EG(exception) != NULL)) {
6736 UNDEF_RESULT();
6737 HANDLE_EXCEPTION();
6738 }
6739 if (!value) {
6740 /* failure in get_current_data */
6741 ZEND_VM_C_GOTO(fe_fetch_w_exit);
6742 }
6743 if (RETURN_VALUE_USED(opline)) {
6744 if (iter->funcs->get_current_key) {
6745 iter->funcs->get_current_key(iter, EX_VAR(opline->result.var));
6746 if (UNEXPECTED(EG(exception) != NULL)) {
6747 UNDEF_RESULT();
6748 HANDLE_EXCEPTION();
6749 }
6750 } else {
6751 ZVAL_LONG(EX_VAR(opline->result.var), iter->index);
6752 }
6753 }
6754 value_type = Z_TYPE_INFO_P(value);
6755 }
6756 } else {
6757 zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6758 if (UNEXPECTED(EG(exception))) {
6759 UNDEF_RESULT();
6760 HANDLE_EXCEPTION();
6761 }
6762 ZEND_VM_C_LABEL(fe_fetch_w_exit):
6763 ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
6764 ZEND_VM_CONTINUE();
6765 }
6766
6767 if (EXPECTED((value_type & Z_TYPE_MASK) != IS_REFERENCE)) {
6768 zend_refcounted *gc = Z_COUNTED_P(value);
6769 zval *ref;
6770 ZVAL_NEW_EMPTY_REF(value);
6771 ref = Z_REFVAL_P(value);
6772 ZVAL_COPY_VALUE_EX(ref, value, gc, value_type);
6773 }
6774 if (EXPECTED(OP2_TYPE == IS_CV)) {
6775 zval *variable_ptr = EX_VAR(opline->op2.var);
6776 if (EXPECTED(variable_ptr != value)) {
6777 zend_reference *ref;
6778
6779 ref = Z_REF_P(value);
6780 GC_ADDREF(ref);
6781 i_zval_ptr_dtor(variable_ptr);
6782 ZVAL_REF(variable_ptr, ref);
6783 }
6784 } else {
6785 Z_ADDREF_P(value);
6786 ZVAL_REF(EX_VAR(opline->op2.var), Z_REF_P(value));
6787 }
6788 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6789 }
6790
6791 ZEND_VM_HOT_HANDLER(154, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET, SPEC(ISSET))
6792 {
6793 USE_OPLINE
6794 zval *value;
6795
6796 value = EX_VAR(opline->op1.var);
6797 if (!(opline->extended_value & ZEND_ISEMPTY)) {
6798 if (Z_TYPE_P(value) > IS_NULL &&
6799 (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) {
6800 ZEND_VM_SMART_BRANCH_TRUE();
6801 ZVAL_TRUE(EX_VAR(opline->result.var));
6802 ZEND_VM_NEXT_OPCODE();
6803 } else {
6804 ZEND_VM_SMART_BRANCH_FALSE();
6805 ZVAL_FALSE(EX_VAR(opline->result.var));
6806 ZEND_VM_NEXT_OPCODE();
6807 }
6808 } else {
6809 int result;
6810
6811 SAVE_OPLINE();
6812 result = !i_zend_is_true(value);
6813 if (UNEXPECTED(EG(exception))) {
6814 ZVAL_UNDEF(EX_VAR(opline->result.var));
6815 HANDLE_EXCEPTION();
6816 }
6817 ZEND_VM_SMART_BRANCH(result, 0);
6818 ZVAL_BOOL(EX_VAR(opline->result.var), result);
6819 ZEND_VM_NEXT_OPCODE();
6820 }
6821 }
6822
6823 ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
6824 {
6825 USE_OPLINE
6826 zval *value;
6827 int result;
6828 zend_free_op free_op1;
6829 zval *varname;
6830 zend_string *name, *tmp_name;
6831 HashTable *target_symbol_table;
6832
6833 SAVE_OPLINE();
6834 varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
6835 if (OP1_TYPE == IS_CONST) {
6836 name = Z_STR_P(varname);
6837 } else {
6838 name = zval_get_tmp_string(varname, &tmp_name);
6839 }
6840
6841 target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
6842 value = zend_hash_find_ex(target_symbol_table, name, OP1_TYPE == IS_CONST);
6843
6844 if (OP1_TYPE != IS_CONST) {
6845 zend_tmp_string_release(tmp_name);
6846 }
6847 FREE_OP1();
6848
6849 if (!value) {
6850 result = (opline->extended_value & ZEND_ISEMPTY);
6851 } else {
6852 if (Z_TYPE_P(value) == IS_INDIRECT) {
6853 value = Z_INDIRECT_P(value);
6854 }
6855 if (!(opline->extended_value & ZEND_ISEMPTY)) {
6856 if (Z_ISREF_P(value)) {
6857 value = Z_REFVAL_P(value);
6858 }
6859 result = Z_TYPE_P(value) > IS_NULL;
6860 } else {
6861 result = !i_zend_is_true(value);
6862 }
6863 }
6864
6865 ZEND_VM_SMART_BRANCH(result, 1);
6866 ZVAL_BOOL(EX_VAR(opline->result.var), result);
6867 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6868 }
6869
6870 /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
6871 ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, ANY, CLASS_FETCH, ISSET|CACHE_SLOT)
6872 {
6873 USE_OPLINE
6874 zval *value;
6875 int result;
6876
6877 SAVE_OPLINE();
6878
6879 result = zend_fetch_static_property_address(&value, NULL, opline->extended_value & ~ZEND_ISEMPTY, BP_VAR_IS, 0 OPLINE_CC EXECUTE_DATA_CC);
6880
6881 if (!(opline->extended_value & ZEND_ISEMPTY)) {
6882 result = result == SUCCESS && Z_TYPE_P(value) > IS_NULL &&
6883 (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
6884 } else {
6885 result = result != SUCCESS || !i_zend_is_true(value);
6886 }
6887
6888 ZEND_VM_SMART_BRANCH(result, 1);
6889 ZVAL_BOOL(EX_VAR(opline->result.var), result);
6890 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6891 }
6892
6893 ZEND_VM_COLD_CONSTCONST_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|CV, CONST|TMPVAR|CV, ISSET)
6894 {
6895 USE_OPLINE
6896 zend_free_op free_op1, free_op2;
6897 zval *container;
6898 int result;
6899 zend_ulong hval;
6900 zval *offset;
6901
6902 SAVE_OPLINE();
6903 container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_IS);
6904 offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
6905
6906 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
6907 HashTable *ht;
6908 zval *value;
6909 zend_string *str;
6910
6911 ZEND_VM_C_LABEL(isset_dim_obj_array):
6912 ht = Z_ARRVAL_P(container);
6913 ZEND_VM_C_LABEL(isset_again):
6914 if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
6915 str = Z_STR_P(offset);
6916 if (OP2_TYPE != IS_CONST) {
6917 if (ZEND_HANDLE_NUMERIC(str, hval)) {
6918 ZEND_VM_C_GOTO(num_index_prop);
6919 }
6920 }
6921 value = zend_hash_find_ex_ind(ht, str, OP2_TYPE == IS_CONST);
6922 } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
6923 hval = Z_LVAL_P(offset);
6924 ZEND_VM_C_LABEL(num_index_prop):
6925 value = zend_hash_index_find(ht, hval);
6926 } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
6927 offset = Z_REFVAL_P(offset);
6928 ZEND_VM_C_GOTO(isset_again);
6929 } else {
6930 value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
6931 if (UNEXPECTED(EG(exception))) {
6932 result = 0;
6933 ZEND_VM_C_GOTO(isset_dim_obj_exit);
6934 }
6935 }
6936
6937 if (!(opline->extended_value & ZEND_ISEMPTY)) {
6938 /* > IS_NULL means not IS_UNDEF and not IS_NULL */
6939 result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
6940 (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
6941
6942 if (OP1_TYPE & (IS_CONST|IS_CV)) {
6943 /* avoid exception check */
6944 FREE_OP2();
6945 ZEND_VM_SMART_BRANCH(result, 0);
6946 ZVAL_BOOL(EX_VAR(opline->result.var), result);
6947 ZEND_VM_NEXT_OPCODE();
6948 }
6949 } else {
6950 result = (value == NULL || !i_zend_is_true(value));
6951 }
6952 ZEND_VM_C_GOTO(isset_dim_obj_exit);
6953 } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
6954 container = Z_REFVAL_P(container);
6955 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
6956 ZEND_VM_C_GOTO(isset_dim_obj_array);
6957 }
6958 }
6959
6960 if (OP2_TYPE == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
6961 offset++;
6962 }
6963 if (!(opline->extended_value & ZEND_ISEMPTY)) {
6964 result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
6965 } else {
6966 result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
6967 }
6968
6969 ZEND_VM_C_LABEL(isset_dim_obj_exit):
6970 FREE_OP2();
6971 FREE_OP1();
6972 ZEND_VM_SMART_BRANCH(result, 1);
6973 ZVAL_BOOL(EX_VAR(opline->result.var), result);
6974 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
6975 }
6976
6977 ZEND_VM_COLD_CONST_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET|CACHE_SLOT)
6978 {
6979 USE_OPLINE
6980 zend_free_op free_op1, free_op2;
6981 zval *container;
6982 int result;
6983 zval *offset;
6984
6985 SAVE_OPLINE();
6986 container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
6987
6988 if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
6989 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
6990 }
6991
6992 offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
6993
6994 if (OP1_TYPE == IS_CONST ||
6995 (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
6996 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
6997 container = Z_REFVAL_P(container);
6998 if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
6999 result = (opline->extended_value & ZEND_ISEMPTY);
7000 ZEND_VM_C_GOTO(isset_object_finish);
7001 }
7002 } else {
7003 result = (opline->extended_value & ZEND_ISEMPTY);
7004 ZEND_VM_C_GOTO(isset_object_finish);
7005 }
7006 }
7007
7008 result =
7009 (opline->extended_value & ZEND_ISEMPTY) ^
7010 Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
7011
7012 ZEND_VM_C_LABEL(isset_object_finish):
7013 FREE_OP2();
7014 FREE_OP1();
7015 ZEND_VM_SMART_BRANCH(result, 1);
7016 ZVAL_BOOL(EX_VAR(opline->result.var), result);
7017 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7018 }
7019
7020 ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST)
7021 {
7022 USE_OPLINE
7023
7024 zend_free_op free_op1, free_op2;
7025 zval *key, *subject;
7026 HashTable *ht;
7027 uint32_t result;
7028
7029 SAVE_OPLINE();
7030
7031 key = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
7032 subject = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
7033
7034 if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
7035 ZEND_VM_C_LABEL(array_key_exists_array):
7036 ht = Z_ARRVAL_P(subject);
7037 result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
7038 } else {
7039 if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
7040 subject = Z_REFVAL_P(subject);
7041 if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
7042 ZEND_VM_C_GOTO(array_key_exists_array);
7043 }
7044 }
7045 result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC);
7046 }
7047
7048 FREE_OP2();
7049 FREE_OP1();
7050 ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1);
7051 Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result;
7052 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7053 }
7054
7055 /* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
7056 ZEND_VM_COLD_HANDLER(79, ZEND_EXIT, ANY, ANY)
7057 {
7058 USE_OPLINE
7059
7060 SAVE_OPLINE();
7061 if (OP1_TYPE != IS_UNUSED) {
7062 zend_free_op free_op1;
7063 zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
7064
7065 do {
7066 if (Z_TYPE_P(ptr) == IS_LONG) {
7067 EG(exit_status) = Z_LVAL_P(ptr);
7068 } else {
7069 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) {
7070 ptr = Z_REFVAL_P(ptr);
7071 if (Z_TYPE_P(ptr) == IS_LONG) {
7072 EG(exit_status) = Z_LVAL_P(ptr);
7073 break;
7074 }
7075 }
7076 zend_print_zval(ptr, 0);
7077 }
7078 } while (0);
7079 FREE_OP1();
7080 }
7081 zend_bailout();
7082 ZEND_VM_NEXT_OPCODE(); /* Never reached */
7083 }
7084
7085 ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
7086 {
7087 USE_OPLINE
7088
7089 ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
7090
7091 if (EG(error_reporting)) {
7092 do {
7093 EG(error_reporting) = 0;
7094 if (!EG(error_reporting_ini_entry)) {
7095 zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1);
7096 if (zv) {
7097 EG(error_reporting_ini_entry) = (zend_ini_entry *)Z_PTR_P(zv);
7098 } else {
7099 break;
7100 }
7101 }
7102 if (!EG(error_reporting_ini_entry)->modified) {
7103 if (!EG(modified_ini_directives)) {
7104 ALLOC_HASHTABLE(EG(modified_ini_directives));
7105 zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
7106 }
7107 if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), EG(error_reporting_ini_entry)) != NULL)) {
7108 EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
7109 EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
7110 EG(error_reporting_ini_entry)->modified = 1;
7111 }
7112 }
7113 } while (0);
7114 }
7115 ZEND_VM_NEXT_OPCODE();
7116 }
7117
7118 ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
7119 {
7120 USE_OPLINE
7121
7122 if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
7123 EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
7124 }
7125 ZEND_VM_NEXT_OPCODE();
7126 }
7127
7128 ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
7129 {
7130 USE_OPLINE
7131 zend_free_op free_op1;
7132 zval *value;
7133 zval *ref = NULL;
7134 int ret;
7135
7136 SAVE_OPLINE();
7137 value = GET_OP1_ZVAL_PTR(BP_VAR_R);
7138
7139 if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
7140 if (OP1_TYPE == IS_VAR) {
7141 ref = value;
7142 }
7143 value = Z_REFVAL_P(value);
7144 }
7145
7146 ret = i_zend_is_true(value);
7147
7148 if (UNEXPECTED(EG(exception))) {
7149 FREE_OP1();
7150 ZVAL_UNDEF(EX_VAR(opline->result.var));
7151 HANDLE_EXCEPTION();
7152 }
7153
7154 if (ret) {
7155 zval *result = EX_VAR(opline->result.var);
7156
7157 ZVAL_COPY_VALUE(result, value);
7158 if (OP1_TYPE == IS_CONST) {
7159 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
7160 } else if (OP1_TYPE == IS_CV) {
7161 if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
7162 } else if (OP1_TYPE == IS_VAR && ref) {
7163 zend_reference *r = Z_REF_P(ref);
7164
7165 if (UNEXPECTED(GC_DELREF(r) == 0)) {
7166 efree_size(r, sizeof(zend_reference));
7167 } else if (Z_OPT_REFCOUNTED_P(result)) {
7168 Z_ADDREF_P(result);
7169 }
7170 }
7171 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
7172 }
7173
7174 FREE_OP1();
7175 ZEND_VM_NEXT_OPCODE();
7176 }
7177
7178 ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
7179 {
7180 USE_OPLINE
7181 zend_free_op free_op1;
7182 zval *value;
7183 zval *ref = NULL;
7184
7185 SAVE_OPLINE();
7186 value = GET_OP1_ZVAL_PTR(BP_VAR_IS);
7187
7188 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
7189 if (OP1_TYPE & IS_VAR) {
7190 ref = value;
7191 }
7192 value = Z_REFVAL_P(value);
7193 }
7194
7195 if (Z_TYPE_P(value) > IS_NULL) {
7196 zval *result = EX_VAR(opline->result.var);
7197 ZVAL_COPY_VALUE(result, value);
7198 if (OP1_TYPE == IS_CONST) {
7199 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
7200 } else if (OP1_TYPE == IS_CV) {
7201 if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
7202 } else if ((OP1_TYPE & IS_VAR) && ref) {
7203 zend_reference *r = Z_REF_P(ref);
7204
7205 if (UNEXPECTED(GC_DELREF(r) == 0)) {
7206 efree_size(r, sizeof(zend_reference));
7207 } else if (Z_OPT_REFCOUNTED_P(result)) {
7208 Z_ADDREF_P(result);
7209 }
7210 }
7211 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
7212 }
7213
7214 FREE_OP1();
7215 ZEND_VM_NEXT_OPCODE();
7216 }
7217
7218 ZEND_VM_HOT_HANDLER(31, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
7219 {
7220 USE_OPLINE
7221 zend_free_op free_op1;
7222 zval *value;
7223 zval *result = EX_VAR(opline->result.var);
7224
7225 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
7226 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
7227 SAVE_OPLINE();
7228 ZVAL_UNDEFINED_OP1();
7229 ZVAL_NULL(result);
7230 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7231 }
7232
7233 if (OP1_TYPE == IS_CV) {
7234 ZVAL_COPY_DEREF(result, value);
7235 } else if (OP1_TYPE == IS_VAR) {
7236 if (UNEXPECTED(Z_ISREF_P(value))) {
7237 ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
7238 if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
7239 efree_size(Z_REF_P(value), sizeof(zend_reference));
7240 } else if (Z_OPT_REFCOUNTED_P(result)) {
7241 Z_ADDREF_P(result);
7242 }
7243 } else {
7244 ZVAL_COPY_VALUE(result, value);
7245 }
7246 } else {
7247 ZVAL_COPY_VALUE(result, value);
7248 if (OP1_TYPE == IS_CONST) {
7249 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
7250 Z_ADDREF_P(result);
7251 }
7252 }
7253 }
7254 ZEND_VM_NEXT_OPCODE();
7255 }
7256
7257 ZEND_VM_COLD_HANDLER(101, ZEND_EXT_STMT, ANY, ANY)
7258 {
7259 USE_OPLINE
7260
7261 if (!EG(no_extensions)) {
7262 SAVE_OPLINE();
7263 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, execute_data);
7264 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7265 }
7266 ZEND_VM_NEXT_OPCODE();
7267 }
7268
7269 ZEND_VM_COLD_HANDLER(102, ZEND_EXT_FCALL_BEGIN, ANY, ANY)
7270 {
7271 USE_OPLINE
7272
7273 if (!EG(no_extensions)) {
7274 SAVE_OPLINE();
7275 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, execute_data);
7276 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7277 }
7278 ZEND_VM_NEXT_OPCODE();
7279 }
7280
7281 ZEND_VM_COLD_HANDLER(103, ZEND_EXT_FCALL_END, ANY, ANY)
7282 {
7283 USE_OPLINE
7284
7285 if (!EG(no_extensions)) {
7286 SAVE_OPLINE();
7287 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, execute_data);
7288 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7289 }
7290 ZEND_VM_NEXT_OPCODE();
7291 }
7292
7293 ZEND_VM_HANDLER(144, ZEND_DECLARE_CLASS, CONST, ANY)
7294 {
7295 USE_OPLINE
7296
7297 SAVE_OPLINE();
7298 do_bind_class(RT_CONSTANT(opline, opline->op1), (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL);
7299 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7300 }
7301
7302 ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST)
7303 {
7304 USE_OPLINE
7305 zval *lcname, *zv;
7306 zend_class_entry *ce;
7307
7308 ce = CACHED_PTR(opline->extended_value);
7309 if (ce == NULL) {
7310 lcname = RT_CONSTANT(opline, opline->op1);
7311 zv = zend_hash_find_ex(EG(class_table), Z_STR_P(lcname + 1), 1);
7312 if (zv) {
7313 SAVE_OPLINE();
7314 ce = Z_CE_P(zv);
7315 zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
7316 if (UNEXPECTED(!zv)) {
7317 zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
7318 } else {
7319 if (zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2))) == FAILURE) {
7320 /* Reload bucket pointer, the hash table may have been reallocated */
7321 zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
7322 zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
7323 HANDLE_EXCEPTION();
7324 }
7325 }
7326 }
7327 CACHE_PTR(opline->extended_value, ce);
7328 }
7329 ZEND_VM_NEXT_OPCODE();
7330 }
7331
7332 ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT)
7333 {
7334 zval *zv;
7335 zend_class_entry *ce;
7336 USE_OPLINE
7337
7338 ce = CACHED_PTR(opline->extended_value);
7339 if (UNEXPECTED(ce == NULL)) {
7340 zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1));
7341 zv = zend_hash_find_ex(EG(class_table), rtd_key, 1);
7342 if (UNEXPECTED(zv == NULL)) {
7343 SAVE_OPLINE();
7344 do {
7345 ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED);
7346 if (zend_preload_autoload
7347 && zend_preload_autoload(EX(func)->op_array.filename) == SUCCESS) {
7348 zv = zend_hash_find_ex(EG(class_table), rtd_key, 1);
7349 if (EXPECTED(zv != NULL)) {
7350 break;
7351 }
7352 }
7353 zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded");
7354 } while (0);
7355 }
7356 ZEND_ASSERT(zv != NULL);
7357 ce = Z_CE_P(zv);
7358 if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
7359 SAVE_OPLINE();
7360 if (zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL) == FAILURE) {
7361 HANDLE_EXCEPTION();
7362 }
7363 }
7364 CACHE_PTR(opline->extended_value, ce);
7365 }
7366 Z_CE_P(EX_VAR(opline->result.var)) = ce;
7367 ZEND_VM_NEXT_OPCODE();
7368 }
7369
7370 ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY)
7371 {
7372 USE_OPLINE
7373
7374 SAVE_OPLINE();
7375 do_bind_function(RT_CONSTANT(opline, opline->op1));
7376 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7377 }
7378
7379 ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM)
7380 {
7381 USE_OPLINE
7382
7383 if ((uint32_t)++EG(ticks_count) >= opline->extended_value) {
7384 EG(ticks_count) = 0;
7385 if (zend_ticks_function) {
7386 SAVE_OPLINE();
7387 zend_ticks_function(opline->extended_value);
7388 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7389 }
7390 }
7391 ZEND_VM_NEXT_OPCODE();
7392 }
7393
7394 ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT)
7395 {
7396 USE_OPLINE
7397 zend_free_op free_op1;
7398 zval *expr;
7399 zend_bool result;
7400
7401 SAVE_OPLINE();
7402 expr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
7403
7404 ZEND_VM_C_LABEL(try_instanceof):
7405 if (Z_TYPE_P(expr) == IS_OBJECT) {
7406 zend_class_entry *ce;
7407
7408 if (OP2_TYPE == IS_CONST) {
7409 ce = CACHED_PTR(opline->extended_value);
7410 if (UNEXPECTED(ce == NULL)) {
7411 ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
7412 if (EXPECTED(ce)) {
7413 CACHE_PTR(opline->extended_value, ce);
7414 }
7415 }
7416 } else if (OP2_TYPE == IS_UNUSED) {
7417 ce = zend_fetch_class(NULL, opline->op2.num);
7418 if (UNEXPECTED(ce == NULL)) {
7419 ZEND_ASSERT(EG(exception));
7420 FREE_OP1();
7421 ZVAL_UNDEF(EX_VAR(opline->result.var));
7422 HANDLE_EXCEPTION();
7423 }
7424 } else {
7425 ce = Z_CE_P(EX_VAR(opline->op2.var));
7426 }
7427 result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
7428 } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
7429 expr = Z_REFVAL_P(expr);
7430 ZEND_VM_C_GOTO(try_instanceof);
7431 } else {
7432 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
7433 ZVAL_UNDEFINED_OP1();
7434 }
7435 result = 0;
7436 }
7437 FREE_OP1();
7438 ZEND_VM_SMART_BRANCH(result, 1);
7439 ZVAL_BOOL(EX_VAR(opline->result.var), result);
7440 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7441 }
7442
7443 ZEND_VM_HOT_HANDLER(104, ZEND_EXT_NOP, ANY, ANY)
7444 {
7445 USE_OPLINE
7446
7447 ZEND_VM_NEXT_OPCODE();
7448 }
7449
7450 ZEND_VM_HOT_HANDLER(0, ZEND_NOP, ANY, ANY)
7451 {
7452 USE_OPLINE
7453
7454 ZEND_VM_NEXT_OPCODE();
7455 }
7456
ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper,ANY,ANY,uint32_t try_catch_offset,uint32_t op_num)7457 ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_catch_offset, uint32_t op_num)
7458 {
7459 /* May be NULL during generator closing (only finally blocks are executed) */
7460 zend_object *ex = EG(exception);
7461
7462 /* Walk try/catch/finally structures upwards, performing the necessary actions */
7463 while (try_catch_offset != (uint32_t) -1) {
7464 zend_try_catch_element *try_catch =
7465 &EX(func)->op_array.try_catch_array[try_catch_offset];
7466
7467 if (op_num < try_catch->catch_op && ex) {
7468 /* Go to catch block */
7469 cleanup_live_vars(execute_data, op_num, try_catch->catch_op);
7470 ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->catch_op], 0);
7471
7472 } else if (op_num < try_catch->finally_op) {
7473 /* Go to finally block */
7474 zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[try_catch->finally_end].op1.var);
7475 cleanup_live_vars(execute_data, op_num, try_catch->finally_op);
7476 Z_OBJ_P(fast_call) = EG(exception);
7477 EG(exception) = NULL;
7478 Z_OPLINE_NUM_P(fast_call) = (uint32_t)-1;
7479 ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->finally_op], 0);
7480
7481 } else if (op_num < try_catch->finally_end) {
7482 zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[try_catch->finally_end].op1.var);
7483
7484 /* cleanup incomplete RETURN statement */
7485 if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1
7486 && (EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2_type & (IS_TMP_VAR | IS_VAR))) {
7487 zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var);
7488
7489 zval_ptr_dtor(return_value);
7490 }
7491
7492 /* Chain potential exception from wrapping finally block */
7493 if (Z_OBJ_P(fast_call)) {
7494 if (ex) {
7495 zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
7496 } else {
7497 EG(exception) = Z_OBJ_P(fast_call);
7498 }
7499 ex = Z_OBJ_P(fast_call);
7500 }
7501 }
7502
7503 try_catch_offset--;
7504 }
7505
7506 /* Uncaught exception */
7507 cleanup_live_vars(execute_data, op_num, 0);
7508 if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
7509 zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
7510 zend_generator_close(generator, 1);
7511 ZEND_VM_RETURN();
7512 } else {
7513 /* We didn't execute RETURN, and have to initialize return_value */
7514 if (EX(return_value)) {
7515 ZVAL_UNDEF(EX(return_value));
7516 }
7517 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
7518 }
7519 }
7520
7521 ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
7522 {
7523 const zend_op *throw_op = EG(opline_before_exception);
7524 uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
7525 int i, current_try_catch_offset = -1;
7526
7527 if ((throw_op->opcode == ZEND_FREE || throw_op->opcode == ZEND_FE_FREE)
7528 && throw_op->extended_value & ZEND_FREE_ON_RETURN) {
7529 /* exceptions thrown because of loop var destruction on return/break/...
7530 * are logically thrown at the end of the foreach loop, so adjust the
7531 * throw_op_num.
7532 */
7533 const zend_live_range *range = find_live_range(
7534 &EX(func)->op_array, throw_op_num, throw_op->op1.var);
7535 throw_op_num = range->end;
7536 }
7537
7538 /* Find the innermost try/catch/finally the exception was thrown in */
7539 for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
7540 zend_try_catch_element *try_catch = &EX(func)->op_array.try_catch_array[i];
7541 if (try_catch->try_op > throw_op_num) {
7542 /* further blocks will not be relevant... */
7543 break;
7544 }
7545 if (throw_op_num < try_catch->catch_op || throw_op_num < try_catch->finally_end) {
7546 current_try_catch_offset = i;
7547 }
7548 }
7549
7550 cleanup_unfinished_calls(execute_data, throw_op_num);
7551
7552 if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) {
7553 switch (throw_op->opcode) {
7554 case ZEND_ADD_ARRAY_ELEMENT:
7555 case ZEND_ADD_ARRAY_UNPACK:
7556 case ZEND_ROPE_INIT:
7557 case ZEND_ROPE_ADD:
7558 break; /* exception while building structures, live range handling will free those */
7559
7560 case ZEND_FETCH_CLASS:
7561 case ZEND_DECLARE_ANON_CLASS:
7562 break; /* return value is zend_class_entry pointer */
7563
7564 default:
7565 zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var));
7566 }
7567 }
7568
7569 ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, current_try_catch_offset, op_num, throw_op_num);
7570 }
7571
7572 ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
7573 {
7574 USE_OPLINE
7575 int ret;
7576
7577 SAVE_OPLINE();
7578 ret = zend_user_opcode_handlers[opline->opcode](execute_data);
7579 opline = EX(opline);
7580
7581 switch (ret) {
7582 case ZEND_USER_OPCODE_CONTINUE:
7583 ZEND_VM_CONTINUE();
7584 case ZEND_USER_OPCODE_RETURN:
7585 if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
7586 zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
7587 zend_generator_close(generator, 1);
7588 ZEND_VM_RETURN();
7589 } else {
7590 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
7591 }
7592 case ZEND_USER_OPCODE_ENTER:
7593 ZEND_VM_ENTER();
7594 case ZEND_USER_OPCODE_LEAVE:
7595 ZEND_VM_LEAVE();
7596 case ZEND_USER_OPCODE_DISPATCH:
7597 ZEND_VM_DISPATCH(opline->opcode, opline);
7598 default:
7599 ZEND_VM_DISPATCH((zend_uchar)(ret & 0xff), opline);
7600 }
7601 }
7602
7603 ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
7604 {
7605 USE_OPLINE
7606 zend_free_op free_op1, free_op2;
7607 zval *name;
7608 zval *val;
7609 zend_constant c;
7610
7611 SAVE_OPLINE();
7612 name = GET_OP1_ZVAL_PTR(BP_VAR_R);
7613 val = GET_OP2_ZVAL_PTR(BP_VAR_R);
7614
7615 ZVAL_COPY(&c.value, val);
7616 if (Z_OPT_CONSTANT(c.value)) {
7617 if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
7618 zval_ptr_dtor_nogc(&c.value);
7619 FREE_OP1();
7620 FREE_OP2();
7621 HANDLE_EXCEPTION();
7622 }
7623 }
7624 /* non persistent, case sensitive */
7625 ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, PHP_USER_CONSTANT);
7626 c.name = zend_string_copy(Z_STR_P(name));
7627
7628 if (zend_register_constant(&c) == FAILURE) {
7629 }
7630
7631 FREE_OP1();
7632 FREE_OP2();
7633 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7634 }
7635
7636 ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED, CACHE_SLOT)
7637 {
7638 USE_OPLINE
7639 zend_function *func;
7640 zval *zfunc;
7641 zval *object;
7642 zend_class_entry *called_scope;
7643
7644 func = CACHED_PTR(opline->extended_value);
7645 if (UNEXPECTED(func == NULL)) {
7646 zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
7647 ZEND_ASSERT(zfunc != NULL);
7648 func = Z_FUNC_P(zfunc);
7649 ZEND_ASSERT(func->type == ZEND_USER_FUNCTION);
7650 CACHE_PTR(opline->extended_value, func);
7651 }
7652
7653 if (Z_TYPE(EX(This)) == IS_OBJECT) {
7654 called_scope = Z_OBJCE(EX(This));
7655 if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) ||
7656 (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
7657 object = NULL;
7658 } else {
7659 object = &EX(This);
7660 }
7661 } else {
7662 called_scope = Z_CE(EX(This));
7663 object = NULL;
7664 }
7665 zend_create_closure(EX_VAR(opline->result.var), func,
7666 EX(func)->op_array.scope, called_scope, object);
7667
7668 ZEND_VM_NEXT_OPCODE();
7669 }
7670
7671 ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
7672 {
7673 USE_OPLINE
7674 zval *var_ptr;
7675
7676 var_ptr = EX_VAR(opline->op1.var);
7677 if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
7678 if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
7679 ZVAL_UNREF(var_ptr);
7680 }
7681 }
7682
7683 ZEND_VM_NEXT_OPCODE();
7684 }
7685
ZEND_VM_COLD_HELPER(zend_yield_in_closed_generator_helper,ANY,ANY)7686 ZEND_VM_COLD_HELPER(zend_yield_in_closed_generator_helper, ANY, ANY)
7687 {
7688 USE_OPLINE
7689
7690 SAVE_OPLINE();
7691 zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator");
7692 FREE_UNFETCHED_OP2();
7693 FREE_UNFETCHED_OP1();
7694 UNDEF_RESULT();
7695 HANDLE_EXCEPTION();
7696 }
7697
7698 ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED, SRC)
7699 {
7700 USE_OPLINE
7701
7702 zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
7703
7704 SAVE_OPLINE();
7705 if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
7706 ZEND_VM_DISPATCH_TO_HELPER(zend_yield_in_closed_generator_helper);
7707 }
7708
7709 /* Destroy the previously yielded value */
7710 zval_ptr_dtor(&generator->value);
7711
7712 /* Destroy the previously yielded key */
7713 zval_ptr_dtor(&generator->key);
7714
7715 /* Set the new yielded value */
7716 if (OP1_TYPE != IS_UNUSED) {
7717 zend_free_op free_op1;
7718
7719 if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
7720 /* Constants and temporary variables aren't yieldable by reference,
7721 * but we still allow them with a notice. */
7722 if (OP1_TYPE & (IS_CONST|IS_TMP_VAR)) {
7723 zval *value;
7724
7725 zend_error(E_NOTICE, "Only variable references should be yielded by reference");
7726
7727 value = GET_OP1_ZVAL_PTR(BP_VAR_R);
7728 ZVAL_COPY_VALUE(&generator->value, value);
7729 if (OP1_TYPE == IS_CONST) {
7730 if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
7731 Z_ADDREF(generator->value);
7732 }
7733 }
7734 } else {
7735 zval *value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
7736
7737 /* If a function call result is yielded and the function did
7738 * not return by reference we throw a notice. */
7739 do {
7740 if (OP1_TYPE == IS_VAR) {
7741 ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
7742 if (opline->extended_value == ZEND_RETURNS_FUNCTION
7743 && !Z_ISREF_P(value_ptr)) {
7744 zend_error(E_NOTICE, "Only variable references should be yielded by reference");
7745 ZVAL_COPY(&generator->value, value_ptr);
7746 break;
7747 }
7748 }
7749 if (Z_ISREF_P(value_ptr)) {
7750 Z_ADDREF_P(value_ptr);
7751 } else {
7752 ZVAL_MAKE_REF_EX(value_ptr, 2);
7753 }
7754 ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
7755 } while (0);
7756
7757 FREE_OP1_VAR_PTR();
7758 }
7759 } else {
7760 zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
7761
7762 /* Consts, temporary variables and references need copying */
7763 if (OP1_TYPE == IS_CONST) {
7764 ZVAL_COPY_VALUE(&generator->value, value);
7765 if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
7766 Z_ADDREF(generator->value);
7767 }
7768 } else if (OP1_TYPE == IS_TMP_VAR) {
7769 ZVAL_COPY_VALUE(&generator->value, value);
7770 } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
7771 ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
7772 FREE_OP1_IF_VAR();
7773 } else {
7774 ZVAL_COPY_VALUE(&generator->value, value);
7775 if (OP1_TYPE == IS_CV) {
7776 if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
7777 }
7778 }
7779 }
7780 } else {
7781 /* If no value was specified yield null */
7782 ZVAL_NULL(&generator->value);
7783 }
7784
7785 /* Set the new yielded key */
7786 if (OP2_TYPE != IS_UNUSED) {
7787 zend_free_op free_op2;
7788 zval *key = GET_OP2_ZVAL_PTR(BP_VAR_R);
7789
7790 /* Consts, temporary variables and references need copying */
7791 if (OP2_TYPE == IS_CONST) {
7792 ZVAL_COPY_VALUE(&generator->key, key);
7793 if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) {
7794 Z_ADDREF(generator->key);
7795 }
7796 } else if (OP2_TYPE == IS_TMP_VAR) {
7797 ZVAL_COPY_VALUE(&generator->key, key);
7798 } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
7799 ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
7800 FREE_OP2_IF_VAR();
7801 } else {
7802 ZVAL_COPY_VALUE(&generator->key, key);
7803 if (OP2_TYPE == IS_CV) {
7804 if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
7805 }
7806 }
7807
7808 if (Z_TYPE(generator->key) == IS_LONG
7809 && Z_LVAL(generator->key) > generator->largest_used_integer_key
7810 ) {
7811 generator->largest_used_integer_key = Z_LVAL(generator->key);
7812 }
7813 } else {
7814 /* If no key was specified we use auto-increment keys */
7815 generator->largest_used_integer_key++;
7816 ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
7817 }
7818
7819 if (RETURN_VALUE_USED(opline)) {
7820 /* If the return value of yield is used set the send
7821 * target and initialize it to NULL */
7822 generator->send_target = EX_VAR(opline->result.var);
7823 ZVAL_NULL(generator->send_target);
7824 } else {
7825 generator->send_target = NULL;
7826 }
7827
7828 /* We increment to the next op, so we are at the correct position when the
7829 * generator is resumed. */
7830 ZEND_VM_INC_OPCODE();
7831
7832 /* The GOTO VM uses a local opline variable. We need to set the opline
7833 * variable in execute_data so we don't resume at an old position. */
7834 SAVE_OPLINE();
7835
7836 ZEND_VM_RETURN();
7837 }
7838
7839 ZEND_VM_HANDLER(166, ZEND_YIELD_FROM, CONST|TMP|VAR|CV, ANY)
7840 {
7841 USE_OPLINE
7842
7843 zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
7844
7845 zval *val;
7846 zend_free_op free_op1;
7847
7848 SAVE_OPLINE();
7849 val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
7850
7851 if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
7852 zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
7853 FREE_OP1();
7854 UNDEF_RESULT();
7855 HANDLE_EXCEPTION();
7856 }
7857
7858 if (Z_TYPE_P(val) == IS_ARRAY) {
7859 ZVAL_COPY_VALUE(&generator->values, val);
7860 if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
7861 Z_ADDREF_P(val);
7862 }
7863 Z_FE_POS(generator->values) = 0;
7864
7865 FREE_OP1_IF_VAR();
7866 } else if (OP1_TYPE != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
7867 zend_class_entry *ce = Z_OBJCE_P(val);
7868 if (ce == zend_ce_generator) {
7869 zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val);
7870
7871 if (OP1_TYPE != IS_TMP_VAR) {
7872 Z_ADDREF_P(val);
7873 }
7874 FREE_OP1_IF_VAR();
7875
7876 if (Z_ISUNDEF(new_gen->retval)) {
7877 if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) {
7878 zend_throw_error(NULL, "Impossible to yield from the Generator being currently run");
7879 zval_ptr_dtor(val);
7880 UNDEF_RESULT();
7881 HANDLE_EXCEPTION();
7882 } else {
7883 zend_generator_yield_from(generator, new_gen);
7884 }
7885 } else if (UNEXPECTED(new_gen->execute_data == NULL)) {
7886 zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
7887 zval_ptr_dtor(val);
7888 UNDEF_RESULT();
7889 HANDLE_EXCEPTION();
7890 } else {
7891 if (RETURN_VALUE_USED(opline)) {
7892 ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval);
7893 }
7894 ZEND_VM_NEXT_OPCODE();
7895 }
7896 } else {
7897 zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
7898 FREE_OP1();
7899
7900 if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
7901 if (!EG(exception)) {
7902 zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
7903 }
7904 UNDEF_RESULT();
7905 HANDLE_EXCEPTION();
7906 }
7907
7908 iter->index = 0;
7909 if (iter->funcs->rewind) {
7910 iter->funcs->rewind(iter);
7911 if (UNEXPECTED(EG(exception) != NULL)) {
7912 OBJ_RELEASE(&iter->std);
7913 UNDEF_RESULT();
7914 HANDLE_EXCEPTION();
7915 }
7916 }
7917
7918 ZVAL_OBJ(&generator->values, &iter->std);
7919 }
7920 } else {
7921 zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
7922 FREE_OP1();
7923 UNDEF_RESULT();
7924 HANDLE_EXCEPTION();
7925 }
7926
7927 /* This is the default return value
7928 * when the expression is a Generator, it will be overwritten in zend_generator_resume() */
7929 if (RETURN_VALUE_USED(opline)) {
7930 ZVAL_NULL(EX_VAR(opline->result.var));
7931 }
7932
7933 /* This generator has no send target (though the generator we delegate to might have one) */
7934 generator->send_target = NULL;
7935
7936 /* We increment to the next op, so we are at the correct position when the
7937 * generator is resumed. */
7938 ZEND_VM_INC_OPCODE();
7939
7940 /* The GOTO VM uses a local opline variable. We need to set the opline
7941 * variable in execute_data so we don't resume at an old position. */
7942 SAVE_OPLINE();
7943
7944 ZEND_VM_RETURN();
7945 }
7946
7947 ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
7948 {
7949 USE_OPLINE
7950 zval *fast_call = EX_VAR(opline->op1.var);
7951 SAVE_OPLINE();
7952
7953 /* cleanup incomplete RETURN statement */
7954 if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1
7955 && (EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2_type & (IS_TMP_VAR | IS_VAR))) {
7956 zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var);
7957
7958 zval_ptr_dtor(return_value);
7959 }
7960
7961 /* cleanup delayed exception */
7962 if (Z_OBJ_P(fast_call) != NULL) {
7963 /* discard the previously thrown exception */
7964 OBJ_RELEASE(Z_OBJ_P(fast_call));
7965 Z_OBJ_P(fast_call) = NULL;
7966 }
7967
7968 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
7969 }
7970
7971 ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, ANY)
7972 {
7973 USE_OPLINE
7974 zval *fast_call = EX_VAR(opline->result.var);
7975
7976 Z_OBJ_P(fast_call) = NULL;
7977 /* set return address */
7978 Z_OPLINE_NUM_P(fast_call) = opline - EX(func)->op_array.opcodes;
7979 ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
7980 }
7981
7982 ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH)
7983 {
7984 USE_OPLINE
7985 zval *fast_call = EX_VAR(opline->op1.var);
7986 uint32_t current_try_catch_offset, current_op_num;
7987
7988 if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1) {
7989 const zend_op *fast_ret = EX(func)->op_array.opcodes + Z_OPLINE_NUM_P(fast_call);
7990
7991 ZEND_VM_JMP_EX(fast_ret + 1, 0);
7992 }
7993
7994 /* special case for unhandled exceptions */
7995 EG(exception) = Z_OBJ_P(fast_call);
7996 Z_OBJ_P(fast_call) = NULL;
7997 current_try_catch_offset = opline->op2.num;
7998 current_op_num = opline - EX(func)->op_array.opcodes;
7999 ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, current_try_catch_offset, op_num, current_op_num);
8000 }
8001
8002 ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST, CACHE_SLOT)
8003 {
8004 USE_OPLINE
8005 zend_free_op free_op1, free_op2;
8006 zend_string *varname;
8007 zval *value;
8008 zval *variable_ptr;
8009 uintptr_t idx;
8010 zend_reference *ref;
8011
8012 ZEND_VM_REPEATABLE_OPCODE
8013
8014 varname = Z_STR_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
8015
8016 /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
8017 idx = (uintptr_t)CACHED_PTR(opline->extended_value) - 1;
8018 if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) {
8019 Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx);
8020
8021 if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
8022 (EXPECTED(p->key == varname) ||
8023 (EXPECTED(p->h == ZSTR_H(varname)) &&
8024 EXPECTED(p->key != NULL) &&
8025 EXPECTED(zend_string_equal_content(p->key, varname))))) {
8026
8027 value = (zval*)p; /* value = &p->val; */
8028 ZEND_VM_C_GOTO(check_indirect);
8029 }
8030 }
8031
8032 value = zend_hash_find_ex(&EG(symbol_table), varname, 1);
8033 if (UNEXPECTED(value == NULL)) {
8034 value = zend_hash_add_new(&EG(symbol_table), varname, &EG(uninitialized_zval));
8035 idx = (char*)value - (char*)EG(symbol_table).arData;
8036 /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
8037 CACHE_PTR(opline->extended_value, (void*)(idx + 1));
8038 } else {
8039 idx = (char*)value - (char*)EG(symbol_table).arData;
8040 /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
8041 CACHE_PTR(opline->extended_value, (void*)(idx + 1));
8042 ZEND_VM_C_LABEL(check_indirect):
8043 /* GLOBAL variable may be an INDIRECT pointer to CV */
8044 if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
8045 value = Z_INDIRECT_P(value);
8046 if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
8047 ZVAL_NULL(value);
8048 }
8049 }
8050 }
8051
8052 if (UNEXPECTED(!Z_ISREF_P(value))) {
8053 ZVAL_MAKE_REF_EX(value, 2);
8054 ref = Z_REF_P(value);
8055 } else {
8056 ref = Z_REF_P(value);
8057 GC_ADDREF(ref);
8058 }
8059
8060 variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
8061
8062 if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
8063 zend_refcounted *ref = Z_COUNTED_P(variable_ptr);
8064 uint32_t refcnt = GC_DELREF(ref);
8065
8066 if (EXPECTED(variable_ptr != value)) {
8067 if (refcnt == 0) {
8068 SAVE_OPLINE();
8069 rc_dtor_func(ref);
8070 if (UNEXPECTED(EG(exception))) {
8071 ZVAL_NULL(variable_ptr);
8072 HANDLE_EXCEPTION();
8073 }
8074 } else {
8075 gc_check_possible_root(ref);
8076 }
8077 }
8078 }
8079 ZVAL_REF(variable_ptr, ref);
8080
8081 ZEND_VM_REPEAT_OPCODE(ZEND_BIND_GLOBAL);
8082 ZEND_VM_NEXT_OPCODE();
8083 }
8084
8085 ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
8086 {
8087 USE_OPLINE
8088 zval *value;
8089 zend_free_op free_op1;
8090
8091 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8092 if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
8093 ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
8094 FREE_OP1();
8095 ZEND_VM_NEXT_OPCODE();
8096 } else {
8097 zend_bool strict;
8098
8099 if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
8100 value = Z_REFVAL_P(value);
8101 if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
8102 ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
8103 FREE_OP1();
8104 ZEND_VM_NEXT_OPCODE();
8105 }
8106 }
8107
8108 SAVE_OPLINE();
8109 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
8110 value = ZVAL_UNDEFINED_OP1();
8111 }
8112 strict = EX_USES_STRICT_TYPES();
8113 do {
8114 if (EXPECTED(!strict)) {
8115 zend_string *str;
8116 zval tmp;
8117
8118 ZVAL_COPY(&tmp, value);
8119 if (zend_parse_arg_str_weak(&tmp, &str)) {
8120 ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
8121 zval_ptr_dtor(&tmp);
8122 break;
8123 }
8124 zval_ptr_dtor(&tmp);
8125 }
8126 if (!EG(exception)) {
8127 zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
8128 }
8129 ZVAL_NULL(EX_VAR(opline->result.var));
8130 } while (0);
8131 }
8132 FREE_OP1();
8133 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8134 }
8135
8136 ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMPVAR|CV, ANY, TYPE_MASK)
8137 {
8138 USE_OPLINE
8139 zval *value;
8140 int result = 0;
8141 zend_free_op free_op1;
8142
8143 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8144 if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
8145 ZEND_VM_C_LABEL(type_check_resource):
8146 if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
8147 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
8148 result = 1;
8149 }
8150 } else if ((OP1_TYPE & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) {
8151 value = Z_REFVAL_P(value);
8152 if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
8153 ZEND_VM_C_GOTO(type_check_resource);
8154 }
8155 } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
8156 result = ((1 << IS_NULL) & opline->extended_value) != 0;
8157 SAVE_OPLINE();
8158 ZVAL_UNDEFINED_OP1();
8159 if (UNEXPECTED(EG(exception))) {
8160 ZVAL_UNDEF(EX_VAR(opline->result.var));
8161 HANDLE_EXCEPTION();
8162 }
8163 }
8164 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
8165 SAVE_OPLINE();
8166 FREE_OP1();
8167 ZEND_VM_SMART_BRANCH(result, 1);
8168 ZVAL_BOOL(EX_VAR(opline->result.var), result);
8169 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8170 } else {
8171 ZEND_VM_SMART_BRANCH(result, 0);
8172 ZVAL_BOOL(EX_VAR(opline->result.var), result);
8173 ZEND_VM_NEXT_OPCODE();
8174 }
8175 }
8176
8177 ZEND_VM_HOT_HANDLER(122, ZEND_DEFINED, CONST, ANY, CACHE_SLOT)
8178 {
8179 USE_OPLINE
8180 zend_constant *c;
8181
8182 c = CACHED_PTR(opline->extended_value);
8183 if (EXPECTED(c != NULL)) {
8184 if (!IS_SPECIAL_CACHE_VAL(c)) {
8185 ZEND_VM_C_LABEL(defined_true):
8186 ZEND_VM_SMART_BRANCH_TRUE();
8187 ZVAL_TRUE(EX_VAR(opline->result.var));
8188 ZEND_VM_NEXT_OPCODE();
8189 } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) {
8190 ZEND_VM_C_LABEL(defined_false):
8191 ZEND_VM_SMART_BRANCH_FALSE();
8192 ZVAL_FALSE(EX_VAR(opline->result.var));
8193 ZEND_VM_NEXT_OPCODE();
8194 }
8195 }
8196 if (zend_quick_check_constant(RT_CONSTANT(opline, opline->op1) OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
8197 CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
8198 ZEND_VM_C_GOTO(defined_false);
8199 } else {
8200 ZEND_VM_C_GOTO(defined_true);
8201 }
8202 }
8203
8204 ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR)
8205 {
8206 USE_OPLINE
8207
8208 if (EG(assertions) <= 0) {
8209 zend_op *target = OP_JMP_ADDR(opline, opline->op2);
8210 if (RETURN_VALUE_USED(opline)) {
8211 ZVAL_TRUE(EX_VAR(opline->result.var));
8212 }
8213 ZEND_VM_JMP_EX(target, 0);
8214 } else {
8215 ZEND_VM_NEXT_OPCODE();
8216 }
8217 }
8218
8219 ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, UNUSED|CLASS_FETCH, ANY)
8220 {
8221 uint32_t fetch_type;
8222 zend_class_entry *called_scope, *scope;
8223 USE_OPLINE
8224
8225 fetch_type = opline->op1.num;
8226
8227 scope = EX(func)->op_array.scope;
8228 if (UNEXPECTED(scope == NULL)) {
8229 SAVE_OPLINE();
8230 zend_throw_error(NULL, "Cannot use \"%s\" when no class scope is active",
8231 fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
8232 fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
8233 ZVAL_UNDEF(EX_VAR(opline->result.var));
8234 HANDLE_EXCEPTION();
8235 }
8236
8237 switch (fetch_type) {
8238 case ZEND_FETCH_CLASS_SELF:
8239 ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
8240 break;
8241 case ZEND_FETCH_CLASS_PARENT:
8242 if (UNEXPECTED(scope->parent == NULL)) {
8243 SAVE_OPLINE();
8244 zend_throw_error(NULL,
8245 "Cannot use \"parent\" when current class scope has no parent");
8246 ZVAL_UNDEF(EX_VAR(opline->result.var));
8247 HANDLE_EXCEPTION();
8248 }
8249 ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
8250 break;
8251 case ZEND_FETCH_CLASS_STATIC:
8252 if (Z_TYPE(EX(This)) == IS_OBJECT) {
8253 called_scope = Z_OBJCE(EX(This));
8254 } else {
8255 called_scope = Z_CE(EX(This));
8256 }
8257 ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
8258 break;
8259 EMPTY_SWITCH_DEFAULT_CASE()
8260 }
8261 ZEND_VM_NEXT_OPCODE();
8262 }
8263
8264 ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
8265 {
8266 zend_array *args = NULL;
8267 zend_function *fbc = EX(func);
8268 zval *ret = EX(return_value);
8269 uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS);
8270 uint32_t num_args = EX_NUM_ARGS();
8271 zend_execute_data *call;
8272
8273 SAVE_OPLINE();
8274
8275 if (num_args) {
8276 zval *p = ZEND_CALL_ARG(execute_data, 1);
8277 zval *end = p + num_args;
8278
8279 args = zend_new_array(num_args);
8280 zend_hash_real_init_packed(args);
ZEND_HASH_FILL_PACKED(args)8281 ZEND_HASH_FILL_PACKED(args) {
8282 do {
8283 ZEND_HASH_FILL_ADD(p);
8284 p++;
8285 } while (p != end);
8286 } ZEND_HASH_FILL_END();
8287 }
8288
8289 call = execute_data;
8290 execute_data = EG(current_execute_data) = EX(prev_execute_data);
8291
8292 call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call;
8293 ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
8294 ZEND_CALL_NUM_ARGS(call) = 2;
8295
8296 ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
8297 if (args) {
8298 ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
8299 } else {
8300 ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2));
8301 }
8302 zend_free_trampoline(fbc);
8303 fbc = call->func;
8304
8305 if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
8306 if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
8307 init_func_run_time_cache(&fbc->op_array);
8308 }
8309 execute_data = call;
8310 i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
8311 if (EXPECTED(zend_execute_ex == execute_ex)) {
8312 LOAD_OPLINE_EX();
8313 ZEND_VM_ENTER_EX();
8314 } else {
8315 SAVE_OPLINE_EX();
8316 execute_data = EX(prev_execute_data);
8317 LOAD_OPLINE();
8318 ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
8319 zend_execute_ex(call);
8320 }
8321 } else {
8322 zval retval;
8323
8324 ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
8325
8326 EG(current_execute_data) = call;
8327
8328 if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
8329 && UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
8330 zend_vm_stack_free_call_frame(call);
8331 if (ret) {
8332 ZVAL_UNDEF(ret);
8333 }
8334 ZEND_VM_C_GOTO(call_trampoline_end);
8335 }
8336
8337 if (ret == NULL) {
8338 ret = &retval;
8339 }
8340
8341 ZVAL_NULL(ret);
8342 if (!zend_execute_internal) {
8343 /* saves one function call if zend_execute_internal is not used */
8344 fbc->internal_function.handler(call, ret);
8345 } else {
8346 zend_execute_internal(call, ret);
8347 }
8348
8349 #if ZEND_DEBUG
8350 if (!EG(exception) && call->func) {
8351 ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
8352 zend_verify_internal_return_type(call->func, ret));
8353 ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
8354 ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
8355 }
8356 #endif
8357
8358 EG(current_execute_data) = call->prev_execute_data;
8359
8360 ZEND_VM_C_LABEL(call_trampoline_end):
8361 zend_vm_stack_free_args(call);
8362 if (ret == &retval) {
8363 zval_ptr_dtor(ret);
8364 }
8365 }
8366
8367 execute_data = EG(current_execute_data);
8368
8369 if (!EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
8370 ZEND_VM_RETURN();
8371 }
8372
8373 if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
8374 zend_object *object = Z_OBJ(call->This);
8375 OBJ_RELEASE(object);
8376 }
8377 zend_vm_stack_free_call_frame(call);
8378
8379 if (UNEXPECTED(EG(exception) != NULL)) {
8380 zend_rethrow_exception(execute_data);
8381 HANDLE_EXCEPTION_LEAVE();
8382 }
8383
8384 LOAD_OPLINE();
8385 ZEND_VM_INC_OPCODE();
8386 ZEND_VM_LEAVE();
8387 }
8388
8389 ZEND_VM_HANDLER(182, ZEND_BIND_LEXICAL, TMP, CV, REF)
8390 {
8391 USE_OPLINE
8392 zend_free_op free_op1, free_op2;
8393 zval *closure, *var;
8394
8395 closure = GET_OP1_ZVAL_PTR(BP_VAR_R);
8396 if (opline->extended_value & ZEND_BIND_REF) {
8397 /* By-ref binding */
8398 var = GET_OP2_ZVAL_PTR(BP_VAR_W);
8399 if (Z_ISREF_P(var)) {
8400 Z_ADDREF_P(var);
8401 } else {
8402 ZVAL_MAKE_REF_EX(var, 2);
8403 }
8404 } else {
8405 var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8406 if (UNEXPECTED(Z_ISUNDEF_P(var)) && !(opline->extended_value & ZEND_BIND_IMPLICIT)) {
8407 SAVE_OPLINE();
8408 var = ZVAL_UNDEFINED_OP2();
8409 if (UNEXPECTED(EG(exception))) {
8410 HANDLE_EXCEPTION();
8411 }
8412 }
8413 ZVAL_DEREF(var);
8414 Z_TRY_ADDREF_P(var);
8415 }
8416
8417 zend_closure_bind_var_ex(closure,
8418 (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)), var);
8419 ZEND_VM_NEXT_OPCODE();
8420 }
8421
8422 ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
8423 {
8424 USE_OPLINE
8425 zend_free_op free_op1;
8426 HashTable *ht;
8427 zval *value;
8428 zval *variable_ptr;
8429
8430 variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
8431 i_zval_ptr_dtor(variable_ptr);
8432
8433 ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
8434 if (!ht) {
8435 ZEND_ASSERT(EX(func)->op_array.fn_flags & (ZEND_ACC_IMMUTABLE|ZEND_ACC_PRELOADED));
8436 ht = zend_array_dup(EX(func)->op_array.static_variables);
8437 ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
8438 } else if (GC_REFCOUNT(ht) > 1) {
8439 if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
8440 GC_DELREF(ht);
8441 }
8442 ht = zend_array_dup(ht);
8443 ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
8444 }
8445
8446 value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
8447
8448 if (opline->extended_value & ZEND_BIND_REF) {
8449 if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
8450 SAVE_OPLINE();
8451 if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
8452 ZVAL_NULL(variable_ptr);
8453 HANDLE_EXCEPTION();
8454 }
8455 }
8456 if (UNEXPECTED(!Z_ISREF_P(value))) {
8457 zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
8458 GC_SET_REFCOUNT(ref, 2);
8459 GC_TYPE_INFO(ref) = IS_REFERENCE;
8460 ZVAL_COPY_VALUE(&ref->val, value);
8461 ref->sources.ptr = NULL;
8462 Z_REF_P(value) = ref;
8463 Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
8464 ZVAL_REF(variable_ptr, ref);
8465 } else {
8466 Z_ADDREF_P(value);
8467 ZVAL_REF(variable_ptr, Z_REF_P(value));
8468 }
8469 } else {
8470 ZVAL_COPY(variable_ptr, value);
8471 }
8472
8473 ZEND_VM_NEXT_OPCODE();
8474 }
8475
8476 ZEND_VM_HANDLER(184, ZEND_FETCH_THIS, UNUSED, UNUSED)
8477 {
8478 USE_OPLINE
8479
8480 if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
8481 zval *result = EX_VAR(opline->result.var);
8482
8483 ZVAL_OBJ(result, Z_OBJ(EX(This)));
8484 Z_ADDREF_P(result);
8485 ZEND_VM_NEXT_OPCODE();
8486 } else {
8487 ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper);
8488 }
8489 }
8490
8491 ZEND_VM_HANDLER(186, ZEND_ISSET_ISEMPTY_THIS, UNUSED, UNUSED)
8492 {
8493 USE_OPLINE
8494
8495 ZVAL_BOOL(EX_VAR(opline->result.var),
8496 (opline->extended_value & ZEND_ISEMPTY) ^
8497 (Z_TYPE(EX(This)) == IS_OBJECT));
8498 ZEND_VM_NEXT_OPCODE();
8499 }
8500
8501 ZEND_VM_HANDLER(49, ZEND_CHECK_VAR, CV, UNUSED)
8502 {
8503 USE_OPLINE
8504 zval *op1 = EX_VAR(opline->op1.var);
8505
8506 if (UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
8507 SAVE_OPLINE();
8508 ZVAL_UNDEFINED_OP1();
8509 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8510 }
8511 ZEND_VM_NEXT_OPCODE();
8512 }
8513
8514 ZEND_VM_HANDLER(140, ZEND_MAKE_REF, VAR|CV, UNUSED)
8515 {
8516 USE_OPLINE
8517 zval *op1 = EX_VAR(opline->op1.var);
8518
8519 if (OP1_TYPE == IS_CV) {
8520 if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
8521 ZVAL_NEW_EMPTY_REF(op1);
8522 Z_SET_REFCOUNT_P(op1, 2);
8523 ZVAL_NULL(Z_REFVAL_P(op1));
8524 ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
8525 } else {
8526 if (Z_ISREF_P(op1)) {
8527 Z_ADDREF_P(op1);
8528 } else {
8529 ZVAL_MAKE_REF_EX(op1, 2);
8530 }
8531 ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
8532 }
8533 } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) {
8534 op1 = Z_INDIRECT_P(op1);
8535 if (EXPECTED(!Z_ISREF_P(op1))) {
8536 ZVAL_MAKE_REF_EX(op1, 2);
8537 } else {
8538 GC_ADDREF(Z_REF_P(op1));
8539 }
8540 ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
8541 } else {
8542 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1);
8543 }
8544 ZEND_VM_NEXT_OPCODE();
8545 }
8546
8547 ZEND_VM_COLD_CONSTCONST_HANDLER(187, ZEND_SWITCH_LONG, CONST|TMPVARCV, CONST, JMP_ADDR)
8548 {
8549 USE_OPLINE
8550 zend_free_op free_op1, free_op2;
8551 zval *op, *jump_zv;
8552 HashTable *jumptable;
8553
8554 op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8555 jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
8556
8557 if (Z_TYPE_P(op) != IS_LONG) {
8558 ZVAL_DEREF(op);
8559 if (Z_TYPE_P(op) != IS_LONG) {
8560 /* Wrong type, fall back to ZEND_CASE chain */
8561 ZEND_VM_NEXT_OPCODE();
8562 }
8563 }
8564
8565 jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
8566 if (jump_zv != NULL) {
8567 ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
8568 ZEND_VM_CONTINUE();
8569 } else {
8570 /* default */
8571 ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
8572 ZEND_VM_CONTINUE();
8573 }
8574 }
8575
8576 ZEND_VM_COLD_CONSTCONST_HANDLER(188, ZEND_SWITCH_STRING, CONST|TMPVARCV, CONST, JMP_ADDR)
8577 {
8578 USE_OPLINE
8579 zend_free_op free_op1, free_op2;
8580 zval *op, *jump_zv;
8581 HashTable *jumptable;
8582
8583 op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8584 jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
8585
8586 if (Z_TYPE_P(op) != IS_STRING) {
8587 if (OP1_TYPE == IS_CONST) {
8588 /* Wrong type, fall back to ZEND_CASE chain */
8589 ZEND_VM_NEXT_OPCODE();
8590 } else {
8591 ZVAL_DEREF(op);
8592 if (Z_TYPE_P(op) != IS_STRING) {
8593 /* Wrong type, fall back to ZEND_CASE chain */
8594 ZEND_VM_NEXT_OPCODE();
8595 }
8596 }
8597 }
8598
8599 jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), OP1_TYPE == IS_CONST);
8600 if (jump_zv != NULL) {
8601 ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
8602 ZEND_VM_CONTINUE();
8603 } else {
8604 /* default */
8605 ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
8606 ZEND_VM_CONTINUE();
8607 }
8608 }
8609
8610 ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM)
8611 {
8612 USE_OPLINE
8613 zend_free_op free_op1;
8614 zval *op1;
8615 HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
8616 zval *result;
8617
8618 SAVE_OPLINE();
8619 op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
8620 if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
8621 result = zend_hash_find_ex(ht, Z_STR_P(op1), OP1_TYPE == IS_CONST);
8622 } else if (opline->extended_value) {
8623 if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
8624 result = zend_hash_index_find(ht, Z_LVAL_P(op1));
8625 } else {
8626 result = NULL;
8627 }
8628 } else if (Z_TYPE_P(op1) <= IS_FALSE) {
8629 result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1);
8630 } else {
8631 zend_string *key;
8632 zval key_tmp, result_tmp, *val;
8633
8634 result = NULL;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht,key,val)8635 ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
8636 ZVAL_STR(&key_tmp, key);
8637 compare_function(&result_tmp, op1, &key_tmp);
8638 if (Z_LVAL(result_tmp) == 0) {
8639 result = val;
8640 break;
8641 }
8642 } ZEND_HASH_FOREACH_END();
8643 }
8644 FREE_OP1();
8645 ZEND_VM_SMART_BRANCH(result, 1);
8646 ZVAL_BOOL(EX_VAR(opline->result.var), result != NULL);
8647 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8648 }
8649
8650 ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
8651 {
8652 USE_OPLINE
8653 zend_free_op free_op1;
8654 zval *op1;
8655 zend_long count;
8656
8657 SAVE_OPLINE();
8658 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8659 while (1) {
8660 if (Z_TYPE_P(op1) == IS_ARRAY) {
8661 count = zend_array_count(Z_ARRVAL_P(op1));
8662 break;
8663 } else if (Z_TYPE_P(op1) == IS_OBJECT) {
8664 /* first, we check if the handler is defined */
8665 if (Z_OBJ_HT_P(op1)->count_elements) {
8666 if (SUCCESS == Z_OBJ_HT_P(op1)->count_elements(op1, &count)) {
8667 break;
8668 }
8669 if (UNEXPECTED(EG(exception))) {
8670 count = 0;
8671 break;
8672 }
8673 }
8674
8675 /* if not and the object implements Countable we call its count() method */
8676 if (instanceof_function(Z_OBJCE_P(op1), zend_ce_countable)) {
8677 zval retval;
8678
8679 zend_call_method_with_0_params(op1, NULL, NULL, "count", &retval);
8680 count = zval_get_long(&retval);
8681 zval_ptr_dtor(&retval);
8682 break;
8683 }
8684
8685 /* If There's no handler and it doesn't implement Countable then add a warning */
8686 count = 1;
8687 } else if ((OP1_TYPE & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
8688 op1 = Z_REFVAL_P(op1);
8689 continue;
8690 } else if (Z_TYPE_P(op1) <= IS_NULL) {
8691 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
8692 ZVAL_UNDEFINED_OP1();
8693 }
8694 count = 0;
8695 } else {
8696 count = 1;
8697 }
8698 zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count");
8699 break;
8700 }
8701
8702 ZVAL_LONG(EX_VAR(opline->result.var), count);
8703 FREE_OP1();
8704 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8705 }
8706
8707 ZEND_VM_COLD_CONST_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMPVAR|CV, UNUSED)
8708 {
8709 USE_OPLINE
8710
8711 if (OP1_TYPE == IS_UNUSED) {
8712 if (UNEXPECTED(!EX(func)->common.scope)) {
8713 SAVE_OPLINE();
8714 zend_error(E_WARNING, "get_class() called without object from outside a class");
8715 ZVAL_FALSE(EX_VAR(opline->result.var));
8716 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8717 } else {
8718 ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
8719 ZEND_VM_NEXT_OPCODE();
8720 }
8721 } else {
8722 zend_free_op free_op1;
8723 zval *op1;
8724
8725 SAVE_OPLINE();
8726 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8727 while (1) {
8728 if (Z_TYPE_P(op1) == IS_OBJECT) {
8729 ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
8730 } else if ((OP1_TYPE & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
8731 op1 = Z_REFVAL_P(op1);
8732 continue;
8733 } else {
8734 if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
8735 ZVAL_UNDEFINED_OP1();
8736 }
8737 zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1)));
8738 ZVAL_FALSE(EX_VAR(opline->result.var));
8739 }
8740 break;
8741 }
8742 FREE_OP1();
8743 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8744 }
8745 }
8746
8747 ZEND_VM_HANDLER(192, ZEND_GET_CALLED_CLASS, UNUSED, UNUSED)
8748 {
8749 USE_OPLINE
8750
8751 if (Z_TYPE(EX(This)) == IS_OBJECT) {
8752 ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE(EX(This))->name);
8753 } else if (Z_CE(EX(This))) {
8754 ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_CE(EX(This))->name);
8755 } else {
8756 ZVAL_FALSE(EX_VAR(opline->result.var));
8757 if (UNEXPECTED(!EX(func)->common.scope)) {
8758 SAVE_OPLINE();
8759 zend_error(E_WARNING, "get_called_class() called from outside a class");
8760 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8761 }
8762 }
8763 ZEND_VM_NEXT_OPCODE();
8764 }
8765
8766 ZEND_VM_COLD_CONST_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|VAR|CV, UNUSED)
8767 {
8768 USE_OPLINE
8769 zend_free_op free_op1;
8770 zval *op1;
8771 zend_string *type;
8772
8773 SAVE_OPLINE();
8774 op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
8775 type = zend_zval_get_type(op1);
8776 if (EXPECTED(type)) {
8777 ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type);
8778 } else {
8779 ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
8780 }
8781 FREE_OP1();
8782 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
8783 }
8784
8785 ZEND_VM_HANDLER(171, ZEND_FUNC_NUM_ARGS, UNUSED, UNUSED)
8786 {
8787 USE_OPLINE
8788
8789 ZVAL_LONG(EX_VAR(opline->result.var), EX_NUM_ARGS());
8790 ZEND_VM_NEXT_OPCODE();
8791 }
8792
8793 ZEND_VM_HANDLER(172, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
8794 {
8795 USE_OPLINE
8796 zend_array *ht;
8797 uint32_t arg_count, result_size, skip;
8798
8799 arg_count = EX_NUM_ARGS();
8800 if (OP1_TYPE == IS_CONST) {
8801 skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1));
8802 if (arg_count < skip) {
8803 result_size = 0;
8804 } else {
8805 result_size = arg_count - skip;
8806 }
8807 } else {
8808 skip = 0;
8809 result_size = arg_count;
8810 }
8811
8812 if (result_size) {
8813 uint32_t first_extra_arg = EX(func)->op_array.num_args;
8814
8815 ht = zend_new_array(result_size);
8816 ZVAL_ARR(EX_VAR(opline->result.var), ht);
8817 zend_hash_real_init_packed(ht);
ZEND_HASH_FILL_PACKED(ht)8818 ZEND_HASH_FILL_PACKED(ht) {
8819 zval *p, *q;
8820 uint32_t i = skip;
8821 p = EX_VAR_NUM(i);
8822 if (arg_count > first_extra_arg) {
8823 while (i < first_extra_arg) {
8824 q = p;
8825 if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
8826 ZVAL_DEREF(q);
8827 if (Z_OPT_REFCOUNTED_P(q)) {
8828 Z_ADDREF_P(q);
8829 }
8830 ZEND_HASH_FILL_SET(q);
8831 } else {
8832 ZEND_HASH_FILL_SET_NULL();
8833 }
8834 ZEND_HASH_FILL_NEXT();
8835 p++;
8836 i++;
8837 }
8838 if (skip < first_extra_arg) {
8839 skip = 0;
8840 } else {
8841 skip -= first_extra_arg;
8842 }
8843 p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip);
8844 }
8845 while (i < arg_count) {
8846 q = p;
8847 if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
8848 ZVAL_DEREF(q);
8849 if (Z_OPT_REFCOUNTED_P(q)) {
8850 Z_ADDREF_P(q);
8851 }
8852 ZEND_HASH_FILL_SET(q);
8853 } else {
8854 ZEND_HASH_FILL_SET_NULL();
8855 }
8856 ZEND_HASH_FILL_NEXT();
8857 p++;
8858 i++;
8859 }
8860 } ZEND_HASH_FILL_END();
8861 ht->nNumOfElements = result_size;
8862 } else {
8863 ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var));
8864 }
8865 ZEND_VM_NEXT_OPCODE();
8866 }
8867
8868 ZEND_VM_HANDLER(167, ZEND_COPY_TMP, TMPVAR, UNUSED)
8869 {
8870 USE_OPLINE
8871 zend_free_op free_op1;
8872 zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
8873 zval *result = EX_VAR(opline->result.var);
8874 ZVAL_COPY(result, value);
8875 ZEND_VM_NEXT_OPCODE();
8876 }
8877
8878 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_JMP, (OP_JMP_ADDR(op, op->op1) > op), ZEND_JMP_FORWARD, JMP_ADDR, ANY)
8879 {
8880 USE_OPLINE
8881
8882 OPLINE = OP_JMP_ADDR(opline, opline->op1);
8883 ZEND_VM_CONTINUE();
8884 }
8885
8886 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
8887 {
8888 USE_OPLINE
8889 zval *op1, *op2, *result;
8890
8891 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8892 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8893 result = EX_VAR(opline->result.var);
8894 ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
8895 ZEND_VM_NEXT_OPCODE();
8896 }
8897
8898 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
8899 {
8900 USE_OPLINE
8901 zval *op1, *op2, *result;
8902
8903 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8904 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8905 result = EX_VAR(opline->result.var);
8906 fast_long_add_function(result, op1, op2);
8907 ZEND_VM_NEXT_OPCODE();
8908 }
8909
8910 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
8911 {
8912 USE_OPLINE
8913 zval *op1, *op2, *result;
8914
8915 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8916 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8917 result = EX_VAR(opline->result.var);
8918 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
8919 ZEND_VM_NEXT_OPCODE();
8920 }
8921
8922 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SUB, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
8923 {
8924 USE_OPLINE
8925 zval *op1, *op2, *result;
8926
8927 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8928 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8929 result = EX_VAR(opline->result.var);
8930 ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
8931 ZEND_VM_NEXT_OPCODE();
8932 }
8933
8934 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
8935 {
8936 USE_OPLINE
8937 zval *op1, *op2, *result;
8938
8939 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8940 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8941 result = EX_VAR(opline->result.var);
8942 fast_long_sub_function(result, op1, op2);
8943 ZEND_VM_NEXT_OPCODE();
8944 }
8945
8946 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_SUB_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
8947 {
8948 USE_OPLINE
8949 zval *op1, *op2, *result;
8950
8951 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8952 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8953 result = EX_VAR(opline->result.var);
8954 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
8955 ZEND_VM_NEXT_OPCODE();
8956 }
8957
8958 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
8959 {
8960 USE_OPLINE
8961 zval *op1, *op2, *result;
8962
8963 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8964 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8965 result = EX_VAR(opline->result.var);
8966 ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2));
8967 ZEND_VM_NEXT_OPCODE();
8968 }
8969
8970 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
8971 {
8972 USE_OPLINE
8973 zval *op1, *op2, *result;
8974 zend_long overflow;
8975
8976 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8977 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8978 result = EX_VAR(opline->result.var);
8979 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
8980 Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
8981 ZEND_VM_NEXT_OPCODE();
8982 }
8983
8984 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_MUL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
8985 {
8986 USE_OPLINE
8987 zval *op1, *op2, *result;
8988
8989 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8990 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
8991 result = EX_VAR(opline->result.var);
8992 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
8993 ZEND_VM_NEXT_OPCODE();
8994 }
8995
8996 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
8997 {
8998 USE_OPLINE
8999 zval *op1, *op2;
9000 int result;
9001
9002 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9003 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9004 result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
9005 ZEND_VM_SMART_BRANCH(result, 0);
9006 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9007 ZEND_VM_NEXT_OPCODE();
9008 }
9009
9010 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
9011 {
9012 USE_OPLINE
9013 zval *op1, *op2;
9014 int result;
9015
9016 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9017 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9018 result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
9019 ZEND_VM_SMART_BRANCH(result, 0);
9020 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9021 ZEND_VM_NEXT_OPCODE();
9022 }
9023
9024 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
9025 {
9026 USE_OPLINE
9027 zval *op1, *op2;
9028 int result;
9029
9030 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9031 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9032 result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
9033 ZEND_VM_SMART_BRANCH(result, 0);
9034 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9035 ZEND_VM_NEXT_OPCODE();
9036 }
9037
9038 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
9039 {
9040 USE_OPLINE
9041 zval *op1, *op2;
9042 int result;
9043
9044 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9045 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9046 result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
9047 ZEND_VM_SMART_BRANCH(result, 0);
9048 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9049 ZEND_VM_NEXT_OPCODE();
9050 }
9051
9052 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
9053 {
9054 USE_OPLINE
9055 zval *op1, *op2;
9056 int result;
9057
9058 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9059 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9060 result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
9061 ZEND_VM_SMART_BRANCH(result, 0);
9062 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9063 ZEND_VM_NEXT_OPCODE();
9064 }
9065
9066 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
9067 {
9068 USE_OPLINE
9069 zval *op1, *op2;
9070 int result;
9071
9072 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9073 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9074 result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
9075 ZEND_VM_SMART_BRANCH(result, 0);
9076 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9077 ZEND_VM_NEXT_OPCODE();
9078 }
9079
9080 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_OR_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
9081 {
9082 USE_OPLINE
9083 zval *op1, *op2;
9084 int result;
9085
9086 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9087 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9088 result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
9089 ZEND_VM_SMART_BRANCH(result, 0);
9090 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9091 ZEND_VM_NEXT_OPCODE();
9092 }
9093
9094 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_OR_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
9095 {
9096 USE_OPLINE
9097 zval *op1, *op2;
9098 int result;
9099
9100 op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9101 op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9102 result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
9103 ZEND_VM_SMART_BRANCH(result, 0);
9104 ZVAL_BOOL(EX_VAR(opline->result.var), result);
9105 ZEND_VM_NEXT_OPCODE();
9106 }
9107
9108 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG_NO_OVERFLOW, CV, ANY, SPEC(RETVAL))
9109 {
9110 USE_OPLINE
9111 zval *var_ptr;
9112
9113 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9114 Z_LVAL_P(var_ptr)++;
9115 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
9116 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
9117 }
9118 ZEND_VM_NEXT_OPCODE();
9119 }
9120
9121 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG, CV, ANY, SPEC(RETVAL))
9122 {
9123 USE_OPLINE
9124 zval *var_ptr;
9125
9126 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9127 fast_long_increment_function(var_ptr);
9128 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
9129 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
9130 }
9131 ZEND_VM_NEXT_OPCODE();
9132 }
9133
9134 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG_NO_OVERFLOW, CV, ANY, SPEC(RETVAL))
9135 {
9136 USE_OPLINE
9137 zval *var_ptr;
9138
9139 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9140 Z_LVAL_P(var_ptr)--;
9141 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
9142 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
9143 }
9144 ZEND_VM_NEXT_OPCODE();
9145 }
9146
9147 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG, CV, ANY, SPEC(RETVAL))
9148 {
9149 USE_OPLINE
9150 zval *var_ptr;
9151
9152 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9153 fast_long_decrement_function(var_ptr);
9154 if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
9155 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
9156 }
9157 ZEND_VM_NEXT_OPCODE();
9158 }
9159
9160 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG_NO_OVERFLOW, CV, ANY)
9161 {
9162 USE_OPLINE
9163 zval *var_ptr;
9164
9165 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9166 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
9167 Z_LVAL_P(var_ptr)++;
9168 ZEND_VM_NEXT_OPCODE();
9169 }
9170
9171 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG, CV, ANY)
9172 {
9173 USE_OPLINE
9174 zval *var_ptr;
9175
9176 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9177 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
9178 fast_long_increment_function(var_ptr);
9179 ZEND_VM_NEXT_OPCODE();
9180 }
9181
9182 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG_NO_OVERFLOW, CV, ANY)
9183 {
9184 USE_OPLINE
9185 zval *var_ptr;
9186
9187 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9188 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
9189 Z_LVAL_P(var_ptr)--;
9190 ZEND_VM_NEXT_OPCODE();
9191 }
9192
9193 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG, CV, ANY)
9194 {
9195 USE_OPLINE
9196 zval *var_ptr;
9197
9198 var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
9199 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
9200 fast_long_decrement_function(var_ptr);
9201 ZEND_VM_NEXT_OPCODE();
9202 }
9203
9204 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (op1_info == MAY_BE_LONG), ZEND_QM_ASSIGN_LONG, CONST|TMPVARCV, ANY)
9205 {
9206 USE_OPLINE
9207 zend_free_op free_op1;
9208 zval *value;
9209
9210 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9211 ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value));
9212 ZEND_VM_NEXT_OPCODE();
9213 }
9214
9215 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (op1_info == MAY_BE_DOUBLE), ZEND_QM_ASSIGN_DOUBLE, CONST|TMPVARCV, ANY)
9216 {
9217 USE_OPLINE
9218 zend_free_op free_op1;
9219 zval *value;
9220
9221 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9222 ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value));
9223 ZEND_VM_NEXT_OPCODE();
9224 }
9225
9226 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))), ZEND_QM_ASSIGN_NOREF, CONST|TMPVARCV, ANY)
9227 {
9228 USE_OPLINE
9229 zend_free_op free_op1;
9230 zval *value;
9231
9232 value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9233 ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
9234 ZEND_VM_NEXT_OPCODE();
9235 }
9236
9237 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))), ZEND_FETCH_DIM_R_INDEX, CONST|TMPVAR|CV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
9238 {
9239 USE_OPLINE
9240 zend_free_op free_op1, free_op2;
9241 zval *container, *dim, *value;
9242 zend_long offset;
9243 HashTable *ht;
9244
9245 container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9246 dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
9247 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
9248 ZEND_VM_C_LABEL(fetch_dim_r_index_array):
9249 if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
9250 offset = Z_LVAL_P(dim);
9251 } else {
9252 offset = zval_get_long(dim);
9253 }
9254 ht = Z_ARRVAL_P(container);
9255 ZEND_HASH_INDEX_FIND(ht, offset, value, ZEND_VM_C_LABEL(fetch_dim_r_index_undef));
9256 ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
9257 if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
9258 SAVE_OPLINE();
9259 FREE_OP1();
9260 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
9261 } else {
9262 ZEND_VM_NEXT_OPCODE();
9263 }
9264 } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
9265 container = Z_REFVAL_P(container);
9266 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
9267 ZEND_VM_C_GOTO(fetch_dim_r_index_array);
9268 } else {
9269 ZEND_VM_C_GOTO(fetch_dim_r_index_slow);
9270 }
9271 } else {
9272 ZEND_VM_C_LABEL(fetch_dim_r_index_slow):
9273 SAVE_OPLINE();
9274 if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
9275 dim++;
9276 }
9277 zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
9278 FREE_OP1();
9279 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
9280 }
9281
9282 ZEND_VM_C_LABEL(fetch_dim_r_index_undef):
9283 ZVAL_NULL(EX_VAR(opline->result.var));
9284 SAVE_OPLINE();
9285 zend_undefined_offset(offset);
9286 FREE_OP1();
9287 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
9288 }
9289
9290 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_SIMPLE, CV|VAR, NUM)
9291 {
9292 USE_OPLINE
9293 zval *varptr, *arg;
9294 zend_free_op free_op1;
9295
9296 varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9297 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
9298
9299 if (OP1_TYPE == IS_CV) {
9300 ZVAL_COPY(arg, varptr);
9301 } else /* if (OP1_TYPE == IS_VAR) */ {
9302 ZVAL_COPY_VALUE(arg, varptr);
9303 }
9304
9305 ZEND_VM_NEXT_OPCODE();
9306 }
9307
9308 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_EX_SIMPLE, CV|VAR, NUM)
9309 {
9310 USE_OPLINE
9311 zval *varptr, *arg;
9312 zend_free_op free_op1;
9313 uint32_t arg_num = opline->op2.num;
9314
9315 if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
9316 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
9317 }
9318
9319 varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
9320 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
9321
9322 if (OP1_TYPE == IS_CV) {
9323 ZVAL_COPY(arg, varptr);
9324 } else /* if (OP1_TYPE == IS_VAR) */ {
9325 ZVAL_COPY_VALUE(arg, varptr);
9326 }
9327
9328 ZEND_VM_NEXT_OPCODE();
9329 }
9330
9331 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAL, op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)), ZEND_SEND_VAL_SIMPLE, CONST, NUM)
9332 {
9333 USE_OPLINE
9334 zval *value, *arg;
9335 zend_free_op free_op1;
9336
9337 value = GET_OP1_ZVAL_PTR(BP_VAR_R);
9338 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
9339 ZVAL_COPY_VALUE(arg, value);
9340 ZEND_VM_NEXT_OPCODE();
9341 }
9342
9343 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAL_EX, op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)), ZEND_SEND_VAL_EX_SIMPLE, CONST, NUM)
9344 {
9345 USE_OPLINE
9346 zval *value, *arg;
9347 zend_free_op free_op1;
9348 uint32_t arg_num = opline->op2.num;
9349
9350 if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
9351 ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper);
9352 }
9353 value = GET_OP1_ZVAL_PTR(BP_VAR_R);
9354 arg = ZEND_CALL_VAR(EX(call), opline->result.var);
9355 ZVAL_COPY_VALUE(arg, value);
9356 ZEND_VM_NEXT_OPCODE();
9357 }
9358
9359 ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FE_FETCH_R, op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY, ZEND_FE_FETCH_R_SIMPLE, VAR, CV, JMP_ADDR, SPEC(RETVAL))
9360 {
9361 USE_OPLINE
9362 zval *array;
9363 zval *value, *variable_ptr;
9364 uint32_t value_type;
9365 HashTable *fe_ht;
9366 HashPosition pos;
9367 Bucket *p;
9368
9369 array = EX_VAR(opline->op1.var);
9370 SAVE_OPLINE();
9371 fe_ht = Z_ARRVAL_P(array);
9372 pos = Z_FE_POS_P(array);
9373 p = fe_ht->arData + pos;
9374 while (1) {
9375 if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
9376 /* reached end of iteration */
9377 ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
9378 ZEND_VM_CONTINUE();
9379 }
9380 value = &p->val;
9381 value_type = Z_TYPE_INFO_P(value);
9382 if (EXPECTED(value_type != IS_UNDEF)) {
9383 if (UNEXPECTED(value_type == IS_INDIRECT)) {
9384 value = Z_INDIRECT_P(value);
9385 value_type = Z_TYPE_INFO_P(value);
9386 if (EXPECTED(value_type != IS_UNDEF)) {
9387 break;
9388 }
9389 } else {
9390 break;
9391 }
9392 }
9393 pos++;
9394 p++;
9395 }
9396 Z_FE_POS_P(array) = pos + 1;
9397 if (RETURN_VALUE_USED(opline)) {
9398 if (!p->key) {
9399 ZVAL_LONG(EX_VAR(opline->result.var), p->h);
9400 } else {
9401 ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
9402 }
9403 }
9404
9405 variable_ptr = EX_VAR(opline->op2.var);
9406 zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
9407 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
9408 }
9409
9410 ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
9411
ZEND_VM_HELPER(zend_interrupt_helper,ANY,ANY)9412 ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY)
9413 {
9414 EG(vm_interrupt) = 0;
9415 SAVE_OPLINE();
9416 if (EG(timed_out)) {
9417 zend_timeout(0);
9418 } else if (zend_interrupt_function) {
9419 zend_interrupt_function(execute_data);
9420 ZEND_VM_ENTER();
9421 }
9422 ZEND_VM_CONTINUE();
9423 }
9424