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