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