From 0517436bf94beb5c454fd8be1d73ef3efa01c0e5 Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Mon, 31 Jan 2000 18:21:54 +0000 Subject: [PATCH] - Fix foreach() - Fix indirect reference with object properties --- Zend/zend-parser.y | 12 ++++++++---- Zend/zend_alloc.c | 2 +- Zend/zend_execute.c | 40 ++++++++++++++++++++++++++-------------- Zend/zend_fast_cache.h | 14 +++++++++----- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y index e83f7c5266..461216d793 100644 --- a/Zend/zend-parser.y +++ b/Zend/zend-parser.y @@ -201,7 +201,7 @@ unticked_statement: | T_REQUIRE expr ';' { do_require(&$2 CLS_CC); } | T_USE use_filename ';' { use_filename($2.u.constant.value.str.val, $2.u.constant.value.str.len CLS_CC); zval_dtor(&$2.u.constant); } | T_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); } - | T_FOREACH '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); } + | T_FOREACH '(' w_expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); } | T_DECLARE { do_declare_begin(CLS_C); } '(' declare_list ')' declare_statement { do_declare_end(CLS_C); } | ';' /* empty statement */ ; @@ -560,6 +560,10 @@ expr: | expr_without_variable { $$ = $1; } ; +w_expr: + w_cvar { $$ = $1; } + | expr_without_variable { $$ = $1; } +; r_cvar: @@ -612,14 +616,14 @@ ref_list: ; object_property: - object_dim_list { $$ = $1; } - | cvar_without_objects { do_end_variable_parse(BP_VAR_R, 0 CLS_CC); $$ = $1; } + object_dim_list { znode tmp_znode; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&$$, &tmp_znode, &$1 CLS_CC);} + | cvar_without_objects { do_end_variable_parse(BP_VAR_R, 0 CLS_CC); } { znode tmp_znode; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&$$, &tmp_znode, &$1 CLS_CC);} ; object_dim_list: object_dim_list '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 CLS_CC); } | object_dim_list '{' expr '}' { fetch_string_offset(&$$, &$1, &$3 CLS_CC); } - | variable_name { znode tmp_znode; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&$$, &tmp_znode, &$1 CLS_CC);} + | variable_name ; variable_name: diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 7b41548978..d520551149 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -395,7 +395,7 @@ ZEND_API void shutdown_memory_manager(int silent, int clean_cache) } } -#if ZEND_DEBUG +#if (ZEND_DEBUG) do { zval display_memory_cache_stats; int i, j; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 19e25fb4c9..f6d7ddb1e0 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2102,25 +2102,37 @@ send_by_ref: } NEXT_OPCODE(); case ZEND_FE_RESET: { - zval *array = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); - - if (EG(free_op1)) { /* If TMP_VAR then make it a VAR */ - zval *tmp; - - ALLOC_ZVAL(tmp); - *tmp = *array; - INIT_PZVAL(tmp); - array = tmp; + zval *array_ptr; + zval **array_ptr_ptr; + + if ((opline->op1.op_type == IS_CONST) || (opline->op1.op_type == IS_TMP_VAR)) { + array_ptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); + if (EG(free_op1)) { /* IS_TMP_VAR */ + zval *tmp; + + ALLOC_ZVAL(tmp); + *tmp = *array_ptr; + INIT_PZVAL(tmp); + array_ptr = tmp; + } else { /* IS_CONST */ + array_ptr->refcount++; + } } else { - array->refcount++; + array_ptr_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R); + if (!PZVAL_IS_REF(*array_ptr_ptr)){ + SEPARATE_ZVAL(array_ptr_ptr); + } + array_ptr = *array_ptr_ptr; + array_ptr->is_ref = 1; + array_ptr->refcount++; } - PZVAL_LOCK(array); - Ts[opline->result.u.var].var.ptr = array; + PZVAL_LOCK(array_ptr); + Ts[opline->result.u.var].var.ptr = array_ptr; Ts[opline->result.u.var].var.ptr_ptr = &Ts[opline->result.u.var].var.ptr; - if (array->type == IS_ARRAY) { + if (array_ptr->type == IS_ARRAY) { /* probably redundant */ - zend_hash_internal_pointer_reset(array->value.ht); + zend_hash_internal_pointer_reset(array_ptr->value.ht); } else { /* JMP to the end of foreach - TBD */ } diff --git a/Zend/zend_fast_cache.h b/Zend/zend_fast_cache.h index 660ec9df80..f62f0ee12a 100644 --- a/Zend/zend_fast_cache.h +++ b/Zend/zend_fast_cache.h @@ -21,7 +21,13 @@ #ifndef _ZEND_FAST_CACHE_H #define _ZEND_FAST_CACHE_H -#define ZEND_ENABLE_FAST_CACHE 1 +#ifndef ZEND_ENABLE_FAST_CACHE +# if ZEND_DEBUG +# define ZEND_ENABLE_FAST_CACHE 0 +# else +# define ZEND_ENABLE_FAST_CACHE 1 +# endif +#endif typedef struct _zend_fast_cache_list_entry { struct _zend_fast_cache_list_entry *next; @@ -30,13 +36,11 @@ typedef struct _zend_fast_cache_list_entry { #define MAX_FAST_CACHE_TYPES 4 - - +#define ZVAL_CACHE_LIST 0 +#define HASHTABLE_CACHE_LIST 1 #if ZEND_ENABLE_FAST_CACHE -#define ZVAL_CACHE_LIST 0 -#define HASHTABLE_CACHE_LIST 1 #include "zend_globals.h" #include "zend_globals_macros.h" -- 2.50.1