From: Zeev Suraski Date: Thu, 31 Jul 2003 09:06:11 +0000 (+0000) Subject: Finish the array overloading patch X-Git-Tag: BEFORE_ARG_INFO~34 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=accd6b623b417fe24ea94278620dd2b0f9b18cd8;p=php Finish the array overloading patch --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2158f938db..605e4e491d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -247,13 +247,18 @@ void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *o *result = last_op->result; break; case ZEND_FETCH_DIM_RW: +#if 1 last_op->opcode = op; last_op->extended_value = ZEND_ASSIGN_DIM; zend_do_op_data(opline, op2 TSRMLS_CC); + opline->op2.u.var = get_temporary_variable(CG(active_op_array)); + opline->op2.u.EA.type = 0; + opline->op2.op_type = IS_VAR; SET_UNUSED(opline->result); *result = last_op->result; break; +#endif default: opline->opcode = op; opline->op1 = *op1; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 6179a7fe25..7b0a3ae54a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1519,24 +1519,46 @@ static inline int zend_binary_assign_op_obj_helper(int (*binary_op)(zval *result } -inline int zend_binary_assign_op_helper(void *binary_op_arg, ZEND_OPCODE_HANDLER_ARGS) +inline int zend_binary_assign_op_helper(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS) { zval **var_ptr; - int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC); + zval *value; + zend_bool increment_opline = 0; 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); + return zend_binary_assign_op_obj_helper(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + break; + case ZEND_ASSIGN_DIM: { + zend_op *op_data = EX(opline)+1; + zval **object_ptr = get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + + if ((*object_ptr)->type == IS_OBJECT) { + zend_assign_to_object(&EX(opline)->result, object_ptr, &EX(opline)->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC); + EX(opline)++; + NEXT_OPCODE(); + } else { + zend_op *data_opline = EX(opline)+1; + + (*object_ptr)->refcount++; /* undo the effect of get_obj_zval_ptr_ptr() */ + zend_fetch_dimension_address(&data_opline->op2, &EX(opline)->op1, &EX(opline)->op2, EX(Ts), BP_VAR_RW TSRMLS_CC); + + value = get_zval_ptr(&data_opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R); + var_ptr = get_zval_ptr_ptr(&data_opline->op2, EX(Ts), BP_VAR_RW); + EG(free_op2) = 0; + increment_opline = 1; +// zend_assign_to_variable(&EX(opline)->result, &data_opline->op2, &data_opline->op1, value, (EG(free_op1)?IS_TMP_VAR:EX(opline)->op1.op_type), EX(Ts) TSRMLS_CC); + } + } break; default: + value = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R); + var_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_RW); + EG(free_op1) = 0; /* do nothing */ break; } - var_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_RW); - binary_op = binary_op_arg; - if (!var_ptr) { zend_error(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -1550,12 +1572,16 @@ inline int zend_binary_assign_op_helper(void *binary_op_arg, ZEND_OPCODE_HANDLER SEPARATE_ZVAL_IF_NOT_REF(var_ptr); - binary_op(*var_ptr, *var_ptr, get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC); + binary_op(*var_ptr, *var_ptr, value TSRMLS_CC); EX_T(EX(opline)->result.u.var).var.ptr_ptr = var_ptr; SELECTIVE_PZVAL_LOCK(*var_ptr, &EX(opline)->result); + FREE_OP(Ex(Ts), &EX(opline)->op1, EG(free_op1)); FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2)); AI_USE_PTR(EX_T(EX(opline)->result.u.var).var); + if (increment_opline) { + EX(opline)++; + } NEXT_OPCODE(); }