]> granicus.if.org Git - php/commitdiff
Support static closures
authorNikita Popov <nikic@php.net>
Fri, 18 Jul 2014 13:47:46 +0000 (15:47 +0200)
committerNikita Popov <nikic@php.net>
Fri, 18 Jul 2014 13:47:46 +0000 (15:47 +0200)
Zend/zend_ast.c
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_language_parser.y

index 891b36d9afe2d2ee9cb1ead850957726b2b55971..69321e044d0823ec215efe987ba512b71000a7f7 100644 (file)
@@ -46,16 +46,17 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr)
 }
 
 ZEND_API zend_ast *zend_ast_create_func_decl(
-       zend_ast_kind kind, zend_bool returns_ref, zend_uint start_lineno, zend_uint end_lineno,
+       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_func_decl *ast = emalloc(sizeof(zend_ast_func_decl));
 
        ast->kind = kind;
-       ast->returns_ref = returns_ref;
+       ast->attr = 0;
        ast->start_lineno = start_lineno;
        ast->end_lineno = end_lineno;
+       ast->flags = flags;
        ast->lex_pos = lex_pos;
        ast->doc_comment = doc_comment;
        ast->name = name;
index d3eca8117cb3dbcc3c0078322f0a3988ba050492..f20446fd2281c11651868bfc6dc40b9b0c53f67a 100644 (file)
@@ -125,9 +125,10 @@ typedef struct _zend_ast_zval {
 /* Using a separate structure as it needs a bunch of extra information. */
 typedef struct _zend_ast_func_decl {
        zend_ast_kind kind;
-       zend_bool returns_ref;
+       zend_ast_attr attr; /* Unused - for structure compatibility */
        zend_uint start_lineno;
        zend_uint end_lineno;
+       zend_uint flags;
        unsigned char *lex_pos;
        zend_string *doc_comment;
        zend_string *name;
@@ -148,7 +149,7 @@ ZEND_API zend_ast *zend_ast_create(
        zend_uint children, zend_ast_kind kind, ...);
 
 ZEND_API zend_ast *zend_ast_create_func_decl(
-       zend_ast_kind kind, zend_bool by_ref, zend_uint start_lineno, zend_uint end_lineno,
+       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
 );
index e6e641abf0e559949777271dcb8e301316f99895..1d16b9b3d34eaadf84bb3aff1dc598f4d910e6b8 100644 (file)
@@ -7023,14 +7023,12 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
                op_array->function_name = STR_COPY(name);
        }
 
+       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);
        }
-       if (fn->returns_ref) {
-               op_array->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
-       }
        if (is_closure) {
                op_array->fn_flags |= ZEND_ACC_CLOSURE;
        }
@@ -7116,7 +7114,6 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
        zend_release_labels(0 TSRMLS_CC);
 
        // TODO.AST __autoload
-       // TODO.AST doc comment
 
        /* Pop the switch and foreach separators */
        zend_stack_del_top(&CG(switch_cond_stack));
index 68049e098f99a8fb36f521d5fedaddebb2b38b63..1dd800e6e4257be4637b928ea92a291c787a738c 100644 (file)
@@ -388,8 +388,8 @@ unset_variable:
 ;
 
 function_declaration_statement:
-       function is_reference T_STRING '(' parameter_list ')' '{' inner_statement_list '}'
-               { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_FUNC_DECL, $2.op_type,
+       function returns_ref T_STRING '(' parameter_list ')' '{' inner_statement_list '}'
+               { $$.u.ast = zend_ast_create_func_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); }
 ;
@@ -870,14 +870,17 @@ expr_without_variable:
        |       T_YIELD expr { $$.u.ast = zend_ast_create_binary(ZEND_YIELD, $2.u.ast, NULL); }
        |       T_YIELD expr T_DOUBLE_ARROW expr
                        { $$.u.ast = zend_ast_create_binary(ZEND_YIELD, $4.u.ast, $2.u.ast); }
-       |       function is_reference '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'
-                       { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_CLOSURE, $2.op_type,
+       |       function returns_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'
+                       { $$.u.ast = zend_ast_create_func_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 function2 is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); }
-               '(' parameter_list ')' { zend_compile_params($6.u.ast TSRMLS_CC); zend_ast_destroy($6.u.ast); } lexical_vars { zend_compile_closure_uses($9.u.ast TSRMLS_CC); if ($9.u.ast) zend_ast_destroy($9.u.ast); }
-               '{' inner_statement_list '}' { AS($12); zend_do_end_function_declaration(&$2 TSRMLS_CC); $$.u.ast = AST_ZNODE(&$4); }
+                             $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,
+                             $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); }
 ;
 
 function:
@@ -885,6 +888,11 @@ function:
                { $$.EA = CG(zend_lineno); $$.u.op.ptr = CG(doc_comment); CG(doc_comment) = NULL; }
 ;
 
+returns_ref:
+               /* empty */     { $$.EA = 0; }
+       |       '&'                     { $$.EA = ZEND_ACC_RETURN_REFERENCE; }
+;
+
 function2:
        T_FUNCTION { $$.EA = CG(zend_lineno); }
 ;