mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix caching of default params with side-effects
Fixes GH-9965 Closes GH-9935
This commit is contained in:
parent
649083d05a
commit
8731fb2d09
8 changed files with 84 additions and 43 deletions
2
NEWS
2
NEWS
|
@ -16,6 +16,8 @@ PHP NEWS
|
|||
executed on threads not managed by TSRM. (Kévin Dunglas)
|
||||
. Fixed potential NULL pointer dereference Windows shm*() functions. (cmb)
|
||||
. Added shadow stack support for fibers. (Chen Hu)
|
||||
. Fix bug GH-9965 (Fix accidental caching of default arguments with side
|
||||
effects). (ilutov)
|
||||
|
||||
- Fileinfo:
|
||||
. Upgrade bundled libmagic to 5.43. (Anatol)
|
||||
|
|
25
Zend/tests/function_default_argument_cache.phpt
Normal file
25
Zend/tests/function_default_argument_cache.phpt
Normal file
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
Function default argument is not cached when its evaluation had side effects
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
public function __toString() {
|
||||
static $i = 0;
|
||||
return (string) $i++;
|
||||
}
|
||||
}
|
||||
|
||||
function test(string $foo = new Foo() . '') {
|
||||
var_dump($foo);
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "0"
|
||||
string(1) "1"
|
||||
string(1) "2"
|
|
@ -498,17 +498,17 @@ zend_class_entry *zend_ast_fetch_class(zend_ast *ast, zend_class_entry *scope)
|
|||
return zend_fetch_class_with_scope(zend_ast_get_str(ast), (ast->attr >> ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT) | ZEND_FETCH_CLASS_EXCEPTION, scope);
|
||||
}
|
||||
|
||||
static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *ast, zend_class_entry *scope, bool *short_circuited_ptr)
|
||||
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *ast, zend_class_entry *scope, zend_ast_evaluate_ctx *ctx)
|
||||
{
|
||||
zval op1, op2;
|
||||
zend_result ret = SUCCESS;
|
||||
*short_circuited_ptr = false;
|
||||
ctx->short_circuited = false;
|
||||
|
||||
switch (ast->kind) {
|
||||
case ZEND_AST_BINARY_OP:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
} else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
} else if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
} else {
|
||||
|
@ -520,9 +520,9 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
break;
|
||||
case ZEND_AST_GREATER:
|
||||
case ZEND_AST_GREATER_EQUAL:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
} else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
} else if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
} else {
|
||||
|
@ -535,7 +535,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
}
|
||||
break;
|
||||
case ZEND_AST_UNARY_OP:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
} else {
|
||||
unary_op_type op = get_unary_op(ast->attr);
|
||||
|
@ -588,12 +588,12 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
}
|
||||
break;
|
||||
case ZEND_AST_AND:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
if (zend_is_true(&op1)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
|
@ -606,14 +606,14 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
zval_ptr_dtor_nogc(&op1);
|
||||
break;
|
||||
case ZEND_AST_OR:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
if (zend_is_true(&op1)) {
|
||||
ZVAL_TRUE(result);
|
||||
} else {
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
|
@ -624,7 +624,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
zval_ptr_dtor_nogc(&op1);
|
||||
break;
|
||||
case ZEND_AST_CONDITIONAL:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
if (!ast->child[1]) {
|
||||
*result = op1;
|
||||
} else {
|
||||
if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(result, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
|
@ -640,7 +640,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
zval_ptr_dtor_nogc(&op1);
|
||||
}
|
||||
} else {
|
||||
if (UNEXPECTED(zend_ast_evaluate(result, ast->child[2], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(result, ast->child[2], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
|
@ -649,14 +649,14 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
}
|
||||
break;
|
||||
case ZEND_AST_COALESCE:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
if (Z_TYPE(op1) > IS_NULL) {
|
||||
*result = op1;
|
||||
} else {
|
||||
if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(result, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
|
@ -665,7 +665,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
}
|
||||
break;
|
||||
case ZEND_AST_UNARY_PLUS:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
} else {
|
||||
ZVAL_LONG(&op1, 0);
|
||||
|
@ -674,7 +674,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
}
|
||||
break;
|
||||
case ZEND_AST_UNARY_MINUS:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
} else {
|
||||
ZVAL_LONG(&op1, 0);
|
||||
|
@ -695,7 +695,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
for (i = 0; i < list->children; i++) {
|
||||
zend_ast *elem = list->child[i];
|
||||
if (elem->kind == ZEND_AST_UNPACK) {
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, elem->child[0], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(result);
|
||||
return FAILURE;
|
||||
}
|
||||
|
@ -708,14 +708,14 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
continue;
|
||||
}
|
||||
if (elem->child[1]) {
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, elem->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(result);
|
||||
return FAILURE;
|
||||
}
|
||||
} else {
|
||||
ZVAL_UNDEF(&op1);
|
||||
}
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, elem->child[0], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, elem->child[0], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
zval_ptr_dtor_nogc(result);
|
||||
return FAILURE;
|
||||
|
@ -734,13 +734,11 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
|
||||
bool short_circuited;
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
if (short_circuited) {
|
||||
*short_circuited_ptr = true;
|
||||
if (ctx->short_circuited) {
|
||||
ZVAL_NULL(result);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -753,7 +751,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
break;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
|
@ -787,7 +785,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
zval case_value_zv;
|
||||
ZVAL_UNDEF(&case_value_zv);
|
||||
if (case_value_ast != NULL) {
|
||||
if (UNEXPECTED(zend_ast_evaluate(&case_value_zv, case_value_ast, scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&case_value_zv, case_value_ast, scope, ctx) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -834,6 +832,9 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
return FAILURE;
|
||||
}
|
||||
|
||||
/* Even if there is no constructor, the object can have cause side-effects in various ways (__toString(), __get(), __isset(), etc). */
|
||||
ctx->had_side_effects = true;
|
||||
|
||||
zend_ast_list *args_ast = zend_ast_get_list(ast->child[1]);
|
||||
if (args_ast->attr) {
|
||||
/* Has named arguments. */
|
||||
|
@ -846,7 +847,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
name = zend_ast_get_str(arg_ast->child[0]);
|
||||
arg_ast = arg_ast->child[1];
|
||||
}
|
||||
if (zend_ast_evaluate(&arg, arg_ast, scope) == FAILURE) {
|
||||
if (zend_ast_evaluate_ex(&arg, arg_ast, scope, ctx) == FAILURE) {
|
||||
zend_array_destroy(args);
|
||||
zval_ptr_dtor(result);
|
||||
return FAILURE;
|
||||
|
@ -876,7 +877,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
ALLOCA_FLAG(use_heap)
|
||||
zval *args = do_alloca(sizeof(zval) * args_ast->children, use_heap);
|
||||
for (uint32_t i = 0; i < args_ast->children; i++) {
|
||||
if (zend_ast_evaluate(&args[i], args_ast->child[i], scope) == FAILURE) {
|
||||
if (zend_ast_evaluate_ex(&args[i], args_ast->child[i], scope, ctx) == FAILURE) {
|
||||
for (uint32_t j = 0; j < i; j++) {
|
||||
zval_ptr_dtor(&args[j]);
|
||||
}
|
||||
|
@ -908,22 +909,20 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
case ZEND_AST_PROP:
|
||||
case ZEND_AST_NULLSAFE_PROP:
|
||||
{
|
||||
bool short_circuited;
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, ctx) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
if (short_circuited) {
|
||||
*short_circuited_ptr = true;
|
||||
if (ctx->short_circuited) {
|
||||
ZVAL_NULL(result);
|
||||
return SUCCESS;
|
||||
}
|
||||
if (ast->kind == ZEND_AST_NULLSAFE_PROP && Z_TYPE(op1) == IS_NULL) {
|
||||
*short_circuited_ptr = true;
|
||||
ctx->short_circuited = true;
|
||||
ZVAL_NULL(result);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(&op1);
|
||||
return FAILURE;
|
||||
}
|
||||
|
@ -976,8 +975,8 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as
|
|||
|
||||
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope)
|
||||
{
|
||||
bool short_circuited;
|
||||
return zend_ast_evaluate_ex(result, ast, scope, &short_circuited);
|
||||
zend_ast_evaluate_ctx ctx = {0};
|
||||
return zend_ast_evaluate_ex(result, ast, scope, &ctx);
|
||||
}
|
||||
|
||||
static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
|
||||
|
|
|
@ -297,7 +297,13 @@ ZEND_API zend_ast *zend_ast_create_decl(
|
|||
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
bool had_side_effects;
|
||||
bool short_circuited;
|
||||
} zend_ast_evaluate_ctx;
|
||||
|
||||
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope);
|
||||
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *ast, zend_class_entry *scope, zend_ast_evaluate_ctx *ctx);
|
||||
ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix);
|
||||
|
||||
ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast);
|
||||
|
|
|
@ -179,6 +179,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
|
|||
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant(zval *pp);
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *pp, zend_class_entry *scope);
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_with_ctx(zval *pp, zend_class_entry *scope, zend_ast_evaluate_ctx *ctx);
|
||||
|
||||
/* dedicated Zend executor functions - do not use! */
|
||||
struct _zend_vm_stack {
|
||||
|
|
|
@ -670,7 +670,7 @@ ZEND_API bool zend_is_executing(void) /* {{{ */
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_with_ctx(zval *p, zend_class_entry *scope, zend_ast_evaluate_ctx *ctx)
|
||||
{
|
||||
if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
|
||||
zend_ast *ast = Z_ASTVAL_P(p);
|
||||
|
@ -687,7 +687,7 @@ ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_e
|
|||
} else {
|
||||
zval tmp;
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(&tmp, ast, scope) != SUCCESS)) {
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&tmp, ast, scope, ctx) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
zval_ptr_dtor_nogc(p);
|
||||
|
@ -698,6 +698,12 @@ ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_e
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_entry *scope)
|
||||
{
|
||||
zend_ast_evaluate_ctx ctx = {0};
|
||||
return zval_update_constant_with_ctx(p, scope, &ctx);
|
||||
}
|
||||
|
||||
ZEND_API zend_result ZEND_FASTCALL zval_update_constant(zval *pp) /* {{{ */
|
||||
{
|
||||
return zval_update_constant_ex(pp, EG(current_execute_data) ? zend_get_executed_scope() : CG(active_class_entry));
|
||||
|
|
|
@ -5510,12 +5510,13 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT)
|
|||
} else {
|
||||
SAVE_OPLINE();
|
||||
ZVAL_COPY(param, default_value);
|
||||
if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
zend_ast_evaluate_ctx ctx = {0};
|
||||
if (UNEXPECTED(zval_update_constant_with_ctx(param, EX(func)->op_array.scope, &ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(param);
|
||||
ZVAL_UNDEF(param);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
if (!Z_REFCOUNTED_P(param)) {
|
||||
if (!Z_REFCOUNTED_P(param) && !ctx.had_side_effects) {
|
||||
ZVAL_COPY_VALUE(cache_val, param);
|
||||
}
|
||||
}
|
||||
|
|
5
Zend/zend_vm_execute.h
generated
5
Zend/zend_vm_execute.h
generated
|
@ -3834,12 +3834,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON
|
|||
} else {
|
||||
SAVE_OPLINE();
|
||||
ZVAL_COPY(param, default_value);
|
||||
if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
zend_ast_evaluate_ctx ctx = {0};
|
||||
if (UNEXPECTED(zval_update_constant_with_ctx(param, EX(func)->op_array.scope, &ctx) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(param);
|
||||
ZVAL_UNDEF(param);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
if (!Z_REFCOUNTED_P(param)) {
|
||||
if (!Z_REFCOUNTED_P(param) && !ctx.had_side_effects) {
|
||||
ZVAL_COPY_VALUE(cache_val, param);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue