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