]> granicus.if.org Git - php/commitdiff
Pre-evaluate magic constants
authorNikita Popov <nikic@php.net>
Mon, 21 Jul 2014 16:02:31 +0000 (18:02 +0200)
committerNikita Popov <nikic@php.net>
Mon, 21 Jul 2014 16:02:31 +0000 (18:02 +0200)
Zend/zend_ast.c
Zend/zend_compile.c

index aea1c817400a3469f205790532dcc07bb535d143..a528dc376732fa4ec39394b2feba53be43d5b10c 100644 (file)
@@ -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)
index 10024d7394cea317dd7690e8a621bd9a4a6d699e..90316aa1671ba47c511a7c4d7b1a54d2e1fb0031 100644 (file)
@@ -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;
        }
 }