]> granicus.if.org Git - php/commitdiff
Port static vars
authorNikita Popov <nikic@php.net>
Sat, 12 Jul 2014 15:00:53 +0000 (17:00 +0200)
committerNikita Popov <nikic@php.net>
Sat, 12 Jul 2014 15:00:53 +0000 (17:00 +0200)
Need to figure out the constant expr stuff

Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_language_parser.y

index 59d383a64eed1397c0d914c6c7e67b0a619b165f..0769bfa61b61ee721afc753cd2992d39c67dea07 100644 (file)
@@ -73,6 +73,7 @@ enum _zend_ast_kind {
        ZEND_AST_STMT_LIST,
 
        ZEND_AST_GLOBAL,
+       ZEND_AST_STATIC,
        ZEND_AST_UNSET,
        ZEND_AST_RETURN,
        ZEND_AST_LABEL,
index 933ac8ffe846d5423035b37c6e186b6f4f8a072a..4f190d764a20a9d01107a876b6c257bfcbe17828 100644 (file)
@@ -5878,6 +5878,22 @@ void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC) /* {{{
 }
 /* }}} */
 
+// TODO.AST Sort out the whole constant folding issue
+static void _tmp_compile_const_expr(zval *result, zend_ast *ast TSRMLS_DC) {
+       ast = zend_ast_copy(ast);
+       zend_eval_const_expr(&ast TSRMLS_CC);
+       zend_compile_const_expr(&ast TSRMLS_CC);
+       if (ast->kind == ZEND_AST_ZVAL) {
+               ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast));
+               if (Z_TYPE_P(result) == IS_ARRAY) {
+                       zend_make_immutable_array_r(result TSRMLS_CC);                  
+               }
+               efree(ast);
+       } else {
+               ZVAL_NEW_AST(result, ast);
+       }
+}
+
 /* {{{ zend_dirname
    Returns directory name component of path */
 ZEND_API size_t zend_dirname(char *path, size_t len)
@@ -6913,6 +6929,46 @@ void zend_compile_global_var(zend_ast *ast TSRMLS_DC) {
        efree(fetch_ast);
 }
 
+void zend_compile_static_var(zend_ast *ast TSRMLS_DC) {
+       zend_ast *var_ast = ast->child[0];
+       zend_ast *value_ast = ast->child[1];
+
+       znode var_node, result;
+       zval value_zv;
+       zend_op *opline;
+
+       zend_compile_expr(&var_node, var_ast TSRMLS_CC);
+       if (var_node.op_type == IS_CONST) {
+               if (Z_TYPE(var_node.u.constant) != IS_STRING) {
+                       convert_to_string(&var_node.u.constant);
+               }
+       }
+
+       if (value_ast) {
+               _tmp_compile_const_expr(&value_zv, value_ast TSRMLS_CC);
+       } else {
+               ZVAL_NULL(&value_zv);
+       }
+
+       if (!CG(active_op_array)->static_variables) {
+               if (CG(active_op_array)->scope) {
+                       CG(active_op_array)->scope->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
+               }
+               ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
+               zend_hash_init(CG(active_op_array)->static_variables, 8, NULL, ZVAL_PTR_DTOR, 0);
+       }
+
+       zend_hash_update(CG(active_op_array)->static_variables,
+               Z_STR(var_node.u.constant), &value_zv);
+
+       opline = emit_op(&result, ZEND_FETCH_W, &var_node, NULL TSRMLS_CC);
+       opline->extended_value = ZEND_FETCH_STATIC;
+
+       zend_ast *fetch_ast = zend_ast_create_unary(ZEND_AST_VAR, var_ast);
+       zend_compile_assign_ref_common(NULL, fetch_ast, &result TSRMLS_CC);
+       efree(fetch_ast);
+}
+
 void zend_compile_unset(zend_ast *ast TSRMLS_DC) {
        zend_ast *var_ast = ast->child[0];
 
@@ -8263,6 +8319,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) {
                case ZEND_AST_GLOBAL:
                        zend_compile_global_var(ast TSRMLS_CC);
                        break;
+               case ZEND_AST_STATIC:
+                       zend_compile_static_var(ast TSRMLS_CC);
+                       break;
                case ZEND_AST_UNSET:
                        zend_compile_unset(ast TSRMLS_CC);
                        break;
index 6170e9aa12b3ab51beb0a253702dc799c68bd595..7cfcb70d6231bf1d44cdeb1bcc2e9ffdf16635c3 100644 (file)
@@ -345,7 +345,7 @@ unticked_statement:
        |       T_RETURN expr ';'
                        { $$.u.ast = zend_ast_create_unary(ZEND_AST_RETURN, $2.u.ast); }
        |       T_GLOBAL global_var_list ';' { $$.u.ast = $2.u.ast; }
-       |       T_STATIC static_var_list ';' { AN($$); }
+       |       T_STATIC static_var_list ';' { $$.u.ast = $2.u.ast; }
        |       T_ECHO echo_expr_list ';' { $$.u.ast = $2.u.ast; }
        |       T_INLINE_HTML { $$.u.ast = zend_ast_create_unary(ZEND_ECHO, AST_ZVAL(&$1)); }
        |       expr ';' { $$.u.ast = $1.u.ast; }
@@ -361,9 +361,6 @@ unticked_statement:
        |       ';'     /* empty statement */ { $$.u.ast = NULL; }
        |       T_TRY '{' inner_statement_list '}' catch_list finally_statement
                        { $$.u.ast = zend_ast_create_ternary(ZEND_AST_TRY, $3.u.ast, $5.u.ast, $6.u.ast); }
-       /*|     T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}' { AS($4); }
-               catch_statement { zend_do_bind_catch(&$1, &$7 TSRMLS_CC); }
-               finally_statement { zend_do_end_finally(&$1, &$6, &$8 TSRMLS_CC); AN($$); }*/
        |       T_THROW expr ';' { $$.u.ast = zend_ast_create_unary(ZEND_THROW, $2.u.ast); }
        |       T_GOTO T_STRING ';' { $$.u.ast = zend_ast_create_unary(ZEND_GOTO, AST_ZVAL(&$2)); }
 ;
@@ -374,17 +371,11 @@ catch_list:
        |       catch_list T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}'
                        { $$.u.ast = zend_ast_dynamic_add($1.u.ast,
                              zend_ast_create_ternary(ZEND_AST_CATCH, $4.u.ast, AST_ZVAL(&$5), $8.u.ast)); }
-       /*|     T_CATCH '(' { zend_initialize_try_catch_element(&$1 TSRMLS_CC); } 
-               fully_qualified_class_name { zend_do_first_catch(&$2 TSRMLS_CC); }
-               T_VARIABLE ')' { zend_do_begin_catch(&$1, &$4, &$6, &$2 TSRMLS_CC); }
-               '{' inner_statement_list '}' { AS($10); zend_do_end_catch(&$1 TSRMLS_CC); }
-               additional_catches { zend_do_mark_last_catch(&$2, &$13 TSRMLS_CC); $$ = $1;}*/
 ;
 
 finally_statement:
                /* empty */ { $$.u.ast = NULL; }
        |       T_FINALLY '{' inner_statement_list '}' { $$.u.ast = $3.u.ast; }
-       /*|     T_FINALLY { zend_do_finally(&$1 TSRMLS_CC); } '{' inner_statement_list '}' { AS($4); $$ = $1; }*/
 ;
 
 unset_variables:
@@ -615,11 +606,15 @@ global_var:
 
 
 static_var_list:
-               static_var_list ',' T_VARIABLE { zend_do_fetch_static_variable(&$3, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }
-       |       static_var_list ',' T_VARIABLE '=' static_scalar { Z_CONST_FLAGS($5.u.constant) = 0; zend_do_fetch_static_variable(&$3, &$5, ZEND_FETCH_STATIC TSRMLS_CC); }
-       |       T_VARIABLE  { zend_do_fetch_static_variable(&$1, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }
-       |       T_VARIABLE '=' static_scalar { Z_CONST_FLAGS($3.u.constant) = 0; zend_do_fetch_static_variable(&$1, &$3, ZEND_FETCH_STATIC TSRMLS_CC); }
+               static_var_list ',' static_var { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
+       |       static_var { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.u.ast); }
+;
 
+static_var:
+               T_VARIABLE
+                       { $$.u.ast = zend_ast_create_binary(ZEND_AST_STATIC, AST_ZVAL(&$1), NULL); }
+       |       T_VARIABLE '=' expr
+                       { $$.u.ast = zend_ast_create_binary(ZEND_AST_STATIC, AST_ZVAL(&$1), $3.u.ast); }
 ;