summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_ast.c218
-rw-r--r--Zend/zend_ast.h94
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_language_scanner.c2
-rw-r--r--Zend/zend_language_scanner.l2
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: