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