diff options
author | Dmitry Stogov <dmitry@php.net> | 2007-11-20 11:01:28 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2007-11-20 11:01:28 +0000 |
commit | de46d9458982b7b0e7aaffa89c18eb5c81dc6f81 (patch) | |
tree | 2e372c5463a337c0aa25748df3201108af87c3b3 /Zend/zend_execute.c | |
parent | 10f6cd5cb0b10fe0c8906d18aaf967079c674fb5 (diff) | |
download | php-git-de46d9458982b7b0e7aaffa89c18eb5c81dc6f81.tar.gz |
ZEND_FETCH_DIM optimization
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 130 |
1 files changed, 70 insertions, 60 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 7d0d3c2c89..8f1e0f0e46 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1044,6 +1044,7 @@ fetch_string_dim: static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC) { zval *container; + zval **retval; if (!container_ptr) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -1051,41 +1052,14 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container container = *container_ptr; - if (container == EG(error_zval_ptr)) { - if (result) { - result->var.ptr_ptr = &EG(error_zval_ptr); - PZVAL_LOCK(*result->var.ptr_ptr); - if (type == BP_VAR_R || type == BP_VAR_IS) { - AI_USE_PTR(result->var); - } - } - return; - } - - if (Z_TYPE_P(container)==IS_NULL - || (Z_TYPE_P(container)==IS_BOOL && Z_LVAL_P(container)==0) - || (Z_TYPE_P(container)==IS_STRING && Z_STRLEN_P(container)==0)) { - switch (type) { - case BP_VAR_RW: - case BP_VAR_W: - if (!PZVAL_IS_REF(container)) { - SEPARATE_ZVAL(container_ptr); - container = *container_ptr; - } - zval_dtor(container); - array_init(container); - break; - } - } - switch (Z_TYPE_P(container)) { - zval **retval; case IS_ARRAY: if ((type==BP_VAR_W || type==BP_VAR_RW) && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) { SEPARATE_ZVAL(container_ptr); container = *container_ptr; } +fetch_from_array: if (dim == NULL) { zval *new_zval = &EG(uninitialized_zval); @@ -1100,23 +1074,49 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container } if (result) { result->var.ptr_ptr = retval; - PZVAL_LOCK(*result->var.ptr_ptr); + PZVAL_LOCK(*retval); + if (type == BP_VAR_R || type == BP_VAR_IS) { + AI_USE_PTR(result->var); + } } + return; break; - case IS_NULL: { - /* for read-mode only */ - if (result) { + + case IS_NULL: + if (container == EG(error_zval_ptr)) { + if (result) { + result->var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + if (type == BP_VAR_R || type == BP_VAR_IS) { + AI_USE_PTR(result->var); + } + } + } else if (type == BP_VAR_RW || type == BP_VAR_W) { +convert_to_array: + if (!PZVAL_IS_REF(container)) { + SEPARATE_ZVAL(container_ptr); + container = *container_ptr; + } + zval_dtor(container); + array_init(container); + goto fetch_from_array; + } else if (result) { + /* for read-mode only */ result->var.ptr_ptr = &EG(uninitialized_zval_ptr); - PZVAL_LOCK(*result->var.ptr_ptr); - } - if (type==BP_VAR_W || type==BP_VAR_RW) { - zend_error(E_WARNING, "Cannot use a NULL value as an array"); + PZVAL_LOCK(EG(uninitialized_zval_ptr)); + if (type == BP_VAR_R || type == BP_VAR_IS) { + AI_USE_PTR(result->var); + } } + return; break; - } + case IS_STRING: { zval tmp; + if ((type == BP_VAR_RW || type == BP_VAR_W) && Z_STRLEN_P(container)==0) { + goto convert_to_array; + } if (dim == NULL) { zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); } @@ -1163,6 +1163,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container return; } break; + case IS_OBJECT: if (!Z_OBJ_HT_P(container)->read_dimension) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -1209,35 +1210,44 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container if (dim_is_tmp_var) { zval_ptr_dtor(&dim); } - return; } + return; break; - default: { - switch (type) { - case BP_VAR_UNSET: - zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); - /* break missing intentionally */ - case BP_VAR_R: - case BP_VAR_IS: - retval = &EG(uninitialized_zval_ptr); - break; - default: - retval = &EG(error_zval_ptr); - break; - } - if (result) { - result->var.ptr_ptr = retval; - PZVAL_LOCK(*result->var.ptr_ptr); - } - if (type==BP_VAR_W || type==BP_VAR_RW) { + + case IS_BOOL: + if ((type == BP_VAR_RW || type == BP_VAR_W) && Z_LVAL_P(container)==0) { + goto convert_to_array; + } + /* break missing intentionally */ + + default: + switch (type) { + case BP_VAR_UNSET: + zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); + /* break missing intentionally */ + case BP_VAR_R: + case BP_VAR_IS: + if (result) { + result->var.ptr_ptr = &EG(uninitialized_zval_ptr); + PZVAL_LOCK(EG(uninitialized_zval_ptr)); + AI_USE_PTR(result->var); + } + return; + break; + case BP_VAR_W: + case BP_VAR_RW: zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } + /* break missing intentionally */ + default: + if (result) { + result->var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } + return; + break; } break; } - if (result && (type == BP_VAR_R || type == BP_VAR_IS)) { - AI_USE_PTR(result->var); - } } static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC) |