Skip to content

Commit 6320984

Browse files
committed
Elide ZEND_DEREF for by-ref list assign in stmt context
1 parent 143dfe8 commit 6320984

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

Zend/zend_compile.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo
101101
static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type, bool by_ref);
102102
static void zend_compile_expr(znode *result, zend_ast *ast);
103103
static void zend_compile_stmt(zend_ast *ast);
104-
static void zend_compile_assign(znode *result, zend_ast *ast);
104+
static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt);
105105

106106
#ifdef ZEND_CHECK_STACK_LIMIT
107107
zend_never_inline static void zend_stack_limit_error(void)
@@ -3406,8 +3406,7 @@ static void zend_compile_list_assign(
34063406
}
34073407

34083408
if (result) {
3409-
if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) {
3410-
// FIXME: [&$a] = ...; currently emits ZEND_DEREF, avoidable?
3409+
if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) {
34113410
zend_emit_op_tmp(result, ZEND_DEREF, expr_node, NULL);
34123411
} else {
34133412
*result = *expr_node;
@@ -3482,7 +3481,7 @@ static void zend_compile_expr_with_potential_assign_to_self(
34823481
}
34833482
}
34843483

3485-
static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
3484+
static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt) /* {{{ */
34863485
{
34873486
zend_ast *var_ast = ast->child[0];
34883487
zend_ast *expr_ast = ast->child[1];
@@ -3572,7 +3571,10 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
35723571
}
35733572
}
35743573

3575-
zend_compile_list_assign(result, var_ast, &expr_node, var_ast->attr, BP_VAR_R);
3574+
zend_compile_list_assign(!stmt ? result : NULL, var_ast, &expr_node, var_ast->attr, BP_VAR_R);
3575+
if (stmt) {
3576+
result->op_type = IS_UNUSED;
3577+
}
35763578
return;
35773579
EMPTY_SWITCH_DEFAULT_CASE();
35783580
}
@@ -11958,6 +11960,12 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
1195811960
case ZEND_AST_CAST_VOID:
1195911961
zend_compile_void_cast(NULL, ast);
1196011962
break;
11963+
case ZEND_AST_ASSIGN: {
11964+
znode result;
11965+
zend_compile_assign(&result, ast, true);
11966+
zend_do_free(&result);
11967+
return;
11968+
}
1196111969
case ZEND_AST_ASSIGN_REF:
1196211970
zend_compile_assign_ref(NULL, ast, BP_VAR_R);
1196311971
return;
@@ -12007,7 +12015,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
1200712015
zend_compile_var(result, ast, BP_VAR_R, false);
1200812016
return;
1200912017
case ZEND_AST_ASSIGN:
12010-
zend_compile_assign(result, ast);
12018+
zend_compile_assign(result, ast, false);
1201112019
return;
1201212020
case ZEND_AST_ASSIGN_REF:
1201312021
zend_compile_assign_ref(result, ast, BP_VAR_R);

0 commit comments

Comments
 (0)