list() with keys (no foreach or tests)

This commit is contained in:
Andrea Faulds 2016-01-10 20:46:44 +00:00
parent 0e5fa32883
commit cede13ccfe
4 changed files with 105 additions and 26 deletions

View file

@ -2713,19 +2713,42 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
{
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t i;
zend_ulong next_index = 0;
zend_bool has_elems = 0;
for (i = 0; i < list->children; ++i) {
zend_ast *var_ast = list->child[i];
zend_ast *pair_ast = list->child[i];
zend_ast *var_ast;
zend_ast *key_ast;
znode fetch_result, dim_node;
if (var_ast == NULL) {
if (pair_ast == NULL) {
next_index++;
continue;
}
has_elems = 1;
dim_node.op_type = IS_CONST;
ZVAL_LONG(&dim_node.u.constant, i);
var_ast = pair_ast->child[0];
key_ast = pair_ast->child[1];
if (key_ast) {
zend_compile_expr(&dim_node, key_ast);
zend_handle_numeric_op(&dim_node);
if (Z_TYPE(dim_node.u.constant) != IS_LONG && Z_TYPE(dim_node.u.constant) != IS_STRING) {
zend_error_noreturn(E_COMPILE_ERROR, "Key must be an integer or string literal");
}
if (Z_TYPE(dim_node.u.constant) == IS_LONG) {
next_index = Z_LVAL(dim_node.u.constant);
}
} else {
dim_node.op_type = IS_CONST;
ZVAL_LONG(&dim_node.u.constant, next_index);
next_index++;
}
has_elems = 1;
if (expr_node->op_type == IS_CONST) {
Z_TRY_ADDREF(expr_node->u.constant);

View file

@ -1177,8 +1177,12 @@ assignment_list:
;
assignment_list_element:
variable { $$ = $1; }
variable { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $1, NULL); }
| scalar T_DOUBLE_ARROW variable
{ $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, $1); }
| T_LIST '(' assignment_list ')' { $$ = $3; }
| scalar T_DOUBLE_ARROW T_LIST '(' assignment_list ')'
{ $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); }
| /* empty */ { $$ = NULL; }
;

View file

@ -2073,13 +2073,26 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
ZEND_VM_C_LABEL(try_fetch_list):
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
zval *value;
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
} else if (OP1_TYPE != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&

View file

@ -5753,13 +5753,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HA
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
zval *value;
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
} else if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
@ -37866,13 +37879,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
zval *value;
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
} else if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
@ -51017,13 +51043,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_H
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
zval *value;
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&