8000 Handle lifecycle of static variables in const-expression · php/php-src@f54c7ce · GitHub
[go: up one dir, main page]

Skip to content

Commit f54c7ce

Browse files
committed
Handle lifecycle of static variables in const-expression
1 parent 398e73a commit f54c7ce

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
--TEST--
2+
Closures in const expressions support static variables.
3+
--FILE--
4+
<?php
5+
6+
const Closure = static function () {
7+
static $x = [];
8+
static $i = 1;
9+
$i *= 2;
10+
$x[] = $i;
11+
var_dump($x);
12+
};
13+
14+
var_dump(Closure);
15+
(Closure)();
16+
(Closure)();
17+
(Closure)();
18+
var_dump(Closure);
19+
20+
?>
21+
--EXPECTF--
22+
object(Closure)#%d (4) {
23+
["name"]=>
24+
string(%d) "{closure:%s:%d}"
25+
["file"]=>
26+
string(%d) "%s"
27+
["line"]=>
28+
int(3)
29+
["static"]=>
30+
array(2) {
31+
["x"]=>
32+
array(0) {
33+
}
34+
["i"]=>
35+
int(1)
36+
}
37+
}
38+
array(1) {
39+
[0]=>
40+
int(2)
41+
}
42+
array(2) {
43+
[0]=>
44+
int(2)
45+
[1]=>
46+
int(4)
47+
}
48+
array(3) {
49+
[0]=>
50+
int(2)
51+
[1]=>
52+
int(4)
53+
[2]=>
54+
int(8)
55+
}
56+
object(Closure)#%d (4) {
57+
["name"]=>
58+
string(%d) "{closure:%s:%d}"
59+
["file"]=>
60+
string(%d) "%s"
61+
["line"]=>
62+
int(3)
63+
["static"]=>
64+
array(2) {
65+
["x"]=>
66+
array(3) {
67+
[0]=>
68+
int(2)
69+
[1]=>
70+
int(4)
71+
[2]=>
72+
int(8)
73+
}
74+
["i"]=>
75+
int(8)
76+
}
77+
}

Zend/zend_ast.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,9 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
12781278
new->lineno = old->lineno;
12791279
new->op_array = old->op_array;
12801280
function_add_ref((zend_function *)new->op_array);
1281+
if (new->op_array->static_variables) {
1282+
GC_TRY_ADDREF(new->op_array->static_variables);
1283+
}
12811284
buf = (void*)((char*)buf + sizeof(zend_ast_op_array));
12821285
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
12831286
zend_ast_fcc *old = (zend_ast_fcc*)ast;
@@ -1354,6 +1357,9 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
13541357
} else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
13551358
zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
13561359
} else if (EXPECTED(ast->kind == ZEND_AST_OP_ARRAY)) {
1360+
if (zend_ast_get_op_array(ast)->op_array->static_variables) {
1361+
zend_array_release(zend_ast_get_op_array(ast)->op_array->static_variables);
1362+
}
13571363
destroy_op_array(zend_ast_get_op_array(ast)->op_array);
13581364
} else if (EXPECTED(zend_ast_is_decl(ast))) {
13591365
zend_ast_decl *decl = (zend_ast_decl *) ast;

0 commit comments

Comments
 (0)
0