Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions Zend/Optimizer/block_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,29 +289,34 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
MAKE_NOP(opline);
++(*opt_count);
break;
case ZEND_ASSIGN:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_PRE_INC_STATIC_PROP:
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_QM_ASSIGN:
if (src < op_array->opcodes + block->start) {
break;
}
src->result_type = IS_UNUSED;
VAR_SOURCE(opline->op1) = NULL;
MAKE_NOP(opline);
++(*opt_count);
if (src->op1_type & (IS_VAR|IS_TMP_VAR)) {
src->opcode = ZEND_FREE;
} else if (src->op1_type == IS_CONST) {
MAKE_NOP(src);
} else if (src->op1_type == IS_CV) {
src->opcode = ZEND_CHECK_VAR;
SET_UNUSED(src->result);
}
break;
default:
if (!zend_op_may_elide_result(src->opcode)) {
break;
}
if (src < op_array->opcodes + block->start) {
break;
}
src->result_type = IS_UNUSED;
VAR_SOURCE(opline->op1) = NULL;
MAKE_NOP(opline);
++(*opt_count);
break;
}
}
Expand Down
9 changes: 8 additions & 1 deletion Zend/Optimizer/dce.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ static inline bool may_have_side_effects(
case ZEND_FUNC_GET_ARGS:
case ZEND_ARRAY_KEY_EXISTS:
case ZEND_COPY_TMP:
case ZEND_DEREF:
/* No side effects */
return false;
case ZEND_FREE:
Expand Down Expand Up @@ -162,10 +163,16 @@ static inline bool may_have_side_effects(
case ZEND_EXT_FCALL_END:
case ZEND_TICKS:
case ZEND_YIELD:
case ZEND_YIELD_FROM:
case ZEND_VERIFY_NEVER_TYPE:
/* Intrinsic side effects */
return true;
case ZEND_YIELD_FROM: {
uint32_t t1 = OP1_INFO();
if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY && MAY_BE_EMPTY_ONLY(t1)) {
return false;
}
return true;
}
case ZEND_DO_FCALL:
case ZEND_DO_FCALL_BY_NAME:
case ZEND_DO_ICALL:
Expand Down
8 changes: 8 additions & 0 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -5033,6 +5033,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
case ZEND_COPY_TMP:
case ZEND_JMP_NULL:
case ZEND_JMP_FRAMELESS:
case ZEND_DEREF:
return 0;
case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL:
Expand Down Expand Up @@ -5336,6 +5337,13 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
return 1;
}
return 0;
case ZEND_YIELD_FROM: {
uint32_t t1 = OP1_INFO();
if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY && MAY_BE_EMPTY_ONLY(t1)) {
return false;
}
return true;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YIELD_FROM from generators can throw if the generator is closed, even for empty arrays. So this optimization may be unsound.

}
default:
return 1;
}
Expand Down
2 changes: 2 additions & 0 deletions Zend/tests/list/bug73663.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
--TEST--
Bug #73663 ("Invalid opcode 65/16/8" occurs with a variable created with list())
--XFAIL--
list() assign resulting in a ref only when there's a single by-ref fetch is kinda weird.
--FILE--
<?php
function change(&$ref) {
Expand Down
8 changes: 4 additions & 4 deletions Zend/tests/operator_unsupported_types.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ Unsupported operand types: stdClass * stdClass
Unsupported operand types: stdClass * resource
Unsupported operand types: stdClass * string
Unsupported operand types: resource * array
Unsupported operand types: stdClass * resource
Unsupported operand types: resource * stdClass
Unsupported operand types: resource * resource
Unsupported operand types: resource * string
Unsupported operand types: string * array
Expand Down Expand Up @@ -753,7 +753,7 @@ Unsupported operand types: stdClass & stdClass
Unsupported operand types: stdClass & resource
Unsupported operand types: stdClass & string
Unsupported operand types: resource & array
Unsupported operand types: stdClass & resource
Unsupported operand types: resource & stdClass
Unsupported operand types: resource & resource
Unsupported operand types: resource & string
Unsupported operand types: string & array
Expand Down Expand Up @@ -828,7 +828,7 @@ Unsupported operand types: stdClass | stdClass
Unsupported operand types: stdClass | resource
Unsupported operand types: stdClass | string
Unsupported operand types: resource | array
Unsupported operand types: stdClass | resource
Unsupported operand types: resource | stdClass
Unsupported operand types: resource | resource
Unsupported operand types: resource | string
Unsupported operand types: string | array
Expand Down Expand Up @@ -903,7 +903,7 @@ Unsupported operand types: stdClass ^ stdClass
Unsupported operand types: stdClass ^ resource
Unsupported operand types: stdClass ^ string
Unsupported operand types: resource ^ array
Unsupported operand types: stdClass ^ resource
Unsupported operand types: resource ^ stdClass
Unsupported operand types: resource ^ resource
Unsupported operand types: resource ^ string
Unsupported operand types: string ^ array
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_closures.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ {
fcc.called_scope = zend_get_called_scope(EG(current_execute_data));

zend_call_function(&fci, &fcc);

zend_return_unwrap_ref(EG(current_execute_data), return_value);
zval_ptr_dtor(&fci.params[1]);
}
/* }}} */
Expand Down
Loading