From 080e8bffa5a373f662dfb0aa5178e4a8b22312fa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 26 Jun 2014 16:56:50 +0200 Subject: [PATCH] Compile const refs to CONST --- Zend/zend_compile.c | 37 ++++++++++++++++++++++++++++++++++++- Zend/zend_language_parser.y | 15 ++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 58b9252e5e3..50e6e5f5fff 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7795,7 +7795,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) { || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS || kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM - || kind == ZEND_AST_CLASS_CONST; + || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST; } void zend_compile_const_expr_class_const(zend_ast **ast_ptr TSRMLS_DC) { @@ -7836,6 +7836,38 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr TSRMLS_DC) { *ast_ptr = zend_ast_create_constant(&result); } +void zend_compile_const_expr_const(zend_ast **ast_ptr TSRMLS_DC) { + zend_ast *ast = *ast_ptr; + zend_ast *const_name_ast = ast->child[0]; + zend_bool check_namespace = const_name_ast->attr; + zend_bool is_compound; + + znode const_name, result; + zend_compile_expr(&const_name, const_name_ast TSRMLS_CC); + + is_compound = zend_is_compound_name(&const_name.u.constant); + + if (zend_constant_ct_subst(&result, &const_name.u.constant, 0 TSRMLS_CC)) { + zend_ast_destroy(ast); + *ast_ptr = zend_ast_create_constant(&result.u.constant); + return; + } + + zend_resolve_const_name(&const_name, &check_namespace TSRMLS_CC); + result = const_name; + + Z_TYPE_INFO(result.u.constant) = IS_CONSTANT_EX; + if (IS_INTERNED(Z_STR(result.u.constant))) { + Z_TYPE_FLAGS(result.u.constant) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); + } + if (!is_compound) { + Z_CONST_FLAGS(result.u.constant) = IS_CONSTANT_UNQUALIFIED; + } + + zend_ast_destroy(ast); + *ast_ptr = zend_ast_create_constant(&result.u.constant); +} + void zend_compile_const_expr(zend_ast **ast_ptr TSRMLS_DC) { zend_ast *ast = *ast_ptr; if (ast == NULL || ast->kind == ZEND_CONST) { @@ -7857,6 +7889,9 @@ void zend_compile_const_expr(zend_ast **ast_ptr TSRMLS_DC) { case ZEND_AST_CLASS_CONST: zend_compile_const_expr_class_const(ast_ptr TSRMLS_CC); break; + case ZEND_AST_CONST: + zend_compile_const_expr_const(ast_ptr TSRMLS_CC); + break; } } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index fc24b7e878c..6de001a5702 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -982,9 +982,18 @@ static_scalar_value: | class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { $$.u.ast = zend_ast_create_binary( ZEND_AST_CLASS_CONST, AST_ZVAL(&$1), AST_ZVAL(&$3)); } - | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = AST_ZVAL(&$$); } - | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = AST_ZVAL(&$$); } - | T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_NEW_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = AST_ZVAL(&$$); } + | namespace_name + { $$.u.ast = zend_ast_create_unary( + ZEND_AST_CONST, zend_ast_create_zval_ex(&$1.u.constant, 1)); } + | T_NAMESPACE T_NS_SEPARATOR namespace_name + { ZVAL_EMPTY_STRING(&$1.u.constant); + zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); + $$.u.ast = zend_ast_create_unary(ZEND_AST_CONST, AST_ZVAL(&$1)); } + | T_NS_SEPARATOR namespace_name + { zval tmp; ZVAL_NEW_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); + if (Z_DELREF($2.u.constant) == 0) { efree(Z_STR($2.u.constant)); } + Z_STR($2.u.constant) = Z_STR(tmp); + $$.u.ast = zend_ast_create_unary(ZEND_AST_CONST, AST_ZVAL(&$2)); } | common_scalar { $$.u.ast = $1.u.ast; } | T_ARRAY '(' static_array_pair_list ')' { $$.u.ast = $3.u.ast; } | '[' static_array_pair_list ']' { $$.u.ast = $2.u.ast; }