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