From: Zeev Suraski Date: Wed, 30 Jul 2003 17:40:54 +0000 (+0000) Subject: Support overloading of $foo["bar"] += "baz" X-Git-Tag: BEFORE_ARG_INFO~42 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f41f62c2ff97d48244880e936720d80248fd246c;p=php Support overloading of $foo["bar"] += "baz" --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index bdb0cb04dc..a3fea89248 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -237,21 +237,32 @@ void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *o zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number]; - if (last_op->opcode == ZEND_FETCH_OBJ_RW) { - last_op->opcode = op; - last_op->extended_value = ZEND_ASSIGN_OBJ; + switch (last_op->opcode) { + case ZEND_FETCH_OBJ_RW: + last_op->opcode = op; + last_op->extended_value = ZEND_ASSIGN_OBJ; - zend_do_op_data(opline, op2 TSRMLS_CC); - SET_UNUSED(opline->result); - *result = last_op->result; - } else { - opline->opcode = op; - opline->op1 = *op1; - opline->op2 = *op2; - opline->result.op_type = IS_VAR; - opline->result.u.EA.type = 0; - opline->result.u.var = get_temporary_variable(CG(active_op_array)); - *result = opline->result; + zend_do_op_data(opline, op2 TSRMLS_CC); + SET_UNUSED(opline->result); + *result = last_op->result; + break; + case ZEND_FETCH_DIM_RW: + last_op->opcode = op; + last_op->extended_value = ZEND_ASSIGN_DIM; + + zend_do_op_data(opline, op2 TSRMLS_CC); + SET_UNUSED(opline->result); + *result = last_op->result; + break; + default: + opline->opcode = op; + opline->op1 = *op1; + opline->op2 = *op2; + opline->result.op_type = IS_VAR; + opline->result.u.EA.type = 0; + opline->result.u.var = get_temporary_variable(CG(active_op_array)); + *result = opline->result; + break; } } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index fc7e0fbcc9..34b6faf06f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1465,7 +1465,8 @@ static inline int zend_binary_assign_op_obj_helper(int (*binary_op)(zval *result } /* here property is a string */ - if (Z_OBJ_HT_P(object)->get_property_zval_ptr) { + if (EX(opline)->extended_value == ZEND_ASSIGN_OBJ + && Z_OBJ_HT_P(object)->get_property_zval_ptr) { zval **zptr = Z_OBJ_HT_P(object)->get_property_zval_ptr(object, property TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ SEPARATE_ZVAL_IF_NOT_REF(zptr); @@ -1478,10 +1479,26 @@ static inline int zend_binary_assign_op_obj_helper(int (*binary_op)(zval *result } if (!have_get_ptr) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, 0 TSRMLS_CC); + zval *z; + + switch (EX(opline)->extended_value) { + case ZEND_ASSIGN_OBJ: + z = Z_OBJ_HT_P(object)->read_property(object, property, 0 TSRMLS_CC); + break; + case ZEND_ASSIGN_DIM: + z = Z_OBJ_HT_P(object)->read_dimension(object, property, 0 TSRMLS_CC); + break; + } SEPARATE_ZVAL_IF_NOT_REF(&z); binary_op(z, z, value TSRMLS_CC); - Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC); + switch (EX(opline)->extended_value) { + case ZEND_ASSIGN_OBJ: + Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC); + break; + case ZEND_ASSIGN_DIM: + Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC); + break; + } *retval = z; SELECTIVE_PZVAL_LOCK(*retval, result); if (z->refcount <= 1) { @@ -1507,8 +1524,14 @@ inline int zend_binary_assign_op_helper(void *binary_op_arg, ZEND_OPCODE_HANDLER zval **var_ptr; int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC); - if (EX(opline)->extended_value == ZEND_ASSIGN_OBJ) { - return zend_binary_assign_op_obj_helper(binary_op_arg, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + switch (EX(opline)->extended_value) { + case ZEND_ASSIGN_OBJ: + case ZEND_ASSIGN_DIM: + return zend_binary_assign_op_obj_helper(binary_op_arg, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + break; + default: + /* do nothing */ + break; } var_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_RW);