summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-11-20 11:01:28 +0000
committerDmitry Stogov <dmitry@php.net>2007-11-20 11:01:28 +0000
commitde46d9458982b7b0e7aaffa89c18eb5c81dc6f81 (patch)
tree2e372c5463a337c0aa25748df3201108af87c3b3 /Zend/zend_execute.c
parent10f6cd5cb0b10fe0c8906d18aaf967079c674fb5 (diff)
downloadphp-git-de46d9458982b7b0e7aaffa89c18eb5c81dc6f81.tar.gz
ZEND_FETCH_DIM optimization
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r--Zend/zend_execute.c130
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)