From: Nikita Popov Date: Mon, 21 Jul 2014 16:02:31 +0000 (+0200) Subject: Pre-evaluate magic constants X-Git-Tag: POST_AST_MERGE^2~105 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df970e9fc20fa720298d478fd652f1785623793b;p=php Pre-evaluate magic constants --- diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index aea1c81740..a528dc3767 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -321,7 +321,7 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) zend_ast *copy = zend_ast_create_zval_ex(zend_ast_get_zval(ast), ast->attr); zval_copy_ctor(zend_ast_get_zval(copy)); return copy; - } else if (ast->children) { + } else { zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast *) * (ast->children - 1)); int i; new->kind = ast->kind; @@ -332,7 +332,6 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) } return new; } - return zend_ast_create_dynamic(ast->kind); } ZEND_API void zend_ast_destroy(zend_ast *ast) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 10024d7394..90316aa167 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7349,11 +7349,9 @@ void zend_compile_encaps_list(znode *result, zend_ast *ast TSRMLS_DC) { } } -void zend_compile_magic_const(znode *result, zend_ast *ast TSRMLS_DC) { +zend_bool zend_try_ct_compile_magic_const(zval *zv, zend_ast *ast TSRMLS_DC) { zend_op_array *op_array = CG(active_op_array); zend_class_entry *ce = CG(active_class_entry); - zval *zv = &result->u.constant; - result->op_type = IS_CONST; switch (ast->attr) { case T_FUNC_C: @@ -7380,13 +7378,7 @@ void zend_compile_magic_const(znode *result, zend_ast *ast TSRMLS_DC) { case T_CLASS_C: if (ce) { if (ZEND_CE_IS_TRAIT(ce)) { - zval const_zv; - ZVAL_STRING(&const_zv, "__CLASS__"); - zend_ast *const_ast = zend_ast_create_unary(ZEND_AST_CONST, - zend_ast_create_zval(&const_zv)); - zend_compile_const(result, const_ast TSRMLS_CC); - efree(const_ast); - zval_ptr_dtor(&const_zv); + return 0; } else { ZVAL_STR(zv, STR_COPY(ce->name)); } @@ -7403,6 +7395,28 @@ void zend_compile_magic_const(znode *result, zend_ast *ast TSRMLS_DC) { break; EMPTY_SWITCH_DEFAULT_CASE() } + + return 1; +} + +void zend_compile_magic_const(znode *result, zend_ast *ast TSRMLS_DC) { + zend_class_entry *ce = CG(active_class_entry); + + if (zend_try_ct_compile_magic_const(&result->u.constant, ast TSRMLS_CC)) { + result->op_type = IS_CONST; + return; + } + + ZEND_ASSERT(ast->attr == T_CLASS_C && ce && ZEND_CE_IS_TRAIT(ce)); + + { + zval const_zv; + ZVAL_STRING(&const_zv, "__CLASS__"); + zend_ast *const_ast = zend_ast_create_unary(ZEND_AST_CONST, + zend_ast_create_zval(&const_zv)); + zend_compile_const(result, const_ast TSRMLS_CC); + zend_ast_destroy(const_ast); + } } zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) { @@ -7912,6 +7926,16 @@ void zend_eval_const_array(zend_ast **ast_ptr TSRMLS_DC) { *ast_ptr = zend_ast_create_zval(&array); } +void zend_eval_const_magic_const(zend_ast **ast_ptr TSRMLS_DC) { + zend_ast *ast = *ast_ptr; + zval result; + + if (zend_try_ct_compile_magic_const(&result, ast TSRMLS_CC)) { + zend_ast_destroy(ast); + *ast_ptr = zend_ast_create_zval(&result); + } +} + void zend_eval_const_expr(zend_ast **ast_ptr TSRMLS_DC) { zend_ast *ast = *ast_ptr; if (!ast || ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_ZNODE) { @@ -7940,6 +7964,9 @@ void zend_eval_const_expr(zend_ast **ast_ptr TSRMLS_DC) { case ZEND_AST_ARRAY: zend_eval_const_array(ast_ptr TSRMLS_CC); break; + case ZEND_AST_MAGIC_CONST: + zend_eval_const_magic_const(ast_ptr TSRMLS_CC); + break; } }