}
/* }}} */
+// 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)
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];
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;
| 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; }
| ';' /* 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)); }
;
| 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:
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); }
;