mirror of
https://github.com/php/php-src.git
synced 2026-04-14 03:22:58 +02:00
Support overloading of $foo["bar"] += "baz"
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user