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:
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user