diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index e51c9d699ef..355f627e300 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -134,30 +134,39 @@ 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 */ +ZEND_API zend_ast_list *zend_ast_create_list(zend_uint init_children, zend_ast_kind kind, ...) { TSRMLS_FETCH(); 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); list->children = 0; - return (zend_ast *) list; + + { + va_list va; + zend_uint i; + va_start(va, kind); + for (i = 0; i < init_children; ++i) { + list = zend_ast_list_add(list, va_arg(va, zend_ast *)); + } + va_end(va); + } + + return list; } 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_ast_list *list = zend_ast_get_list(ast); +ZEND_API zend_ast_list *zend_ast_list_add(zend_ast_list *list, zend_ast *op) { if (list->children >= 4 && is_power_of_two(list->children)) { TSRMLS_FETCH(); 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; + return list; } static void zend_ast_add_array_element(zval *result, zval *offset, zval *expr TSRMLS_DC) diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 86bb6ed2a21..1d9863d9767 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -197,8 +197,8 @@ ZEND_API zend_ast *zend_ast_create_decl( zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2 ); -ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind); -ZEND_API zend_ast *zend_ast_dynamic_add(zend_ast *ast, zend_ast *op); +ZEND_API zend_ast_list *zend_ast_create_list(zend_uint init_children, zend_ast_kind kind, ...); +ZEND_API zend_ast_list *zend_ast_list_add(zend_ast_list *list, zend_ast *op); ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC); @@ -264,10 +264,6 @@ static inline zend_ast *zend_ast_create_ternary( return zend_ast_create(3, kind, op0, op1, op2); } -static inline zend_ast *zend_ast_create_dynamic_and_add(zend_ast_kind kind, zend_ast *op) { - return zend_ast_dynamic_add(zend_ast_create_dynamic(kind), op); -} - static inline zend_ast *zend_ast_create_binary_op(zend_uint opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(2, ZEND_AST_BINARY_OP, opcode, op0, op1); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ea50715183f..892c04fa9d3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6873,7 +6873,7 @@ void zend_compile_shell_exec(znode *result, zend_ast *ast TSRMLS_DC) { ZVAL_STRING(&fn_name, "shell_exec"); name_ast = zend_ast_create_zval(&fn_name); - args_ast = zend_ast_dynamic_add(zend_ast_create_dynamic(ZEND_AST_ARG_LIST), expr_ast); + args_ast = (zend_ast *) zend_ast_create_list(1, ZEND_AST_ARG_LIST, expr_ast); call_ast = zend_ast_create_binary(ZEND_AST_CALL, name_ast, args_ast); zend_compile_expr(result, call_ast TSRMLS_CC); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 20d2c4fc44d..1de42b29918 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -100,6 +100,7 @@ static inline znode *zend_ast_get_znode(zend_ast *ast) { typedef union _zend_parser_stack_elem { zend_ast *ast; + zend_ast_list *list; zend_string *str; zend_ulong num; } zend_parser_stack_elem; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 14932f32824..bfba46792a8 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -226,8 +226,8 @@ start: ; top_statement_list: - top_statement_list top_statement { $$.ast = zend_ast_dynamic_add($1.ast, $2.ast); } - | /* empty */ { $$.ast = zend_ast_create_dynamic(ZEND_AST_STMT_LIST); } + top_statement_list top_statement { $$.list = zend_ast_list_add($1.list, $2.ast); } + | /* empty */ { $$.list = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; namespace_name: @@ -273,9 +273,9 @@ top_statement: use_declarations: use_declarations ',' use_declaration - { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + { $$.list = zend_ast_list_add($1.list, $3.ast); } | use_declaration - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_USE, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_USE, $1.ast); } ; use_declaration: @@ -290,16 +290,15 @@ use_declaration: ; const_list: - const_list ',' const_decl { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | const_decl - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_CONST_DECL, $1.ast); } + const_list ',' const_decl { $$.list = zend_ast_list_add($1.list, $3.ast); } + | const_decl { $$.list = zend_ast_create_list(1, ZEND_AST_CONST_DECL, $1.ast); } ; inner_statement_list: inner_statement_list inner_statement - { $$.ast = zend_ast_dynamic_add($1.ast, $2.ast); } + { $$.list = zend_ast_list_add($1.list, $2.ast); } | /* empty */ - { $$.ast = zend_ast_create_dynamic(ZEND_AST_STMT_LIST); } + { $$.list = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; @@ -361,9 +360,9 @@ unticked_statement: catch_list: /* empty */ - { $$.ast = zend_ast_create_dynamic(ZEND_AST_CATCH_LIST); } + { $$.list = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); } | catch_list T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}' - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_ternary(ZEND_AST_CATCH, $4.ast, $5.ast, $8.ast)); } ; @@ -373,8 +372,8 @@ finally_statement: ; unset_variables: - unset_variable { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.ast); } - | unset_variables ',' unset_variable { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + unset_variable { $$.list = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1.ast); } + | unset_variables ',' unset_variable { $$.list = zend_ast_list_add($1.list, $3.ast); } ; unset_variable: @@ -469,12 +468,12 @@ switch_case_list: ; case_list: - /* empty */ { $$.ast = zend_ast_create_dynamic(ZEND_AST_SWITCH_LIST); } + /* empty */ { $$.list = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } | case_list T_CASE expr case_separator inner_statement_list - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_binary(ZEND_AST_SWITCH_CASE, $3.ast, $5.ast)); } | case_list T_DEFAULT case_separator inner_statement_list - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_binary(ZEND_AST_SWITCH_CASE, NULL, $4.ast)); } ; @@ -492,47 +491,47 @@ while_statement: if_stmt_without_else: T_IF parenthesis_expr statement - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_IF, + { $$.list = zend_ast_create_list(1, ZEND_AST_IF, zend_ast_create_binary(ZEND_AST_IF_ELEM, $2.ast, $3.ast)); } | if_stmt_without_else T_ELSEIF parenthesis_expr statement - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_binary(ZEND_AST_IF_ELEM, $3.ast, $4.ast)); } ; if_stmt: if_stmt_without_else { $$.ast = $1.ast; } | if_stmt_without_else T_ELSE statement - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_binary(ZEND_AST_IF_ELEM, NULL, $3.ast)); } ; alt_if_stmt_without_else: T_IF parenthesis_expr ':' inner_statement_list - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_IF, + { $$.list = zend_ast_create_list(1, ZEND_AST_IF, zend_ast_create_binary(ZEND_AST_IF_ELEM, $2.ast, $4.ast)); } | alt_if_stmt_without_else T_ELSEIF parenthesis_expr ':' inner_statement_list - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_binary(ZEND_AST_IF_ELEM, $3.ast, $5.ast)); } ; alt_if_stmt: alt_if_stmt_without_else T_ENDIF ';' { $$.ast = $1.ast; } | alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';' - { $$.ast = zend_ast_dynamic_add($1.ast, + { $$.list = zend_ast_list_add($1.list, zend_ast_create_binary(ZEND_AST_IF_ELEM, NULL, $4.ast)); } ; parameter_list: non_empty_parameter_list { $$.ast = $1.ast; } - | /* empty */ { $$.ast = zend_ast_create_dynamic(ZEND_AST_PARAM_LIST); } + | /* empty */ { $$.list = zend_ast_create_list(0, ZEND_AST_PARAM_LIST); } ; non_empty_parameter_list: parameter - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_PARAM_LIST, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_PARAM_LIST, $1.ast); } | non_empty_parameter_list ',' parameter - { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + { $$.list = zend_ast_list_add($1.list, $3.ast); } ; parameter: @@ -553,15 +552,15 @@ optional_type: ; argument_list: - '(' ')' { $$.ast = zend_ast_create_dynamic(ZEND_AST_ARG_LIST); } + '(' ')' { $$.list = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } | '(' non_empty_argument_list ')' { $$.ast = $2.ast; } ; non_empty_argument_list: argument - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_ARG_LIST, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1.ast); } | non_empty_argument_list ',' argument - { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + { $$.list = zend_ast_list_add($1.list, $3.ast); } ; argument: @@ -572,8 +571,8 @@ argument: ; global_var_list: - global_var_list ',' global_var { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | global_var { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.ast); } + global_var_list ',' global_var { $$.list = zend_ast_list_add($1.list, $3.ast); } + | global_var { $$.list = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1.ast); } ; global_var: @@ -584,8 +583,8 @@ global_var: static_var_list: - static_var_list ',' static_var { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | static_var { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.ast); } + static_var_list ',' static_var { $$.list = zend_ast_list_add($1.list, $3.ast); } + | static_var { $$.list = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1.ast); } ; static_var: @@ -598,9 +597,9 @@ static_var: class_statement_list: class_statement_list class_statement - { $$.ast = zend_ast_dynamic_add($1.ast, $2.ast); } + { $$.list = zend_ast_list_add($1.list, $2.ast); } | /* empty */ - { $$.ast = zend_ast_create_dynamic(ZEND_AST_STMT_LIST); } + { $$.list = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; @@ -619,8 +618,8 @@ class_statement: ; name_list: - name { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_NAME_LIST, $1.ast); } - | name_list ',' name { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + name { $$.list = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1.ast); } + | name_list ',' name { $$.list = zend_ast_list_add($1.list, $3.ast); } ; trait_adaptations: @@ -631,9 +630,9 @@ trait_adaptations: trait_adaptation_list: trait_adaptation - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_TRAIT_ADAPTATIONS, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_TRAIT_ADAPTATIONS, $1.ast); } | trait_adaptation_list trait_adaptation - { $$.ast = zend_ast_dynamic_add($1.ast, $2.ast); } + { $$.list = zend_ast_list_add($1.list, $2.ast); } ; trait_adaptation: @@ -703,8 +702,8 @@ member_modifier: ; property_list: - property_list ',' property { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | property { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_PROP_DECL, $1.ast); } + property_list ',' property { $$.list = zend_ast_list_add($1.list, $3.ast); } + | property { $$.list = zend_ast_create_list(1, ZEND_AST_PROP_DECL, $1.ast); } ; property: @@ -714,9 +713,9 @@ property: ; class_const_list: - class_const_list ',' const_decl { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + class_const_list ',' const_decl { $$.list = zend_ast_list_add($1.list, $3.ast); } | const_decl - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_CLASS_CONST_DECL, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1.ast); } ; const_decl: @@ -725,8 +724,8 @@ const_decl: ; echo_expr_list: - echo_expr_list ',' echo_expr { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | echo_expr { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.ast); } + echo_expr_list ',' echo_expr { $$.list = zend_ast_list_add($1.list, $3.ast); } + | echo_expr { $$.list = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1.ast); } ; echo_expr: expr { $$.ast = zend_ast_create_unary(ZEND_AST_ECHO, $1.ast); } @@ -738,8 +737,8 @@ for_expr: ; non_empty_for_expr: - non_empty_for_expr ',' expr { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | expr { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_EXPR_LIST, $1.ast); } + non_empty_for_expr ',' expr { $$.list = zend_ast_list_add($1.list, $3.ast); } + | expr { $$.list = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1.ast); } ; new_expr: @@ -891,8 +890,8 @@ lexical_vars: ; lexical_var_list: - lexical_var_list ',' lexical_var { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } - | lexical_var { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_CLOSURE_USES, $1.ast); } + lexical_var_list ',' lexical_var { $$.list = zend_ast_list_add($1.list, $3.ast); } + | lexical_var { $$.list = zend_ast_create_list(1, ZEND_AST_CLOSURE_USES, $1.ast); } ; lexical_var: @@ -940,7 +939,7 @@ backticks_expr: ctor_arguments: - /* empty */ { $$.ast = zend_ast_create_dynamic(ZEND_AST_ARG_LIST); } + /* empty */ { $$.list = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } | argument_list { $$.ast = $1.ast; } ; @@ -1069,9 +1068,9 @@ member_name: assignment_list: assignment_list ',' assignment_list_element - { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + { $$.list = zend_ast_list_add($1.list, $3.ast); } | assignment_list_element - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_LIST, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_LIST, $1.ast); } ; assignment_list_element: @@ -1082,15 +1081,15 @@ assignment_list_element: array_pair_list: - /* empty */ { $$.ast = zend_ast_create_dynamic(ZEND_AST_ARRAY); } + /* empty */ { $$.list = zend_ast_create_list(0, ZEND_AST_ARRAY); } | non_empty_array_pair_list possible_comma { $$.ast = $1.ast; } ; non_empty_array_pair_list: non_empty_array_pair_list ',' array_pair - { $$.ast = zend_ast_dynamic_add($1.ast, $3.ast); } + { $$.list = zend_ast_list_add($1.list, $3.ast); } | array_pair - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_ARRAY, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_ARRAY, $1.ast); } ; array_pair: @@ -1105,14 +1104,13 @@ array_pair: encaps_list: encaps_list encaps_var - { $$.ast = zend_ast_dynamic_add($1.ast, $2.ast); } + { $$.list = zend_ast_list_add($1.list, $2.ast); } | encaps_list T_ENCAPSED_AND_WHITESPACE - { $$.ast = zend_ast_dynamic_add($1.ast, $2.ast); } + { $$.list = zend_ast_list_add($1.list, $2.ast); } | encaps_var - { $$.ast = zend_ast_create_dynamic_and_add(ZEND_AST_ENCAPS_LIST, $1.ast); } + { $$.list = zend_ast_create_list(1, ZEND_AST_ENCAPS_LIST, $1.ast); } | T_ENCAPSED_AND_WHITESPACE encaps_var - { $$.ast = zend_ast_dynamic_add(zend_ast_create_dynamic_and_add( - ZEND_AST_ENCAPS_LIST, $1.ast), $2.ast); } + { $$.list = zend_ast_create_list(2, ZEND_AST_ENCAPS_LIST, $1.ast, $2.ast); } ; encaps_var: