From: Zeev Suraski Date: Wed, 30 Jul 2003 17:12:06 +0000 (+0000) Subject: Improve array overloading - support unset($foo["bar"]) X-Git-Tag: BEFORE_ARG_INFO~44 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c0b46739caab84c0cf1aff21c3456de335afe395;p=php Improve array overloading - support unset($foo["bar"]) --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index bd01035d44..bdb0cb04dc 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2890,8 +2890,10 @@ void zend_do_unset(znode *variable TSRMLS_DC) last_op->opcode = ZEND_UNSET_VAR; break; case ZEND_FETCH_DIM_UNSET: + last_op->opcode = ZEND_UNSET_DIM; + break; case ZEND_FETCH_OBJ_UNSET: - last_op->opcode = ZEND_UNSET_DIM_OBJ; + last_op->opcode = ZEND_UNSET_OBJ; break; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1142585ea0..aa5a9f501c 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -571,7 +571,8 @@ int zendlex(znode *zendlval TSRMLS_DC); #define ZEND_INCLUDE_OR_EVAL 73 #define ZEND_UNSET_VAR 74 -#define ZEND_UNSET_DIM_OBJ 75 +#define ZEND_UNSET_DIM 75 +#define ZEND_UNSET_OBJ 76 #define ZEND_FE_RESET 77 #define ZEND_FE_FETCH 78 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index eaf3d98c0d..fc7e0fbcc9 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -338,6 +338,9 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode if (opcode == ZEND_ASSIGN_OBJ) { Z_OBJ_HT_P(object)->write_property(object, property, value TSRMLS_CC); } else { + if (!Z_OBJ_HT_P(object)->write_dimension) { + zend_error(E_ERROR, "Cannot use object as array"); + } Z_OBJ_HT_P(object)->write_dimension(object, property, value TSRMLS_CC); } if (property == &tmp) { @@ -848,13 +851,17 @@ static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2, break; case IS_OBJECT: if (type == BP_VAR_R) { - zval *dim = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R); - zval *overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim TSRMLS_CC); - - *retval = &overloaded_result; - AI_USE_PTR(T(result->u.var).var); - FREE_OP(Ts, op2, EG(free_op2)); - SELECTIVE_PZVAL_LOCK(**retval, result); + if (!Z_OBJ_HT_P(container)->read_dimension) { + zend_error(E_ERROR, "Cannot use object as array"); + } else { + zval *dim = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R); + zval *overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim TSRMLS_CC); + + *retval = &overloaded_result; + AI_USE_PTR(T(result->u.var).var); + FREE_OP(Ts, op2, EG(free_op2)); + SELECTIVE_PZVAL_LOCK(**retval, result); + } } break; default: { @@ -3404,6 +3411,7 @@ int zend_unset_var_handler(ZEND_OPCODE_HANDLER_ARGS) } + int zend_unset_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS) { zval **container = get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R TSRMLS_CC); @@ -3413,13 +3421,30 @@ int zend_unset_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS) if (container) { HashTable *ht; - if ((*container)->type == IS_ARRAY) { - ht = (*container)->value.ht; - } else { - ht = NULL; - if ((*container)->type == IS_OBJECT) { - Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC); - } + switch (EX(opline)->opcode) { + case ZEND_UNSET_DIM: + switch (Z_TYPE_PP(container)) { + case IS_ARRAY: + ht = Z_ARRVAL_PP(container); + break; + case IS_OBJECT: + ht = NULL; + if (!Z_OBJ_HT_P(*container)->unset_dimension) { + zend_error(E_ERROR, "Cannot use object as array"); + } + Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC); + break; + default: + ht = NULL; + break; + } + break; + case ZEND_UNSET_OBJ: + ht = NULL; + if (Z_TYPE_PP(container) == IS_OBJECT) { + Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC); + } + break; } if (ht) { switch (offset->type) { @@ -4044,7 +4069,8 @@ void zend_init_opcodes_handlers() zend_opcode_handlers[ZEND_INCLUDE_OR_EVAL] = zend_include_or_eval_handler; zend_opcode_handlers[ZEND_UNSET_VAR] = zend_unset_var_handler; - zend_opcode_handlers[ZEND_UNSET_DIM_OBJ] = zend_unset_dim_obj_handler; + zend_opcode_handlers[ZEND_UNSET_DIM] = zend_unset_dim_obj_handler; + zend_opcode_handlers[ZEND_UNSET_OBJ] = zend_unset_dim_obj_handler; zend_opcode_handlers[ZEND_FE_RESET] = zend_fe_reset_handler; zend_opcode_handlers[ZEND_FE_FETCH] = zend_fe_fetch_handler; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 7405377aad..a5d913d409 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -452,6 +452,13 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) } } + +static void zend_std_unset_dimension(zval *object, zval *offset TSRMLS_DC) +{ + zend_error(E_ERROR, "Cannot use object as array"); +} + + static void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) { zval ***args; @@ -875,6 +882,7 @@ zend_object_handlers std_object_handlers = { NULL, /* set */ zend_std_has_property, /* has_property */ zend_std_unset_property, /* unset_property */ + zend_std_unset_dimension, /* unset_dimension */ zend_std_get_properties, /* get_properties */ zend_std_get_method, /* get_method */ NULL, /* call_method */ diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 0a642b95a8..5f3d29c98f 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -59,6 +59,9 @@ typedef int (*zend_object_has_property_t)(zval *object, zval *member, int check_ /* Used to remove a property of the object */ typedef void (*zend_object_unset_property_t)(zval *object, zval *member TSRMLS_DC); +/* Used to remove a property of the object */ +typedef void (*zend_object_unset_dimension_t)(zval *object, zval *offset TSRMLS_DC); + /* Used to get hash of the properties of the object, as hash of zval's */ typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC); @@ -99,6 +102,7 @@ typedef struct _zend_object_handlers { zend_object_set_t set; zend_object_has_property_t has_property; zend_object_unset_property_t unset_property; + zend_object_unset_dimension_t unset_dimension; zend_object_get_properties_t get_properties; zend_object_get_method_t get_method; zend_object_call_method_t call_method;