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