1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Emit EXT_STMT after each pipe stage, and attach the TMP var that holds the intermediary result (#19377)

* Emit EXT_STMT after each pipe stage, and attach the TMP var that holds the intermediary result
* Add ZEND_EXT_STMT to keeps_op1_alive as per review
* Fix leak with EXT_STMT when pipe result is unused

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
This commit is contained in:
Derick Rethans
2025-08-12 10:26:06 +01:00
committed by GitHub
parent 07a9c25c71
commit 4d6dde595c
3 changed files with 22 additions and 7 deletions

View File

@@ -420,6 +420,14 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
}
break;
case ZEND_EXT_STMT:
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
/* Variable will be deleted later by FREE, so we can't optimize it */
Tsource[VAR_NUM(opline->op1.var)] = NULL;
break;
}
break;
case ZEND_CASE:
case ZEND_CASE_STRICT:
case ZEND_COPY_TMP:

View File

@@ -821,7 +821,8 @@ static void zend_do_free(znode *op1) /* {{{ */
} else {
while (opline >= CG(active_op_array)->opcodes) {
if ((opline->opcode == ZEND_FETCH_LIST_R ||
opline->opcode == ZEND_FETCH_LIST_W) &&
opline->opcode == ZEND_FETCH_LIST_W ||
opline->opcode == ZEND_EXT_STMT) &&
opline->op1_type == IS_VAR &&
opline->op1.var == op1->u.op.var) {
zend_emit_op(NULL, ZEND_FREE, op1, NULL);
@@ -1920,7 +1921,7 @@ static void zend_add_to_list(void *result, void *item) /* {{{ */
}
/* }}} */
static void zend_do_extended_stmt(void) /* {{{ */
static void zend_do_extended_stmt(znode* result) /* {{{ */
{
zend_op *opline;
@@ -1931,6 +1932,9 @@ static void zend_do_extended_stmt(void) /* {{{ */
opline = get_next_op();
opline->opcode = ZEND_EXT_STMT;
if (result) {
SET_NODE(opline->op1, result);
}
}
/* }}} */
@@ -6050,7 +6054,7 @@ static void zend_compile_for(zend_ast *ast) /* {{{ */
zend_update_jump_target_to_next(opnum_jmp);
zend_compile_for_expr_list(&result, cond_ast);
zend_do_extended_stmt();
zend_do_extended_stmt(NULL);
zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start);
@@ -6171,7 +6175,7 @@ static void zend_compile_if(zend_ast *ast) /* {{{ */
if (i > 0) {
CG(zend_lineno) = cond_ast->lineno;
zend_do_extended_stmt();
zend_do_extended_stmt(NULL);
}
zend_compile_expr(&cond_node, cond_ast);
@@ -6505,6 +6509,8 @@ static void zend_compile_pipe(znode *result, zend_ast *ast)
}
zend_compile_expr(result, fcall_ast);
CG(zend_lineno) = fcall_ast->lineno;
zend_do_extended_stmt(result);
}
static void zend_compile_match(znode *result, zend_ast *ast)
@@ -8537,7 +8543,7 @@ static zend_op_array *zend_compile_func_decl_ex(
/* put the implicit return on the really last line */
CG(zend_lineno) = decl->end_lineno;
zend_do_extended_stmt();
zend_do_extended_stmt(NULL);
zend_emit_final_return(0);
pass_two(CG(active_op_array));
@@ -11607,7 +11613,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
CG(zend_lineno) = ast->lineno;
if ((CG(compiler_options) & ZEND_COMPILE_EXTENDED_STMT) && !zend_is_unticked_stmt(ast)) {
zend_do_extended_stmt();
zend_do_extended_stmt(NULL);
}
switch (ast->kind) {

View File

@@ -903,7 +903,8 @@ static bool keeps_op1_alive(zend_op *opline) {
|| opline->opcode == ZEND_MATCH_ERROR
|| opline->opcode == ZEND_FETCH_LIST_R
|| opline->opcode == ZEND_FETCH_LIST_W
|| opline->opcode == ZEND_COPY_TMP) {
|| opline->opcode == ZEND_COPY_TMP
|| opline->opcode == ZEND_EXT_STMT) {
return 1;
}
ZEND_ASSERT(opline->opcode != ZEND_FE_FETCH_R