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