]> granicus.if.org Git - php/commitdiff
Support overloading of $foo["bar"] += "baz"
authorZeev Suraski <zeev@php.net>
Wed, 30 Jul 2003 17:40:54 +0000 (17:40 +0000)
committerZeev Suraski <zeev@php.net>
Wed, 30 Jul 2003 17:40:54 +0000 (17:40 +0000)
Zend/zend_compile.c
Zend/zend_execute.c

index bdb0cb04dc389b3c2b1e140d3798cbce57524c8a..a3fea89248e54eed8ddc4f6dee966e5e17a038c2 100644 (file)
@@ -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;
        }
 }
 
index fc7e0fbcc98d802de86d056d36853b958c50f347..34b6faf06f59f014ab3e54f4e0a8a061554c6838 100644 (file)
@@ -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);