]> granicus.if.org Git - php/commitdiff
Reimplemented special constant handling. Now __HALT_COMPILER_OFFSET__ is resolved...
authorDmitry Stogov <dmitry@zend.com>
Wed, 18 Mar 2015 12:31:29 +0000 (15:31 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 18 Mar 2015 12:33:56 +0000 (15:33 +0300)
Zend/zend_compile.c
Zend/zend_constants.c
Zend/zend_execute_API.c
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h

index f2de2c74d8acdca7dbc6bbcdca31f5a88ca9da4b..962bb14b42a0651c258b1fa2ef043b8592f76139 100644 (file)
@@ -5975,6 +5975,22 @@ void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
                return;
        }
 
+       if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__")) {
+               zend_ast *last = CG(ast);
+
+               while (last->kind == ZEND_AST_STMT_LIST) {
+                       zend_ast_list *list = zend_ast_get_list(last);
+                       last = list->child[list->children-1];
+               }
+               if (last->kind == ZEND_AST_HALT_COMPILER) {
+                       result->op_type = IS_CONST;
+                       ZVAL_LONG(&result->u.constant,
+                               Z_LVAL_P(zend_ast_get_zval(last->child[0])));
+                       zend_string_release(resolved_name);
+                       return;
+               }
+       }
+
        opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL);
        opline->op2_type = IS_CONST;
 
@@ -6161,12 +6177,7 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
                    CG(active_class_entry) &&
                    (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
 
-       {
-               zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST,
-                       zend_ast_create_zval_from_str(zend_string_init("__CLASS__", sizeof("__CLASS__") - 1, 0)));
-               zend_compile_const(result, const_ast);
-               zend_ast_destroy(const_ast);
-       }
+       zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
 }
 /* }}} */
 
@@ -6298,8 +6309,8 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
 
        {
                zval const_zv;
-               ZVAL_STRING(&const_zv, "__CLASS__");
-               Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX;
+               Z_STR(const_zv) = zend_string_init("__CLASS__", sizeof("__CLASS__")-1, 0);
+               Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX | (IS_CONSTANT_CLASS << Z_CONST_FLAGS_SHIFT);
 
                zend_ast_destroy(ast);
                *ast_ptr = zend_ast_create_zval(&const_zv);
index 4ca7ef4571f4bb9589947e93d404721571797da5..bf4e26a0e861943f47fd1c1017c3a4482609498c 100644 (file)
@@ -231,36 +231,6 @@ static zend_constant *zend_get_special_constant(const char *name, size_t name_le
 
        if (!EG(current_execute_data)) {
                return NULL;
-       } else if (name_len == sizeof("__CLASS__")-1 &&
-                 !memcmp(name, "__CLASS__", sizeof("__CLASS__")-1)) {
-
-               /* Returned constants may be cached, so they have to be stored */
-               if (EG(scope) && EG(scope)->name) {
-                       size_t const_name_len;
-                       zend_string *const_name;
-
-                       const_name_len = sizeof("\0__CLASS__") + EG(scope)->name->len;
-                       const_name = zend_string_alloc(const_name_len, 0);
-                       memcpy(const_name->val, "\0__CLASS__", sizeof("\0__CLASS__")-1);
-                       zend_str_tolower_copy(const_name->val + sizeof("\0__CLASS__")-1, EG(scope)->name->val, EG(scope)->name->len);
-                       if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
-                               c = emalloc(sizeof(zend_constant));
-                               memset(c, 0, sizeof(zend_constant));
-                               ZVAL_STR_COPY(&c->value, EG(scope)->name);
-                               zend_hash_add_ptr(EG(zend_constants), const_name, c);
-                       }
-                       zend_string_release(const_name);
-               } else {
-                       zend_string *const_name = zend_string_init("\0__CLASS__", sizeof("\0__CLASS__")-1, 0);
-                       if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
-                               c = emalloc(sizeof(zend_constant));
-                               memset(c, 0, sizeof(zend_constant));
-                               ZVAL_EMPTY_STRING(&c->value);
-                               zend_hash_add_ptr(EG(zend_constants), const_name, c);
-                       }
-                       zend_string_release(const_name);
-               }
-               return c;
        } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
                  !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
                const char *cfilename;
@@ -465,12 +435,12 @@ zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags)
                                            (c->flags & CONST_CS) != 0) {
 
                                                key--;
-                                               c = zend_get_special_constant(Z_STRVAL_P(key), Z_STRLEN_P(key));
+                                               c = NULL;
                                        }
                                }
                        } else {
                                key--;
-                               c = zend_get_special_constant(Z_STRVAL_P(key), Z_STRLEN_P(key));
+                               c = NULL;
                        }
                }
        }
index c3bd69a5b1e1dea9410c4d4bcf0d15f506ac41fd..556e5c60e166ca6e08feedcc6e07c49fa95ea587 100644 (file)
@@ -535,8 +535,17 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
                SEPARATE_ZVAL_NOREF(p);
                MARK_CONSTANT_VISITED(p);
                refcount =  Z_REFCOUNTED_P(p) ? Z_REFCOUNT_P(p) : 1;
-               const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p));
-               if (!const_value) {
+               if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) {
+                       ZEND_ASSERT(EG(current_execute_data));
+                       if (inline_change) {
+                               zend_string_release(Z_STR_P(p));
+                       }
+                       if (EG(scope) && EG(scope)->name) {
+                               ZVAL_STR_COPY(p, EG(scope)->name);
+                       } else {
+                               ZVAL_EMPTY_STRING(p);
+                       }
+               } else if ((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL) {
                        char *actual = Z_STRVAL_P(p);
 
                        if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
index 3f1258f7bfa996b4c16ebfbc3fce25a8df84c797..0cfd8fca907fc7ef1e9e2179ecac575ceefa409f 100644 (file)
@@ -389,6 +389,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define IS_CONSTANT_UNQUALIFIED                0x010
 #define IS_LEXICAL_VAR                         0x020
 #define IS_LEXICAL_REF                         0x040
+#define IS_CONSTANT_CLASS           0x080  /* __CLASS__ in trait */
 #define IS_CONSTANT_IN_NAMESPACE       0x100  /* used only in opline->extended_value */
 
 /* zval.u2.var_flags */
index 995fabc17d3a8abfa5c415ef32a6721d9ce50088..ab2c7b89a37818aab2df1d758899a54e5ae388ac 100644 (file)
@@ -7363,3 +7363,14 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY)
        }
 }
 
+ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY)
+{
+       USE_OPLINE
+
+       if (EG(scope) && EG(scope)->name) {
+               ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+       } else {
+               ZVAL_EMPTY_STRING(EX_VAR(opline->result.var));
+       }
+       ZEND_VM_NEXT_OPCODE();
+}
\ No newline at end of file
index 3f7defc088f34523f668279c84494c551cfedc8e..e5547f3e1eaf9910bea3e3114e5afb8615cc1da4 100644 (file)
@@ -1779,7 +1779,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
        }
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       if (EG(scope) && EG(scope)->name) {
+               ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+       } else {
+               ZVAL_EMPTY_STRING(EX_VAR(opline->result.var));
+       }
+       ZEND_VM_NEXT_OPCODE();
+}static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
 
@@ -45490,31 +45500,31 @@ void zend_init_opcodes_handlers(void)
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
+       ZEND_FETCH_CLASS_NAME_SPEC_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
index 9bc531634d0c48540152417a18842cf0ef076500..d464b9ba50afa4c4a5aaae4413eade5d39ae3b98 100644 (file)
@@ -179,7 +179,7 @@ const char *zend_vm_opcodes_map[171] = {
        "ZEND_ADD_TRAIT",
        "ZEND_BIND_TRAITS",
        "ZEND_SEPARATE",
-       NULL,
+       "ZEND_FETCH_CLASS_NAME",
        NULL,
        "ZEND_DISCARD_EXCEPTION",
        "ZEND_YIELD",
index 3965740fb27f52a92ac3c6f5bdd321ad5e00c275..86fe5590d67740400154a3a987d3cc44abb2ce68 100644 (file)
@@ -186,6 +186,7 @@ END_EXTERN_C()
 #define ZEND_ADD_TRAIT                       154
 #define ZEND_BIND_TRAITS                     155
 #define ZEND_SEPARATE                        156
+#define ZEND_FETCH_CLASS_NAME                157
 #define ZEND_DISCARD_EXCEPTION               159
 #define ZEND_YIELD                           160
 #define ZEND_GENERATOR_RETURN                161