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