diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index de5787895fa..e51c9d699ef 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -23,10 +23,19 @@ #include "zend_API.h" #include "zend_operators.h" -ZEND_API zend_ast *zend_ast_create_znode(znode *node) -{ +static inline void *zend_ast_alloc(size_t size TSRMLS_DC) { + return zend_arena_alloc(&CG(ast_arena), size); +} + +static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size TSRMLS_DC) { + void *new = zend_ast_alloc(new_size TSRMLS_CC); + memcpy(new, old, old_size); + return new; +} + +ZEND_API zend_ast *zend_ast_create_znode(znode *node) { TSRMLS_FETCH(); - zend_ast_znode *ast = zend_arena_alloc(&CG(ast_arena), sizeof(zend_ast_znode)); + zend_ast_znode *ast = zend_ast_alloc(sizeof(zend_ast_znode) TSRMLS_CC); ast->kind = ZEND_AST_ZNODE; ast->attr = 0; ast->lineno = CG(zend_lineno); @@ -34,10 +43,9 @@ ZEND_API zend_ast *zend_ast_create_znode(znode *node) return (zend_ast *) ast; } -ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) -{ +ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { TSRMLS_FETCH(); - zend_ast_zval *ast = zend_arena_alloc(&CG(ast_arena), sizeof(zend_ast_zval)); + zend_ast_zval *ast = zend_ast_alloc(sizeof(zend_ast_zval) TSRMLS_CC); ast->kind = ZEND_AST_ZVAL; ast->attr = attr; ZVAL_COPY_VALUE(&ast->val, zv); @@ -46,19 +54,18 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) } ZEND_API zend_ast *zend_ast_create_decl( - zend_ast_kind kind, zend_uint flags, zend_uint start_lineno, zend_uint end_lineno, - unsigned char *lex_pos, zend_string *doc_comment, zend_string *name, - zend_ast *child0, zend_ast *child1, zend_ast *child2 + zend_ast_kind kind, zend_uint flags, zend_uint start_lineno, zend_string *doc_comment, + zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2 ) { TSRMLS_FETCH(); - zend_ast_decl *ast = zend_arena_alloc(&CG(ast_arena), sizeof(zend_ast_decl)); + zend_ast_decl *ast = zend_ast_alloc(sizeof(zend_ast_decl) TSRMLS_CC); ast->kind = kind; ast->attr = 0; ast->start_lineno = start_lineno; - ast->end_lineno = end_lineno; + ast->end_lineno = CG(zend_lineno); ast->flags = flags; - ast->lex_pos = lex_pos; + ast->lex_pos = LANG_SCNG(yy_text); ast->doc_comment = doc_comment; ast->name = name; ast->child[0] = child0; @@ -75,7 +82,7 @@ static zend_ast *zend_ast_create_from_va_list( zend_uint i; zend_ast *ast; - ast = zend_arena_alloc(&CG(ast_arena), sizeof(zend_ast) + (children - 1) * sizeof(zend_ast *)); + ast = zend_ast_alloc(sizeof(zend_ast) + (children - 1) * sizeof(zend_ast *) TSRMLS_CC); ast->kind = kind; ast->attr = attr; ast->lineno = UINT_MAX; @@ -123,11 +130,14 @@ ZEND_API zend_ast *zend_ast_create( return ast; } +size_t zend_ast_list_size(zend_uint children) { + return sizeof(zend_ast_list) + sizeof(zend_ast *) * (children - 1); +} + ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind) { /* use 4 children as default */ TSRMLS_FETCH(); - zend_ast_list *list = zend_arena_alloc(&CG(ast_arena), - sizeof(zend_ast_list) + sizeof(zend_ast *) * 3); + zend_ast_list *list = zend_ast_alloc(zend_ast_list_size(4) TSRMLS_CC); list->kind = kind; list->attr = 0; list->lineno = CG(zend_lineno); @@ -139,16 +149,12 @@ static inline zend_bool is_power_of_two(unsigned short n) { return n == (n & -n); } -ZEND_API zend_ast *zend_ast_dynamic_add(zend_ast *ast, zend_ast *op) -{ +ZEND_API zend_ast *zend_ast_dynamic_add(zend_ast *ast, zend_ast *op) { zend_ast_list *list = zend_ast_get_list(ast); if (list->children >= 4 && is_power_of_two(list->children)) { TSRMLS_FETCH(); - size_t old_size = sizeof(zend_ast_list) + sizeof(zend_ast *) * (list->children - 1); - zend_ast_list *new_list = zend_arena_alloc(&CG(ast_arena), - sizeof(zend_ast_list) + sizeof(zend_ast *) * (list->children * 2 - 1)); - memcpy(new_list, list, old_size); - list = new_list; + list = zend_ast_realloc(list, + zend_ast_list_size(list->children), zend_ast_list_size(list->children * 2) TSRMLS_CC); } list->child[list->children++] = op; return (zend_ast *) list; diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 87b26405a60..86bb6ed2a21 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -25,13 +25,13 @@ #include "zend.h" - -#define ZEND_AST_IS_LIST_SHIFT 11 -#define ZEND_AST_NUM_CHILDREN_SHIFT 12 +#define ZEND_AST_SPECIAL_SHIFT 6 +#define ZEND_AST_IS_LIST_SHIFT 7 +#define ZEND_AST_NUM_CHILDREN_SHIFT 8 enum _zend_ast_kind { - /* first 256 kinds are reserved for opcodes */ - ZEND_AST_ZVAL = 256, + /* special nodes */ + ZEND_AST_ZVAL = 1 << ZEND_AST_SPECIAL_SHIFT, ZEND_AST_ZNODE, /* declaration nodes */ @@ -150,7 +150,7 @@ typedef unsigned short zend_ast_kind; typedef unsigned short zend_ast_attr; struct _zend_ast { - zend_ast_kind kind; /* Type of the node (either opcode or ZEND_AST_* constant) */ + zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */ zend_ast_attr attr; /* Additional attribute, use depending on node type */ zend_uint lineno; /* Line number */ zend_ast *child[1]; /* Array of children (using struct hack) */ @@ -165,6 +165,7 @@ typedef struct _zend_ast_list { zend_ast *child[1]; } zend_ast_list; +/* Lineno is stored in val.u2.lineno */ typedef struct _zend_ast_zval { zend_ast_kind kind; zend_ast_attr attr; @@ -192,9 +193,8 @@ ZEND_API zend_ast *zend_ast_create( zend_uint children, zend_ast_kind kind, ...); ZEND_API zend_ast *zend_ast_create_decl( - zend_ast_kind kind, zend_uint flags, zend_uint start_lineno, zend_uint end_lineno, - unsigned char *lex_pos, zend_string *doc_comment, zend_string *name, - zend_ast *child0, zend_ast *child1, zend_ast *child2 + zend_ast_kind kind, zend_uint flags, zend_uint start_lineno, zend_string *doc_comment, + zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2 ); ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind); @@ -217,17 +217,18 @@ static inline zend_ast_list *zend_ast_get_list(zend_ast *ast) { return (zend_ast_list *) ast; } -/* Only for non-lists! */ -static inline zend_uint zend_ast_get_num_children(zend_ast *ast) { - return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT; -} - static inline zval *zend_ast_get_zval(zend_ast *ast) { + ZEND_ASSERT(ast->kind == ZEND_AST_ZVAL); return &((zend_ast_zval *) ast)->val; } static inline zend_string *zend_ast_get_str(zend_ast *ast) { return Z_STR_P(zend_ast_get_zval(ast)); } + +static inline zend_uint zend_ast_get_num_children(zend_ast *ast) { + ZEND_ASSERT(!zend_ast_is_list(ast)); + return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT; +} static inline zend_uint zend_ast_get_lineno(zend_ast *ast) { if (ast->kind == ZEND_AST_ZVAL) { zval *zv = zend_ast_get_zval(ast); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index f48fffcf8bf..14932f32824 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -385,9 +385,8 @@ function_declaration_statement: function returns_ref T_STRING '(' parameter_list ')' { $$.str = CG(doc_comment); CG(doc_comment) = NULL; } '{' inner_statement_list '}' - { $$.ast = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2.num, - $1.num, CG(zend_lineno), LANG_SCNG(yy_text), $7.str, - zend_ast_get_str($3.ast), $5.ast, NULL, $9.ast); } + { $$.ast = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2.num, $1.num, $7.str, + zend_ast_get_str($3.ast), $5.ast, NULL, $9.ast); } ; is_reference: @@ -406,16 +405,14 @@ class_declaration_statement: T_STRING extends_from implements_list { $$.str = CG(doc_comment); CG(doc_comment) = NULL; } '{' class_statement_list '}' - { $$.ast = zend_ast_create_decl(ZEND_AST_CLASS, $1.num, $2.num, - CG(zend_lineno), LANG_SCNG(yy_text), $6.str, + { $$.ast = zend_ast_create_decl(ZEND_AST_CLASS, $1.num, $2.num, $6.str, zend_ast_get_str($3.ast), $4.ast, $5.ast, $8.ast); } | T_INTERFACE { $$.num = CG(zend_lineno); } T_STRING interface_extends_list { $$.str = CG(doc_comment); CG(doc_comment) = NULL; } '{' class_statement_list '}' - { $$.ast = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $2.num, - CG(zend_lineno), LANG_SCNG(yy_text), $5.str, + { $$.ast = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $2.num, $5.str, zend_ast_get_str($3.ast), NULL, $4.ast, $7.ast); } ; @@ -617,8 +614,7 @@ class_statement: | method_modifiers function returns_ref T_STRING '(' parameter_list ')' { $$.str = CG(doc_comment); CG(doc_comment) = NULL; } method_body - { $$.ast = zend_ast_create_decl(ZEND_AST_METHOD, $3.num | $1.num, - $2.num, CG(zend_lineno), LANG_SCNG(yy_text), $8.str, + { $$.ast = zend_ast_create_decl(ZEND_AST_METHOD, $3.num | $1.num, $2.num, $8.str, zend_ast_get_str($4.ast), $6.ast, NULL, $9.ast); } ; @@ -869,15 +865,13 @@ expr_without_variable: | function returns_ref '(' parameter_list ')' lexical_vars { $$.str = CG(doc_comment); CG(doc_comment) = NULL; } '{' inner_statement_list '}' - { $$.ast = zend_ast_create_decl(ZEND_AST_CLOSURE, $2.num, - $1.num, CG(zend_lineno), LANG_SCNG(yy_text), $7.str, + { $$.ast = zend_ast_create_decl(ZEND_AST_CLOSURE, $2.num, $1.num, $7.str, STR_INIT("{closure}", sizeof("{closure}") - 1, 0), $4.ast, $6.ast, $9.ast); } | T_STATIC function returns_ref '(' parameter_list ')' lexical_vars { $$.str = CG(doc_comment); CG(doc_comment) = NULL; } '{' inner_statement_list '}' - { $$.ast = zend_ast_create_decl(ZEND_AST_CLOSURE, - $3.num | ZEND_ACC_STATIC, $2.num, CG(zend_lineno), LANG_SCNG(yy_text), + { $$.ast = zend_ast_create_decl(ZEND_AST_CLOSURE, $3.num | ZEND_ACC_STATIC, $2.num, $8.str, STR_INIT("{closure}", sizeof("{closure}") - 1, 0), $5.ast, $7.ast, $10.ast); } ;