1: /*
2: +----------------------------------------------------------------------+
3: | Zend Engine |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1998-2013 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: zend_vm_def.h,v 1.1.1.4 2013/10/14 08:02:49 misho Exp $ */
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|TMP|VAR|CV, CONST|TMP|VAR|CV)
29: {
30: USE_OPLINE
31: zend_free_op free_op1, free_op2;
32:
33: SAVE_OPLINE();
34: fast_add_function(&EX_T(opline->result.var).tmp_var,
35: GET_OP1_ZVAL_PTR(BP_VAR_R),
36: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
37: FREE_OP1();
38: FREE_OP2();
39: CHECK_EXCEPTION();
40: ZEND_VM_NEXT_OPCODE();
41: }
42:
43: ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
44: {
45: USE_OPLINE
46: zend_free_op free_op1, free_op2;
47:
48: SAVE_OPLINE();
49: fast_sub_function(&EX_T(opline->result.var).tmp_var,
50: GET_OP1_ZVAL_PTR(BP_VAR_R),
51: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
52: FREE_OP1();
53: FREE_OP2();
54: CHECK_EXCEPTION();
55: ZEND_VM_NEXT_OPCODE();
56: }
57:
58: ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
59: {
60: USE_OPLINE
61: zend_free_op free_op1, free_op2;
62:
63: SAVE_OPLINE();
64: fast_mul_function(&EX_T(opline->result.var).tmp_var,
65: GET_OP1_ZVAL_PTR(BP_VAR_R),
66: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
67: FREE_OP1();
68: FREE_OP2();
69: CHECK_EXCEPTION();
70: ZEND_VM_NEXT_OPCODE();
71: }
72:
73: ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
74: {
75: USE_OPLINE
76: zend_free_op free_op1, free_op2;
77:
78: SAVE_OPLINE();
79: fast_div_function(&EX_T(opline->result.var).tmp_var,
80: GET_OP1_ZVAL_PTR(BP_VAR_R),
81: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
82: FREE_OP1();
83: FREE_OP2();
84: CHECK_EXCEPTION();
85: ZEND_VM_NEXT_OPCODE();
86: }
87:
88: ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
89: {
90: USE_OPLINE
91: zend_free_op free_op1, free_op2;
92:
93: SAVE_OPLINE();
94: fast_mod_function(&EX_T(opline->result.var).tmp_var,
95: GET_OP1_ZVAL_PTR(BP_VAR_R),
96: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
97: FREE_OP1();
98: FREE_OP2();
99: CHECK_EXCEPTION();
100: ZEND_VM_NEXT_OPCODE();
101: }
102:
103: ZEND_VM_HANDLER(6, ZEND_SL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
104: {
105: USE_OPLINE
106: zend_free_op free_op1, free_op2;
107:
108: SAVE_OPLINE();
109: shift_left_function(&EX_T(opline->result.var).tmp_var,
110: GET_OP1_ZVAL_PTR(BP_VAR_R),
111: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
112: FREE_OP1();
113: FREE_OP2();
114: CHECK_EXCEPTION();
115: ZEND_VM_NEXT_OPCODE();
116: }
117:
118: ZEND_VM_HANDLER(7, ZEND_SR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
119: {
120: USE_OPLINE
121: zend_free_op free_op1, free_op2;
122:
123: SAVE_OPLINE();
124: shift_right_function(&EX_T(opline->result.var).tmp_var,
125: GET_OP1_ZVAL_PTR(BP_VAR_R),
126: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
127: FREE_OP1();
128: FREE_OP2();
129: CHECK_EXCEPTION();
130: ZEND_VM_NEXT_OPCODE();
131: }
132:
133: ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
134: {
135: USE_OPLINE
136: zend_free_op free_op1, free_op2;
137:
138: SAVE_OPLINE();
139: concat_function(&EX_T(opline->result.var).tmp_var,
140: GET_OP1_ZVAL_PTR(BP_VAR_R),
141: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
142: FREE_OP1();
143: FREE_OP2();
144: CHECK_EXCEPTION();
145: ZEND_VM_NEXT_OPCODE();
146: }
147:
148: ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
149: {
150: USE_OPLINE
151: zend_free_op free_op1, free_op2;
152:
153: SAVE_OPLINE();
154: is_identical_function(&EX_T(opline->result.var).tmp_var,
155: GET_OP1_ZVAL_PTR(BP_VAR_R),
156: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
157: FREE_OP1();
158: FREE_OP2();
159: CHECK_EXCEPTION();
160: ZEND_VM_NEXT_OPCODE();
161: }
162:
163: ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
164: {
165: USE_OPLINE
166: zend_free_op free_op1, free_op2;
167: zval *result = &EX_T(opline->result.var).tmp_var;
168:
169: SAVE_OPLINE();
170: is_identical_function(result,
171: GET_OP1_ZVAL_PTR(BP_VAR_R),
172: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
173: Z_LVAL_P(result) = !Z_LVAL_P(result);
174: FREE_OP1();
175: FREE_OP2();
176: CHECK_EXCEPTION();
177: ZEND_VM_NEXT_OPCODE();
178: }
179:
180: ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
181: {
182: USE_OPLINE
183: zend_free_op free_op1, free_op2;
184: zval *result = &EX_T(opline->result.var).tmp_var;
185:
186: SAVE_OPLINE();
187: ZVAL_BOOL(result, fast_equal_function(result,
188: GET_OP1_ZVAL_PTR(BP_VAR_R),
189: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
190: FREE_OP1();
191: FREE_OP2();
192: CHECK_EXCEPTION();
193: ZEND_VM_NEXT_OPCODE();
194: }
195:
196: ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
197: {
198: USE_OPLINE
199: zend_free_op free_op1, free_op2;
200: zval *result = &EX_T(opline->result.var).tmp_var;
201:
202: SAVE_OPLINE();
203: ZVAL_BOOL(result, fast_not_equal_function(result,
204: GET_OP1_ZVAL_PTR(BP_VAR_R),
205: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
206: FREE_OP1();
207: FREE_OP2();
208: CHECK_EXCEPTION();
209: ZEND_VM_NEXT_OPCODE();
210: }
211:
212: ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
213: {
214: USE_OPLINE
215: zend_free_op free_op1, free_op2;
216: zval *result = &EX_T(opline->result.var).tmp_var;
217:
218: SAVE_OPLINE();
219: ZVAL_BOOL(result, fast_is_smaller_function(result,
220: GET_OP1_ZVAL_PTR(BP_VAR_R),
221: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
222: FREE_OP1();
223: FREE_OP2();
224: CHECK_EXCEPTION();
225: ZEND_VM_NEXT_OPCODE();
226: }
227:
228: ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
229: {
230: USE_OPLINE
231: zend_free_op free_op1, free_op2;
232: zval *result = &EX_T(opline->result.var).tmp_var;
233:
234: SAVE_OPLINE();
235: ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
236: GET_OP1_ZVAL_PTR(BP_VAR_R),
237: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
238: FREE_OP1();
239: FREE_OP2();
240: CHECK_EXCEPTION();
241: ZEND_VM_NEXT_OPCODE();
242: }
243:
244: ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
245: {
246: USE_OPLINE
247: zend_free_op free_op1, free_op2;
248:
249: SAVE_OPLINE();
250: bitwise_or_function(&EX_T(opline->result.var).tmp_var,
251: GET_OP1_ZVAL_PTR(BP_VAR_R),
252: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
253: FREE_OP1();
254: FREE_OP2();
255: CHECK_EXCEPTION();
256: ZEND_VM_NEXT_OPCODE();
257: }
258:
259: ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
260: {
261: USE_OPLINE
262: zend_free_op free_op1, free_op2;
263:
264: SAVE_OPLINE();
265: bitwise_and_function(&EX_T(opline->result.var).tmp_var,
266: GET_OP1_ZVAL_PTR(BP_VAR_R),
267: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
268: FREE_OP1();
269: FREE_OP2();
270: CHECK_EXCEPTION();
271: ZEND_VM_NEXT_OPCODE();
272: }
273:
274: ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
275: {
276: USE_OPLINE
277: zend_free_op free_op1, free_op2;
278:
279: SAVE_OPLINE();
280: bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
281: GET_OP1_ZVAL_PTR(BP_VAR_R),
282: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
283: FREE_OP1();
284: FREE_OP2();
285: CHECK_EXCEPTION();
286: ZEND_VM_NEXT_OPCODE();
287: }
288:
289: ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
290: {
291: USE_OPLINE
292: zend_free_op free_op1, free_op2;
293:
294: SAVE_OPLINE();
295: boolean_xor_function(&EX_T(opline->result.var).tmp_var,
296: GET_OP1_ZVAL_PTR(BP_VAR_R),
297: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
298: FREE_OP1();
299: FREE_OP2();
300: CHECK_EXCEPTION();
301: ZEND_VM_NEXT_OPCODE();
302: }
303:
304: ZEND_VM_HANDLER(12, ZEND_BW_NOT, CONST|TMP|VAR|CV, ANY)
305: {
306: USE_OPLINE
307: zend_free_op free_op1;
308:
309: SAVE_OPLINE();
310: bitwise_not_function(&EX_T(opline->result.var).tmp_var,
311: GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
312: FREE_OP1();
313: CHECK_EXCEPTION();
314: ZEND_VM_NEXT_OPCODE();
315: }
316:
317: ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMP|VAR|CV, ANY)
318: {
319: USE_OPLINE
320: zend_free_op free_op1;
321:
322: SAVE_OPLINE();
323: boolean_not_function(&EX_T(opline->result.var).tmp_var,
324: GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
325: FREE_OP1();
326: CHECK_EXCEPTION();
327: ZEND_VM_NEXT_OPCODE();
328: }
329:
330: ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
331: {
332: USE_OPLINE
333: zend_free_op free_op1, free_op2, free_op_data1;
334: zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
335: zval *object;
336: zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
337: zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
338: int have_get_ptr = 0;
339:
340: if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
341: zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
342: }
343:
344: make_real_object(object_ptr TSRMLS_CC);
345: object = *object_ptr;
346:
347: if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
348: zend_error(E_WARNING, "Attempt to assign property of non-object");
349: FREE_OP2();
350: FREE_OP(free_op_data1);
351:
352: if (RETURN_VALUE_USED(opline)) {
353: PZVAL_LOCK(&EG(uninitialized_zval));
354: EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
355: EX_T(opline->result.var).var.ptr_ptr = NULL;
356: }
357: } else {
358: /* here we are sure we are dealing with an object */
359: if (IS_OP2_TMP_FREE()) {
360: MAKE_REAL_ZVAL_PTR(property);
361: }
362:
363: /* here property is a string */
364: if (opline->extended_value == ZEND_ASSIGN_OBJ
365: && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
366: zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
367: if (zptr != NULL) { /* NULL means no success in getting PTR */
368: SEPARATE_ZVAL_IF_NOT_REF(zptr);
369:
370: have_get_ptr = 1;
371: binary_op(*zptr, *zptr, value TSRMLS_CC);
372: if (RETURN_VALUE_USED(opline)) {
373: PZVAL_LOCK(*zptr);
374: EX_T(opline->result.var).var.ptr = *zptr;
375: EX_T(opline->result.var).var.ptr_ptr = NULL;
376: }
377: }
378: }
379:
380: if (!have_get_ptr) {
381: zval *z = NULL;
382:
383: if (opline->extended_value == ZEND_ASSIGN_OBJ) {
384: if (Z_OBJ_HT_P(object)->read_property) {
385: z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
386: }
387: } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
388: if (Z_OBJ_HT_P(object)->read_dimension) {
389: z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
390: }
391: }
392: if (z) {
393: if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
394: zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);
395:
396: if (Z_REFCOUNT_P(z) == 0) {
397: GC_REMOVE_ZVAL_FROM_BUFFER(z);
398: zval_dtor(z);
399: FREE_ZVAL(z);
400: }
401: z = value;
402: }
403: Z_ADDREF_P(z);
404: SEPARATE_ZVAL_IF_NOT_REF(&z);
405: binary_op(z, z, value TSRMLS_CC);
406: if (opline->extended_value == ZEND_ASSIGN_OBJ) {
407: Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
408: } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
409: Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
410: }
411: if (RETURN_VALUE_USED(opline)) {
412: PZVAL_LOCK(z);
413: EX_T(opline->result.var).var.ptr = z;
414: EX_T(opline->result.var).var.ptr_ptr = NULL;
415: }
416: zval_ptr_dtor(&z);
417: } else {
418: zend_error(E_WARNING, "Attempt to assign property of non-object");
419: if (RETURN_VALUE_USED(opline)) {
420: PZVAL_LOCK(&EG(uninitialized_zval));
421: EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
422: EX_T(opline->result.var).var.ptr_ptr = NULL;
423: }
424: }
425: }
426:
427: if (IS_OP2_TMP_FREE()) {
428: zval_ptr_dtor(&property);
429: } else {
430: FREE_OP2();
431: }
432: FREE_OP(free_op_data1);
433: }
434:
435: FREE_OP1_VAR_PTR();
436: /* assign_obj has two opcodes! */
437: CHECK_EXCEPTION();
438: ZEND_VM_INC_OPCODE();
439: ZEND_VM_NEXT_OPCODE();
440: }
441:
442: ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
443: {
444: USE_OPLINE
445: zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
446: zval **var_ptr;
447: zval *value;
448:
449: SAVE_OPLINE();
450: switch (opline->extended_value) {
451: case ZEND_ASSIGN_OBJ:
452: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
453: break;
454: case ZEND_ASSIGN_DIM: {
455: zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
456:
457: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
458: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
459: } else if (UNEXPECTED(Z_TYPE_PP(container) == IS_OBJECT)) {
460: if (OP1_TYPE == IS_VAR && !OP1_FREE) {
461: Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
462: }
463: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
464: } else {
465: zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
466:
467: zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, OP2_TYPE, BP_VAR_RW TSRMLS_CC);
468: value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
469: var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
470: }
471: }
472: break;
473: default:
474: value = GET_OP2_ZVAL_PTR(BP_VAR_R);
475: var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
476: /* do nothing */
477: break;
478: }
479:
480: if (UNEXPECTED(var_ptr == NULL)) {
481: zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
482: }
483:
484: if (UNEXPECTED(*var_ptr == &EG(error_zval))) {
485: if (RETURN_VALUE_USED(opline)) {
486: PZVAL_LOCK(&EG(uninitialized_zval));
487: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
488: }
489: FREE_OP2();
490: FREE_OP1_VAR_PTR();
491: CHECK_EXCEPTION();
492: if (opline->extended_value == ZEND_ASSIGN_DIM) {
493: ZEND_VM_INC_OPCODE();
494: }
495: ZEND_VM_NEXT_OPCODE();
496: }
497:
498: SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
499:
500: if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT)
501: && Z_OBJ_HANDLER_PP(var_ptr, get)
502: && Z_OBJ_HANDLER_PP(var_ptr, set)) {
503: /* proxy object */
504: zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
505: Z_ADDREF_P(objval);
506: binary_op(objval, objval, value TSRMLS_CC);
507: Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
508: zval_ptr_dtor(&objval);
509: } else {
510: binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
511: }
512:
513: if (RETURN_VALUE_USED(opline)) {
514: PZVAL_LOCK(*var_ptr);
515: AI_SET_PTR(&EX_T(opline->result.var), *var_ptr);
516: }
517: FREE_OP2();
518:
519: if (opline->extended_value == ZEND_ASSIGN_DIM) {
520: FREE_OP(free_op_data1);
521: FREE_OP_VAR_PTR(free_op_data2);
522: FREE_OP1_VAR_PTR();
523: CHECK_EXCEPTION();
524: ZEND_VM_INC_OPCODE();
525: } else {
526: FREE_OP1_VAR_PTR();
527: CHECK_EXCEPTION();
528: }
529: ZEND_VM_NEXT_OPCODE();
530: }
531:
532: ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
533: {
534: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, add_function);
535: }
536:
537: ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
538: {
539: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, sub_function);
540: }
541:
542: ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
543: {
544: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mul_function);
545: }
546:
547: ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
548: {
549: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, div_function);
550: }
551:
552: ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
553: {
554: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mod_function);
555: }
556:
557: ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
558: {
559: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_left_function);
560: }
561:
562: ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
563: {
564: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_right_function);
565: }
566:
567: ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
568: {
569: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, concat_function);
570: }
571:
572: ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
573: {
574: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_or_function);
575: }
576:
577: ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
578: {
579: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_and_function);
580: }
581:
582: ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
583: {
584: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_xor_function);
585: }
586:
587: ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op)
588: {
589: USE_OPLINE
590: zend_free_op free_op1, free_op2;
591: zval **object_ptr;
592: zval *object;
593: zval *property;
594: zval **retval;
595: int have_get_ptr = 0;
596:
597: SAVE_OPLINE();
598: object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
599: property = GET_OP2_ZVAL_PTR(BP_VAR_R);
600: retval = &EX_T(opline->result.var).var.ptr;
601:
602: if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
603: zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
604: }
605:
606: make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
607: object = *object_ptr;
608:
609: if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
610: zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
611: FREE_OP2();
612: if (RETURN_VALUE_USED(opline)) {
613: PZVAL_LOCK(&EG(uninitialized_zval));
614: *retval = &EG(uninitialized_zval);
615: }
616: FREE_OP1_VAR_PTR();
617: CHECK_EXCEPTION();
618: ZEND_VM_NEXT_OPCODE();
619: }
620:
621: /* here we are sure we are dealing with an object */
622:
623: if (IS_OP2_TMP_FREE()) {
624: MAKE_REAL_ZVAL_PTR(property);
625: }
626:
627: if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
628: zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
629: if (zptr != NULL) { /* NULL means no success in getting PTR */
630: SEPARATE_ZVAL_IF_NOT_REF(zptr);
631:
632: have_get_ptr = 1;
633: incdec_op(*zptr);
634: if (RETURN_VALUE_USED(opline)) {
635: *retval = *zptr;
636: PZVAL_LOCK(*retval);
637: }
638: }
639: }
640:
641: if (!have_get_ptr) {
642: if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
643: zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
644:
645: if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
646: zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);
647:
648: if (Z_REFCOUNT_P(z) == 0) {
649: GC_REMOVE_ZVAL_FROM_BUFFER(z);
650: zval_dtor(z);
651: FREE_ZVAL(z);
652: }
653: z = value;
654: }
655: Z_ADDREF_P(z);
656: SEPARATE_ZVAL_IF_NOT_REF(&z);
657: incdec_op(z);
658: *retval = z;
659: Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
660: SELECTIVE_PZVAL_LOCK(*retval, opline);
661: zval_ptr_dtor(&z);
662: } else {
663: zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
664: if (RETURN_VALUE_USED(opline)) {
665: PZVAL_LOCK(&EG(uninitialized_zval));
666: *retval = &EG(uninitialized_zval);
667: }
668: }
669: }
670:
671: if (IS_OP2_TMP_FREE()) {
672: zval_ptr_dtor(&property);
673: } else {
674: FREE_OP2();
675: }
676: FREE_OP1_VAR_PTR();
677: CHECK_EXCEPTION();
678: ZEND_VM_NEXT_OPCODE();
679: }
680:
681: ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
682: {
683: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, increment_function);
684: }
685:
686: ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
687: {
688: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, decrement_function);
689: }
690:
691: ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op)
692: {
693: USE_OPLINE
694: zend_free_op free_op1, free_op2;
695: zval **object_ptr;
696: zval *object;
697: zval *property;
698: zval *retval;
699: int have_get_ptr = 0;
700:
701: SAVE_OPLINE();
702: object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
703: property = GET_OP2_ZVAL_PTR(BP_VAR_R);
704: retval = &EX_T(opline->result.var).tmp_var;
705:
706: if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
707: zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
708: }
709:
710: make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
711: object = *object_ptr;
712:
713: if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
714: zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
715: FREE_OP2();
716: ZVAL_NULL(retval);
717: FREE_OP1_VAR_PTR();
718: CHECK_EXCEPTION();
719: ZEND_VM_NEXT_OPCODE();
720: }
721:
722: /* here we are sure we are dealing with an object */
723:
724: if (IS_OP2_TMP_FREE()) {
725: MAKE_REAL_ZVAL_PTR(property);
726: }
727:
728: if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
729: zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
730: if (zptr != NULL) { /* NULL means no success in getting PTR */
731: have_get_ptr = 1;
732: SEPARATE_ZVAL_IF_NOT_REF(zptr);
733:
734: ZVAL_COPY_VALUE(retval, *zptr);
735: zendi_zval_copy_ctor(*retval);
736:
737: incdec_op(*zptr);
738:
739: }
740: }
741:
742: if (!have_get_ptr) {
743: if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
744: zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
745: zval *z_copy;
746:
747: if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
748: zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);
749:
750: if (Z_REFCOUNT_P(z) == 0) {
751: GC_REMOVE_ZVAL_FROM_BUFFER(z);
752: zval_dtor(z);
753: FREE_ZVAL(z);
754: }
755: z = value;
756: }
757: ZVAL_COPY_VALUE(retval, z);
758: zendi_zval_copy_ctor(*retval);
759: ALLOC_ZVAL(z_copy);
760: INIT_PZVAL_COPY(z_copy, z);
761: zendi_zval_copy_ctor(*z_copy);
762: incdec_op(z_copy);
763: Z_ADDREF_P(z);
764: Z_OBJ_HT_P(object)->write_property(object, property, z_copy, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
765: zval_ptr_dtor(&z_copy);
766: zval_ptr_dtor(&z);
767: } else {
768: zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
769: ZVAL_NULL(retval);
770: }
771: }
772:
773: if (IS_OP2_TMP_FREE()) {
774: zval_ptr_dtor(&property);
775: } else {
776: FREE_OP2();
777: }
778: FREE_OP1_VAR_PTR();
779: CHECK_EXCEPTION();
780: ZEND_VM_NEXT_OPCODE();
781: }
782:
783: ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
784: {
785: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, increment_function);
786: }
787:
788: ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
789: {
790: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, decrement_function);
791: }
792:
793: ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
794: {
795: USE_OPLINE
796: zend_free_op free_op1;
797: zval **var_ptr;
798:
799: SAVE_OPLINE();
800: var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
801:
802: if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
803: zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
804: }
805: if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) {
806: if (RETURN_VALUE_USED(opline)) {
807: PZVAL_LOCK(&EG(uninitialized_zval));
808: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
809: }
810: FREE_OP1_VAR_PTR();
811: CHECK_EXCEPTION();
812: ZEND_VM_NEXT_OPCODE();
813: }
814:
815: SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
816:
817: if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT)
818: && Z_OBJ_HANDLER_PP(var_ptr, get)
819: && Z_OBJ_HANDLER_PP(var_ptr, set)) {
820: /* proxy object */
821: zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
822: Z_ADDREF_P(val);
823: fast_increment_function(val);
824: Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
825: zval_ptr_dtor(&val);
826: } else {
827: fast_increment_function(*var_ptr);
828: }
829:
830: if (RETURN_VALUE_USED(opline)) {
831: PZVAL_LOCK(*var_ptr);
832: AI_SET_PTR(&EX_T(opline->result.var), *var_ptr);
833: }
834:
835: FREE_OP1_VAR_PTR();
836: CHECK_EXCEPTION();
837: ZEND_VM_NEXT_OPCODE();
838: }
839:
840: ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
841: {
842: USE_OPLINE
843: zend_free_op free_op1;
844: zval **var_ptr;
845:
846: SAVE_OPLINE();
847: var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
848:
849: if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
850: zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
851: }
852: if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) {
853: if (RETURN_VALUE_USED(opline)) {
854: PZVAL_LOCK(&EG(uninitialized_zval));
855: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
856: }
857: FREE_OP1_VAR_PTR();
858: CHECK_EXCEPTION();
859: ZEND_VM_NEXT_OPCODE();
860: }
861:
862: SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
863:
864: if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT)
865: && Z_OBJ_HANDLER_PP(var_ptr, get)
866: && Z_OBJ_HANDLER_PP(var_ptr, set)) {
867: /* proxy object */
868: zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
869: Z_ADDREF_P(val);
870: fast_decrement_function(val);
871: Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
872: zval_ptr_dtor(&val);
873: } else {
874: fast_decrement_function(*var_ptr);
875: }
876:
877: if (RETURN_VALUE_USED(opline)) {
878: PZVAL_LOCK(*var_ptr);
879: AI_SET_PTR(&EX_T(opline->result.var), *var_ptr);
880: }
881:
882: FREE_OP1_VAR_PTR();
883: CHECK_EXCEPTION();
884: ZEND_VM_NEXT_OPCODE();
885: }
886:
887: ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
888: {
889: USE_OPLINE
890: zend_free_op free_op1;
891: zval **var_ptr, *retval;
892:
893: SAVE_OPLINE();
894: var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
895:
896: if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
897: zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
898: }
899: if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) {
900: ZVAL_NULL(&EX_T(opline->result.var).tmp_var);
901: FREE_OP1_VAR_PTR();
902: CHECK_EXCEPTION();
903: ZEND_VM_NEXT_OPCODE();
904: }
905:
906: retval = &EX_T(opline->result.var).tmp_var;
907: ZVAL_COPY_VALUE(retval, *var_ptr);
908: zendi_zval_copy_ctor(*retval);
909:
910: SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
911:
912: if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT)
913: && Z_OBJ_HANDLER_PP(var_ptr, get)
914: && Z_OBJ_HANDLER_PP(var_ptr, set)) {
915: /* proxy object */
916: zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
917: Z_ADDREF_P(val);
918: fast_increment_function(val);
919: Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
920: zval_ptr_dtor(&val);
921: } else {
922: fast_increment_function(*var_ptr);
923: }
924:
925: FREE_OP1_VAR_PTR();
926: CHECK_EXCEPTION();
927: ZEND_VM_NEXT_OPCODE();
928: }
929:
930: ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
931: {
932: USE_OPLINE
933: zend_free_op free_op1;
934: zval **var_ptr, *retval;
935:
936: SAVE_OPLINE();
937: var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
938:
939: if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
940: zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
941: }
942: if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) {
943: ZVAL_NULL(&EX_T(opline->result.var).tmp_var);
944: FREE_OP1_VAR_PTR();
945: CHECK_EXCEPTION();
946: ZEND_VM_NEXT_OPCODE();
947: }
948:
949: retval = &EX_T(opline->result.var).tmp_var;
950: ZVAL_COPY_VALUE(retval, *var_ptr);
951: zendi_zval_copy_ctor(*retval);
952:
953: SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
954:
955: if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT)
956: && Z_OBJ_HANDLER_PP(var_ptr, get)
957: && Z_OBJ_HANDLER_PP(var_ptr, set)) {
958: /* proxy object */
959: zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
960: Z_ADDREF_P(val);
961: fast_decrement_function(val);
962: Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
963: zval_ptr_dtor(&val);
964: } else {
965: fast_decrement_function(*var_ptr);
966: }
967:
968: FREE_OP1_VAR_PTR();
969: CHECK_EXCEPTION();
970: ZEND_VM_NEXT_OPCODE();
971: }
972:
973: ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
974: {
975: USE_OPLINE
976: zend_free_op free_op1;
977: zval *z;
978:
979: SAVE_OPLINE();
980: z = GET_OP1_ZVAL_PTR(BP_VAR_R);
981:
982: if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
983: INIT_PZVAL(z);
984: }
985: zend_print_variable(z);
986:
987: FREE_OP1();
988: CHECK_EXCEPTION();
989: ZEND_VM_NEXT_OPCODE();
990: }
991:
992: ZEND_VM_HANDLER(41, ZEND_PRINT, CONST|TMP|VAR|CV, ANY)
993: {
994: USE_OPLINE
995:
996: ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1);
997: ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ECHO);
998: }
999:
1000: ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|VAR, int type)
1001: {
1002: USE_OPLINE
1003: zend_free_op free_op1;
1004: zval *varname;
1005: zval **retval;
1006: zval tmp_varname;
1007: HashTable *target_symbol_table;
1008: ulong hash_value;
1009:
1010: SAVE_OPLINE();
1011: varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
1012:
1013: if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
1014: ZVAL_COPY_VALUE(&tmp_varname, varname);
1015: zval_copy_ctor(&tmp_varname);
1016: Z_SET_REFCOUNT(tmp_varname, 1);
1017: Z_UNSET_ISREF(tmp_varname);
1018: convert_to_string(&tmp_varname);
1019: varname = &tmp_varname;
1020: }
1021:
1022: if (OP2_TYPE != IS_UNUSED) {
1023: zend_class_entry *ce;
1024:
1025: if (OP2_TYPE == IS_CONST) {
1026: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
1027: ce = CACHED_PTR(opline->op2.literal->cache_slot);
1028: } else {
1029: ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
1030: if (UNEXPECTED(ce == NULL)) {
1031: if (OP1_TYPE != IS_CONST && varname == &tmp_varname) {
1032: zval_dtor(&tmp_varname);
1033: }
1034: FREE_OP1();
1035: CHECK_EXCEPTION();
1036: ZEND_VM_NEXT_OPCODE();
1037: }
1038: CACHE_PTR(opline->op2.literal->cache_slot, ce);
1039: }
1040: } else {
1041: ce = EX_T(opline->op2.var).class_entry;
1042: }
1043: retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
1044: FREE_OP1();
1045: } else {
1046: target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
1047: /*
1048: if (!target_symbol_table) {
1049: CHECK_EXCEPTION();
1050: ZEND_VM_NEXT_OPCODE();
1051: }
1052: */
1053: if (OP1_TYPE == IS_CONST) {
1054: hash_value = Z_HASH_P(varname);
1055: } else if (IS_INTERNED(Z_STRVAL_P(varname))) {
1056: hash_value = INTERNED_HASH(Z_STRVAL_P(varname));
1057: } else {
1058: hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1);
1059: }
1060:
1061: if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) {
1062: switch (type) {
1063: case BP_VAR_R:
1064: case BP_VAR_UNSET:
1065: zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
1066: /* break missing intentionally */
1067: case BP_VAR_IS:
1068: retval = &EG(uninitialized_zval_ptr);
1069: break;
1070: case BP_VAR_RW:
1071: zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
1072: /* break missing intentionally */
1073: case BP_VAR_W:
1074: Z_ADDREF_P(&EG(uninitialized_zval));
1075: zend_hash_quick_update(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **) &retval);
1076: break;
1077: EMPTY_SWITCH_DEFAULT_CASE()
1078: }
1079: }
1080: switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
1081: case ZEND_FETCH_GLOBAL:
1082: if (OP1_TYPE != IS_TMP_VAR) {
1083: FREE_OP1();
1084: }
1085: break;
1086: case ZEND_FETCH_LOCAL:
1087: FREE_OP1();
1088: break;
1089: case ZEND_FETCH_STATIC:
1090: zval_update_constant(retval, (void*) 1 TSRMLS_CC);
1091: break;
1092: case ZEND_FETCH_GLOBAL_LOCK:
1093: if (OP1_TYPE == IS_VAR && !free_op1.var) {
1094: PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
1095: }
1096: break;
1097: }
1098: }
1099:
1100:
1101: if (OP1_TYPE != IS_CONST && varname == &tmp_varname) {
1102: zval_dtor(&tmp_varname);
1103: }
1104: if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
1105: SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
1106: }
1107: PZVAL_LOCK(*retval);
1108: switch (type) {
1109: case BP_VAR_R:
1110: case BP_VAR_IS:
1111: AI_SET_PTR(&EX_T(opline->result.var), *retval);
1112: break;
1113: case BP_VAR_UNSET: {
1114: zend_free_op free_res;
1115:
1116: PZVAL_UNLOCK(*retval, &free_res);
1117: if (retval != &EG(uninitialized_zval_ptr)) {
1118: SEPARATE_ZVAL_IF_NOT_REF(retval);
1119: }
1120: PZVAL_LOCK(*retval);
1121: FREE_OP_VAR_PTR(free_res);
1122: }
1123: /* break missing intentionally */
1124: default:
1125: EX_T(opline->result.var).var.ptr_ptr = retval;
1126: break;
1127: }
1128: CHECK_EXCEPTION();
1129: ZEND_VM_NEXT_OPCODE();
1130: }
1131:
1132: ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1133: {
1134: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R);
1135: }
1136:
1137: ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1138: {
1139: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W);
1140: }
1141:
1142: ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1143: {
1144: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW);
1145: }
1146:
1147: ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1148: {
1149: USE_OPLINE
1150:
1151: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type,
1152: ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R);
1153: }
1154:
1155: ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1156: {
1157: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
1158: }
1159:
1160: ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
1161: {
1162: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS);
1163: }
1164:
1165: ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
1166: {
1167: USE_OPLINE
1168: zend_free_op free_op1, free_op2;
1169: zval **container;
1170:
1171: SAVE_OPLINE();
1172:
1173: if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
1174: OP1_TYPE != IS_CV &&
1175: EX_T(opline->op1.var).var.ptr_ptr) {
1176: PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
1177: }
1178: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
1179: zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
1180: FREE_OP2();
1181: FREE_OP1_VAR_PTR();
1182: CHECK_EXCEPTION();
1183: ZEND_VM_NEXT_OPCODE();
1184: }
1185:
1186: ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1187: {
1188: USE_OPLINE
1189: zend_free_op free_op1, free_op2;
1190: zval **container;
1191:
1192: SAVE_OPLINE();
1193: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1194:
1195: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1196: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1197: }
1198: zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W TSRMLS_CC);
1199: FREE_OP2();
1200: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1201: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1202: }
1203: FREE_OP1_VAR_PTR();
1204:
1205: /* We are going to assign the result by reference */
1206: if (UNEXPECTED(opline->extended_value != 0)) {
1207: zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
1208:
1209: if (retval_ptr) {
1210: Z_DELREF_PP(retval_ptr);
1211: SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
1212: Z_ADDREF_PP(retval_ptr);
1213: }
1214: }
1215:
1216: CHECK_EXCEPTION();
1217: ZEND_VM_NEXT_OPCODE();
1218: }
1219:
1220: ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1221: {
1222: USE_OPLINE
1223: zend_free_op free_op1, free_op2;
1224: zval **container;
1225:
1226: SAVE_OPLINE();
1227: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
1228:
1229: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1230: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1231: }
1232: zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_RW TSRMLS_CC);
1233: FREE_OP2();
1234: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1235: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1236: }
1237: FREE_OP1_VAR_PTR();
1238: CHECK_EXCEPTION();
1239: ZEND_VM_NEXT_OPCODE();
1240: }
1241:
1242: ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV)
1243: {
1244: USE_OPLINE
1245: zend_free_op free_op1, free_op2;
1246: zval **container;
1247:
1248: SAVE_OPLINE();
1249: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS);
1250: zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_IS TSRMLS_CC);
1251: FREE_OP2();
1252: FREE_OP1_VAR_PTR();
1253: CHECK_EXCEPTION();
1254: ZEND_VM_NEXT_OPCODE();
1255: }
1256:
1257: ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1258: {
1259: USE_OPLINE
1260: zend_free_op free_op1, free_op2;
1261: zval **container;
1262:
1263: SAVE_OPLINE();
1264:
1265: if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
1266: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1267: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1268: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1269: }
1270: zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W TSRMLS_CC);
1271: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1272: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1273: }
1274: } else {
1275: if (OP2_TYPE == IS_UNUSED) {
1276: zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
1277: }
1278: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
1279: zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
1280: }
1281: FREE_OP2();
1282: FREE_OP1_VAR_PTR();
1283: CHECK_EXCEPTION();
1284: ZEND_VM_NEXT_OPCODE();
1285: }
1286:
1287: ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
1288: {
1289: USE_OPLINE
1290: zend_free_op free_op1, free_op2;
1291: zval **container;
1292:
1293: SAVE_OPLINE();
1294: container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET);
1295:
1296: if (OP1_TYPE == IS_CV) {
1297: if (container != &EG(uninitialized_zval_ptr)) {
1298: SEPARATE_ZVAL_IF_NOT_REF(container);
1299: }
1300: }
1301: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1302: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1303: }
1304: zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_UNSET TSRMLS_CC);
1305: FREE_OP2();
1306: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1307: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1308: }
1309: FREE_OP1_VAR_PTR();
1310: if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
1311: zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
1312: } else {
1313: zend_free_op free_res;
1314: zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
1315:
1316: PZVAL_UNLOCK(*retval_ptr, &free_res);
1317: if (retval_ptr != &EG(uninitialized_zval_ptr)) {
1318: SEPARATE_ZVAL_IF_NOT_REF(retval_ptr);
1319: }
1320: PZVAL_LOCK(*retval_ptr);
1321: FREE_OP_VAR_PTR(free_res);
1322: CHECK_EXCEPTION();
1323: ZEND_VM_NEXT_OPCODE();
1324: }
1325: }
1326:
1327: ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1328: {
1329: USE_OPLINE
1330: zend_free_op free_op1;
1331: zval *container;
1332: zend_free_op free_op2;
1333: zval *offset;
1334:
1335: SAVE_OPLINE();
1336: container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
1337: offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
1338:
1339: if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
1340: UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
1341: zend_error(E_NOTICE, "Trying to get property of non-object");
1342: PZVAL_LOCK(&EG(uninitialized_zval));
1343: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1344: FREE_OP2();
1345: } else {
1346: zval *retval;
1347:
1348: if (IS_OP2_TMP_FREE()) {
1349: MAKE_REAL_ZVAL_PTR(offset);
1350: }
1351:
1352: /* here we are sure we are dealing with an object */
1353: retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
1354:
1355: PZVAL_LOCK(retval);
1356: AI_SET_PTR(&EX_T(opline->result.var), retval);
1357:
1358: if (IS_OP2_TMP_FREE()) {
1359: zval_ptr_dtor(&offset);
1360: } else {
1361: FREE_OP2();
1362: }
1363: }
1364:
1365: FREE_OP1();
1366: CHECK_EXCEPTION();
1367: ZEND_VM_NEXT_OPCODE();
1368: }
1369:
1370: ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1371: {
1372: ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper);
1373: }
1374:
1375: ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1376: {
1377: USE_OPLINE
1378: zend_free_op free_op1, free_op2;
1379: zval *property;
1380: zval **container;
1381:
1382: SAVE_OPLINE();
1383: property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1384:
1385: if (OP1_TYPE == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
1386: PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
1387: EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
1388: }
1389:
1390: if (IS_OP2_TMP_FREE()) {
1391: MAKE_REAL_ZVAL_PTR(property);
1392: }
1393: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
1394: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1395: zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1396: }
1397:
1398: zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_W TSRMLS_CC);
1399: if (IS_OP2_TMP_FREE()) {
1400: zval_ptr_dtor(&property);
1401: } else {
1402: FREE_OP2();
1403: }
1404: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1405: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1406: }
1407: FREE_OP1_VAR_PTR();
1408:
1409: /* We are going to assign the result by reference */
1410: if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
1411: zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
1412:
1413: Z_DELREF_PP(retval_ptr);
1414: SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
1415: Z_ADDREF_PP(retval_ptr);
1416: EX_T(opline->result.var).var.ptr = *EX_T(opline->result.var).var.ptr_ptr;
1417: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
1418: }
1419:
1420: CHECK_EXCEPTION();
1421: ZEND_VM_NEXT_OPCODE();
1422: }
1423:
1424: ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1425: {
1426: USE_OPLINE
1427: zend_free_op free_op1, free_op2;
1428: zval *property;
1429: zval **container;
1430:
1431: SAVE_OPLINE();
1432: property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1433: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
1434:
1435: if (IS_OP2_TMP_FREE()) {
1436: MAKE_REAL_ZVAL_PTR(property);
1437: }
1438: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1439: zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1440: }
1441: zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_RW TSRMLS_CC);
1442: if (IS_OP2_TMP_FREE()) {
1443: zval_ptr_dtor(&property);
1444: } else {
1445: FREE_OP2();
1446: }
1447: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1448: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1449: }
1450: FREE_OP1_VAR_PTR();
1451: CHECK_EXCEPTION();
1452: ZEND_VM_NEXT_OPCODE();
1453: }
1454:
1455: ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1456: {
1457: USE_OPLINE
1458: zend_free_op free_op1;
1459: zval *container;
1460: zend_free_op free_op2;
1461: zval *offset;
1462:
1463: SAVE_OPLINE();
1464: container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
1465: offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
1466:
1467: if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
1468: UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
1469: PZVAL_LOCK(&EG(uninitialized_zval));
1470: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1471: FREE_OP2();
1472: } else {
1473: zval *retval;
1474:
1475: if (IS_OP2_TMP_FREE()) {
1476: MAKE_REAL_ZVAL_PTR(offset);
1477: }
1478:
1479: /* here we are sure we are dealing with an object */
1480: retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
1481:
1482: PZVAL_LOCK(retval);
1483: AI_SET_PTR(&EX_T(opline->result.var), retval);
1484:
1485: if (IS_OP2_TMP_FREE()) {
1486: zval_ptr_dtor(&offset);
1487: } else {
1488: FREE_OP2();
1489: }
1490: }
1491:
1492: FREE_OP1();
1493: CHECK_EXCEPTION();
1494: ZEND_VM_NEXT_OPCODE();
1495: }
1496:
1497: ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1498: {
1499: USE_OPLINE
1500:
1501: if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
1502: /* Behave like FETCH_OBJ_W */
1503: zend_free_op free_op1, free_op2;
1504: zval *property;
1505: zval **container;
1506:
1507: SAVE_OPLINE();
1508: property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1509: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
1510:
1511: if (IS_OP2_TMP_FREE()) {
1512: MAKE_REAL_ZVAL_PTR(property);
1513: }
1514: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1515: zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1516: }
1517: zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_W TSRMLS_CC);
1518: if (IS_OP2_TMP_FREE()) {
1519: zval_ptr_dtor(&property);
1520: } else {
1521: FREE_OP2();
1522: }
1523: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1524: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1525: }
1526: FREE_OP1_VAR_PTR();
1527: CHECK_EXCEPTION();
1528: ZEND_VM_NEXT_OPCODE();
1529: } else {
1530: ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper);
1531: }
1532: }
1533:
1534: ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1535: {
1536: USE_OPLINE
1537: zend_free_op free_op1, free_op2, free_res;
1538: zval **container;
1539: zval *property;
1540:
1541: SAVE_OPLINE();
1542: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
1543: property = GET_OP2_ZVAL_PTR(BP_VAR_R);
1544:
1545: if (OP1_TYPE == IS_CV) {
1546: if (container != &EG(uninitialized_zval_ptr)) {
1547: SEPARATE_ZVAL_IF_NOT_REF(container);
1548: }
1549: }
1550: if (IS_OP2_TMP_FREE()) {
1551: MAKE_REAL_ZVAL_PTR(property);
1552: }
1553: if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
1554: zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
1555: }
1556: zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_UNSET TSRMLS_CC);
1557: if (IS_OP2_TMP_FREE()) {
1558: zval_ptr_dtor(&property);
1559: } else {
1560: FREE_OP2();
1561: }
1562: if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
1563: EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
1564: }
1565: FREE_OP1_VAR_PTR();
1566:
1567: PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res);
1568: if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
1569: SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.var).var.ptr_ptr);
1570: }
1571: PZVAL_LOCK(*EX_T(opline->result.var).var.ptr_ptr);
1572: FREE_OP_VAR_PTR(free_res);
1573: CHECK_EXCEPTION();
1574: ZEND_VM_NEXT_OPCODE();
1575: }
1576:
1577: ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST)
1578: {
1579: USE_OPLINE
1580: zend_free_op free_op1;
1581: zval *container;
1582:
1583: SAVE_OPLINE();
1584: container = GET_OP1_ZVAL_PTR(BP_VAR_R);
1585:
1586: if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
1587: PZVAL_LOCK(&EG(uninitialized_zval));
1588: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1589: } else {
1590: zend_free_op free_op2;
1591: zval *value = *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
1592:
1593: PZVAL_LOCK(value);
1594: AI_SET_PTR(&EX_T(opline->result.var), value);
1595: FREE_OP2();
1596: }
1597: CHECK_EXCEPTION();
1598: ZEND_VM_NEXT_OPCODE();
1599: }
1600:
1601: ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
1602: {
1603: USE_OPLINE
1604: zend_free_op free_op1, free_op2;
1605: zval **object_ptr;
1606: zval *property_name;
1607:
1608: SAVE_OPLINE();
1609: object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
1610: property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
1611:
1612: if (IS_OP2_TMP_FREE()) {
1613: MAKE_REAL_ZVAL_PTR(property_name);
1614: }
1615: if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
1616: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1617: }
1618: zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
1619: if (IS_OP2_TMP_FREE()) {
1620: zval_ptr_dtor(&property_name);
1621: } else {
1622: FREE_OP2();
1623: }
1624: FREE_OP1_VAR_PTR();
1625: /* assign_obj has two opcodes! */
1626: CHECK_EXCEPTION();
1627: ZEND_VM_INC_OPCODE();
1628: ZEND_VM_NEXT_OPCODE();
1629: }
1630:
1631: ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
1632: {
1633: USE_OPLINE
1634: zend_free_op free_op1;
1635: zval **object_ptr;
1636:
1637: SAVE_OPLINE();
1638: object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1639:
1640: if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
1641: zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
1642: }
1643: if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
1644: zend_free_op free_op2;
1645: zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
1646:
1647: if (IS_OP2_TMP_FREE()) {
1648: MAKE_REAL_ZVAL_PTR(property_name);
1649: }
1650: zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
1651: if (IS_OP2_TMP_FREE()) {
1652: zval_ptr_dtor(&property_name);
1653: } else {
1654: FREE_OP2();
1655: }
1656: } else {
1657: zend_free_op free_op2, free_op_data1, free_op_data2;
1658: zval *value;
1659: zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
1660: zval **variable_ptr_ptr;
1661:
1662: zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, OP2_TYPE, BP_VAR_W TSRMLS_CC);
1663: FREE_OP2();
1664:
1665: value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
1666: variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
1667: if (UNEXPECTED(variable_ptr_ptr == NULL)) {
1668: if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
1669: if (RETURN_VALUE_USED(opline)) {
1670: zval *retval;
1671:
1672: ALLOC_ZVAL(retval);
1673: ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1);
1674: INIT_PZVAL(retval);
1675: AI_SET_PTR(&EX_T(opline->result.var), retval);
1676: }
1677: } else if (RETURN_VALUE_USED(opline)) {
1678: PZVAL_LOCK(&EG(uninitialized_zval));
1679: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1680: }
1681: } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) {
1682: if (IS_TMP_FREE(free_op_data1)) {
1683: zval_dtor(value);
1684: }
1685: if (RETURN_VALUE_USED(opline)) {
1686: PZVAL_LOCK(&EG(uninitialized_zval));
1687: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1688: }
1689: } else {
1690: if ((opline+1)->op1_type == IS_TMP_VAR) {
1691: value = zend_assign_tmp_to_variable(variable_ptr_ptr, value TSRMLS_CC);
1692: } else if ((opline+1)->op1_type == IS_CONST) {
1693: value = zend_assign_const_to_variable(variable_ptr_ptr, value TSRMLS_CC);
1694: } else {
1695: value = zend_assign_to_variable(variable_ptr_ptr, value TSRMLS_CC);
1696: }
1697: if (RETURN_VALUE_USED(opline)) {
1698: PZVAL_LOCK(value);
1699: AI_SET_PTR(&EX_T(opline->result.var), value);
1700: }
1701: }
1702: FREE_OP_VAR_PTR(free_op_data2);
1703: FREE_OP_IF_VAR(free_op_data1);
1704: }
1705: FREE_OP1_VAR_PTR();
1706: /* assign_dim has two opcodes! */
1707: CHECK_EXCEPTION();
1708: ZEND_VM_INC_OPCODE();
1709: ZEND_VM_NEXT_OPCODE();
1710: }
1711:
1712: ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
1713: {
1714: USE_OPLINE
1715: zend_free_op free_op1, free_op2;
1716: zval *value;
1717: zval **variable_ptr_ptr;
1718:
1719: SAVE_OPLINE();
1720: value = GET_OP2_ZVAL_PTR(BP_VAR_R);
1721: variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1722:
1723: if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
1724: if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, OP2_TYPE TSRMLS_CC)) {
1725: if (RETURN_VALUE_USED(opline)) {
1726: zval *retval;
1727:
1728: ALLOC_ZVAL(retval);
1729: ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1);
1730: INIT_PZVAL(retval);
1731: AI_SET_PTR(&EX_T(opline->result.var), retval);
1732: }
1733: } else if (RETURN_VALUE_USED(opline)) {
1734: PZVAL_LOCK(&EG(uninitialized_zval));
1735: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1736: }
1737: } else if (OP1_TYPE == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) {
1738: if (IS_OP2_TMP_FREE()) {
1739: zval_dtor(value);
1740: }
1741: if (RETURN_VALUE_USED(opline)) {
1742: PZVAL_LOCK(&EG(uninitialized_zval));
1743: AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
1744: }
1745: } else {
1746: if (OP2_TYPE == IS_TMP_VAR) {
1747: value = zend_assign_tmp_to_variable(variable_ptr_ptr, value TSRMLS_CC);
1748: } else if (OP2_TYPE == IS_CONST) {
1749: value = zend_assign_const_to_variable(variable_ptr_ptr, value TSRMLS_CC);
1750: } else {
1751: value = zend_assign_to_variable(variable_ptr_ptr, value TSRMLS_CC);
1752: }
1753: if (RETURN_VALUE_USED(opline)) {
1754: PZVAL_LOCK(value);
1755: AI_SET_PTR(&EX_T(opline->result.var), value);
1756: }
1757: }
1758:
1759: FREE_OP1_VAR_PTR();
1760:
1761: /* zend_assign_to_variable() always takes care of op2, never free it! */
1762: FREE_OP2_IF_VAR();
1763:
1764: CHECK_EXCEPTION();
1765: ZEND_VM_NEXT_OPCODE();
1766: }
1767:
1768: ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
1769: {
1770: USE_OPLINE
1771: zend_free_op free_op1, free_op2;
1772: zval **variable_ptr_ptr;
1773: zval **value_ptr_ptr;
1774:
1775: SAVE_OPLINE();
1776: value_ptr_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);
1777:
1778: if (OP2_TYPE == IS_VAR &&
1779: value_ptr_ptr &&
1780: !Z_ISREF_PP(value_ptr_ptr) &&
1781: opline->extended_value == ZEND_RETURNS_FUNCTION &&
1782: !EX_T(opline->op2.var).var.fcall_returned_reference) {
1783: if (free_op2.var == NULL) {
1784: PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
1785: }
1786: zend_error(E_STRICT, "Only variables should be assigned by reference");
1787: if (UNEXPECTED(EG(exception) != NULL)) {
1788: FREE_OP2_VAR_PTR();
1789: HANDLE_EXCEPTION();
1790: }
1791: ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
1792: } else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
1793: PZVAL_LOCK(*value_ptr_ptr);
1794: }
1795: if (OP1_TYPE == IS_VAR && UNEXPECTED(EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr)) {
1796: zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
1797: }
1798:
1799: variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
1800: if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
1801: (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
1802: zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
1803: }
1804: zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
1805:
1806: if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
1807: Z_DELREF_PP(variable_ptr_ptr);
1808: }
1809:
1810: if (RETURN_VALUE_USED(opline)) {
1811: PZVAL_LOCK(*variable_ptr_ptr);
1812: AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr);
1813: }
1814:
1815: FREE_OP1_VAR_PTR();
1816: FREE_OP2_VAR_PTR();
1817:
1818: CHECK_EXCEPTION();
1819: ZEND_VM_NEXT_OPCODE();
1820: }
1821:
1822: ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
1823: {
1824: USE_OPLINE
1825:
1826: #if DEBUG_ZEND>=2
1827: printf("Jumping to %d\n", opline->op1.opline_num);
1828: #endif
1829: ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
1830: ZEND_VM_CONTINUE(); /* CHECK_ME */
1831: }
1832:
1833: ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY)
1834: {
1835: USE_OPLINE
1836: zend_free_op free_op1;
1837: zval *val;
1838: int ret;
1839:
1840: SAVE_OPLINE();
1841: val = GET_OP1_ZVAL_PTR(BP_VAR_R);
1842:
1843: if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
1844: ret = Z_LVAL_P(val);
1845: } else {
1846: ret = i_zend_is_true(val);
1847: FREE_OP1();
1848: if (UNEXPECTED(EG(exception) != NULL)) {
1849: HANDLE_EXCEPTION();
1850: }
1851: }
1852: if (!ret) {
1853: #if DEBUG_ZEND>=2
1854: printf("Conditional jmp to %d\n", opline->op2.opline_num);
1855: #endif
1856: ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1857: ZEND_VM_CONTINUE();
1858: }
1859:
1860: ZEND_VM_NEXT_OPCODE();
1861: }
1862:
1863: ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY)
1864: {
1865: USE_OPLINE
1866: zend_free_op free_op1;
1867: zval *val;
1868: int ret;
1869:
1870: SAVE_OPLINE();
1871: val = GET_OP1_ZVAL_PTR(BP_VAR_R);
1872:
1873: if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
1874: ret = Z_LVAL_P(val);
1875: } else {
1876: ret = i_zend_is_true(val);
1877: FREE_OP1();
1878: if (UNEXPECTED(EG(exception) != NULL)) {
1879: HANDLE_EXCEPTION();
1880: }
1881: }
1882: if (ret) {
1883: #if DEBUG_ZEND>=2
1884: printf("Conditional jmp to %d\n", opline->op2.opline_num);
1885: #endif
1886: ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1887: ZEND_VM_CONTINUE();
1888: }
1889:
1890: ZEND_VM_NEXT_OPCODE();
1891: }
1892:
1893: ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY)
1894: {
1895: USE_OPLINE
1896: zend_free_op free_op1;
1897: zval *val;
1898: int retval;
1899:
1900: SAVE_OPLINE();
1901: val = GET_OP1_ZVAL_PTR(BP_VAR_R);
1902:
1903: if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
1904: retval = Z_LVAL_P(val);
1905: } else {
1906: retval = i_zend_is_true(val);
1907: FREE_OP1();
1908: if (UNEXPECTED(EG(exception) != NULL)) {
1909: HANDLE_EXCEPTION();
1910: }
1911: }
1912: if (EXPECTED(retval != 0)) {
1913: #if DEBUG_ZEND>=2
1914: printf("Conditional jmp on true to %d\n", opline->extended_value);
1915: #endif
1916: ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
1917: ZEND_VM_CONTINUE(); /* CHECK_ME */
1918: } else {
1919: #if DEBUG_ZEND>=2
1920: printf("Conditional jmp on false to %d\n", opline->op2.opline_num);
1921: #endif
1922: ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
1923: ZEND_VM_CONTINUE(); /* CHECK_ME */
1924: }
1925: }
1926:
1927: ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|VAR|CV, ANY)
1928: {
1929: USE_OPLINE
1930: zend_free_op free_op1;
1931: zval *val;
1932: int retval;
1933:
1934: SAVE_OPLINE();
1935: val = GET_OP1_ZVAL_PTR(BP_VAR_R);
1936:
1937: if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
1938: retval = Z_LVAL_P(val);
1939: } else {
1940: retval = i_zend_is_true(val);
1941: FREE_OP1();
1942: if (UNEXPECTED(EG(exception) != NULL)) {
1943: HANDLE_EXCEPTION();
1944: }
1945: }
1946: Z_LVAL(EX_T(opline->result.var).tmp_var) = retval;
1947: Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL;
1948: if (!retval) {
1949: #if DEBUG_ZEND>=2
1950: printf("Conditional jmp to %d\n", opline->op2.opline_num);
1951: #endif
1952: ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1953: ZEND_VM_CONTINUE();
1954: }
1955: ZEND_VM_NEXT_OPCODE();
1956: }
1957:
1958: ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|VAR|CV, ANY)
1959: {
1960: USE_OPLINE
1961: zend_free_op free_op1;
1962: zval *val;
1963: int retval;
1964:
1965: SAVE_OPLINE();
1966: val = GET_OP1_ZVAL_PTR(BP_VAR_R);
1967:
1968: if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
1969: retval = Z_LVAL_P(val);
1970: } else {
1971: retval = i_zend_is_true(val);
1972: FREE_OP1();
1973: if (UNEXPECTED(EG(exception) != NULL)) {
1974: HANDLE_EXCEPTION();
1975: }
1976: }
1977: Z_LVAL(EX_T(opline->result.var).tmp_var) = retval;
1978: Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL;
1979: if (retval) {
1980: #if DEBUG_ZEND>=2
1981: printf("Conditional jmp to %d\n", opline->op2.opline_num);
1982: #endif
1983: ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
1984: ZEND_VM_CONTINUE();
1985: }
1986: ZEND_VM_NEXT_OPCODE();
1987: }
1988:
1989: ZEND_VM_HANDLER(70, ZEND_FREE, TMP|VAR, ANY)
1990: {
1991: USE_OPLINE
1992:
1993: SAVE_OPLINE();
1994: if (OP1_TYPE == IS_TMP_VAR) {
1995: zendi_zval_dtor(EX_T(opline->op1.var).tmp_var);
1996: } else {
1997: zval_ptr_dtor(&EX_T(opline->op1.var).var.ptr);
1998: }
1999: CHECK_EXCEPTION();
2000: ZEND_VM_NEXT_OPCODE();
2001: }
2002:
2003: ZEND_VM_HANDLER(53, ZEND_INIT_STRING, ANY, ANY)
2004: {
2005: USE_OPLINE
2006: zval *tmp = &EX_T(opline->result.var).tmp_var;
2007:
2008: SAVE_OPLINE();
2009: tmp->value.str.val = emalloc(1);
2010: tmp->value.str.val[0] = 0;
2011: tmp->value.str.len = 0;
2012: Z_SET_REFCOUNT_P(tmp, 1);
2013: tmp->type = IS_STRING;
2014: Z_UNSET_ISREF_P(tmp);
2015: /*CHECK_EXCEPTION();*/
2016: ZEND_VM_NEXT_OPCODE();
2017: }
2018:
2019: ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST)
2020: {
2021: USE_OPLINE
2022: zval *str = &EX_T(opline->result.var).tmp_var;
2023:
2024: SAVE_OPLINE();
2025:
2026: if (OP1_TYPE == IS_UNUSED) {
2027: /* Initialize for erealloc in add_char_to_string */
2028: Z_STRVAL_P(str) = NULL;
2029: Z_STRLEN_P(str) = 0;
2030: Z_TYPE_P(str) = IS_STRING;
2031:
2032: INIT_PZVAL(str);
2033: }
2034:
2035: add_char_to_string(str, str, opline->op2.zv);
2036:
2037: /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
2038: /*CHECK_EXCEPTION();*/
2039: ZEND_VM_NEXT_OPCODE();
2040: }
2041:
2042: ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP|UNUSED, CONST)
2043: {
2044: USE_OPLINE
2045: zval *str = &EX_T(opline->result.var).tmp_var;
2046:
2047: SAVE_OPLINE();
2048:
2049: if (OP1_TYPE == IS_UNUSED) {
2050: /* Initialize for erealloc in add_string_to_string */
2051: Z_STRVAL_P(str) = NULL;
2052: Z_STRLEN_P(str) = 0;
2053: Z_TYPE_P(str) = IS_STRING;
2054:
2055: INIT_PZVAL(str);
2056: }
2057:
2058: add_string_to_string(str, str, opline->op2.zv);
2059:
2060: /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
2061: /*CHECK_EXCEPTION();*/
2062: ZEND_VM_NEXT_OPCODE();
2063: }
2064:
2065: ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV)
2066: {
2067: USE_OPLINE
2068: zend_free_op free_op2;
2069: zval *str = &EX_T(opline->result.var).tmp_var;
2070: zval *var;
2071: zval var_copy;
2072: int use_copy = 0;
2073:
2074: SAVE_OPLINE();
2075: var = GET_OP2_ZVAL_PTR(BP_VAR_R);
2076:
2077: if (OP1_TYPE == IS_UNUSED) {
2078: /* Initialize for erealloc in add_string_to_string */
2079: Z_STRVAL_P(str) = NULL;
2080: Z_STRLEN_P(str) = 0;
2081: Z_TYPE_P(str) = IS_STRING;
2082:
2083: INIT_PZVAL(str);
2084: }
2085:
2086: if (Z_TYPE_P(var) != IS_STRING) {
2087: zend_make_printable_zval(var, &var_copy, &use_copy);
2088:
2089: if (use_copy) {
2090: var = &var_copy;
2091: }
2092: }
2093: add_string_to_string(str, str, var);
2094:
2095: if (use_copy) {
2096: zval_dtor(var);
2097: }
2098: /* original comment, possibly problematic:
2099: * FREE_OP is missing intentionally here - we're always working on the same temporary variable
2100: * (Zeev): I don't think it's problematic, we only use variables
2101: * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
2102: * string offsets or overloaded objects
2103: */
2104: FREE_OP2();
2105:
2106: CHECK_EXCEPTION();
2107: ZEND_VM_NEXT_OPCODE();
2108: }
2109:
2110: ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
2111: {
2112: USE_OPLINE
2113:
2114: SAVE_OPLINE();
2115: EG(exception) = NULL;
2116: if (OP2_TYPE == IS_UNUSED) {
2117: EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
2118: CHECK_EXCEPTION();
2119: ZEND_VM_NEXT_OPCODE();
2120: } else {
2121: zend_free_op free_op2;
2122: zval *class_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2123:
2124: if (OP2_TYPE == IS_CONST) {
2125: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
2126: EX_T(opline->result.var).class_entry = CACHED_PTR(opline->op2.literal->cache_slot);
2127: } else {
2128: EX_T(opline->result.var).class_entry = zend_fetch_class_by_name(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->op2.literal + 1, opline->extended_value TSRMLS_CC);
2129: CACHE_PTR(opline->op2.literal->cache_slot, EX_T(opline->result.var).class_entry);
2130: }
2131: } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
2132: EX_T(opline->result.var).class_entry = Z_OBJCE_P(class_name);
2133: } else if (Z_TYPE_P(class_name) == IS_STRING) {
2134: EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
2135: } else {
2136: zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
2137: }
2138:
2139: FREE_OP2();
2140: CHECK_EXCEPTION();
2141: ZEND_VM_NEXT_OPCODE();
2142: }
2143: }
2144:
2145: ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
2146: {
2147: USE_OPLINE
2148: zval *function_name;
2149: char *function_name_strval;
2150: int function_name_strlen;
2151: zend_free_op free_op1, free_op2;
2152:
2153: SAVE_OPLINE();
2154: zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
2155:
2156: function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2157:
2158: if (OP2_TYPE != IS_CONST &&
2159: UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
2160: zend_error_noreturn(E_ERROR, "Method name must be a string");
2161: }
2162:
2163: function_name_strval = Z_STRVAL_P(function_name);
2164: function_name_strlen = Z_STRLEN_P(function_name);
2165:
2166: EX(object) = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
2167:
2168: if (EXPECTED(EX(object) != NULL) &&
2169: EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
2170: EX(called_scope) = Z_OBJCE_P(EX(object));
2171:
2172: if (OP2_TYPE != IS_CONST ||
2173: (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
2174: zval *object = EX(object);
2175:
2176: if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
2177: zend_error_noreturn(E_ERROR, "Object does not support method calls");
2178: }
2179:
2180: /* First, locate the function. */
2181: EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
2182: if (UNEXPECTED(EX(fbc) == NULL)) {
2183: zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
2184: }
2185: if (OP2_TYPE == IS_CONST &&
2186: EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
2187: EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
2188: EXPECTED(EX(object) == object)) {
2189: CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
2190: }
2191: }
2192: } else {
2193: zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
2194: }
2195:
2196: if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
2197: EX(object) = NULL;
2198: } else {
2199: if (!PZVAL_IS_REF(EX(object))) {
2200: Z_ADDREF_P(EX(object)); /* For $this pointer */
2201: } else {
2202: zval *this_ptr;
2203: ALLOC_ZVAL(this_ptr);
2204: INIT_PZVAL_COPY(this_ptr, EX(object));
2205: zval_copy_ctor(this_ptr);
2206: EX(object) = this_ptr;
2207: }
2208: }
2209:
2210: FREE_OP2();
2211: FREE_OP1_IF_VAR();
2212:
2213: CHECK_EXCEPTION();
2214: ZEND_VM_NEXT_OPCODE();
2215: }
2216:
2217: ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUSED|CV)
2218: {
2219: USE_OPLINE
2220: zval *function_name;
2221: zend_class_entry *ce;
2222:
2223: SAVE_OPLINE();
2224: zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
2225:
2226: if (OP1_TYPE == IS_CONST) {
2227: /* no function found. try a static method in class */
2228: if (CACHED_PTR(opline->op1.literal->cache_slot)) {
2229: ce = CACHED_PTR(opline->op1.literal->cache_slot);
2230: } else {
2231: ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), opline->op1.literal + 1, opline->extended_value TSRMLS_CC);
2232: if (UNEXPECTED(EG(exception) != NULL)) {
2233: HANDLE_EXCEPTION();
2234: }
2235: if (UNEXPECTED(ce == NULL)) {
2236: zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op1.zv));
2237: }
2238: CACHE_PTR(opline->op1.literal->cache_slot, ce);
2239: }
2240: EX(called_scope) = ce;
2241: } else {
2242: ce = EX_T(opline->op1.var).class_entry;
2243:
2244: if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
2245: EX(called_scope) = EG(called_scope);
2246: } else {
2247: EX(called_scope) = ce;
2248: }
2249: }
2250:
2251: if (OP1_TYPE == IS_CONST &&
2252: OP2_TYPE == IS_CONST &&
2253: CACHED_PTR(opline->op2.literal->cache_slot)) {
2254: EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
2255: } else if (OP1_TYPE != IS_CONST &&
2256: OP2_TYPE == IS_CONST &&
2257: (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
2258: /* do nothing */
2259: } else if (OP2_TYPE != IS_UNUSED) {
2260: char *function_name_strval = NULL;
2261: int function_name_strlen = 0;
2262: zend_free_op free_op2;
2263:
2264: if (OP2_TYPE == IS_CONST) {
2265: function_name_strval = Z_STRVAL_P(opline->op2.zv);
2266: function_name_strlen = Z_STRLEN_P(opline->op2.zv);
2267: } else {
2268: function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2269:
2270: if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
2271: zend_error_noreturn(E_ERROR, "Function name must be a string");
2272: } else {
2273: function_name_strval = Z_STRVAL_P(function_name);
2274: function_name_strlen = Z_STRLEN_P(function_name);
2275: }
2276: }
2277:
2278: if (function_name_strval) {
2279: if (ce->get_static_method) {
2280: EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
2281: } else {
2282: EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
2283: }
2284: if (UNEXPECTED(EX(fbc) == NULL)) {
2285: zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
2286: }
2287: if (OP2_TYPE == IS_CONST &&
2288: EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
2289: EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
2290: if (OP1_TYPE == IS_CONST) {
2291: CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
2292: } else {
2293: CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
2294: }
2295: }
2296: }
2297: if (OP2_TYPE != IS_CONST) {
2298: FREE_OP2();
2299: }
2300: } else {
2301: if (UNEXPECTED(ce->constructor == NULL)) {
2302: zend_error_noreturn(E_ERROR, "Cannot call constructor");
2303: }
2304: if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
2305: zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
2306: }
2307: EX(fbc) = ce->constructor;
2308: }
2309:
2310: if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
2311: EX(object) = NULL;
2312: } else {
2313: if (EG(This) &&
2314: Z_OBJ_HT_P(EG(This))->get_class_entry &&
2315: !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
2316: /* We are calling method of the other (incompatible) class,
2317: but passing $this. This is done for compatibility with php-4. */
2318: if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
2319: zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
2320: } else {
2321: /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2322: zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
2323: }
2324: }
2325: if ((EX(object) = EG(This))) {
2326: Z_ADDREF_P(EX(object));
2327: EX(called_scope) = Z_OBJCE_P(EX(object));
2328: }
2329: }
2330:
2331: CHECK_EXCEPTION();
2332: ZEND_VM_NEXT_OPCODE();
2333: }
2334:
2335: ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
2336: {
2337: USE_OPLINE
2338: zval *function_name;
2339: zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
2340:
2341: if (OP2_TYPE == IS_CONST) {
2342: function_name = (zval*)(opline->op2.literal+1);
2343: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
2344: EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
2345: } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
2346: SAVE_OPLINE();
2347: zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
2348: } else {
2349: CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
2350: }
2351: EX(object) = NULL;
2352: /*CHECK_EXCEPTION();*/
2353: ZEND_VM_NEXT_OPCODE();
2354: } else {
2355: char *function_name_strval, *lcname;
2356: int function_name_strlen;
2357: zend_free_op free_op2;
2358:
2359: SAVE_OPLINE();
2360: function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
2361:
2362: if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
2363: function_name_strval = Z_STRVAL_P(function_name);
2364: function_name_strlen = Z_STRLEN_P(function_name);
2365: if (function_name_strval[0] == '\\') {
2366: function_name_strlen -= 1;
2367: lcname = zend_str_tolower_dup(function_name_strval + 1, function_name_strlen);
2368: } else {
2369: lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
2370: }
2371: if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
2372: zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
2373: }
2374: efree(lcname);
2375: FREE_OP2();
2376: EX(object) = NULL;
2377: CHECK_EXCEPTION();
2378: ZEND_VM_NEXT_OPCODE();
2379: } else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR &&
2380: EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
2381: Z_OBJ_HANDLER_P(function_name, get_closure) &&
2382: Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
2383: if (EX(object)) {
2384: Z_ADDREF_P(EX(object));
2385: }
2386: if (OP2_TYPE == IS_VAR && OP2_FREE &&
2387: EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
2388: /* Delay closure destruction until its invocation */
2389: EX(fbc)->common.prototype = (zend_function*)function_name;
2390: } else {
2391: FREE_OP2();
2392: }
2393: CHECK_EXCEPTION();
2394: ZEND_VM_NEXT_OPCODE();
2395: } else if (OP2_TYPE != IS_CONST &&
2396: EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
2397: zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
2398: zend_class_entry *ce;
2399: zval **method = NULL;
2400: zval **obj = NULL;
2401:
2402: zend_hash_index_find(Z_ARRVAL_P(function_name), 0, (void **) &obj);
2403: zend_hash_index_find(Z_ARRVAL_P(function_name), 1, (void **) &method);
2404:
2405: if (!obj || !method) {
2406: zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
2407: }
2408:
2409: if (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT) {
2410: zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
2411: }
2412:
2413: if (Z_TYPE_PP(method) != IS_STRING) {
2414: zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
2415: }
2416:
2417: if (Z_TYPE_PP(obj) == IS_STRING) {
2418: ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
2419: if (UNEXPECTED(EG(exception) != NULL)) {
2420: HANDLE_EXCEPTION();
2421: }
2422: if (UNEXPECTED(ce == NULL)) {
2423: zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
2424: }
2425: EX(called_scope) = ce;
2426: EX(object) = NULL;
2427:
2428: if (ce->get_static_method) {
2429: EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
2430: } else {
2431: EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
2432: }
2433: } else {
2434: EX(object) = *obj;
2435: ce = EX(called_scope) = Z_OBJCE_PP(obj);
2436:
2437: EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
2438: if (UNEXPECTED(EX(fbc) == NULL)) {
2439: zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
2440: }
2441:
2442: if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
2443: EX(object) = NULL;
2444: } else {
2445: if (!PZVAL_IS_REF(EX(object))) {
2446: Z_ADDREF_P(EX(object)); /* For $this pointer */
2447: } else {
2448: zval *this_ptr;
2449: ALLOC_ZVAL(this_ptr);
2450: INIT_PZVAL_COPY(this_ptr, EX(object));
2451: zval_copy_ctor(this_ptr);
2452: EX(object) = this_ptr;
2453: }
2454: }
2455: }
2456:
2457: if (UNEXPECTED(EX(fbc) == NULL)) {
2458: zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
2459: }
2460: FREE_OP2();
2461: CHECK_EXCEPTION();
2462: ZEND_VM_NEXT_OPCODE();
2463: } else {
2464: zend_error_noreturn(E_ERROR, "Function name must be a string");
2465: }
2466: }
2467: }
2468:
2469:
2470: ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
2471: {
2472: USE_OPLINE
2473: zend_literal *func_name;
2474:
2475: zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
2476:
2477: func_name = opline->op2.literal + 1;
2478: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
2479: EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
2480: } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
2481: func_name++;
2482: if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
2483: SAVE_OPLINE();
2484: zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
2485: } else {
2486: CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
2487: }
2488: } else {
2489: CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
2490: }
2491:
2492: EX(object) = NULL;
2493: ZEND_VM_NEXT_OPCODE();
2494: }
2495:
2496: ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
2497: {
2498: zend_bool nested;
2499: zend_op_array *op_array = EX(op_array);
2500:
2501: EG(current_execute_data) = EX(prev_execute_data);
2502: EG(opline_ptr) = NULL;
2503: if (!EG(active_symbol_table)) {
2504: zval ***cv = EX_CVs();
2505: zval ***end = cv + op_array->last_var;
2506: while (cv != end) {
2507: if (*cv) {
2508: zval_ptr_dtor(*cv);
2509: }
2510: cv++;
2511: }
2512: }
2513:
2514: if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
2515: zval_ptr_dtor((zval**)&op_array->prototype);
2516: }
2517:
2518: nested = EX(nested);
2519:
2520: zend_vm_stack_free(execute_data TSRMLS_CC);
2521:
2522: if (nested) {
2523: execute_data = EG(current_execute_data);
2524: }
2525: if (nested) {
2526: USE_OPLINE
2527:
2528: LOAD_REGS();
2529: LOAD_OPLINE();
2530: if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
2531:
2532: EX(function_state).function = (zend_function *) EX(op_array);
2533: EX(function_state).arguments = NULL;
2534: EX(object) = EX(current_object);
2535:
2536: EG(opline_ptr) = &EX(opline);
2537: EG(active_op_array) = EX(op_array);
2538: EG(return_value_ptr_ptr) = EX(original_return_value);
2539: destroy_op_array(op_array TSRMLS_CC);
2540: efree(op_array);
2541: if (UNEXPECTED(EG(exception) != NULL)) {
2542: zend_throw_exception_internal(NULL TSRMLS_CC);
2543: HANDLE_EXCEPTION_LEAVE();
2544: } else if (RETURN_VALUE_USED(opline)) {
2545: if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
2546: zval *retval;
2547:
2548: ALLOC_ZVAL(retval);
2549: ZVAL_BOOL(retval, 1);
2550: INIT_PZVAL(retval);
2551: EX_T(opline->result.var).var.ptr = retval;
2552: }
2553: }
2554:
2555: ZEND_VM_INC_OPCODE();
2556: ZEND_VM_LEAVE();
2557: } else {
2558:
2559: EG(opline_ptr) = &EX(opline);
2560: EG(active_op_array) = EX(op_array);
2561: EG(return_value_ptr_ptr) = EX(original_return_value);
2562: if (EG(active_symbol_table)) {
2563: if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
2564: zend_hash_destroy(EG(active_symbol_table));
2565: FREE_HASHTABLE(EG(active_symbol_table));
2566: } else {
2567: /* clean before putting into the cache, since clean
2568: could call dtors, which could use cached hash */
2569: zend_hash_clean(EG(active_symbol_table));
2570: *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
2571: }
2572: }
2573: EG(active_symbol_table) = EX(symbol_table);
2574:
2575: EX(function_state).function = (zend_function *) EX(op_array);
2576: EX(function_state).arguments = NULL;
2577:
2578: if (EG(This)) {
2579: if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
2580: if (IS_CTOR_USED(EX(called_scope))) {
2581: Z_DELREF_P(EG(This));
2582: }
2583: if (Z_REFCOUNT_P(EG(This)) == 1) {
2584: zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
2585: }
2586: }
2587: zval_ptr_dtor(&EG(This));
2588: }
2589: EG(This) = EX(current_this);
2590: EG(scope) = EX(current_scope);
2591: EG(called_scope) = EX(current_called_scope);
2592:
2593: EX(object) = EX(current_object);
2594: EX(called_scope) = DECODE_CTOR(EX(called_scope));
2595:
2596: zend_vm_stack_clear_multiple(TSRMLS_C);
2597:
2598: if (UNEXPECTED(EG(exception) != NULL)) {
2599: zend_throw_exception_internal(NULL TSRMLS_CC);
2600: if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
2601: zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
2602: }
2603: HANDLE_EXCEPTION_LEAVE();
2604: }
2605:
2606: ZEND_VM_INC_OPCODE();
2607: ZEND_VM_LEAVE();
2608: }
2609: }
2610: ZEND_VM_RETURN();
2611: }
2612:
2613: ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
2614: {
2615: USE_OPLINE
2616: zend_bool should_change_scope = 0;
2617: zend_function *fbc = EX(function_state).function;
2618:
2619: SAVE_OPLINE();
2620: if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
2621: if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
2622: zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
2623: CHECK_EXCEPTION();
2624: ZEND_VM_NEXT_OPCODE(); /* Never reached */
2625: }
2626: if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
2627: zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
2628: fbc->common.scope ? fbc->common.scope->name : "",
2629: fbc->common.scope ? "::" : "",
2630: fbc->common.function_name);
2631: }
2632: }
2633: if (fbc->common.scope &&
2634: !(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
2635: !EX(object)) {
2636:
2637: if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
2638: /* FIXME: output identifiers properly */
2639: zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name);
2640: } else {
2641: /* FIXME: output identifiers properly */
2642: /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2643: zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name);
2644: }
2645: }
2646:
2647: if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
2648: should_change_scope = 1;
2649: EX(current_this) = EG(This);
2650: EX(current_scope) = EG(scope);
2651: EX(current_called_scope) = EG(called_scope);
2652: EG(This) = EX(object);
2653: EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
2654: EG(called_scope) = EX(called_scope);
2655: }
2656:
2657: zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc));
2658: EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
2659: LOAD_OPLINE();
2660:
2661: if (fbc->type == ZEND_INTERNAL_FUNCTION) {
2662: temp_variable *ret = &EX_T(opline->result.var);
2663:
2664: if (fbc->common.arg_info) {
2665: zend_uint i=0;
2666: zval **p = (zval**)EX(function_state).arguments;
2667: ulong arg_count = opline->extended_value;
2668:
2669: while (arg_count>0) {
2670: zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC);
2671: arg_count--;
2672: }
2673: }
2674:
2675: if (EXPECTED(EG(exception) == NULL)) {
2676: MAKE_STD_ZVAL(ret->var.ptr);
2677: ZVAL_NULL(ret->var.ptr);
2678: ret->var.ptr_ptr = &ret->var.ptr;
2679: ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
2680:
2681: if (!zend_execute_internal) {
2682: /* saves one function call if zend_execute_internal is not used */
2683: fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
2684: } else {
2685: zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
2686: }
2687:
2688: if (!RETURN_VALUE_USED(opline)) {
2689: zval_ptr_dtor(&ret->var.ptr);
2690: }
2691: } else if (RETURN_VALUE_USED(opline)) {
2692: EX_T(opline->result.var).var.ptr = NULL;
2693: }
2694: } else if (fbc->type == ZEND_USER_FUNCTION) {
2695: EX(original_return_value) = EG(return_value_ptr_ptr);
2696: EG(active_symbol_table) = NULL;
2697: EG(active_op_array) = &fbc->op_array;
2698: EG(return_value_ptr_ptr) = NULL;
2699: if (RETURN_VALUE_USED(opline)) {
2700: temp_variable *ret = &EX_T(opline->result.var);
2701:
2702: ret->var.ptr = NULL;
2703: EG(return_value_ptr_ptr) = &ret->var.ptr;
2704: ret->var.ptr_ptr = &ret->var.ptr;
2705: ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
2706: }
2707:
2708: if (EXPECTED(zend_execute == execute)) {
2709: if (EXPECTED(EG(exception) == NULL)) {
2710: ZEND_VM_ENTER();
2711: }
2712: } else {
2713: zend_execute(EG(active_op_array) TSRMLS_CC);
2714: }
2715:
2716: EG(opline_ptr) = &EX(opline);
2717: EG(active_op_array) = EX(op_array);
2718: EG(return_value_ptr_ptr) = EX(original_return_value);
2719: if (EG(active_symbol_table)) {
2720: if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
2721: zend_hash_destroy(EG(active_symbol_table));
2722: FREE_HASHTABLE(EG(active_symbol_table));
2723: } else {
2724: /* clean before putting into the cache, since clean
2725: could call dtors, which could use cached hash */
2726: zend_hash_clean(EG(active_symbol_table));
2727: *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
2728: }
2729: }
2730: EG(active_symbol_table) = EX(symbol_table);
2731: } else { /* ZEND_OVERLOADED_FUNCTION */
2732: MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
2733: ZVAL_NULL(EX_T(opline->result.var).var.ptr);
2734:
2735: /* Not sure what should be done here if it's a static method */
2736: if (EXPECTED(EX(object) != NULL)) {
2737: Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
2738: } else {
2739: zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
2740: }
2741:
2742: if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
2743: efree((char*)fbc->common.function_name);
2744: }
2745: efree(fbc);
2746:
2747: if (!RETURN_VALUE_USED(opline)) {
2748: zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
2749: } else {
2750: Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
2751: Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
2752: EX_T(opline->result.var).var.fcall_returned_reference = 0;
2753: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
2754: }
2755: }
2756:
2757: EX(function_state).function = (zend_function *) EX(op_array);
2758: EX(function_state).arguments = NULL;
2759:
2760: if (should_change_scope) {
2761: if (EG(This)) {
2762: if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
2763: if (IS_CTOR_USED(EX(called_scope))) {
2764: Z_DELREF_P(EG(This));
2765: }
2766: if (Z_REFCOUNT_P(EG(This)) == 1) {
2767: zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
2768: }
2769: }
2770: zval_ptr_dtor(&EG(This));
2771: }
2772: EG(This) = EX(current_this);
2773: EG(scope) = EX(current_scope);
2774: EG(called_scope) = EX(current_called_scope);
2775: }
2776:
2777: EX(object) = EX(current_object);
2778: EX(called_scope) = DECODE_CTOR(EX(called_scope));
2779:
2780: zend_vm_stack_clear_multiple(TSRMLS_C);
2781:
2782: if (UNEXPECTED(EG(exception) != NULL)) {
2783: zend_throw_exception_internal(NULL TSRMLS_CC);
2784: if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
2785: zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
2786: }
2787: HANDLE_EXCEPTION();
2788: }
2789:
2790: ZEND_VM_NEXT_OPCODE();
2791: }
2792:
2793: ZEND_VM_HANDLER(61, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
2794: {
2795: EX(function_state).function = EX(fbc);
2796: ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
2797: }
2798:
2799: ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
2800: {
2801: USE_OPLINE
2802: zend_free_op free_op1;
2803: zval *fname = GET_OP1_ZVAL_PTR(BP_VAR_R);
2804:
2805: zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
2806:
2807: if (CACHED_PTR(opline->op1.literal->cache_slot)) {
2808: EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
2809: } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(fname), Z_STRLEN_P(fname)+1, Z_HASH_P(fname), (void **) &EX(function_state).function)==FAILURE)) {
2810: SAVE_OPLINE();
2811: zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
2812: } else {
2813: CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function);
2814: }
2815: EX(object) = NULL;
2816:
2817: FREE_OP1();
2818:
2819: ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
2820: }
2821:
2822: ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
2823: {
2824: USE_OPLINE
2825: zval *retval_ptr;
2826: zend_free_op free_op1;
2827:
2828: SAVE_OPLINE();
2829: retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
2830:
2831: if (!EG(return_value_ptr_ptr)) {
2832: if (OP1_TYPE == IS_TMP_VAR) {
2833: FREE_OP1();
2834: }
2835: } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
2836: if (OP1_TYPE == IS_CONST ||
2837: (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
2838: zval *ret;
2839:
2840: ALLOC_ZVAL(ret);
2841: INIT_PZVAL_COPY(ret, retval_ptr);
2842: zval_copy_ctor(ret);
2843: *EG(return_value_ptr_ptr) = ret;
2844: } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
2845: retval_ptr == &EG(uninitialized_zval)) {
2846: zval *ret;
2847:
2848: ALLOC_INIT_ZVAL(ret);
2849: *EG(return_value_ptr_ptr) = ret;
2850: } else {
2851: *EG(return_value_ptr_ptr) = retval_ptr;
2852: Z_ADDREF_P(retval_ptr);
2853: }
2854: } else {
2855: zval *ret;
2856:
2857: ALLOC_ZVAL(ret);
2858: INIT_PZVAL_COPY(ret, retval_ptr);
2859: *EG(return_value_ptr_ptr) = ret;
2860: }
2861: FREE_OP1_IF_VAR();
2862: ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
2863: }
2864:
2865: ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
2866: {
2867: USE_OPLINE
2868: zval *retval_ptr;
2869: zval **retval_ptr_ptr;
2870: zend_free_op free_op1;
2871:
2872: SAVE_OPLINE();
2873:
2874: do {
2875: if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
2876: /* Not supposed to happen, but we'll allow it */
2877: zend_error(E_NOTICE, "Only variable references should be returned by reference");
2878:
2879: retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
2880: if (!EG(return_value_ptr_ptr)) {
2881: if (OP1_TYPE == IS_TMP_VAR) {
2882: FREE_OP1();
2883: }
2884: } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
2885: zval *ret;
2886:
2887: ALLOC_ZVAL(ret);
2888: INIT_PZVAL_COPY(ret, retval_ptr);
2889: zval_copy_ctor(ret);
2890: *EG(return_value_ptr_ptr) = ret;
2891: } else {
2892: zval *ret;
2893:
2894: ALLOC_ZVAL(ret);
2895: INIT_PZVAL_COPY(ret, retval_ptr);
2896: *EG(return_value_ptr_ptr) = ret;
2897: }
2898: break;
2899: }
2900:
2901: retval_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
2902:
2903: if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr_ptr == NULL)) {
2904: zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
2905: }
2906:
2907: if (OP1_TYPE == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) {
2908: if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
2909: EX_T(opline->op1.var).var.fcall_returned_reference) {
2910: } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
2911: zend_error(E_NOTICE, "Only variable references should be returned by reference");
2912: if (EG(return_value_ptr_ptr)) {
2913: zval *ret;
2914:
2915: ALLOC_ZVAL(ret);
2916: INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
2917: zval_copy_ctor(ret);
2918: *EG(return_value_ptr_ptr) = ret;
2919: }
2920: break;
2921: }
2922: }
2923:
2924: if (EG(return_value_ptr_ptr)) {
2925: SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
2926: Z_ADDREF_PP(retval_ptr_ptr);
2927:
2928: *EG(return_value_ptr_ptr) = *retval_ptr_ptr;
2929: }
2930: } while (0);
2931:
2932: FREE_OP1_IF_VAR();
2933: ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
2934: }
2935:
2936: ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
2937: {
2938: USE_OPLINE
2939: zval *value;
2940: zval *exception;
2941: zend_free_op free_op1;
2942:
2943: SAVE_OPLINE();
2944: value = GET_OP1_ZVAL_PTR(BP_VAR_R);
2945:
2946: if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
2947: zend_error_noreturn(E_ERROR, "Can only throw objects");
2948: }
2949: zend_exception_save(TSRMLS_C);
2950: /* Not sure if a complete copy is what we want here */
2951: ALLOC_ZVAL(exception);
2952: INIT_PZVAL_COPY(exception, value);
2953: if (!IS_OP1_TMP_FREE()) {
2954: zval_copy_ctor(exception);
2955: }
2956:
2957: zend_throw_exception_object(exception TSRMLS_CC);
2958: zend_exception_restore(TSRMLS_C);
2959: FREE_OP1_IF_VAR();
2960: HANDLE_EXCEPTION();
2961: }
2962:
2963: ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
2964: {
2965: USE_OPLINE
2966: zend_class_entry *ce, *catch_ce;
2967: zval *exception;
2968:
2969: SAVE_OPLINE();
2970: /* Check whether an exception has been thrown, if not, jump over code */
2971: zend_exception_restore(TSRMLS_C);
2972: if (EG(exception) == NULL) {
2973: ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
2974: ZEND_VM_CONTINUE(); /* CHECK_ME */
2975: }
2976: if (CACHED_PTR(opline->op1.literal->cache_slot)) {
2977: catch_ce = CACHED_PTR(opline->op1.literal->cache_slot);
2978: } else {
2979: catch_ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), opline->op1.literal + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
2980:
2981: CACHE_PTR(opline->op1.literal->cache_slot, catch_ce);
2982: }
2983: ce = Z_OBJCE_P(EG(exception));
2984:
2985: #ifdef HAVE_DTRACE
2986: if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
2987: DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
2988: }
2989: #endif /* HAVE_DTRACE */
2990:
2991: if (ce != catch_ce) {
2992: if (!instanceof_function(ce, catch_ce TSRMLS_CC)) {
2993: if (opline->result.num) {
2994: zend_throw_exception_internal(NULL TSRMLS_CC);
2995: HANDLE_EXCEPTION();
2996: }
2997: ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
2998: ZEND_VM_CONTINUE(); /* CHECK_ME */
2999: }
3000: }
3001:
3002: exception = EG(exception);
3003: if (!EG(active_symbol_table)) {
3004: if (EX_CV(opline->op2.var)) {
3005: zval_ptr_dtor(EX_CV(opline->op2.var));
3006: }
3007: EX_CV(opline->op2.var) = (zval**)EX_CVs() + (EX(op_array)->last_var + opline->op2.var);
3008: *EX_CV(opline->op2.var) = EG(exception);
3009: } else {
3010: zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.var);
3011: zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value,
3012: &EG(exception), sizeof(zval *), (void**)&EX_CV(opline->op2.var));
3013: }
3014: if (UNEXPECTED(EG(exception) != exception)) {
3015: Z_ADDREF_P(EG(exception));
3016: HANDLE_EXCEPTION();
3017: } else {
3018: EG(exception) = NULL;
3019: ZEND_VM_NEXT_OPCODE();
3020: }
3021: }
3022:
3023: ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
3024: {
3025: USE_OPLINE
3026:
3027: SAVE_OPLINE();
3028: if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
3029: && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
3030: zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num);
3031: }
3032: {
3033: zval *valptr;
3034: zval *value;
3035: zend_free_op free_op1;
3036:
3037: value = GET_OP1_ZVAL_PTR(BP_VAR_R);
3038:
3039: ALLOC_ZVAL(valptr);
3040: INIT_PZVAL_COPY(valptr, value);
3041: if (!IS_OP1_TMP_FREE()) {
3042: zval_copy_ctor(valptr);
3043: }
3044: zend_vm_stack_push(valptr TSRMLS_CC);
3045: FREE_OP1_IF_VAR();
3046: }
3047: CHECK_EXCEPTION();
3048: ZEND_VM_NEXT_OPCODE();
3049: }
3050:
3051: ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY)
3052: {
3053: USE_OPLINE
3054: zval *varptr;
3055: zend_free_op free_op1;
3056: varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3057:
3058: if (varptr == &EG(uninitialized_zval)) {
3059: ALLOC_ZVAL(varptr);
3060: INIT_ZVAL(*varptr);
3061: Z_SET_REFCOUNT_P(varptr, 0);
3062: } else if (PZVAL_IS_REF(varptr)) {
3063: zval *original_var = varptr;
3064:
3065: ALLOC_ZVAL(varptr);
3066: ZVAL_COPY_VALUE(varptr, original_var);
3067: Z_UNSET_ISREF_P(varptr);
3068: Z_SET_REFCOUNT_P(varptr, 0);
3069: zval_copy_ctor(varptr);
3070: }
3071: Z_ADDREF_P(varptr);
3072: zend_vm_stack_push(varptr TSRMLS_CC);
3073: FREE_OP1(); /* for string offsets */
3074:
3075: CHECK_EXCEPTION();
3076: ZEND_VM_NEXT_OPCODE();
3077: }
3078:
3079: ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
3080: {
3081: USE_OPLINE
3082: zend_free_op free_op1;
3083: zval *varptr;
3084:
3085: SAVE_OPLINE();
3086: if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
3087: if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
3088: ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
3089: }
3090: } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
3091: ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
3092: }
3093:
3094: if (OP1_TYPE == IS_VAR &&
3095: (opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
3096: EX_T(opline->op1.var).var.fcall_returned_reference &&
3097: EX_T(opline->op1.var).var.ptr) {
3098: varptr = EX_T(opline->op1.var).var.ptr;
3099: PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
3100: } else {
3101: varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3102: }
3103: if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
3104: EX_T(opline->op1.var).var.fcall_returned_reference) &&
3105: varptr != &EG(uninitialized_zval) &&
3106: (PZVAL_IS_REF(varptr) ||
3107: (Z_REFCOUNT_P(varptr) == 1 && (OP1_TYPE == IS_CV || free_op1.var)))) {
3108: Z_SET_ISREF_P(varptr);
3109: Z_ADDREF_P(varptr);
3110: zend_vm_stack_push(varptr TSRMLS_CC);
3111: } else {
3112: zval *valptr;
3113:
3114: if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
3115: !(opline->extended_value & ZEND_ARG_SEND_SILENT) :
3116: !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
3117: zend_error(E_STRICT, "Only variables should be passed by reference");
3118: }
3119: ALLOC_ZVAL(valptr);
3120: INIT_PZVAL_COPY(valptr, varptr);
3121: if (!IS_OP1_TMP_FREE()) {
3122: zval_copy_ctor(valptr);
3123: }
3124: zend_vm_stack_push(valptr TSRMLS_CC);
3125: }
3126: FREE_OP1_IF_VAR();
3127: CHECK_EXCEPTION();
3128: ZEND_VM_NEXT_OPCODE();
3129: }
3130:
3131: ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
3132: {
3133: USE_OPLINE
3134: zend_free_op free_op1;
3135: zval **varptr_ptr;
3136: zval *varptr;
3137:
3138: SAVE_OPLINE();
3139: varptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
3140:
3141: if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) {
3142: zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
3143: }
3144:
3145: if (OP1_TYPE == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) {
3146: ALLOC_INIT_ZVAL(varptr);
3147: zend_vm_stack_push(varptr TSRMLS_CC);
3148: CHECK_EXCEPTION();
3149: ZEND_VM_NEXT_OPCODE();
3150: }
3151:
3152: if (opline->extended_value == ZEND_DO_FCALL_BY_NAME &&
3153: EX(function_state).function->type == ZEND_INTERNAL_FUNCTION &&
3154: !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
3155: ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
3156: }
3157:
3158: SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
3159: varptr = *varptr_ptr;
3160: Z_ADDREF_P(varptr);
3161: zend_vm_stack_push(varptr TSRMLS_CC);
3162:
3163: FREE_OP1_VAR_PTR();
3164: CHECK_EXCEPTION();
3165: ZEND_VM_NEXT_OPCODE();
3166: }
3167:
3168: ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
3169: {
3170: USE_OPLINE
3171:
3172: if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
3173: && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
3174: ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
3175: }
3176: SAVE_OPLINE();
3177: ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
3178: }
3179:
3180: ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
3181: {
3182: USE_OPLINE
3183: zend_uint arg_num = opline->op1.num;
3184: zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
3185:
3186: SAVE_OPLINE();
3187: if (UNEXPECTED(param == NULL)) {
3188: if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
3189: const char *space;
3190: const char *class_name;
3191: zend_execute_data *ptr;
3192:
3193: if (EG(active_op_array)->scope) {
3194: class_name = EG(active_op_array)->scope->name;
3195: space = "::";
3196: } else {
3197: class_name = space = "";
3198: }
3199: ptr = EX(prev_execute_data);
3200:
3201: if(ptr && ptr->op_array) {
3202: zend_error(E_WARNING, "Missing argument %u for %s%s%s(), called in %s on line %d and defined", opline->op1.num, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
3203: } else {
3204: zend_error(E_WARNING, "Missing argument %u for %s%s%s()", opline->op1.num, class_name, space, get_active_function_name(TSRMLS_C));
3205: }
3206: }
3207: } else {
3208: zval **var_ptr;
3209:
3210: zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
3211: var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
3212: Z_DELREF_PP(var_ptr);
3213: *var_ptr = *param;
3214: Z_ADDREF_PP(var_ptr);
3215: }
3216:
3217: CHECK_EXCEPTION();
3218: ZEND_VM_NEXT_OPCODE();
3219: }
3220:
3221: ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
3222: {
3223: USE_OPLINE
3224: zval *assignment_value;
3225: zend_uint arg_num = opline->op1.num;
3226: zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
3227: zval **var_ptr;
3228:
3229: SAVE_OPLINE();
3230: if (param == NULL) {
3231: ALLOC_ZVAL(assignment_value);
3232: *assignment_value = *opline->op2.zv;
3233: if ((Z_TYPE_P(assignment_value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT ||
3234: Z_TYPE_P(assignment_value)==IS_CONSTANT_ARRAY) {
3235: Z_SET_REFCOUNT_P(assignment_value, 1);
3236: zval_update_constant(&assignment_value, 0 TSRMLS_CC);
3237: } else {
3238: zval_copy_ctor(assignment_value);
3239: }
3240: INIT_PZVAL(assignment_value);
3241: } else {
3242: assignment_value = *param;
3243: Z_ADDREF_P(assignment_value);
3244: }
3245:
3246: zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
3247: var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
3248: zval_ptr_dtor(var_ptr);
3249: *var_ptr = assignment_value;
3250:
3251: CHECK_EXCEPTION();
3252: ZEND_VM_NEXT_OPCODE();
3253: }
3254:
3255: ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY)
3256: {
3257: USE_OPLINE
3258: zend_free_op free_op1;
3259: zval *retval = &EX_T(opline->result.var).tmp_var;
3260:
3261: SAVE_OPLINE();
3262: /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
3263: ZVAL_BOOL(retval, i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R)));
3264: FREE_OP1();
3265:
3266: CHECK_EXCEPTION();
3267: ZEND_VM_NEXT_OPCODE();
3268: }
3269:
3270: ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
3271: {
3272: USE_OPLINE
3273: zend_brk_cont_element *el;
3274:
3275: SAVE_OPLINE();
3276: el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
3277: EX(op_array), EX_Ts() TSRMLS_CC);
3278: ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
3279: }
3280:
3281: ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
3282: {
3283: USE_OPLINE
3284: zend_brk_cont_element *el;
3285:
3286: SAVE_OPLINE();
3287: el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
3288: EX(op_array), EX_Ts() TSRMLS_CC);
3289: ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
3290: }
3291:
3292: ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
3293: {
3294: zend_op *brk_opline;
3295: USE_OPLINE
3296: zend_brk_cont_element *el;
3297:
3298: SAVE_OPLINE();
3299: el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
3300: EX(op_array), EX_Ts() TSRMLS_CC);
3301:
3302: brk_opline = EX(op_array)->opcodes + el->brk;
3303:
3304: switch (brk_opline->opcode) {
3305: case ZEND_SWITCH_FREE:
3306: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
3307: zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr);
3308: }
3309: break;
3310: case ZEND_FREE:
3311: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
3312: zendi_zval_dtor(EX_T(brk_opline->op1.var).tmp_var);
3313: }
3314: break;
3315: }
3316: ZEND_VM_JMP(opline->op1.jmp_addr);
3317: }
3318:
3319: ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
3320: {
3321: USE_OPLINE
3322: zend_free_op free_op1, free_op2;
3323:
3324: SAVE_OPLINE();
3325: if (OP1_TYPE==IS_VAR) {
3326: PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
3327: }
3328: is_equal_function(&EX_T(opline->result.var).tmp_var,
3329: GET_OP1_ZVAL_PTR(BP_VAR_R),
3330: GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
3331:
3332: FREE_OP2();
3333: CHECK_EXCEPTION();
3334: ZEND_VM_NEXT_OPCODE();
3335: }
3336:
3337: ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY)
3338: {
3339: USE_OPLINE
3340:
3341: SAVE_OPLINE();
3342: zval_ptr_dtor(&EX_T(opline->op1.var).var.ptr);
3343: CHECK_EXCEPTION();
3344: ZEND_VM_NEXT_OPCODE();
3345: }
3346:
3347: ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
3348: {
3349: USE_OPLINE
3350: zval *object_zval;
3351: zend_function *constructor;
3352:
3353: SAVE_OPLINE();
3354: if (UNEXPECTED((EX_T(opline->op1.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
3355: if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
3356: zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", EX_T(opline->op1.var).class_entry->name);
3357: } else if ((EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
3358: zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", EX_T(opline->op1.var).class_entry->name);
3359: } else {
3360: zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", EX_T(opline->op1.var).class_entry->name);
3361: }
3362: }
3363: ALLOC_ZVAL(object_zval);
3364: object_init_ex(object_zval, EX_T(opline->op1.var).class_entry);
3365: INIT_PZVAL(object_zval);
3366:
3367: constructor = Z_OBJ_HT_P(object_zval)->get_constructor(object_zval TSRMLS_CC);
3368:
3369: if (constructor == NULL) {
3370: if (RETURN_VALUE_USED(opline)) {
3371: AI_SET_PTR(&EX_T(opline->result.var), object_zval);
3372: } else {
3373: zval_ptr_dtor(&object_zval);
3374: }
3375: ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.opline_num);
3376: } else {
3377: if (RETURN_VALUE_USED(opline)) {
3378: PZVAL_LOCK(object_zval);
3379: AI_SET_PTR(&EX_T(opline->result.var), object_zval);
3380: }
3381:
3382: zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline)));
3383:
3384: /* We are not handling overloaded classes right now */
3385: EX(object) = object_zval;
3386: EX(fbc) = constructor;
3387: EX(called_scope) = EX_T(opline->op1.var).class_entry;
3388:
3389: CHECK_EXCEPTION();
3390: ZEND_VM_NEXT_OPCODE();
3391: }
3392: }
3393:
3394: ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
3395: {
3396: USE_OPLINE
3397: zend_free_op free_op1;
3398: zval *obj;
3399: zend_class_entry *ce;
3400: zend_function *clone;
3401: zend_object_clone_obj_t clone_call;
3402:
3403: SAVE_OPLINE();
3404: obj = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
3405:
3406: if (OP1_TYPE == IS_CONST ||
3407: UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
3408: zend_error_noreturn(E_ERROR, "__clone method called on non-object");
3409: }
3410:
3411: ce = Z_OBJCE_P(obj);
3412: clone = ce ? ce->clone : NULL;
3413: clone_call = Z_OBJ_HT_P(obj)->clone_obj;
3414: if (UNEXPECTED(clone_call == NULL)) {
3415: if (ce) {
3416: zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
3417: } else {
3418: zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
3419: }
3420: }
3421:
3422: if (ce && clone) {
3423: if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
3424: /* Ensure that if we're calling a private function, we're allowed to do so.
3425: */
3426: if (UNEXPECTED(ce != EG(scope))) {
3427: zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
3428: }
3429: } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
3430: /* Ensure that if we're calling a protected function, we're allowed to do so.
3431: */
3432: if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
3433: zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
3434: }
3435: }
3436: }
3437:
3438: if (EXPECTED(EG(exception) == NULL)) {
3439: zval *retval;
3440:
3441: ALLOC_ZVAL(retval);
3442: Z_OBJVAL_P(retval) = clone_call(obj TSRMLS_CC);
3443: Z_TYPE_P(retval) = IS_OBJECT;
3444: Z_SET_REFCOUNT_P(retval, 1);
3445: Z_SET_ISREF_P(retval);
3446: if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) {
3447: zval_ptr_dtor(&retval);
3448: } else {
3449: AI_SET_PTR(&EX_T(opline->result.var), retval);
3450: }
3451: }
3452: FREE_OP1_IF_VAR();
3453: CHECK_EXCEPTION();
3454: ZEND_VM_NEXT_OPCODE();
3455: }
3456:
3457: ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
3458: {
3459: USE_OPLINE
3460:
3461: SAVE_OPLINE();
3462: if (OP1_TYPE == IS_UNUSED) {
3463: zend_constant *c;
3464: zval *retval;
3465:
3466: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
3467: c = CACHED_PTR(opline->op2.literal->cache_slot);
3468: } else if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
3469: if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
3470: char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
3471: if(!actual) {
3472: actual = Z_STRVAL_P(opline->op2.zv);
3473: } else {
3474: actual++;
3475: }
3476: /* non-qualified constant - allow text substitution */
3477: zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
3478: ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
3479: CHECK_EXCEPTION();
3480: ZEND_VM_NEXT_OPCODE();
3481: } else {
3482: zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
3483: }
3484: } else {
3485: CACHE_PTR(opline->op2.literal->cache_slot, c);
3486: }
3487: retval = &EX_T(opline->result.var).tmp_var;
3488: ZVAL_COPY_VALUE(retval, &c->value);
3489: zval_copy_ctor(retval);
3490: CHECK_EXCEPTION();
3491: ZEND_VM_NEXT_OPCODE();
3492: } else {
3493: /* class constant */
3494: zend_class_entry *ce;
3495: zval **value;
3496:
3497: if (OP1_TYPE == IS_CONST) {
3498: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
3499: value = CACHED_PTR(opline->op2.literal->cache_slot);
3500: ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
3501: zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
3502: CHECK_EXCEPTION();
3503: ZEND_VM_NEXT_OPCODE();
3504: } else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
3505: ce = CACHED_PTR(opline->op1.literal->cache_slot);
3506: } else {
3507: ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), opline->op1.literal + 1, opline->extended_value TSRMLS_CC);
3508: if (UNEXPECTED(EG(exception) != NULL)) {
3509: HANDLE_EXCEPTION();
3510: }
3511: if (UNEXPECTED(ce == NULL)) {
3512: zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op1.zv));
3513: }
3514: CACHE_PTR(opline->op1.literal->cache_slot, ce);
3515: }
3516: } else {
3517: ce = EX_T(opline->op1.var).class_entry;
3518: if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
3519: ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
3520: zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
3521: CHECK_EXCEPTION();
3522: ZEND_VM_NEXT_OPCODE();
3523: }
3524: }
3525:
3526: if (EXPECTED(zend_hash_quick_find(&ce->constants_table, Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void **) &value) == SUCCESS)) {
3527: if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY ||
3528: (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
3529: zend_class_entry *old_scope = EG(scope);
3530:
3531: EG(scope) = ce;
3532: zval_update_constant(value, (void *) 1 TSRMLS_CC);
3533: EG(scope) = old_scope;
3534: }
3535: if (OP1_TYPE == IS_CONST) {
3536: CACHE_PTR(opline->op2.literal->cache_slot, value);
3537: } else {
3538: CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, value);
3539: }
3540: ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
3541: zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
3542: } else {
3543: zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
3544: }
3545:
3546: CHECK_EXCEPTION();
3547: ZEND_VM_NEXT_OPCODE();
3548: }
3549: }
3550:
3551: ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV)
3552: {
3553: USE_OPLINE
3554: zend_free_op free_op1;
3555: zval *expr_ptr;
3556:
3557: SAVE_OPLINE();
3558: if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && opline->extended_value) {
3559: zval **expr_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
3560:
3561: if (OP1_TYPE == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
3562: zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
3563: }
3564: SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
3565: expr_ptr = *expr_ptr_ptr;
3566: Z_ADDREF_P(expr_ptr);
3567: } else {
3568: expr_ptr=GET_OP1_ZVAL_PTR(BP_VAR_R);
3569: if (IS_OP1_TMP_FREE()) { /* temporary variable */
3570: zval *new_expr;
3571:
3572: ALLOC_ZVAL(new_expr);
3573: INIT_PZVAL_COPY(new_expr, expr_ptr);
3574: expr_ptr = new_expr;
3575: } else if (OP1_TYPE == IS_CONST || PZVAL_IS_REF(expr_ptr)) {
3576: zval *new_expr;
3577:
3578: ALLOC_ZVAL(new_expr);
3579: INIT_PZVAL_COPY(new_expr, expr_ptr);
3580: expr_ptr = new_expr;
3581: zendi_zval_copy_ctor(*expr_ptr);
3582: } else {
3583: Z_ADDREF_P(expr_ptr);
3584: }
3585: }
3586:
3587: if (OP2_TYPE != IS_UNUSED) {
3588: zend_free_op free_op2;
3589: zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
3590: ulong hval;
3591:
3592: switch (Z_TYPE_P(offset)) {
3593: case IS_DOUBLE:
3594: hval = zend_dval_to_lval(Z_DVAL_P(offset));
3595: ZEND_VM_C_GOTO(num_index);
3596: case IS_LONG:
3597: case IS_BOOL:
3598: hval = Z_LVAL_P(offset);
3599: ZEND_VM_C_LABEL(num_index):
3600: zend_hash_index_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), hval, &expr_ptr, sizeof(zval *), NULL);
3601: break;
3602: case IS_STRING:
3603: if (OP2_TYPE == IS_CONST) {
3604: hval = Z_HASH_P(offset);
3605: } else {
3606: ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index));
3607: if (IS_INTERNED(Z_STRVAL_P(offset))) {
3608: hval = INTERNED_HASH(Z_STRVAL_P(offset));
3609: } else {
3610: hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
3611: }
3612: }
3613: zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
3614: break;
3615: case IS_NULL:
3616: zend_hash_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
3617: break;
3618: default:
3619: zend_error(E_WARNING, "Illegal offset type");
3620: zval_ptr_dtor(&expr_ptr);
3621: /* do nothing */
3622: break;
3623: }
3624: FREE_OP2();
3625: } else {
3626: zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL);
3627: }
3628: if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && opline->extended_value) {
3629: FREE_OP1_VAR_PTR();
3630: } else {
3631: FREE_OP1_IF_VAR();
3632: }
3633: CHECK_EXCEPTION();
3634: ZEND_VM_NEXT_OPCODE();
3635: }
3636:
3637: ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
3638: {
3639: USE_OPLINE
3640:
3641: array_init(&EX_T(opline->result.var).tmp_var);
3642: if (OP1_TYPE == IS_UNUSED) {
3643: ZEND_VM_NEXT_OPCODE();
3644: #if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED
3645: } else {
3646: ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
3647: #endif
3648: }
3649: }
3650:
3651: ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
3652: {
3653: USE_OPLINE
3654: zend_free_op free_op1;
3655: zval *expr;
3656: zval *result = &EX_T(opline->result.var).tmp_var;
3657:
3658: SAVE_OPLINE();
3659: expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
3660:
3661: if (opline->extended_value != IS_STRING) {
3662: ZVAL_COPY_VALUE(result, expr);
3663: if (!IS_OP1_TMP_FREE()) {
3664: zendi_zval_copy_ctor(*result);
3665: }
3666: }
3667: switch (opline->extended_value) {
3668: case IS_NULL:
3669: convert_to_null(result);
3670: break;
3671: case IS_BOOL:
3672: convert_to_boolean(result);
3673: break;
3674: case IS_LONG:
3675: convert_to_long(result);
3676: break;
3677: case IS_DOUBLE:
3678: convert_to_double(result);
3679: break;
3680: case IS_STRING: {
3681: zval var_copy;
3682: int use_copy;
3683:
3684: zend_make_printable_zval(expr, &var_copy, &use_copy);
3685: if (use_copy) {
3686: ZVAL_COPY_VALUE(result, &var_copy);
3687: if (IS_OP1_TMP_FREE()) {
3688: FREE_OP1();
3689: }
3690: } else {
3691: ZVAL_COPY_VALUE(result, expr);
3692: if (!IS_OP1_TMP_FREE()) {
3693: zendi_zval_copy_ctor(*result);
3694: }
3695: }
3696: break;
3697: }
3698: case IS_ARRAY:
3699: convert_to_array(result);
3700: break;
3701: case IS_OBJECT:
3702: convert_to_object(result);
3703: break;
3704: }
3705: FREE_OP1_IF_VAR();
3706: CHECK_EXCEPTION();
3707: ZEND_VM_NEXT_OPCODE();
3708: }
3709:
3710: ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
3711: {
3712: USE_OPLINE
3713: zend_op_array *new_op_array=NULL;
3714: zend_free_op free_op1;
3715: zval *inc_filename;
3716: zval *tmp_inc_filename = NULL;
3717: zend_bool failure_retval=0;
3718:
3719: SAVE_OPLINE();
3720: inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R);
3721:
3722: if (inc_filename->type!=IS_STRING) {
3723: MAKE_STD_ZVAL(tmp_inc_filename);
3724: ZVAL_COPY_VALUE(tmp_inc_filename, inc_filename);
3725: zval_copy_ctor(tmp_inc_filename);
3726: convert_to_string(tmp_inc_filename);
3727: inc_filename = tmp_inc_filename;
3728: }
3729:
3730: if (opline->extended_value != ZEND_EVAL && strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)) {
3731: if (opline->extended_value == ZEND_INCLUDE_ONCE || opline->extended_value == ZEND_INCLUDE) {
3732: zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
3733: } else {
3734: zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
3735: }
3736: } else {
3737: switch (opline->extended_value) {
3738: case ZEND_INCLUDE_ONCE:
3739: case ZEND_REQUIRE_ONCE: {
3740: zend_file_handle file_handle;
3741: char *resolved_path;
3742:
3743: resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC);
3744: if (resolved_path) {
3745: failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1);
3746: } else {
3747: resolved_path = Z_STRVAL_P(inc_filename);
3748: }
3749:
3750: if (failure_retval) {
3751: /* do nothing, file already included */
3752: } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) {
3753:
3754: if (!file_handle.opened_path) {
3755: file_handle.opened_path = estrdup(resolved_path);
3756: }
3757:
3758: if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
3759: new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
3760: zend_destroy_file_handle(&file_handle TSRMLS_CC);
3761: } else {
3762: zend_file_handle_dtor(&file_handle TSRMLS_CC);
3763: failure_retval=1;
3764: }
3765: } else {
3766: if (opline->extended_value == ZEND_INCLUDE_ONCE) {
3767: zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
3768: } else {
3769: zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
3770: }
3771: }
3772: if (resolved_path != Z_STRVAL_P(inc_filename)) {
3773: efree(resolved_path);
3774: }
3775: }
3776: break;
3777: case ZEND_INCLUDE:
3778: case ZEND_REQUIRE:
3779: new_op_array = compile_filename(opline->extended_value, inc_filename TSRMLS_CC);
3780: break;
3781: case ZEND_EVAL: {
3782: char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
3783:
3784: new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
3785: efree(eval_desc);
3786: }
3787: break;
3788: EMPTY_SWITCH_DEFAULT_CASE()
3789: }
3790: }
3791: if (tmp_inc_filename) {
3792: zval_ptr_dtor(&tmp_inc_filename);
3793: }
3794: FREE_OP1();
3795: if (UNEXPECTED(EG(exception) != NULL)) {
3796: HANDLE_EXCEPTION();
3797: } else if (EXPECTED(new_op_array != NULL)) {
3798: EX(original_return_value) = EG(return_value_ptr_ptr);
3799: EG(active_op_array) = new_op_array;
3800: if (RETURN_VALUE_USED(opline)) {
3801: EX_T(opline->result.var).var.ptr = NULL;
3802: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
3803: EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr;
3804: } else {
3805: EG(return_value_ptr_ptr) = NULL;
3806: }
3807:
3808: EX(current_object) = EX(object);
3809:
3810: EX(function_state).function = (zend_function *) new_op_array;
3811: EX(object) = NULL;
3812:
3813: if (!EG(active_symbol_table)) {
3814: zend_rebuild_symbol_table(TSRMLS_C);
3815: }
3816:
3817: if (EXPECTED(zend_execute == execute)) {
3818: ZEND_VM_ENTER();
3819: } else {
3820: zend_execute(new_op_array TSRMLS_CC);
3821: }
3822:
3823: EX(function_state).function = (zend_function *) EX(op_array);
3824: EX(object) = EX(current_object);
3825:
3826: EG(opline_ptr) = &EX(opline);
3827: EG(active_op_array) = EX(op_array);
3828: EG(return_value_ptr_ptr) = EX(original_return_value);
3829: destroy_op_array(new_op_array TSRMLS_CC);
3830: efree(new_op_array);
3831: if (UNEXPECTED(EG(exception) != NULL)) {
3832: zend_throw_exception_internal(NULL TSRMLS_CC);
3833: HANDLE_EXCEPTION();
3834: } else if (RETURN_VALUE_USED(opline)) {
3835: if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
3836: zval *retval;
3837:
3838: ALLOC_ZVAL(retval);
3839: ZVAL_BOOL(retval, 1);
3840: INIT_PZVAL(retval);
3841: EX_T(opline->result.var).var.ptr = retval;
3842: }
3843: }
3844:
3845: } else if (RETURN_VALUE_USED(opline)) {
3846: zval *retval;
3847:
3848: ALLOC_ZVAL(retval);
3849: ZVAL_BOOL(retval, failure_retval);
3850: INIT_PZVAL(retval);
3851: AI_SET_PTR(&EX_T(opline->result.var), retval);
3852: }
3853: ZEND_VM_NEXT_OPCODE();
3854: }
3855:
3856: ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
3857: {
3858: USE_OPLINE
3859: zval tmp, *varname;
3860: HashTable *target_symbol_table;
3861: zend_free_op free_op1;
3862:
3863: SAVE_OPLINE();
3864: if (OP1_TYPE == IS_CV &&
3865: OP2_TYPE == IS_UNUSED &&
3866: (opline->extended_value & ZEND_QUICK_SET)) {
3867: if (EG(active_symbol_table)) {
3868: zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.var);
3869:
3870: zend_delete_variable(EX(prev_execute_data), EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value TSRMLS_CC);
3871: EX_CV(opline->op1.var) = NULL;
3872: } else if (EX_CV(opline->op1.var)) {
3873: zval_ptr_dtor(EX_CV(opline->op1.var));
3874: EX_CV(opline->op1.var) = NULL;
3875: }
3876: CHECK_EXCEPTION();
3877: ZEND_VM_NEXT_OPCODE();
3878: }
3879:
3880: varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
3881:
3882: if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
3883: ZVAL_COPY_VALUE(&tmp, varname);
3884: zval_copy_ctor(&tmp);
3885: convert_to_string(&tmp);
3886: varname = &tmp;
3887: } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
3888: Z_ADDREF_P(varname);
3889: }
3890:
3891: if (OP2_TYPE != IS_UNUSED) {
3892: zend_class_entry *ce;
3893:
3894: if (OP2_TYPE == IS_CONST) {
3895: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
3896: ce = CACHED_PTR(opline->op2.literal->cache_slot);
3897: } else {
3898: ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
3899: if (UNEXPECTED(EG(exception) != NULL)) {
3900: if (OP1_TYPE != IS_CONST && varname == &tmp) {
3901: zval_dtor(&tmp);
3902: } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
3903: zval_ptr_dtor(&varname);
3904: }
3905: FREE_OP1();
3906: HANDLE_EXCEPTION();
3907: }
3908: if (UNEXPECTED(ce == NULL)) {
3909: zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op2.zv));
3910: }
3911: CACHE_PTR(opline->op2.literal->cache_slot, ce);
3912: }
3913: } else {
3914: ce = EX_T(opline->op2.var).class_entry;
3915: }
3916: zend_std_unset_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
3917: } else {
3918: ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
3919:
3920: target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
3921: zend_delete_variable(EXECUTE_DATA, target_symbol_table, varname->value.str.val, varname->value.str.len+1, hash_value TSRMLS_CC);
3922: }
3923:
3924: if (OP1_TYPE != IS_CONST && varname == &tmp) {
3925: zval_dtor(&tmp);
3926: } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
3927: zval_ptr_dtor(&varname);
3928: }
3929: FREE_OP1();
3930: CHECK_EXCEPTION();
3931: ZEND_VM_NEXT_OPCODE();
3932: }
3933:
3934: ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
3935: {
3936: USE_OPLINE
3937: zend_free_op free_op1, free_op2;
3938: zval **container;
3939: zval *offset;
3940: ulong hval;
3941:
3942: SAVE_OPLINE();
3943: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
3944: if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
3945: SEPARATE_ZVAL_IF_NOT_REF(container);
3946: }
3947: offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
3948:
3949: if (OP1_TYPE != IS_VAR || container) {
3950: switch (Z_TYPE_PP(container)) {
3951: case IS_ARRAY: {
3952: HashTable *ht = Z_ARRVAL_PP(container);
3953:
3954: switch (Z_TYPE_P(offset)) {
3955: case IS_DOUBLE:
3956: hval = zend_dval_to_lval(Z_DVAL_P(offset));
3957: zend_hash_index_del(ht, hval);
3958: break;
3959: case IS_RESOURCE:
3960: case IS_BOOL:
3961: case IS_LONG:
3962: hval = Z_LVAL_P(offset);
3963: zend_hash_index_del(ht, hval);
3964: break;
3965: case IS_STRING:
3966: if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
3967: Z_ADDREF_P(offset);
3968: }
3969: if (OP2_TYPE == IS_CONST) {
3970: hval = Z_HASH_P(offset);
3971: } else {
3972: ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_dim));
3973: if (IS_INTERNED(Z_STRVAL_P(offset))) {
3974: hval = INTERNED_HASH(Z_STRVAL_P(offset));
3975: } else {
3976: hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
3977: }
3978: }
3979: if (ht == &EG(symbol_table)) {
3980: zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC);
3981: } else {
3982: zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval);
3983: }
3984: if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
3985: zval_ptr_dtor(&offset);
3986: }
3987: break;
3988: ZEND_VM_C_LABEL(num_index_dim):
3989: zend_hash_index_del(ht, hval);
3990: if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
3991: zval_ptr_dtor(&offset);
3992: }
3993: break;
3994: case IS_NULL:
3995: zend_hash_del(ht, "", sizeof(""));
3996: break;
3997: default:
3998: zend_error(E_WARNING, "Illegal offset type in unset");
3999: break;
4000: }
4001: FREE_OP2();
4002: break;
4003: }
4004: case IS_OBJECT:
4005: if (UNEXPECTED(Z_OBJ_HT_P(*container)->unset_dimension == NULL)) {
4006: zend_error_noreturn(E_ERROR, "Cannot use object as array");
4007: }
4008: if (IS_OP2_TMP_FREE()) {
4009: MAKE_REAL_ZVAL_PTR(offset);
4010: }
4011: Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
4012: if (IS_OP2_TMP_FREE()) {
4013: zval_ptr_dtor(&offset);
4014: } else {
4015: FREE_OP2();
4016: }
4017: break;
4018: case IS_STRING:
4019: zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
4020: ZEND_VM_CONTINUE(); /* bailed out before */
4021: default:
4022: FREE_OP2();
4023: break;
4024: }
4025: } else {
4026: FREE_OP2();
4027: }
4028: FREE_OP1_VAR_PTR();
4029:
4030: CHECK_EXCEPTION();
4031: ZEND_VM_NEXT_OPCODE();
4032: }
4033:
4034: ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4035: {
4036: USE_OPLINE
4037: zend_free_op free_op1, free_op2;
4038: zval **container;
4039: zval *offset;
4040:
4041: SAVE_OPLINE();
4042: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
4043: offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
4044:
4045: if (OP1_TYPE != IS_VAR || container) {
4046: if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
4047: SEPARATE_ZVAL_IF_NOT_REF(container);
4048: }
4049: if (Z_TYPE_PP(container) == IS_OBJECT) {
4050: if (IS_OP2_TMP_FREE()) {
4051: MAKE_REAL_ZVAL_PTR(offset);
4052: }
4053: if (Z_OBJ_HT_P(*container)->unset_property) {
4054: Z_OBJ_HT_P(*container)->unset_property(*container, offset, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
4055: } else {
4056: zend_error(E_NOTICE, "Trying to unset property of non-object");
4057: }
4058: if (IS_OP2_TMP_FREE()) {
4059: zval_ptr_dtor(&offset);
4060: } else {
4061: FREE_OP2();
4062: }
4063: } else {
4064: FREE_OP2();
4065: }
4066: } else {
4067: FREE_OP2();
4068: }
4069: FREE_OP1_VAR_PTR();
4070:
4071: CHECK_EXCEPTION();
4072: ZEND_VM_NEXT_OPCODE();
4073: }
4074:
4075: ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
4076: {
4077: USE_OPLINE
4078: zend_free_op free_op1;
4079: zval *array_ptr, **array_ptr_ptr;
4080: HashTable *fe_ht;
4081: zend_object_iterator *iter = NULL;
4082: zend_class_entry *ce = NULL;
4083: zend_bool is_empty = 0;
4084:
4085: SAVE_OPLINE();
4086:
4087: if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
4088: (opline->extended_value & ZEND_FE_RESET_VARIABLE)) {
4089: array_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
4090: if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
4091: MAKE_STD_ZVAL(array_ptr);
4092: ZVAL_NULL(array_ptr);
4093: } else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
4094: if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
4095: zend_error(E_WARNING, "foreach() cannot iterate over objects without PHP class");
4096: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4097: }
4098:
4099: ce = Z_OBJCE_PP(array_ptr_ptr);
4100: if (!ce || ce->get_iterator == NULL) {
4101: SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
4102: Z_ADDREF_PP(array_ptr_ptr);
4103: }
4104: array_ptr = *array_ptr_ptr;
4105: } else {
4106: if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
4107: SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
4108: if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
4109: Z_SET_ISREF_PP(array_ptr_ptr);
4110: }
4111: }
4112: array_ptr = *array_ptr_ptr;
4113: Z_ADDREF_P(array_ptr);
4114: }
4115: } else {
4116: array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4117: if (IS_OP1_TMP_FREE()) { /* IS_TMP_VAR */
4118: zval *tmp;
4119:
4120: ALLOC_ZVAL(tmp);
4121: INIT_PZVAL_COPY(tmp, array_ptr);
4122: array_ptr = tmp;
4123: if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
4124: ce = Z_OBJCE_P(array_ptr);
4125: if (ce && ce->get_iterator) {
4126: Z_DELREF_P(array_ptr);
4127: }
4128: }
4129: } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
4130: ce = Z_OBJCE_P(array_ptr);
4131: if (!ce || !ce->get_iterator) {
4132: Z_ADDREF_P(array_ptr);
4133: }
4134: } else if (OP1_TYPE == IS_CONST ||
4135: ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
4136: !Z_ISREF_P(array_ptr) &&
4137: Z_REFCOUNT_P(array_ptr) > 1)) {
4138: zval *tmp;
4139:
4140: ALLOC_ZVAL(tmp);
4141: INIT_PZVAL_COPY(tmp, array_ptr);
4142: zval_copy_ctor(tmp);
4143: array_ptr = tmp;
4144: } else {
4145: Z_ADDREF_P(array_ptr);
4146: }
4147: }
4148:
4149: if (ce && ce->get_iterator) {
4150: iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC);
4151:
4152: if (iter && EXPECTED(EG(exception) == NULL)) {
4153: array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
4154: } else {
4155: FREE_OP1_IF_VAR();
4156: if (!EG(exception)) {
4157: zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
4158: }
4159: zend_throw_exception_internal(NULL TSRMLS_CC);
4160: HANDLE_EXCEPTION();
4161: }
4162: }
4163:
4164: EX_T(opline->result.var).fe.ptr = array_ptr;
4165:
4166: if (iter) {
4167: iter->index = 0;
4168: if (iter->funcs->rewind) {
4169: iter->funcs->rewind(iter TSRMLS_CC);
4170: if (UNEXPECTED(EG(exception) != NULL)) {
4171: zval_ptr_dtor(&array_ptr);
4172: FREE_OP1_IF_VAR();
4173: HANDLE_EXCEPTION();
4174: }
4175: }
4176: is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
4177: if (UNEXPECTED(EG(exception) != NULL)) {
4178: zval_ptr_dtor(&array_ptr);
4179: FREE_OP1_IF_VAR();
4180: HANDLE_EXCEPTION();
4181: }
4182: iter->index = -1; /* will be set to 0 before using next handler */
4183: } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
4184: zend_hash_internal_pointer_reset(fe_ht);
4185: if (ce) {
4186: zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC);
4187: while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
4188: char *str_key;
4189: uint str_key_len;
4190: ulong int_key;
4191: zend_uchar key_type;
4192:
4193: key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
4194: if (key_type != HASH_KEY_NON_EXISTANT &&
4195: (key_type == HASH_KEY_IS_LONG ||
4196: zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
4197: break;
4198: }
4199: zend_hash_move_forward(fe_ht);
4200: }
4201: }
4202: is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
4203: zend_hash_get_pointer(fe_ht, &EX_T(opline->result.var).fe.fe_pos);
4204: } else {
4205: zend_error(E_WARNING, "Invalid argument supplied for foreach()");
4206: is_empty = 1;
4207: }
4208:
4209: FREE_OP1_IF_VAR();
4210: if (is_empty) {
4211: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4212: } else {
4213: CHECK_EXCEPTION();
4214: ZEND_VM_NEXT_OPCODE();
4215: }
4216: }
4217:
4218: ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
4219: {
4220: USE_OPLINE
4221: zend_free_op free_op1;
4222: zval *array = EX_T(opline->op1.var).fe.ptr;
4223: zval **value;
4224: char *str_key;
4225: uint str_key_len;
4226: ulong int_key;
4227: HashTable *fe_ht;
4228: zend_object_iterator *iter = NULL;
4229: int key_type = 0;
4230: zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
4231:
4232: SAVE_OPLINE();
4233:
4234: switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
4235: default:
4236: case ZEND_ITER_INVALID:
4237: zend_error(E_WARNING, "Invalid argument supplied for foreach()");
4238: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4239:
4240: case ZEND_ITER_PLAIN_OBJECT: {
4241: const char *class_name, *prop_name;
4242: zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
4243:
4244: fe_ht = Z_OBJPROP_P(array);
4245: zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
4246: do {
4247: if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
4248: /* reached end of iteration */
4249: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4250: }
4251: key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
4252:
4253: zend_hash_move_forward(fe_ht);
4254: } while (key_type == HASH_KEY_NON_EXISTANT ||
4255: (key_type != HASH_KEY_IS_LONG &&
4256: zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
4257: zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
4258: if (use_key && key_type != HASH_KEY_IS_LONG) {
4259: zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
4260: str_key_len = strlen(prop_name);
4261: str_key = estrndup(prop_name, str_key_len);
4262: str_key_len++;
4263: }
4264: break;
4265: }
4266:
4267: case ZEND_ITER_PLAIN_ARRAY:
4268: fe_ht = Z_ARRVAL_P(array);
4269: zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
4270: if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
4271: /* reached end of iteration */
4272: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4273: }
4274: if (use_key) {
4275: key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
4276: }
4277: zend_hash_move_forward(fe_ht);
4278: zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
4279: break;
4280:
4281: case ZEND_ITER_OBJECT:
4282: /* !iter happens from exception */
4283: if (iter && ++iter->index > 0) {
4284: /* This could cause an endless loop if index becomes zero again.
4285: * In case that ever happens we need an additional flag. */
4286: iter->funcs->move_forward(iter TSRMLS_CC);
4287: if (UNEXPECTED(EG(exception) != NULL)) {
4288: zval_ptr_dtor(&array);
4289: HANDLE_EXCEPTION();
4290: }
4291: }
4292: /* If index is zero we come from FE_RESET and checked valid() already. */
4293: if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) {
4294: /* reached end of iteration */
4295: if (UNEXPECTED(EG(exception) != NULL)) {
4296: zval_ptr_dtor(&array);
4297: HANDLE_EXCEPTION();
4298: }
4299: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4300: }
4301: iter->funcs->get_current_data(iter, &value TSRMLS_CC);
4302: if (UNEXPECTED(EG(exception) != NULL)) {
4303: zval_ptr_dtor(&array);
4304: HANDLE_EXCEPTION();
4305: }
4306: if (!value) {
4307: /* failure in get_current_data */
4308: ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
4309: }
4310: if (use_key) {
4311: if (iter->funcs->get_current_key) {
4312: key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
4313: if (UNEXPECTED(EG(exception) != NULL)) {
4314: zval_ptr_dtor(&array);
4315: HANDLE_EXCEPTION();
4316: }
4317: } else {
4318: key_type = HASH_KEY_IS_LONG;
4319: int_key = iter->index;
4320: }
4321: }
4322: break;
4323: }
4324:
4325: if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
4326: SEPARATE_ZVAL_IF_NOT_REF(value);
4327: Z_SET_ISREF_PP(value);
4328: EX_T(opline->result.var).var.ptr_ptr = value;
4329: Z_ADDREF_PP(value);
4330: } else {
4331: PZVAL_LOCK(*value);
4332: AI_SET_PTR(&EX_T(opline->result.var), *value);
4333: }
4334:
4335: if (use_key) {
4336: zval *key = &EX_T((opline+1)->result.var).tmp_var;
4337:
4338: switch (key_type) {
4339: case HASH_KEY_IS_STRING:
4340: Z_STRVAL_P(key) = (char*)str_key;
4341: Z_STRLEN_P(key) = str_key_len-1;
4342: Z_TYPE_P(key) = IS_STRING;
4343: break;
4344: case HASH_KEY_IS_LONG:
4345: Z_LVAL_P(key) = int_key;
4346: Z_TYPE_P(key) = IS_LONG;
4347: break;
4348: default:
4349: case HASH_KEY_NON_EXISTANT:
4350: ZVAL_NULL(key);
4351: break;
4352: }
4353: }
4354:
4355: CHECK_EXCEPTION();
4356: ZEND_VM_INC_OPCODE();
4357: ZEND_VM_NEXT_OPCODE();
4358: }
4359:
4360: ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
4361: {
4362: USE_OPLINE
4363: zval **value;
4364: zend_bool isset = 1;
4365:
4366: SAVE_OPLINE();
4367: if (OP1_TYPE == IS_CV &&
4368: OP2_TYPE == IS_UNUSED &&
4369: (opline->extended_value & ZEND_QUICK_SET)) {
4370: if (EX_CV(opline->op1.var)) {
4371: value = EX_CV(opline->op1.var);
4372: } else if (EG(active_symbol_table)) {
4373: zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.var);
4374:
4375: if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
4376: isset = 0;
4377: }
4378: } else {
4379: isset = 0;
4380: }
4381: } else {
4382: HashTable *target_symbol_table;
4383: zend_free_op free_op1;
4384: zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
4385:
4386: if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
4387: ZVAL_COPY_VALUE(&tmp, varname);
4388: zval_copy_ctor(&tmp);
4389: convert_to_string(&tmp);
4390: varname = &tmp;
4391: }
4392:
4393: if (OP2_TYPE != IS_UNUSED) {
4394: zend_class_entry *ce;
4395:
4396: if (OP2_TYPE == IS_CONST) {
4397: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
4398: ce = CACHED_PTR(opline->op2.literal->cache_slot);
4399: } else {
4400: ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
4401: if (UNEXPECTED(ce == NULL)) {
4402: CHECK_EXCEPTION();
4403: ZEND_VM_NEXT_OPCODE();
4404: }
4405: CACHE_PTR(opline->op2.literal->cache_slot, ce);
4406: }
4407: } else {
4408: ce = EX_T(opline->op2.var).class_entry;
4409: }
4410: value = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1, ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
4411: if (!value) {
4412: isset = 0;
4413: }
4414: } else {
4415: target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
4416: if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
4417: isset = 0;
4418: }
4419: }
4420:
4421: if (OP1_TYPE != IS_CONST && varname == &tmp) {
4422: zval_dtor(&tmp);
4423: }
4424: FREE_OP1();
4425: }
4426:
4427: if (opline->extended_value & ZEND_ISSET) {
4428: if (isset && Z_TYPE_PP(value) != IS_NULL) {
4429: ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1);
4430: } else {
4431: ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0);
4432: }
4433: } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
4434: if (!isset || !i_zend_is_true(*value)) {
4435: ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1);
4436: } else {
4437: ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0);
4438: }
4439: }
4440:
4441: CHECK_EXCEPTION();
4442: ZEND_VM_NEXT_OPCODE();
4443: }
4444:
4445: ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|TMP|VAR|CV, int prop_dim)
4446: {
4447: USE_OPLINE
4448: zend_free_op free_op1, free_op2;
4449: zval **container;
4450: zval **value = NULL;
4451: int result = 0;
4452: ulong hval;
4453: zval *offset;
4454:
4455: SAVE_OPLINE();
4456: container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_IS);
4457:
4458: offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
4459:
4460: if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
4461: HashTable *ht;
4462: int isset = 0;
4463:
4464: ht = Z_ARRVAL_PP(container);
4465:
4466: switch (Z_TYPE_P(offset)) {
4467: case IS_DOUBLE:
4468: hval = zend_dval_to_lval(Z_DVAL_P(offset));
4469: ZEND_VM_C_GOTO(num_index_prop);
4470: case IS_RESOURCE:
4471: case IS_BOOL:
4472: case IS_LONG:
4473: hval = Z_LVAL_P(offset);
4474: ZEND_VM_C_LABEL(num_index_prop):
4475: if (zend_hash_index_find(ht, hval, (void **) &value) == SUCCESS) {
4476: isset = 1;
4477: }
4478: break;
4479: case IS_STRING:
4480: if (OP2_TYPE == IS_CONST) {
4481: hval = Z_HASH_P(offset);
4482: } else {
4483: if (!prop_dim) {
4484: ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop));
4485: }
4486: if (IS_INTERNED(Z_STRVAL_P(offset))) {
4487: hval = INTERNED_HASH(Z_STRVAL_P(offset));
4488: } else {
4489: hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
4490: }
4491: }
4492: if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
4493: isset = 1;
4494: }
4495: break;
4496: case IS_NULL:
4497: if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
4498: isset = 1;
4499: }
4500: break;
4501: default:
4502: zend_error(E_WARNING, "Illegal offset type in isset or empty");
4503: break;
4504: }
4505:
4506: if (opline->extended_value & ZEND_ISSET) {
4507: if (isset && Z_TYPE_PP(value) == IS_NULL) {
4508: result = 0;
4509: } else {
4510: result = isset;
4511: }
4512: } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
4513: if (!isset || !i_zend_is_true(*value)) {
4514: result = 0;
4515: } else {
4516: result = 1;
4517: }
4518: }
4519: FREE_OP2();
4520: } else if (Z_TYPE_PP(container) == IS_OBJECT) {
4521: if (IS_OP2_TMP_FREE()) {
4522: MAKE_REAL_ZVAL_PTR(offset);
4523: }
4524: if (prop_dim) {
4525: if (Z_OBJ_HT_P(*container)->has_property) {
4526: result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
4527: } else {
4528: zend_error(E_NOTICE, "Trying to check property of non-object");
4529: result = 0;
4530: }
4531: } else {
4532: if (Z_OBJ_HT_P(*container)->has_dimension) {
4533: result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
4534: } else {
4535: zend_error(E_NOTICE, "Trying to check element of non-array");
4536: result = 0;
4537: }
4538: }
4539: if (IS_OP2_TMP_FREE()) {
4540: zval_ptr_dtor(&offset);
4541: } else {
4542: FREE_OP2();
4543: }
4544: } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
4545: zval tmp;
4546:
4547: if (Z_TYPE_P(offset) != IS_LONG) {
4548: if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */
4549: || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
4550: && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
4551: ZVAL_COPY_VALUE(&tmp, offset);
4552: zval_copy_ctor(&tmp);
4553: convert_to_long(&tmp);
4554: offset = &tmp;
4555: } else {
4556: /* can not be converted to proper offset, return "not set" */
4557: result = 0;
4558: }
4559: }
4560: if (Z_TYPE_P(offset) == IS_LONG) {
4561: if (opline->extended_value & ZEND_ISSET) {
4562: if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
4563: result = 1;
4564: }
4565: } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
4566: if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
4567: result = 1;
4568: }
4569: }
4570: }
4571: FREE_OP2();
4572: } else {
4573: FREE_OP2();
4574: }
4575:
4576: Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL;
4577: if (opline->extended_value & ZEND_ISSET) {
4578: Z_LVAL(EX_T(opline->result.var).tmp_var) = result;
4579: } else {
4580: Z_LVAL(EX_T(opline->result.var).tmp_var) = !result;
4581: }
4582:
4583: FREE_OP1_VAR_PTR();
4584:
4585: CHECK_EXCEPTION();
4586: ZEND_VM_NEXT_OPCODE();
4587: }
4588:
4589: ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4590: {
4591: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, prop_dim, 0);
4592: }
4593:
4594: ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
4595: {
4596: ZEND_VM_DISPATCH_TO_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, prop_dim, 1);
4597: }
4598:
4599: ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMP|VAR|UNUSED|CV, ANY)
4600: {
4601: #if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
4602: USE_OPLINE
4603:
4604: SAVE_OPLINE();
4605: if (OP1_TYPE != IS_UNUSED) {
4606: zend_free_op free_op1;
4607: zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4608:
4609: if (Z_TYPE_P(ptr) == IS_LONG) {
4610: EG(exit_status) = Z_LVAL_P(ptr);
4611: } else {
4612: zend_print_variable(ptr);
4613: }
4614: FREE_OP1();
4615: }
4616: #endif
4617: zend_bailout();
4618: ZEND_VM_NEXT_OPCODE(); /* Never reached */
4619: }
4620:
4621: ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
4622: {
4623: USE_OPLINE
4624:
4625: SAVE_OPLINE();
4626: Z_LVAL(EX_T(opline->result.var).tmp_var) = EG(error_reporting);
4627: Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_LONG; /* shouldn't be necessary */
4628: if (EX(old_error_reporting) == NULL) {
4629: EX(old_error_reporting) = &EX_T(opline->result.var).tmp_var;
4630: }
4631:
4632: if (EG(error_reporting)) {
4633: do {
4634: EG(error_reporting) = 0;
4635: if (!EG(error_reporting_ini_entry)) {
4636: if (UNEXPECTED(zend_hash_find(EG(ini_directives), "error_reporting", sizeof("error_reporting"), (void **) &EG(error_reporting_ini_entry)) == FAILURE)) {
4637: break;
4638: }
4639: }
4640: if (!EG(error_reporting_ini_entry)->modified) {
4641: if (!EG(modified_ini_directives)) {
4642: ALLOC_HASHTABLE(EG(modified_ini_directives));
4643: zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
4644: }
4645: if (EXPECTED(zend_hash_add(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting"), &EG(error_reporting_ini_entry), sizeof(zend_ini_entry*), NULL) == SUCCESS)) {
4646: EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
4647: EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length;
4648: EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
4649: EG(error_reporting_ini_entry)->modified = 1;
4650: }
4651: } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
4652: efree(EG(error_reporting_ini_entry)->value);
4653: }
4654: EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1);
4655: EG(error_reporting_ini_entry)->value_length = sizeof("0")-1;
4656: } while (0);
4657: }
4658: CHECK_EXCEPTION();
4659: ZEND_VM_NEXT_OPCODE();
4660: }
4661:
4662: ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
4663: {
4664: SAVE_OPLINE();
4665: zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name, EX(op_array)->function_name);
4666: ZEND_VM_NEXT_OPCODE(); /* Never reached */
4667: }
4668:
4669: ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
4670: {
4671: USE_OPLINE
4672: zval restored_error_reporting;
4673:
4674: SAVE_OPLINE();
4675: if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.var).tmp_var) != 0) {
4676: Z_TYPE(restored_error_reporting) = IS_LONG;
4677: Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.var).tmp_var);
4678: EG(error_reporting) = Z_LVAL(restored_error_reporting);
4679: convert_to_string(&restored_error_reporting);
4680: if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
4681: if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
4682: EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
4683: efree(EG(error_reporting_ini_entry)->value);
4684: }
4685: EG(error_reporting_ini_entry)->value = Z_STRVAL(restored_error_reporting);
4686: EG(error_reporting_ini_entry)->value_length = Z_STRLEN(restored_error_reporting);
4687: } else {
4688: zendi_zval_dtor(restored_error_reporting);
4689: }
4690: }
4691: if (EX(old_error_reporting) == &EX_T(opline->op1.var).tmp_var) {
4692: EX(old_error_reporting) = NULL;
4693: }
4694: CHECK_EXCEPTION();
4695: ZEND_VM_NEXT_OPCODE();
4696: }
4697:
4698: ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY)
4699: {
4700: USE_OPLINE
4701: zend_free_op free_op1;
4702: zval *value;
4703:
4704: SAVE_OPLINE();
4705: value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4706:
4707: if (i_zend_is_true(value)) {
4708: ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
4709: if (!IS_OP1_TMP_FREE()) {
4710: zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var);
4711: }
4712: FREE_OP1_IF_VAR();
4713: #if DEBUG_ZEND>=2
4714: printf("Conditional jmp to %d\n", opline->op2.opline_num);
4715: #endif
4716: ZEND_VM_JMP(opline->op2.jmp_addr);
4717: }
4718:
4719: FREE_OP1();
4720: CHECK_EXCEPTION();
4721: ZEND_VM_NEXT_OPCODE();
4722: }
4723:
4724: ZEND_VM_HANDLER(158, ZEND_JMP_SET_VAR, CONST|TMP|VAR|CV, ANY)
4725: {
4726: USE_OPLINE
4727: zend_free_op free_op1;
4728: zval *value, *ret;
4729:
4730: SAVE_OPLINE();
4731: value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4732:
4733: if (i_zend_is_true(value)) {
4734: if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
4735: Z_ADDREF_P(value);
4736: EX_T(opline->result.var).var.ptr = value;
4737: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
4738: } else {
4739: ALLOC_ZVAL(ret);
4740: INIT_PZVAL_COPY(ret, value);
4741: EX_T(opline->result.var).var.ptr = ret;
4742: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
4743: if (!IS_OP1_TMP_FREE()) {
4744: zval_copy_ctor(EX_T(opline->result.var).var.ptr);
4745: }
4746: }
4747: FREE_OP1_IF_VAR();
4748: #if DEBUG_ZEND>=2
4749: printf("Conditional jmp to %d\n", opline->op2.opline_num);
4750: #endif
4751: ZEND_VM_JMP(opline->op2.jmp_addr);
4752: }
4753:
4754: FREE_OP1();
4755: CHECK_EXCEPTION();
4756: ZEND_VM_NEXT_OPCODE();
4757: }
4758:
4759: ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
4760: {
4761: USE_OPLINE
4762: zend_free_op free_op1;
4763: zval *value;
4764:
4765: SAVE_OPLINE();
4766: value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4767:
4768: ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
4769: if (!IS_OP1_TMP_FREE()) {
4770: zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
4771: }
4772: FREE_OP1_IF_VAR();
4773: CHECK_EXCEPTION();
4774: ZEND_VM_NEXT_OPCODE();
4775: }
4776:
4777: ZEND_VM_HANDLER(157, ZEND_QM_ASSIGN_VAR, CONST|TMP|VAR|CV, ANY)
4778: {
4779: USE_OPLINE
4780: zend_free_op free_op1;
4781: zval *value, *ret;
4782:
4783: SAVE_OPLINE();
4784: value = GET_OP1_ZVAL_PTR(BP_VAR_R);
4785:
4786: if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
4787: Z_ADDREF_P(value);
4788: EX_T(opline->result.var).var.ptr = value;
4789: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
4790: } else {
4791: ALLOC_ZVAL(ret);
4792: INIT_PZVAL_COPY(ret, value);
4793: EX_T(opline->result.var).var.ptr = ret;
4794: EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
4795: if (!IS_OP1_TMP_FREE()) {
4796: zval_copy_ctor(EX_T(opline->result.var).var.ptr);
4797: }
4798: }
4799:
4800: FREE_OP1_IF_VAR();
4801: CHECK_EXCEPTION();
4802: ZEND_VM_NEXT_OPCODE();
4803: }
4804:
4805: ZEND_VM_HANDLER(101, ZEND_EXT_STMT, ANY, ANY)
4806: {
4807: SAVE_OPLINE();
4808: if (!EG(no_extensions)) {
4809: zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(op_array) TSRMLS_CC);
4810: }
4811: CHECK_EXCEPTION();
4812: ZEND_VM_NEXT_OPCODE();
4813: }
4814:
4815: ZEND_VM_HANDLER(102, ZEND_EXT_FCALL_BEGIN, ANY, ANY)
4816: {
4817: SAVE_OPLINE();
4818: if (!EG(no_extensions)) {
4819: zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(op_array) TSRMLS_CC);
4820: }
4821: CHECK_EXCEPTION();
4822: ZEND_VM_NEXT_OPCODE();
4823: }
4824:
4825: ZEND_VM_HANDLER(103, ZEND_EXT_FCALL_END, ANY, ANY)
4826: {
4827: SAVE_OPLINE();
4828: if (!EG(no_extensions)) {
4829: zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(op_array) TSRMLS_CC);
4830: }
4831: CHECK_EXCEPTION();
4832: ZEND_VM_NEXT_OPCODE();
4833: }
4834:
4835: ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, ANY, ANY)
4836: {
4837: USE_OPLINE
4838:
4839: SAVE_OPLINE();
4840: EX_T(opline->result.var).class_entry = do_bind_class(EX(op_array), opline, EG(class_table), 0 TSRMLS_CC);
4841: CHECK_EXCEPTION();
4842: ZEND_VM_NEXT_OPCODE();
4843: }
4844:
4845: ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY)
4846: {
4847: USE_OPLINE
4848:
4849: SAVE_OPLINE();
4850: EX_T(opline->result.var).class_entry = do_bind_inherited_class(EX(op_array), opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
4851: CHECK_EXCEPTION();
4852: ZEND_VM_NEXT_OPCODE();
4853: }
4854:
4855: ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY)
4856: {
4857: USE_OPLINE
4858: zend_class_entry **pce, **pce_orig;
4859:
4860: SAVE_OPLINE();
4861: if (zend_hash_quick_find(EG(class_table), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void**)&pce) == FAILURE ||
4862: (zend_hash_quick_find(EG(class_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), Z_HASH_P(opline->op1.zv), (void**)&pce_orig) == SUCCESS &&
4863: *pce != *pce_orig)) {
4864: do_bind_inherited_class(EX(op_array), opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
4865: }
4866: CHECK_EXCEPTION();
4867: ZEND_VM_NEXT_OPCODE();
4868: }
4869:
4870: ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY)
4871: {
4872: USE_OPLINE
4873:
4874: SAVE_OPLINE();
4875: do_bind_function(EX(op_array), opline, EG(function_table), 0);
4876: CHECK_EXCEPTION();
4877: ZEND_VM_NEXT_OPCODE();
4878: }
4879:
4880: ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY)
4881: {
4882: USE_OPLINE
4883:
4884: SAVE_OPLINE();
4885: if (++EG(ticks_count)>=opline->extended_value) {
4886: EG(ticks_count)=0;
4887: if (zend_ticks_function) {
4888: zend_ticks_function(opline->extended_value);
4889: }
4890: }
4891: CHECK_EXCEPTION();
4892: ZEND_VM_NEXT_OPCODE();
4893: }
4894:
4895: ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
4896: {
4897: USE_OPLINE
4898: zend_free_op free_op1;
4899: zval *expr;
4900: zend_bool result;
4901:
4902: SAVE_OPLINE();
4903: expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4904:
4905: if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
4906: result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
4907: } else {
4908: result = 0;
4909: }
4910: ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, result);
4911: FREE_OP1();
4912: CHECK_EXCEPTION();
4913: ZEND_VM_NEXT_OPCODE();
4914: }
4915:
4916: ZEND_VM_HANDLER(104, ZEND_EXT_NOP, ANY, ANY)
4917: {
4918: ZEND_VM_NEXT_OPCODE();
4919: }
4920:
4921: ZEND_VM_HANDLER(0, ZEND_NOP, ANY, ANY)
4922: {
4923: ZEND_VM_NEXT_OPCODE();
4924: }
4925:
4926: ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST)
4927: {
4928: USE_OPLINE
4929: zend_class_entry *ce = EX_T(opline->op1.var).class_entry;
4930: zend_class_entry *iface;
4931:
4932: SAVE_OPLINE();
4933: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
4934: iface = CACHED_PTR(opline->op2.literal->cache_slot);
4935: } else {
4936: iface = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, opline->extended_value TSRMLS_CC);
4937: if (UNEXPECTED(iface == NULL)) {
4938: CHECK_EXCEPTION();
4939: ZEND_VM_NEXT_OPCODE();
4940: }
4941: CACHE_PTR(opline->op2.literal->cache_slot, iface);
4942: }
4943:
4944: if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) {
4945: zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name);
4946: }
4947: zend_do_implement_interface(ce, iface TSRMLS_CC);
4948:
4949: CHECK_EXCEPTION();
4950: ZEND_VM_NEXT_OPCODE();
4951: }
4952:
4953: ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY)
4954: {
4955: USE_OPLINE
4956: zend_class_entry *ce = EX_T(opline->op1.var).class_entry;
4957: zend_class_entry *trait;
4958:
4959: SAVE_OPLINE();
4960: if (CACHED_PTR(opline->op2.literal->cache_slot)) {
4961: trait = CACHED_PTR(opline->op2.literal->cache_slot);
4962: } else {
4963: trait = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv),
4964: Z_STRLEN_P(opline->op2.zv),
4965: opline->op2.literal + 1,
4966: opline->extended_value TSRMLS_CC);
4967: if (UNEXPECTED(trait == NULL)) {
4968: CHECK_EXCEPTION();
4969: ZEND_VM_NEXT_OPCODE();
4970: }
4971: if (!((trait->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)) {
4972: zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name, trait->name);
4973: }
4974: CACHE_PTR(opline->op2.literal->cache_slot, trait);
4975: }
4976:
4977: zend_do_implement_trait(ce, trait TSRMLS_CC);
4978:
4979: CHECK_EXCEPTION();
4980: ZEND_VM_NEXT_OPCODE();
4981: }
4982:
4983: ZEND_VM_HANDLER(155, ZEND_BIND_TRAITS, ANY, ANY)
4984: {
4985: USE_OPLINE
4986: zend_class_entry *ce = EX_T(opline->op1.var).class_entry;
4987:
4988: SAVE_OPLINE();
4989: zend_do_bind_traits(ce TSRMLS_CC);
4990: CHECK_EXCEPTION();
4991: ZEND_VM_NEXT_OPCODE();
4992: }
4993:
4994: ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
4995: {
4996: zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
4997: int i;
4998: zend_uint catch_op_num = 0;
4999: int catched = 0;
5000: zval restored_error_reporting;
5001:
5002: void **stack_frame = (void**)(((char*)EX_Ts()) +
5003: (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
5004:
5005: while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
5006: zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
5007: zval_ptr_dtor(&stack_zval_p);
5008: }
5009:
5010: for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
5011: if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
5012: /* further blocks will not be relevant... */
5013: break;
5014: } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
5015: catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
5016: catched = 1;
5017: }
5018: }
5019:
5020: while (EX(fbc)) {
5021: EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
5022: if (EX(object)) {
5023: if (IS_CTOR_CALL(EX(called_scope))) {
5024: if (IS_CTOR_USED(EX(called_scope))) {
5025: Z_DELREF_P(EX(object));
5026: }
5027: if (Z_REFCOUNT_P(EX(object)) == 1) {
5028: zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
5029: }
5030: }
5031: zval_ptr_dtor(&EX(object));
5032: }
5033: EX(called_scope) = DECODE_CTOR(EX(called_scope));
5034: zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
5035: }
5036:
5037: for (i=0; i<EX(op_array)->last_brk_cont; i++) {
5038: if (EX(op_array)->brk_cont_array[i].start < 0) {
5039: continue;
5040: } else if (EX(op_array)->brk_cont_array[i].start > op_num) {
5041: /* further blocks will not be relevant... */
5042: break;
5043: } else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
5044: if (!catched ||
5045: catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
5046: zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
5047:
5048: switch (brk_opline->opcode) {
5049: case ZEND_SWITCH_FREE:
5050: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
5051: zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr);
5052: }
5053: break;
5054: case ZEND_FREE:
5055: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
5056: zendi_zval_dtor(EX_T(brk_opline->op1.var).tmp_var);
5057: }
5058: break;
5059: }
5060: }
5061: }
5062: }
5063:
5064: /* restore previous error_reporting value */
5065: if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
5066: Z_TYPE(restored_error_reporting) = IS_LONG;
5067: Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
5068: convert_to_string(&restored_error_reporting);
5069: zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
5070: zendi_zval_dtor(restored_error_reporting);
5071: }
5072: EX(old_error_reporting) = NULL;
5073:
5074: if (!catched) {
5075: ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
5076: } else {
5077: ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
5078: ZEND_VM_CONTINUE();
5079: }
5080: }
5081:
5082: ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
5083: {
5084: USE_OPLINE
5085:
5086: SAVE_OPLINE();
5087: zend_verify_abstract_class(EX_T(opline->op1.var).class_entry TSRMLS_CC);
5088: CHECK_EXCEPTION();
5089: ZEND_VM_NEXT_OPCODE();
5090: }
5091:
5092: ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
5093: {
5094: USE_OPLINE
5095: int ret;
5096:
5097: SAVE_OPLINE();
5098: ret = zend_user_opcode_handlers[opline->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);
5099: LOAD_OPLINE();
5100:
5101: switch (ret) {
5102: case ZEND_USER_OPCODE_CONTINUE:
5103: ZEND_VM_CONTINUE();
5104: case ZEND_USER_OPCODE_RETURN:
5105: ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
5106: case ZEND_USER_OPCODE_ENTER:
5107: ZEND_VM_ENTER();
5108: case ZEND_USER_OPCODE_LEAVE:
5109: ZEND_VM_LEAVE();
5110: case ZEND_USER_OPCODE_DISPATCH:
5111: ZEND_VM_DISPATCH(opline->opcode, opline);
5112: default:
5113: ZEND_VM_DISPATCH((zend_uchar)(ret & 0xff), opline);
5114: }
5115: }
5116:
5117: ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
5118: {
5119: USE_OPLINE
5120: zend_free_op free_op1, free_op2;
5121: zval *name;
5122: zval *val;
5123: zend_constant c;
5124:
5125: SAVE_OPLINE();
5126: name = GET_OP1_ZVAL_PTR(BP_VAR_R);
5127: val = GET_OP2_ZVAL_PTR(BP_VAR_R);
5128:
5129: if ((Z_TYPE_P(val) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
5130: zval tmp;
5131: zval *tmp_ptr = &tmp;
5132:
5133: ZVAL_COPY_VALUE(&tmp, val);
5134: if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
5135: zval_copy_ctor(&tmp);
5136: }
5137: INIT_PZVAL(&tmp);
5138: zval_update_constant(&tmp_ptr, NULL TSRMLS_CC);
5139: c.value = *tmp_ptr;
5140: } else {
5141: INIT_PZVAL_COPY(&c.value, val);
5142: zval_copy_ctor(&c.value);
5143: }
5144: c.flags = CONST_CS; /* non persistent, case sensetive */
5145: c.name = IS_INTERNED(Z_STRVAL_P(name)) ? Z_STRVAL_P(name) : zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
5146: c.name_len = Z_STRLEN_P(name)+1;
5147: c.module_number = PHP_USER_CONSTANT;
5148:
5149: if (zend_register_constant(&c TSRMLS_CC) == FAILURE) {
5150: }
5151:
5152: FREE_OP1();
5153: FREE_OP2();
5154: CHECK_EXCEPTION();
5155: ZEND_VM_NEXT_OPCODE();
5156: }
5157:
5158: ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
5159: {
5160: USE_OPLINE
5161: zend_function *op_array;
5162:
5163: SAVE_OPLINE();
5164:
5165: if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), Z_HASH_P(opline->op1.zv), (void *) &op_array) == FAILURE) ||
5166: UNEXPECTED(op_array->type != ZEND_USER_FUNCTION)) {
5167: zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
5168: }
5169:
5170: zend_create_closure(&EX_T(opline->result.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC);
5171:
5172: CHECK_EXCEPTION();
5173: ZEND_VM_NEXT_OPCODE();
5174: }
5175:
5176: ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
5177: {
5178: USE_OPLINE
5179: zval *var_ptr, *new_zv;
5180:
5181: SAVE_OPLINE();
5182: var_ptr = EX_T(opline->op1.var).var.ptr;
5183: if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
5184: !PZVAL_IS_REF(var_ptr) &&
5185: Z_REFCOUNT_P(var_ptr) > 1) {
5186:
5187: Z_DELREF_P(var_ptr);
5188: ALLOC_ZVAL(new_zv);
5189: INIT_PZVAL_COPY(new_zv, var_ptr);
5190: var_ptr = new_zv;
5191: zval_copy_ctor(var_ptr);
5192: EX_T(opline->op1.var).var.ptr = var_ptr;
5193: }
5194: ZEND_VM_NEXT_OPCODE();
5195: }
5196:
5197: ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>