Skip to content

Commit 81fa2f5

Browse files
committed
Add dedicated zend_ast_op_array struct
Given that the `ZEND_AST_OP_ARRAY` type already needed special handling in various places, it makes sense to give it its own struct to avoid some of the casts. As a side benefit, it is a little smaller than the `zend_ast_zval` struct.
1 parent e40543a commit 81fa2f5

File tree

8 files changed

+58
-21
lines changed

8 files changed

+58
-21
lines changed

Zend/zend_ast.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, ze
100100
return (zend_ast *) ast;
101101
}
102102

103+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_op_array(zend_op_array *op_array) {
104+
zend_ast_op_array *ast;
105+
106+
ast = zend_ast_alloc(sizeof(zend_ast_op_array));
107+
ast->kind = ZEND_AST_OP_ARRAY;
108+
ast->attr = 0;
109+
ast->lineno = CG(zend_lineno);
110+
ast->op_array = op_array;
111+
112+
return (zend_ast *) ast;
113+
}
114+
103115
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) {
104116
zend_string *name_str = zend_ast_get_str(name);
105117
if (zend_string_equals_ci(name_str, ZSTR_KNOWN(ZEND_STR_CLASS))) {
@@ -992,7 +1004,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
9921004
}
9931005
case ZEND_AST_OP_ARRAY:
9941006
{
995-
zend_function *func = Z_PTR_P(&((zend_ast_zval*)(ast))->val);
1007+
zend_function *func = (zend_function *)zend_ast_get_op_array(ast)->op_array;
9961008

9971009
zend_create_closure(result, func, scope, scope, NULL);
9981010
return SUCCESS;
@@ -1076,8 +1088,10 @@ static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
10761088
{
10771089
size_t size;
10781090

1079-
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT || ast->kind == ZEND_AST_OP_ARRAY) {
1091+
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
10801092
size = sizeof(zend_ast_zval);
1093+
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
1094+
size = sizeof(zend_ast_op_array);
10811095
} else if (zend_ast_is_list(ast)) {
10821096
uint32_t i;
10831097
zend_ast_list *list = zend_ast_get_list(ast);
@@ -1135,12 +1149,13 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
11351149
}
11361150
}
11371151
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
1138-
zend_ast_zval *new = (zend_ast_zval*)buf;
1139-
new->kind = ZEND_AST_OP_ARRAY;
1140-
new->attr = ast->attr;
1141-
ZVAL_COPY(&new->val, &((zend_ast_zval *) ast)->val);
1142-
Z_LINENO(new->val) = zend_ast_get_lineno(ast);
1143-
buf = (void*)((char*)buf + sizeof(zend_ast_zval));
1152+
zend_ast_op_array *old = zend_ast_get_op_array(ast);
1153+
zend_ast_op_array *new = (zend_ast_op_array*)buf;
1154+
new->kind = old->kind;
1155+
new->attr = old->attr;
1156+
new->lineno = old->lineno;
1157+
new->op_array = old->op_array;
1158+
buf = (void*)((char*)buf + sizeof(zend_ast_op_array));
11441159
} else {
11451160
uint32_t i, children = zend_ast_get_num_children(ast);
11461161
zend_ast *new = (zend_ast*)buf;
@@ -1205,7 +1220,7 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
12051220
} else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
12061221
zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
12071222
} else if (EXPECTED(ast->kind == ZEND_AST_OP_ARRAY)) {
1208-
ZEND_ASSERT(!Z_REFCOUNTED(((zend_ast_zval*)(ast))->val));
1223+
/* Nothing to do. */
12091224
} else if (EXPECTED(ast->kind >= ZEND_AST_FUNC_DECL)) {
12101225
zend_ast_decl *decl = (zend_ast_decl *) ast;
12111226

Zend/zend_ast.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ typedef struct _zend_ast_zval {
207207
zval val;
208208
} zend_ast_zval;
209209

210+
typedef struct _zend_op_array zend_op_array;
211+
212+
typedef struct _zend_ast_op_array {
213+
zend_ast_kind kind;
214+
zend_ast_attr attr;
215+
uint32_t lineno;
216+
zend_op_array *op_array;
217+
} zend_ast_op_array;
218+
210219
/* Separate structure for function and class declaration, as they need extra information. */
211220
typedef struct _zend_ast_decl {
212221
zend_ast_kind kind;
@@ -231,6 +240,8 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval)
231240
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr);
232241
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name);
233242

243+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_op_array(zend_op_array *op_array);
244+
234245
#if ZEND_AST_SPEC
235246
# define ZEND_AST_SPEC_CALL(name, ...) \
236247
ZEND_EXPAND_VA(ZEND_AST_SPEC_CALL_(name, __VA_ARGS__, _n, _5, _4, _3, _2, _1, _0)(__VA_ARGS__))
@@ -349,6 +360,11 @@ static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
349360
return Z_STR_P(zv);
350361
}
351362

363+
static zend_always_inline zend_ast_op_array *zend_ast_get_op_array(zend_ast *ast) {
364+
ZEND_ASSERT(ast->kind == ZEND_AST_OP_ARRAY);
365+
return (zend_ast_op_array *) ast;
366+
}
367+
352368
static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) {
353369
ZEND_ASSERT(ast->kind == ZEND_AST_CONSTANT);
354370
ZEND_ASSERT(Z_TYPE(((zend_ast_zval *) ast)->val) == IS_STRING);
@@ -363,7 +379,7 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
363379
if (ast->kind == ZEND_AST_ZVAL) {
364380
zval *zv = zend_ast_get_zval(ast);
365381
return Z_LINENO_P(zv);
366-
} else if (ast->kind == ZEND_AST_CONSTANT || ast->kind == ZEND_AST_OP_ARRAY) {
382+
} else if (ast->kind == ZEND_AST_CONSTANT) {
367383
zval *zv = &((zend_ast_zval *) ast)->val;
368384
return Z_LINENO_P(zv);
369385
} else {

Zend/zend_compile.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11220,13 +11220,10 @@ static void zend_compile_const_expr_closure(zend_ast **ast_ptr)
1122011220
}
1122111221

1122211222
znode node;
11223-
zend_op_array *op = zend_compile_func_decl(&node, *ast_ptr, FUNC_DECL_LEVEL_CONSTEXPR);
11223+
zend_op_array *op = zend_compile_func_decl(&node, (zend_ast*)closure_ast, FUNC_DECL_LEVEL_CONSTEXPR);
1122411224

1122511225
zend_ast_destroy(*ast_ptr);
11226-
zval z;
11227-
ZVAL_PTR(&z, op);
11228-
*ast_ptr = zend_ast_create_zval(&z);
11229-
(*ast_ptr)->kind = ZEND_AST_OP_ARRAY;
11226+
*ast_ptr = zend_ast_create_op_array(op);
1123011227
}
1123111228

1123211229
static void zend_compile_const_expr_args(zend_ast **ast_ptr)

ext/opcache/zend_file_cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ static void zend_file_cache_serialize_ast(zend_ast *ast,
365365
}
366366
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
367367
/* The op_array itself will be serialized as part of the dynamic_func_defs. */
368-
SERIALIZE_PTR(Z_PTR(((zend_ast_zval*)ast)->val));
368+
SERIALIZE_PTR(zend_ast_get_op_array(ast)->op_array);
369369
} else {
370370
uint32_t children = zend_ast_get_num_children(ast);
371371
for (i = 0; i < children; i++) {
@@ -1247,7 +1247,7 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast,
12471247
}
12481248
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
12491249
/* The op_array itself will be unserialized as part of the dynamic_func_defs. */
1250-
UNSERIALIZE_PTR(Z_PTR(((zend_ast_zval*)ast)->val));
1250+
UNSERIALIZE_PTR(zend_ast_get_op_array(ast)->op_array);
12511251
} else {
12521252
uint32_t children = zend_ast_get_num_children(ast);
12531253
for (i = 0; i < children; i++) {

ext/opcache/zend_persist.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,11 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
189189
}
190190
node = (zend_ast *) copy;
191191
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
192-
zend_ast_zval *copy = zend_shared_memdup(ast, sizeof(zend_ast_zval));
193-
zend_persist_op_array(&copy->val);
192+
zend_ast_op_array *copy = zend_shared_memdup(ast, sizeof(zend_ast_op_array));
193+
zval z;
194+
ZVAL_PTR(&z, copy->op_array);
195+
zend_persist_op_array(&z);
196+
copy->op_array = Z_PTR(z);
194197
node = (zend_ast *) copy;
195198
} else {
196199
uint32_t children = zend_ast_get_num_children(ast);

ext/opcache/zend_persist_calc.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@ static void zend_persist_ast_calc(zend_ast *ast)
8787
}
8888
}
8989
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
90-
ADD_SIZE(sizeof(zend_ast_zval));
91-
zend_persist_op_array_calc(&((zend_ast_zval*)(ast))->val);
90+
ADD_SIZE(sizeof(zend_ast_op_array));
91+
zval z;
92+
ZVAL_PTR(&z, zend_ast_get_op_array(ast)->op_array);
93+
zend_persist_op_array_calc(&z);
9294
} else {
9395
uint32_t children = zend_ast_get_num_children(ast);
9496
ADD_SIZE(zend_ast_size(children));

main/debug_gdb_scripts.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,8 @@ asm(
860860
".ascii \"\\n\"\n"
861861
".ascii \" if kind == enum_value('ZEND_AST_ZVAL') or kind == enum_value('ZEND_AST_CONSTANT'):\\n\"\n"
862862
".ascii \" return self.val.cast(gdb.lookup_type('zend_ast_zval'))\\n\"\n"
863+
".ascii \" if kind == enum_value('ZEND_AST_OP_ARRAY'):\\n\"\n"
864+
".ascii \" return self.val.cast(gdb.lookup_type('zend_ast_op_array'))\\n\"\n"
863865
".ascii \" if kind == enum_value('ZEND_AST_ZNODE'):\\n\"\n"
864866
".ascii \" return self.val.cast(gdb.lookup_type('zend_ast_znode'))\\n\"\n"
865867
".ascii \" if self.is_decl():\\n\"\n"

scripts/gdb/php_gdb.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ def cast(self):
190190

191191
if kind == enum_value('ZEND_AST_ZVAL') or kind == enum_value('ZEND_AST_CONSTANT'):
192192
return self.val.cast(gdb.lookup_type('zend_ast_zval'))
193+
if kind == enum_value('ZEND_AST_OP_ARRAY'):
194+
return self.val.cast(gdb.lookup_type('zend_ast_op_array'))
193195
if kind == enum_value('ZEND_AST_ZNODE'):
194196
return self.val.cast(gdb.lookup_type('zend_ast_znode'))
195197
if self.is_decl():

0 commit comments

Comments
 (0)