diff options
-rw-r--r-- | Zend/zend_ast.c | 218 | ||||
-rw-r--r-- | Zend/zend_ast.h | 94 | ||||
-rw-r--r-- | Zend/zend_compile.h | 3 | ||||
-rw-r--r-- | Zend/zend_language_scanner.c | 2 | ||||
-rw-r--r-- | Zend/zend_language_scanner.l | 2 |
5 files changed, 283 insertions, 36 deletions
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index e6b454ea55..bc7eac148c 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -47,7 +47,7 @@ static inline size_t zend_ast_list_size(uint32_t children) { return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children; } -ZEND_API zend_ast *zend_ast_create_znode(znode *node) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) { zend_ast_znode *ast; ast = zend_ast_alloc(sizeof(zend_ast_znode)); @@ -58,7 +58,7 @@ ZEND_API zend_ast *zend_ast_create_znode(znode *node) { return (zend_ast *) ast; } -ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr, uint32_t lineno) { +static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) { zend_ast_zval *ast; ast = zend_ast_alloc(sizeof(zend_ast_zval)); @@ -69,11 +69,31 @@ ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr return (zend_ast *) ast; } -ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { - return zend_ast_create_zval_with_lineno(zv, attr, CG(zend_lineno)); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) { + return zend_ast_create_zval_int(zv, 0, lineno); } -ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { + return zend_ast_create_zval_int(zv, attr, CG(zend_lineno)); +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) { + return zend_ast_create_zval_int(zv, 0, CG(zend_lineno)); +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str) { + zval zv; + ZVAL_STR(&zv, str); + return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno)); +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval) { + zval zv; + ZVAL_LONG(&zv, lval); + return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno)); +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr) { zend_ast_zval *ast; ast = zend_ast_alloc(sizeof(zend_ast_zval)); @@ -107,6 +127,183 @@ ZEND_API zend_ast *zend_ast_create_decl( return (zend_ast *) ast; } +#if ZEND_AST_SPEC +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) { + zend_ast *ast; + + ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 0); + ast = zend_ast_alloc(zend_ast_size(0)); + ast->kind = kind; + ast->attr = 0; + ast->lineno = CG(zend_lineno); + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child) { + zend_ast *ast; + uint32_t lineno; + + ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 1); + ast = zend_ast_alloc(zend_ast_size(1)); + ast->kind = kind; + ast->attr = 0; + ast->child[0] = child; + if (child) { + lineno = zend_ast_get_lineno(child); + } else { + lineno = CG(zend_lineno); + } + ast->lineno = lineno; + ast->lineno = lineno; + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) { + zend_ast *ast; + uint32_t lineno; + + ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 2); + ast = zend_ast_alloc(zend_ast_size(2)); + ast->kind = kind; + ast->attr = 0; + ast->child[0] = child1; + ast->child[1] = child2; + if (child1) { + lineno = zend_ast_get_lineno(child1); + } else if (child2) { + lineno = zend_ast_get_lineno(child2); + } else { + lineno = CG(zend_lineno); + } + ast->lineno = lineno; + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) { + zend_ast *ast; + uint32_t lineno; + + ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 3); + ast = zend_ast_alloc(zend_ast_size(3)); + ast->kind = kind; + ast->attr = 0; + ast->child[0] = child1; + ast->child[1] = child2; + ast->child[2] = child3; + if (child1) { + lineno = zend_ast_get_lineno(child1); + } else if (child2) { + lineno = zend_ast_get_lineno(child2); + } else if (child3) { + lineno = zend_ast_get_lineno(child3); + } else { + lineno = CG(zend_lineno); + } + ast->lineno = lineno; + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) { + zend_ast *ast; + uint32_t lineno; + + ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 4); + ast = zend_ast_alloc(zend_ast_size(4)); + ast->kind = kind; + ast->attr = 0; + ast->child[0] = child1; + ast->child[1] = child2; + ast->child[2] = child3; + ast->child[3] = child4; + if (child1) { + lineno = zend_ast_get_lineno(child1); + } else if (child2) { + lineno = zend_ast_get_lineno(child2); + } else if (child3) { + lineno = zend_ast_get_lineno(child3); + } else if (child4) { + lineno = zend_ast_get_lineno(child4); + } else { + lineno = CG(zend_lineno); + } + ast->lineno = lineno; + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) { + zend_ast *ast; + zend_ast_list *list; + + ast = zend_ast_alloc(zend_ast_list_size(4)); + list = (zend_ast_list *) ast; + list->kind = kind; + list->attr = 0; + list->lineno = CG(zend_lineno); + list->children = 0; + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child) { + zend_ast *ast; + zend_ast_list *list; + uint32_t lineno; + + ast = zend_ast_alloc(zend_ast_list_size(4)); + list = (zend_ast_list *) ast; + list->kind = kind; + list->attr = 0; + list->children = 1; + list->child[0] = child; + if (child) { + lineno = zend_ast_get_lineno(child); + if (lineno > CG(zend_lineno)) { + lineno = CG(zend_lineno); + } + } else { + lineno = CG(zend_lineno); + } + list->lineno = lineno; + + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) { + zend_ast *ast; + zend_ast_list *list; + uint32_t lineno = zend_ast_get_lineno(child1); + + ast = zend_ast_alloc(zend_ast_list_size(4)); + list = (zend_ast_list *) ast; + list->kind = kind; + list->attr = 0; + list->children = 2; + list->child[0] = child1; + list->child[1] = child2; + if (child1) { + lineno = zend_ast_get_lineno(child1); + if (lineno > CG(zend_lineno)) { + lineno = CG(zend_lineno); + } + } else if (child2) { + lineno = zend_ast_get_lineno(child2); + if (lineno > CG(zend_lineno)) { + lineno = CG(zend_lineno); + } + } else { + list->children = 0; + lineno = CG(zend_lineno); + } + list->lineno = lineno; + + return ast; +} +#else static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) { uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT; zend_ast *ast; @@ -185,12 +382,13 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki return ast; } +#endif static inline zend_bool is_power_of_two(uint32_t n) { return ((n != 0) && (n == (n & (~n + 1)))); } -ZEND_API zend_ast *zend_ast_list_add(zend_ast *ast, zend_ast *op) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_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)) { list = zend_ast_realloc(list, @@ -240,7 +438,7 @@ static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr) return SUCCESS; } -ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) +ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) { zval op1, op2; int ret = SUCCESS; @@ -465,7 +663,7 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc return ret; } -static size_t zend_ast_tree_size(zend_ast *ast) +static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast) { size_t size; @@ -494,7 +692,7 @@ static size_t zend_ast_tree_size(zend_ast *ast) return size; } -static void* zend_ast_tree_copy(zend_ast *ast, void *buf) +static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) { if (ast->kind == ZEND_AST_ZVAL) { zend_ast_zval *new = (zend_ast_zval*)buf; @@ -542,7 +740,7 @@ static void* zend_ast_tree_copy(zend_ast *ast, void *buf) return buf; } -ZEND_API zend_ast_ref *zend_ast_copy(zend_ast *ast) +ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast) { size_t tree_size; zend_ast_ref *ref; diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index a9b45ab080..900c1b6562 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -25,6 +25,10 @@ #include "zend.h" +#ifndef ZEND_AST_SPEC +# define ZEND_AST_SPEC 1 +#endif + #define ZEND_AST_SPECIAL_SHIFT 6 #define ZEND_AST_IS_LIST_SHIFT 7 #define ZEND_AST_NUM_CHILDREN_SHIFT 8 @@ -191,26 +195,84 @@ typedef struct _zend_ast_decl { typedef void (*zend_ast_process_t)(zend_ast *ast); extern ZEND_API zend_ast_process_t zend_ast_process; -ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr, uint32_t lineno); -ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str); +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); + +#if ZEND_AST_SPEC +# define ZEND_AST_SPEC_CALL(name, ...) \ + ZEND_AST_SPEC_CALL_(name, __VA_ARGS__, _4, _3, _2, _1, _0)(__VA_ARGS__) +# define ZEND_AST_SPEC_CALL_(name, _, _4, _3, _2, _1, suffix, ...) \ + name ## suffix +# define ZEND_AST_SPEC_CALL_EX(name, ...) \ + ZEND_AST_SPEC_CALL_EX_(name, __VA_ARGS__, _4, _3, _2, _1, _0)(__VA_ARGS__) +# define ZEND_AST_SPEC_CALL_EX_(name, _, _5, _4, _3, _2, _1, suffix, ...) \ + name ## suffix + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4); + +static zend_always_inline zend_ast * zend_ast_create_ex_0(zend_ast_kind kind, zend_ast_attr attr) { + zend_ast *ast = zend_ast_create_0(kind); + ast->attr = attr; + return ast; +} +static zend_always_inline zend_ast * zend_ast_create_ex_1(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child) { + zend_ast *ast = zend_ast_create_1(kind, child); + ast->attr = attr; + return ast; +} +static zend_always_inline zend_ast * zend_ast_create_ex_2(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2) { + zend_ast *ast = zend_ast_create_2(kind, child1, child2); + ast->attr = attr; + return ast; +} +static zend_always_inline zend_ast * zend_ast_create_ex_3(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2, zend_ast *child3) { + zend_ast *ast = zend_ast_create_3(kind, child1, child2, child3); + ast->attr = attr; + return ast; +} +static zend_always_inline zend_ast * zend_ast_create_ex_4(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) { + zend_ast *ast = zend_ast_create_4(kind, child1, child2, child3, child4); + ast->attr = attr; + return ast; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); -ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr); +# define zend_ast_create(...) \ + ZEND_AST_SPEC_CALL(zend_ast_create, __VA_ARGS__) +# define zend_ast_create_ex(...) \ + ZEND_AST_SPEC_CALL_EX(zend_ast_create_ex, __VA_ARGS__) +# define zend_ast_create_list(init_children, ...) \ + ZEND_AST_SPEC_CALL(zend_ast_create_list, __VA_ARGS__) -ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...); +#else ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...); +ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...); +ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...); +#endif + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op); ZEND_API zend_ast *zend_ast_create_decl( zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3 ); -ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...); -ZEND_API zend_ast *zend_ast_list_add(zend_ast *list, zend_ast *op); - -ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope); +ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope); ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix); -ZEND_API zend_ast_ref *zend_ast_copy(zend_ast *ast); +ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast); ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast); ZEND_API void ZEND_FASTCALL zend_ast_ref_destroy(zend_ast_ref *ast); @@ -254,20 +316,6 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { } } -static zend_always_inline zend_ast *zend_ast_create_zval(zval *zv) { - return zend_ast_create_zval_ex(zv, 0); -} -static zend_always_inline zend_ast *zend_ast_create_zval_from_str(zend_string *str) { - zval zv; - ZVAL_STR(&zv, str); - return zend_ast_create_zval(&zv); -} -static zend_always_inline zend_ast *zend_ast_create_zval_from_long(zend_long lval) { - zval zv; - ZVAL_LONG(&zv, lval); - return zend_ast_create_zval(&zv); -} - static zend_always_inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(ZEND_AST_BINARY_OP, opcode, op0, op1); } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f0518f24f2..d6d816b945 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -97,7 +97,8 @@ typedef struct _zend_ast_znode { uint32_t lineno; znode node; } zend_ast_znode; -ZEND_API zend_ast *zend_ast_create_znode(znode *node); + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node); static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) { return &((zend_ast_znode *) ast)->node; diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index d0a6ce2126..0ef393d6e9 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -7879,7 +7879,7 @@ emit_token_with_str: emit_token_with_val: if (PARSER_MODE()) { ZEND_ASSERT(Z_TYPE_P(zendlval) != IS_UNDEF); - elem->ast = zend_ast_create_zval_with_lineno(zendlval, 0, start_line); + elem->ast = zend_ast_create_zval_with_lineno(zendlval, start_line); } emit_token: diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index bb87d818f9..5e256447f1 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -2500,7 +2500,7 @@ emit_token_with_str: emit_token_with_val: if (PARSER_MODE()) { ZEND_ASSERT(Z_TYPE_P(zendlval) != IS_UNDEF); - elem->ast = zend_ast_create_zval_with_lineno(zendlval, 0, start_line); + elem->ast = zend_ast_create_zval_with_lineno(zendlval, start_line); } emit_token: |