Combine code for keyed/unkeyed list()

This commit is contained in:
Nikita Popov 2016-09-28 21:41:56 +02:00
parent 6f9e5684a1
commit 19f1ff5ad0

View File

@ -2804,37 +2804,58 @@ static void zend_verify_list_assign_target(zend_ast *var_ast, zend_bool old_styl
}
/* }}} */
static void zend_compile_unkeyed_list_assign(zend_ast_list *list, znode *expr_node, zend_bool old_style) /* {{{ */
static void zend_compile_list_assign(
znode *result, zend_ast *ast, znode *expr_node, zend_bool old_style) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t i;
zend_bool has_elems = 0;
zend_bool is_keyed =
list->children > 0 && list->child[0] != NULL && list->child[0]->child[1] != NULL;
for (i = 0; i < list->children; ++i) {
zend_ast *elem_ast = list->child[i];
zend_ast *var_ast;
zend_ast *var_ast, *key_ast;
znode fetch_result, dim_node;
if (elem_ast == NULL) {
continue;
if (is_keyed) {
zend_error(E_COMPILE_ERROR,
"Cannot use empty array entries in keyed array assignment");
} else {
continue;
}
}
if (elem_ast->attr) {
zend_error(E_COMPILE_ERROR, "[] and list() assignments cannot be by reference");
}
var_ast = elem_ast->child[0];
key_ast = elem_ast->child[1];
has_elems = 1;
dim_node.op_type = IS_CONST;
ZVAL_LONG(&dim_node.u.constant, i);
if (is_keyed) {
if (key_ast == NULL) {
zend_error(E_COMPILE_ERROR,
"Cannot mix keyed and unkeyed array entries in assignments");
}
zend_compile_expr(&dim_node, key_ast);
} else {
if (key_ast != NULL) {
zend_error(E_COMPILE_ERROR,
"Cannot mix keyed and unkeyed array entries in assignments");
}
dim_node.op_type = IS_CONST;
ZVAL_LONG(&dim_node.u.constant, i);
}
if (expr_node->op_type == IS_CONST) {
Z_TRY_ADDREF(expr_node->u.constant);
}
if (elem_ast->child[1] != NULL) {
zend_error(E_COMPILE_ERROR, "Cannot mix keyed and unkeyed array entries in assignments");
}
zend_verify_list_assign_target(var_ast, old_style);
zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node);
@ -2845,56 +2866,6 @@ static void zend_compile_unkeyed_list_assign(zend_ast_list *list, znode *expr_no
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list");
}
}
/* }}} */
static void zend_compile_keyed_list_assign(zend_ast_list *list, znode *expr_node, zend_bool old_style) /* {{{ */
{
uint32_t i;
for (i = 0; i < list->children; ++i) {
zend_ast *elem_ast = list->child[i];
zend_ast *var_ast, *key_ast;
znode fetch_result, dim_node;
if (elem_ast == NULL) {
zend_error(E_COMPILE_ERROR, "Cannot use empty array entries in keyed array assignment");
}
if (elem_ast->attr) {
zend_error(E_COMPILE_ERROR, "[] and list() assignments cannot be by reference");
}
var_ast = elem_ast->child[0];
key_ast = elem_ast->child[1];
if (key_ast == NULL) {
zend_error(E_COMPILE_ERROR, "Cannot mix keyed and unkeyed array entries in assignments");
}
zend_compile_expr(&dim_node, key_ast);
if (expr_node->op_type == IS_CONST) {
Z_TRY_ADDREF(expr_node->u.constant);
}
zend_verify_list_assign_target(var_ast, old_style);
zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node);
zend_emit_assign_znode(var_ast, &fetch_result);
}
}
/* }}} */
static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node, zend_bool old_style) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
if (list->children > 0 && list->child[0] != NULL && list->child[0]->child[1] != NULL /* has key */) {
zend_compile_keyed_list_assign(list, expr_node, old_style);
} else {
zend_compile_unkeyed_list_assign(list, expr_node, old_style);
}
*result = *expr_node;
}
/* }}} */