mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Add dedicated zend_ast_op_array
struct (#17391)
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.
This commit is contained in:
parent
fd1eacc2ed
commit
cee64ed3bd
8 changed files with 58 additions and 21 deletions
|
@ -100,6 +100,18 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, ze
|
|||
return (zend_ast *) ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_op_array(zend_op_array *op_array) {
|
||||
zend_ast_op_array *ast;
|
||||
|
||||
ast = zend_ast_alloc(sizeof(zend_ast_op_array));
|
||||
ast->kind = ZEND_AST_OP_ARRAY;
|
||||
ast->attr = 0;
|
||||
ast->lineno = CG(zend_lineno);
|
||||
ast->op_array = op_array;
|
||||
|
||||
return (zend_ast *) ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) {
|
||||
zend_string *name_str = zend_ast_get_str(name);
|
||||
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(
|
|||
}
|
||||
case ZEND_AST_OP_ARRAY:
|
||||
{
|
||||
zend_function *func = Z_PTR_P(&((zend_ast_zval*)(ast))->val);
|
||||
zend_function *func = (zend_function *)zend_ast_get_op_array(ast)->op_array;
|
||||
|
||||
zend_create_closure(result, func, scope, scope, NULL);
|
||||
return SUCCESS;
|
||||
|
@ -1076,8 +1088,10 @@ static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
|
|||
{
|
||||
size_t size;
|
||||
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT || ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
|
||||
size = sizeof(zend_ast_zval);
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
size = sizeof(zend_ast_op_array);
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
uint32_t i;
|
||||
zend_ast_list *list = zend_ast_get_list(ast);
|
||||
|
@ -1138,12 +1152,13 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
|
|||
}
|
||||
}
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
zend_ast_zval *new = (zend_ast_zval*)buf;
|
||||
new->kind = ZEND_AST_OP_ARRAY;
|
||||
new->attr = ast->attr;
|
||||
ZVAL_COPY(&new->val, &((zend_ast_zval *) ast)->val);
|
||||
Z_LINENO(new->val) = zend_ast_get_lineno(ast);
|
||||
buf = (void*)((char*)buf + sizeof(zend_ast_zval));
|
||||
zend_ast_op_array *old = zend_ast_get_op_array(ast);
|
||||
zend_ast_op_array *new = (zend_ast_op_array*)buf;
|
||||
new->kind = old->kind;
|
||||
new->attr = old->attr;
|
||||
new->lineno = old->lineno;
|
||||
new->op_array = old->op_array;
|
||||
buf = (void*)((char*)buf + sizeof(zend_ast_op_array));
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
|
@ -1211,7 +1226,7 @@ tail_call:
|
|||
} else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
|
||||
zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
|
||||
} else if (EXPECTED(ast->kind == ZEND_AST_OP_ARRAY)) {
|
||||
ZEND_ASSERT(!Z_REFCOUNTED(((zend_ast_zval*)(ast))->val));
|
||||
/* Nothing to do. */
|
||||
} else if (EXPECTED(zend_ast_is_decl(ast))) {
|
||||
zend_ast_decl *decl = (zend_ast_decl *) ast;
|
||||
|
||||
|
|
|
@ -207,6 +207,15 @@ typedef struct _zend_ast_zval {
|
|||
zval val;
|
||||
} zend_ast_zval;
|
||||
|
||||
typedef struct _zend_op_array zend_op_array;
|
||||
|
||||
typedef struct _zend_ast_op_array {
|
||||
zend_ast_kind kind;
|
||||
zend_ast_attr attr;
|
||||
uint32_t lineno;
|
||||
zend_op_array *op_array;
|
||||
} zend_ast_op_array;
|
||||
|
||||
/* Separate structure for function and class declaration, as they need extra information. */
|
||||
typedef struct _zend_ast_decl {
|
||||
zend_ast_kind kind;
|
||||
|
@ -231,6 +240,8 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval)
|
|||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr);
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name);
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_op_array(zend_op_array *op_array);
|
||||
|
||||
#if ZEND_AST_SPEC
|
||||
# define ZEND_AST_SPEC_CALL(name, ...) \
|
||||
ZEND_EXPAND_VA(ZEND_AST_SPEC_CALL_(name, __VA_ARGS__, _n, _5, _4, _3, _2, _1, _0)(__VA_ARGS__))
|
||||
|
@ -353,6 +364,11 @@ static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
|
|||
return Z_STR_P(zv);
|
||||
}
|
||||
|
||||
static zend_always_inline zend_ast_op_array *zend_ast_get_op_array(zend_ast *ast) {
|
||||
ZEND_ASSERT(ast->kind == ZEND_AST_OP_ARRAY);
|
||||
return (zend_ast_op_array *) ast;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) {
|
||||
ZEND_ASSERT(ast->kind == ZEND_AST_CONSTANT);
|
||||
ZEND_ASSERT(Z_TYPE(((zend_ast_zval *) ast)->val) == IS_STRING);
|
||||
|
@ -369,7 +385,7 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
|
|||
if (ast->kind == ZEND_AST_ZVAL) {
|
||||
zval *zv = zend_ast_get_zval(ast);
|
||||
return Z_LINENO_P(zv);
|
||||
} else if (ast->kind == ZEND_AST_CONSTANT || ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
} else if (ast->kind == ZEND_AST_CONSTANT) {
|
||||
zval *zv = &((zend_ast_zval *) ast)->val;
|
||||
return Z_LINENO_P(zv);
|
||||
} else {
|
||||
|
|
|
@ -11220,13 +11220,10 @@ static void zend_compile_const_expr_closure(zend_ast **ast_ptr)
|
|||
}
|
||||
|
||||
znode node;
|
||||
zend_op_array *op = zend_compile_func_decl(&node, *ast_ptr, FUNC_DECL_LEVEL_CONSTEXPR);
|
||||
zend_op_array *op = zend_compile_func_decl(&node, (zend_ast*)closure_ast, FUNC_DECL_LEVEL_CONSTEXPR);
|
||||
|
||||
zend_ast_destroy(*ast_ptr);
|
||||
zval z;
|
||||
ZVAL_PTR(&z, op);
|
||||
*ast_ptr = zend_ast_create_zval(&z);
|
||||
(*ast_ptr)->kind = ZEND_AST_OP_ARRAY;
|
||||
*ast_ptr = zend_ast_create_op_array(op);
|
||||
}
|
||||
|
||||
static void zend_compile_const_expr_args(zend_ast **ast_ptr)
|
||||
|
|
|
@ -365,7 +365,7 @@ static void zend_file_cache_serialize_ast(zend_ast *ast,
|
|||
}
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
/* The op_array itself will be serialized as part of the dynamic_func_defs. */
|
||||
SERIALIZE_PTR(Z_PTR(((zend_ast_zval*)ast)->val));
|
||||
SERIALIZE_PTR(zend_ast_get_op_array(ast)->op_array);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
|
@ -1250,7 +1250,7 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast,
|
|||
}
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
/* The op_array itself will be unserialized as part of the dynamic_func_defs. */
|
||||
UNSERIALIZE_PTR(Z_PTR(((zend_ast_zval*)ast)->val));
|
||||
UNSERIALIZE_PTR(zend_ast_get_op_array(ast)->op_array);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
|
|
|
@ -189,8 +189,11 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
|
|||
}
|
||||
node = (zend_ast *) copy;
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
zend_ast_zval *copy = zend_shared_memdup(ast, sizeof(zend_ast_zval));
|
||||
zend_persist_op_array(©->val);
|
||||
zend_ast_op_array *copy = zend_shared_memdup(ast, sizeof(zend_ast_op_array));
|
||||
zval z;
|
||||
ZVAL_PTR(&z, copy->op_array);
|
||||
zend_persist_op_array(&z);
|
||||
copy->op_array = Z_PTR(z);
|
||||
node = (zend_ast *) copy;
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
|
|
|
@ -87,8 +87,10 @@ static void zend_persist_ast_calc(zend_ast *ast)
|
|||
}
|
||||
}
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
ADD_SIZE(sizeof(zend_ast_zval));
|
||||
zend_persist_op_array_calc(&((zend_ast_zval*)(ast))->val);
|
||||
ADD_SIZE(sizeof(zend_ast_op_array));
|
||||
zval z;
|
||||
ZVAL_PTR(&z, zend_ast_get_op_array(ast)->op_array);
|
||||
zend_persist_op_array_calc(&z);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
|
|
|
@ -860,6 +860,8 @@ asm(
|
|||
".ascii \"\\n\"\n"
|
||||
".ascii \" if kind == enum_value('ZEND_AST_ZVAL') or kind == enum_value('ZEND_AST_CONSTANT'):\\n\"\n"
|
||||
".ascii \" return self.val.cast(gdb.lookup_type('zend_ast_zval'))\\n\"\n"
|
||||
".ascii \" if kind == enum_value('ZEND_AST_OP_ARRAY'):\\n\"\n"
|
||||
".ascii \" return self.val.cast(gdb.lookup_type('zend_ast_op_array'))\\n\"\n"
|
||||
".ascii \" if kind == enum_value('ZEND_AST_ZNODE'):\\n\"\n"
|
||||
".ascii \" return self.val.cast(gdb.lookup_type('zend_ast_znode'))\\n\"\n"
|
||||
".ascii \" if self.is_decl():\\n\"\n"
|
||||
|
|
|
@ -190,6 +190,8 @@ class ZendAstPrettyPrinter(gdb.printing.PrettyPrinter):
|
|||
|
||||
if kind == enum_value('ZEND_AST_ZVAL') or kind == enum_value('ZEND_AST_CONSTANT'):
|
||||
return self.val.cast(gdb.lookup_type('zend_ast_zval'))
|
||||
if kind == enum_value('ZEND_AST_OP_ARRAY'):
|
||||
return self.val.cast(gdb.lookup_type('zend_ast_op_array'))
|
||||
if kind == enum_value('ZEND_AST_ZNODE'):
|
||||
return self.val.cast(gdb.lookup_type('zend_ast_znode'))
|
||||
if self.is_decl():
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue