]> granicus.if.org Git - php/commitdiff
Prepare zend_ast_decl for reuse with classes
authorNikita Popov <nikic@php.net>
Mon, 21 Jul 2014 13:38:21 +0000 (15:38 +0200)
committerNikita Popov <nikic@php.net>
Mon, 21 Jul 2014 13:38:21 +0000 (15:38 +0200)
Zend/zend_ast.c
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_language_parser.y

index f92d45faaf4a2b0d3263a2e22862c5abad07ff22..b62bae9c853f2a939af244734ca1921f2354fc3c 100644 (file)
@@ -45,12 +45,12 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr)
        return (zend_ast *) ast;
 }
 
-ZEND_API zend_ast *zend_ast_create_func_decl(
+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 *params, zend_ast *uses, zend_ast *stmt
+       zend_ast *child0, zend_ast *child1, zend_ast *child2
 ) {
-       zend_ast_func_decl *ast = emalloc(sizeof(zend_ast_func_decl));
+       zend_ast_decl *ast = emalloc(sizeof(zend_ast_decl));
 
        ast->kind = kind;
        ast->attr = 0;
@@ -60,9 +60,9 @@ ZEND_API zend_ast *zend_ast_create_func_decl(
        ast->lex_pos = lex_pos;
        ast->doc_comment = doc_comment;
        ast->name = name;
-       ast->params = params;
-       ast->uses = uses;
-       ast->stmt = stmt;
+       ast->child[0] = child0;
+       ast->child[1] = child1;
+       ast->child[2] = child2;
 
        return (zend_ast *) ast;
 }
@@ -351,14 +351,14 @@ ZEND_API void zend_ast_destroy(zend_ast *ast)
                case ZEND_AST_CLOSURE:
                case ZEND_AST_METHOD:
                {
-                       zend_ast_func_decl *fn = (zend_ast_func_decl *) ast;
-                       STR_RELEASE(fn->name);
-                       if (fn->doc_comment) {
-                               STR_RELEASE(fn->doc_comment);
+                       zend_ast_decl *decl = (zend_ast_decl *) ast;
+                       STR_RELEASE(decl->name);
+                       if (decl->doc_comment) {
+                               STR_RELEASE(decl->doc_comment);
                        }
-                       zend_ast_destroy(fn->params);
-                       zend_ast_destroy(fn->uses);
-                       zend_ast_destroy(fn->stmt);
+                       zend_ast_destroy(decl->child[0]);
+                       zend_ast_destroy(decl->child[1]);
+                       zend_ast_destroy(decl->child[2]);
                        break;
                }
                default:
index dd260249a4a731bc89a0412e0b5c42b29124e2f8..32316afa3c58b02b8187c6ef07e4708ac7023b97 100644 (file)
@@ -136,8 +136,8 @@ typedef struct _zend_ast_zval {
        zval val;
 } zend_ast_zval;
 
-/* Using a separate structure as it needs a bunch of extra information. */
-typedef struct _zend_ast_func_decl {
+/* Separate structure for function and class declaration, as they need extra information. */
+typedef struct _zend_ast_decl {
        zend_ast_kind kind;
        zend_ast_attr attr; /* Unused - for structure compatibility */
        zend_uint start_lineno;
@@ -146,10 +146,8 @@ typedef struct _zend_ast_func_decl {
        unsigned char *lex_pos;
        zend_string *doc_comment;
        zend_string *name;
-       zend_ast *params;
-       zend_ast *uses;
-       zend_ast *stmt;
-} zend_ast_func_decl;
+       zend_ast *child[3];
+} zend_ast_decl;
 
 static inline zval *zend_ast_get_zval(zend_ast *ast) {
        return &((zend_ast_zval *) ast)->val;
@@ -162,10 +160,10 @@ ZEND_API zend_ast *zend_ast_create_ex(
 ZEND_API zend_ast *zend_ast_create(
        zend_uint children, zend_ast_kind kind, ...);
 
-ZEND_API zend_ast *zend_ast_create_func_decl(
+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 *params, zend_ast *uses, zend_ast *stmt
+       zend_ast *child0, zend_ast *child1, zend_ast *child2
 );
 
 ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind);
index 2763f143d3d2d04eddd40d13a78c830cbc176b8c..d21dde7732d89277b2e13bc420ac2e031c9855c2 100644 (file)
@@ -6230,9 +6230,10 @@ void zend_begin_method_decl(
 }
 
 static void zend_begin_func_decl(
-       znode *result, zend_op_array *op_array, zend_ast_func_decl *fn TSRMLS_DC
+       znode *result, zend_op_array *op_array, zend_ast_decl *decl TSRMLS_DC
 ) {
-       zend_string *name = fn->name, *lcname;
+       zend_ast *params_ast = decl->child[0];
+       zend_string *name = decl->name, *lcname;
        zend_op *opline;
 
        if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
@@ -6261,7 +6262,7 @@ static void zend_begin_func_decl(
                }
        }
 
-       if (zend_str_equals(lcname, ZEND_AUTOLOAD_FUNC_NAME) && fn->params->children != 1) {
+       if (zend_str_equals(lcname, ZEND_AUTOLOAD_FUNC_NAME) && params_ast->children != 1) {
                zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument",
                        ZEND_AUTOLOAD_FUNC_NAME);
        }
@@ -6277,7 +6278,7 @@ static void zend_begin_func_decl(
 
        {
                zval key;
-               build_runtime_defined_function_key(&key, lcname, fn->lex_pos TSRMLS_CC);
+               build_runtime_defined_function_key(&key, lcname, decl->lex_pos TSRMLS_CC);
 
                opline->op1_type = IS_CONST;
                opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
@@ -6289,30 +6290,34 @@ static void zend_begin_func_decl(
 }
 
 void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
-       zend_ast_func_decl *fn = (zend_ast_func_decl *) ast;
+       zend_ast_decl *decl = (zend_ast_decl *) ast;
+       zend_ast *params_ast = decl->child[0];
+       zend_ast *uses_ast = decl->child[1];
+       zend_ast *stmt_ast = decl->child[2];
+       zend_bool is_method = decl->kind == ZEND_AST_METHOD;
+
        zend_op_array *orig_op_array = CG(active_op_array);
        zend_op_array *op_array = emalloc(sizeof(zend_op_array));
-       zend_bool is_method = ast->kind == ZEND_AST_METHOD;
 
        // TODO.AST interactive (not just here - also bpc etc!)
        
        init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
 
-       op_array->fn_flags |= fn->flags;
-       op_array->line_start = fn->start_lineno;
-       op_array->line_end = fn->end_lineno;
-       if (fn->doc_comment) {
-               op_array->doc_comment = STR_COPY(fn->doc_comment);
+       op_array->fn_flags |= decl->flags;
+       op_array->line_start = decl->start_lineno;
+       op_array->line_end = decl->end_lineno;
+       if (decl->doc_comment) {
+               op_array->doc_comment = STR_COPY(decl->doc_comment);
        }
-       if (ast->kind == ZEND_AST_CLOSURE) {
+       if (decl->kind == ZEND_AST_CLOSURE) {
                op_array->fn_flags |= ZEND_ACC_CLOSURE;
        }
 
        if (is_method) {
-               zend_bool has_body = fn->stmt != NULL;
-               zend_begin_method_decl(op_array, fn->name, has_body TSRMLS_CC);
+               zend_bool has_body = stmt_ast != NULL;
+               zend_begin_method_decl(op_array, decl->name, has_body TSRMLS_CC);
        } else {
-               zend_begin_func_decl(result, op_array, fn TSRMLS_CC);
+               zend_begin_func_decl(result, op_array, decl TSRMLS_CC);
        }
 
        CG(active_op_array) = op_array;
@@ -6321,7 +6326,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
 
        if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
                zend_op *opline_ext = emit_op(NULL, ZEND_EXT_NOP, NULL, NULL TSRMLS_CC);
-               opline_ext->lineno = fn->start_lineno;
+               opline_ext->lineno = decl->start_lineno;
        }
 
        {
@@ -6344,9 +6349,9 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
                zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline);
        }
 
-       zend_compile_params(fn->params TSRMLS_CC);
-       zend_compile_closure_uses(fn->uses TSRMLS_CC);
-       zend_compile_stmt(fn->stmt TSRMLS_CC);
+       zend_compile_params(params_ast TSRMLS_CC);
+       zend_compile_closure_uses(uses_ast TSRMLS_CC);
+       zend_compile_stmt(stmt_ast TSRMLS_CC);
 
        if (is_method) {
                zend_check_magic_method_implementation(
index ae3edf3c08a73578c9e99eaf67dc537ad69fdd9f..77c4ef614c0e809421a2e119b11847777e23d57b 100644 (file)
@@ -389,7 +389,7 @@ unset_variable:
 
 function_declaration_statement:
        function returns_ref T_STRING '(' parameter_list ')' '{' inner_statement_list '}'
-               { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_FUNC_DECL, $2.EA,
+               { $$.u.ast = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2.EA,
                      $1.EA, CG(zend_lineno), LANG_SCNG(yy_text), $1.u.op.ptr,
                          Z_STR($3.u.constant), $5.u.ast, NULL, $8.u.ast); }
 ;
@@ -635,7 +635,7 @@ class_statement:
        |       T_USE name_list trait_adaptations
                        { $$.u.ast = zend_ast_create_binary(ZEND_AST_USE_TRAIT, $2.u.ast, $3.u.ast); AS($$); }
        |       method_modifiers function returns_ref T_STRING '(' parameter_list ')' method_body
-                       { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_METHOD, $3.EA | Z_LVAL($1.u.constant),
+                       { $$.u.ast = zend_ast_create_decl(ZEND_AST_METHOD, $3.EA | Z_LVAL($1.u.constant),
                              $2.EA, CG(zend_lineno), LANG_SCNG(yy_text), $2.u.op.ptr,
                                  Z_STR($4.u.constant), $6.u.ast, NULL, $8.u.ast); AS($$); }
 ;
@@ -883,13 +883,13 @@ expr_without_variable:
        |       T_YIELD expr T_DOUBLE_ARROW expr
                        { $$.u.ast = zend_ast_create_binary(ZEND_YIELD, $4.u.ast, $2.u.ast); }
        |       function returns_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'
-                       { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_CLOSURE, $2.EA,
+                       { $$.u.ast = zend_ast_create_decl(ZEND_AST_CLOSURE, $2.EA,
                              $1.EA, CG(zend_lineno), LANG_SCNG(yy_text), $1.u.op.ptr,
                                  STR_INIT("{closure}", sizeof("{closure}") - 1, 0),
                              $4.u.ast, $6.u.ast, $8.u.ast); }
        |       T_STATIC function returns_ref '(' parameter_list ')' lexical_vars
                '{' inner_statement_list '}'
-                       { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_CLOSURE,
+                       { $$.u.ast = zend_ast_create_decl(ZEND_AST_CLOSURE,
                              $3.EA | ZEND_ACC_STATIC, $2.EA, CG(zend_lineno), LANG_SCNG(yy_text),
                              $2.u.op.ptr, STR_INIT("{closure}", sizeof("{closure}") - 1, 0),
                              $5.u.ast, $7.u.ast, $9.u.ast); }