cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_language_parser.y

From: Date: Thu, 24 Jul 2003 12:38:34 +0000
Subject: cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_language_parser.y
Groups: php.zend-engine.cvs 
Request: Send a blank email to php-zend-engine-cvs+get-1526@lists.php.net to get a copy of this message
zeev Thu Jul 24 08:38:34 2003 EDT Modified files: /ZendEngine2 zend_compile.c zend_compile.h zend_execute.c zend_language_parser.y Log: Support references in foreach() Syntax: foreach ($arr as &$val) foreach ($arr as $key => &$val) Index: ZendEngine2/zend_compile.c diff -u ZendEngine2/zend_compile.c:1.439 ZendEngine2/zend_compile.c:1.440 --- ZendEngine2/zend_compile.c:1.439 Wed Jul 23 04:58:46 2003 +++ ZendEngine2/zend_compile.c Thu Jul 24 08:38:33 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.439 2003/07/23 08:58:46 stas Exp $ */ +/* $Id: zend_compile.c,v 1.440 2003/07/24 12:38:33 zeev Exp $ */ #include "zend_language_parser.h" #include "zend.h" @@ -2973,15 +2973,17 @@ opline->result.op_type = IS_TMP_VAR; opline->result.u.var = get_temporary_variable(CG(active_op_array)); opline->op1 = *open_brackets_token; + opline->extended_value = 0; SET_UNUSED(opline->op2); *as_token = opline->result; } -void zend_do_foreach_cont(znode *value, znode *key, znode *as_token TSRMLS_DC) +void zend_do_foreach_cont(znode *value, znode *key, znode *as_token, znode *foreach_token TSRMLS_DC) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); znode result_value, result_key, dummy; + zend_bool assign_by_ref=0; if (key->op_type != IS_UNUSED) { znode *tmp; @@ -2992,6 +2994,18 @@ value = tmp; } + if (key->u.EA.type & ZEND_PARSED_REFERENCE_VARIABLE) { + zend_error(E_COMPILE_ERROR, "Key element cannot be a reference"); + } + + if (value->u.EA.type & ZEND_PARSED_REFERENCE_VARIABLE) { + assign_by_ref = 1; + if (!CG(active_op_array)->opcodes[foreach_token->u.opline_num-1].extended_value) { + zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array expression"); + } + CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value = 1; + } + opline->opcode = ZEND_FETCH_DIM_TMP_VAR; opline->result.op_type = IS_VAR; opline->result.u.EA.type = 0; @@ -3017,7 +3031,11 @@ result_key = opline->result; } - zend_do_assign(&dummy, value, &result_value TSRMLS_CC); + if (1 && assign_by_ref) { + zend_do_assign_ref(&dummy, value, &result_value TSRMLS_CC); + } else { + zend_do_assign(&dummy, value, &result_value TSRMLS_CC); + } CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED; if (key->op_type != IS_UNUSED) { zend_do_assign(&dummy, key, &result_key TSRMLS_CC); Index: ZendEngine2/zend_compile.h diff -u ZendEngine2/zend_compile.h:1.248 ZendEngine2/zend_compile.h:1.249 --- ZendEngine2/zend_compile.h:1.248 Wed Jul 23 04:58:46 2003 +++ ZendEngine2/zend_compile.h Thu Jul 24 08:38:33 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.h,v 1.248 2003/07/23 08:58:46 stas Exp $ */ +/* $Id: zend_compile.h,v 1.249 2003/07/24 12:38:33 zeev Exp $ */ #ifndef ZEND_COMPILE_H #define ZEND_COMPILE_H @@ -405,7 +405,7 @@ void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC); void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable TSRMLS_DC); -void zend_do_foreach_cont(znode *value, znode *key, znode *as_token TSRMLS_DC); +void zend_do_foreach_cont(znode *value, znode *key, znode *as_token, znode *foreach_token TSRMLS_DC); void zend_do_foreach_end(znode *foreach_token, znode *open_brackets_token TSRMLS_DC); void zend_do_declare_begin(TSRMLS_D); @@ -684,11 +684,12 @@ /* variable parsing type (compile-time) */ -#define ZEND_PARSED_MEMBER (1<<0) -#define ZEND_PARSED_METHOD_CALL (1<<1) -#define ZEND_PARSED_STATIC_MEMBER (1<<2) -#define ZEND_PARSED_FUNCTION_CALL (1<<3) -#define ZEND_PARSED_VARIABLE (1<<4) +#define ZEND_PARSED_MEMBER (1<<0) +#define ZEND_PARSED_METHOD_CALL (1<<1) +#define ZEND_PARSED_STATIC_MEMBER (1<<2) +#define ZEND_PARSED_FUNCTION_CALL (1<<3) +#define ZEND_PARSED_VARIABLE (1<<4) +#define ZEND_PARSED_REFERENCE_VARIABLE (1<<5) /* unset types */ Index: ZendEngine2/zend_execute.c diff -u ZendEngine2/zend_execute.c:1.500 ZendEngine2/zend_execute.c:1.501 --- ZendEngine2/zend_execute.c:1.500 Thu Jul 24 04:36:39 2003 +++ ZendEngine2/zend_execute.c Thu Jul 24 08:38:33 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.c,v 1.500 2003/07/24 08:36:39 zeev Exp $ */ +/* $Id: zend_execute.c,v 1.501 2003/07/24 12:38:33 zeev Exp $ */ #define ZEND_INTENSIVE_DEBUGGING 0 @@ -3510,6 +3510,10 @@ array_init(result); + if (EX(opline)->extended_value) { + SEPARATE_ZVAL_IF_NOT_REF(value); + (*value)->is_ref = 1; + } (*value)->refcount++; zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL); Index: ZendEngine2/zend_language_parser.y diff -u ZendEngine2/zend_language_parser.y:1.123 ZendEngine2/zend_language_parser.y:1.124 --- ZendEngine2/zend_language_parser.y:1.123 Sun Jun 22 06:50:43 2003 +++ ZendEngine2/zend_language_parser.y Thu Jul 24 08:38:33 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_parser.y,v 1.123 2003/06/22 10:50:43 zeev Exp $ */ +/* $Id: zend_language_parser.y,v 1.124 2003/07/24 12:38:33 zeev Exp $ */ /* * LALR shift/reduce conflicts and how they are resolved: @@ -207,8 +207,8 @@ | expr ';' { zend_do_free(&$1 TSRMLS_CC); } | T_USE use_filename ';' { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()"); zval_dtor(&$2.u.constant); } | T_UNSET '(' unset_variables ')' ';' - | T_FOREACH '(' variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 1 TSRMLS_CC); } w_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); } - | T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 0 TSRMLS_CC); } w_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); } + | T_FOREACH '(' variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 1 TSRMLS_CC); } foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4, &$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); } + | T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 0 TSRMLS_CC); } w_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4, &$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); } | T_DECLARE { $1.u.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); } | ';' /* empty statement */ | T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}' @@ -297,8 +297,14 @@ ; foreach_optional_arg: - /* empty */ { $$.op_type = IS_UNUSED; } - | T_DOUBLE_ARROW w_variable { $$ = $2; } + /* empty */ { $$.op_type = IS_UNUSED; } + | T_DOUBLE_ARROW foreach_variable { $$ = $2; } +; + + +foreach_variable: + w_variable { $$ = $1; } + | '&' w_variable { $$ = $2; $$.u.EA.type |= ZEND_PARSED_REFERENCE_VARIABLE; } ; for_statement:

« previous php.zend-engine.cvs (#1526) next »