diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-01-30 17:16:09 +0100 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-01-31 13:52:06 +0100 |
| commit | 3d39479f4d7c86c66aa92fc5d0d97fb660109ee9 (patch) | |
| tree | bb64e4169942e0e8707ae4260b912e8e5a55aa7d | |
| parent | 3d478e5cc34a1dbdc00733e4ab684a2509dc71e5 (diff) | |
| download | php-git-3d39479f4d7c86c66aa92fc5d0d97fb660109ee9.tar.gz | |
Remove support for case-insensitive constants
The only remaining case-insensitive constants are null, true and
false, which are handled explicitly.
In the future we may convert them from constants to reserved keywords.
| -rw-r--r-- | Zend/tests/008.phpt | 4 | ||||
| -rw-r--r-- | Zend/zend_builtin_functions.c | 2 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 43 | ||||
| -rw-r--r-- | Zend/zend_constants.c | 214 | ||||
| -rw-r--r-- | Zend/zend_constants.h | 20 | ||||
| -rw-r--r-- | Zend/zend_execute.c | 58 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 35 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/compact_literals.c | 6 |
8 files changed, 129 insertions, 253 deletions
diff --git a/Zend/tests/008.phpt b/Zend/tests/008.phpt index 0766c3e1a4..cacba06370 100644 --- a/Zend/tests/008.phpt +++ b/Zend/tests/008.phpt @@ -29,7 +29,9 @@ NULL Warning: define() expects at least 2 parameters, 1 given in %s on line %d NULL -bool(true) + +Notice: Constant TRUE already defined in %s on line %d +bool(false) Warning: define() expects parameter 3 to be bool, array given in %s on line %d NULL diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 786e6b4813..0cd3e0c0fe 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -854,7 +854,7 @@ ZEND_FUNCTION(defined) Z_PARAM_STR(name) ZEND_PARSE_PARAMETERS_END(); - if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT | ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) { + if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) { RETURN_TRUE; } else { RETURN_FALSE; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 59ff42cc30..d153bf79f4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -585,10 +585,6 @@ static int zend_add_const_name_literal(zend_string *name, zend_bool unqualified) zend_str_tolower(ZSTR_VAL(tmp_name), ns_len); zend_add_literal_string(&tmp_name); - /* lowercased namespace name & lowercased constant name */ - tmp_name = zend_string_tolower(name); - zend_add_literal_string(&tmp_name); - if (!unqualified) { return ret; } @@ -600,11 +596,6 @@ static int zend_add_const_name_literal(zend_string *name, zend_bool unqualified) tmp_name = zend_string_init(after_ns, after_ns_len, 0); zend_add_literal_string(&tmp_name); - /* lowercased unqualified constant name */ - tmp_name = zend_string_alloc(after_ns_len, 0); - zend_str_tolower_copy(ZSTR_VAL(tmp_name), after_ns, after_ns_len); - zend_add_literal_string(&tmp_name); - return ret; } /* }}} */ @@ -1213,22 +1204,9 @@ ZEND_API int zend_unmangle_property_name_ex(const zend_string *name, const char } /* }}} */ -static zend_constant *zend_lookup_reserved_const(const char *name, size_t len) /* {{{ */ -{ - zend_constant *c = zend_hash_find_ptr_lc(EG(zend_constants), name, len); - if (c && !(ZEND_CONSTANT_FLAGS(c) & CONST_CS) && (ZEND_CONSTANT_FLAGS(c) & CONST_CT_SUBST)) { - return c; - } - return NULL; -} -/* }}} */ - static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool is_fully_qualified) /* {{{ */ { - zend_constant *c; - - /* Substitute case-sensitive (or lowercase) constants */ - c = zend_hash_find_ptr(EG(zend_constants), name); + zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name); if (c && ( ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) @@ -1243,19 +1221,19 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i /* Substitute true, false and null (including unqualified usage in namespaces) */ const char *lookup_name = ZSTR_VAL(name); size_t lookup_len = ZSTR_LEN(name); + zval *val; if (!is_fully_qualified) { zend_get_unqualified_name(name, &lookup_name, &lookup_len); } - c = zend_lookup_reserved_const(lookup_name, lookup_len); - if (c) { - ZVAL_COPY_OR_DUP(zv, &c->value); + if ((val = zend_get_special_const(lookup_name, lookup_len))) { + ZVAL_COPY_VALUE(zv, val); return 1; } - } - return 0; + return 0; + } } /* }}} */ @@ -3249,13 +3227,6 @@ int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */ LITERAL_STR(opline->op1, name); opline->extended_value = zend_alloc_cache_slot(); - /* Lowercase constant name in a separate literal */ - { - zval c; - zend_string *lcname = zend_string_tolower(name); - ZVAL_NEW_STR(&c, lcname); - zend_add_literal(&c); - } return SUCCESS; } /* }}} */ @@ -6538,7 +6509,7 @@ void zend_compile_const_decl(zend_ast *ast) /* {{{ */ value_node.op_type = IS_CONST; zend_const_expr_to_zval(value_zv, value_ast); - if (zend_lookup_reserved_const(ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name))) { + if (zend_get_special_const(ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name))) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", ZSTR_VAL(unqualified_name)); } diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 0f3fb9cfa0..6371492dc0 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -33,6 +33,9 @@ #define MARK_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) |= IS_CONSTANT_VISITED_MARK #define RESET_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) &= ~IS_CONSTANT_VISITED_MARK +/* Use for special null/true/false constants. */ +static zval null_value, true_value, false_value; + void free_zend_constant(zval *zv) { zend_constant *c = Z_PTR_P(zv); @@ -99,7 +102,6 @@ void clean_module_constants(int module_number) int zend_startup_constants(void) { EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init(EG(zend_constants), 128, NULL, ZEND_CONSTANT_DTOR, 1); return SUCCESS; } @@ -128,14 +130,17 @@ void zend_register_standard_constants(void) REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS); - /* true/false constants */ - { - REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT | CONST_CT_SUBST); - REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT | CONST_CT_SUBST); - REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS); - } - REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST); + REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS); + + /* Special constants true/false/null. */ + REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT); + REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT); + REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT); + + ZVAL_NULL(&null_value); + ZVAL_TRUE(&true_value); + ZVAL_FALSE(&false_value); } @@ -204,7 +209,7 @@ ZEND_API void zend_register_string_constant(const char *name, size_t name_len, c zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number); } -static zend_constant *zend_get_special_constant(const char *name, size_t name_len) +static zend_constant *zend_get_halt_offset_constant(const char *name, size_t name_len) { zend_constant *c; static const char haltoff[] = "__COMPILER_HALT_OFFSET__"; @@ -230,6 +235,37 @@ static zend_constant *zend_get_special_constant(const char *name, size_t name_le } } +ZEND_API zval *_zend_get_special_const(const char *name, size_t len) /* {{{ */ +{ + if (len == 4) { + if ((name[0] == 'n' || name[0] == 'N') && + (name[1] == 'u' || name[1] == 'U') && + (name[2] == 'l' || name[2] == 'L') && + (name[3] == 'l' || name[3] == 'L') + ) { + return &null_value; + } + if ((name[0] == 't' || name[0] == 'T') && + (name[1] == 'r' || name[1] == 'R') && + (name[2] == 'u' || name[2] == 'U') && + (name[3] == 'e' || name[3] == 'E') + ) { + return &true_value; + } + } else { + if ((name[0] == 'f' || name[0] == 'F') && + (name[1] == 'a' || name[1] == 'A') && + (name[2] == 'l' || name[2] == 'L') && + (name[3] == 's' || name[3] == 'S') && + (name[4] == 'e' || name[4] == 'E') + ) { + return &false_value; + } + } + return 0; +} +/* }}} */ + ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */ { if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) { @@ -243,80 +279,34 @@ ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry * } /* }}} */ -static inline zend_constant *zend_get_constant_str_impl(const char *name, size_t name_len) -{ - zend_constant *c; - ALLOCA_FLAG(use_heap) - - if ((c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len)) == NULL) { - char *lcname = do_alloca(name_len + 1, use_heap); - zend_str_tolower_copy(lcname, name, name_len); - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name_len)) != NULL) { - if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) { - c = NULL; - } - } else { - c = zend_get_special_constant(name, name_len); - } - free_alloca(lcname, use_heap); - } - - return c; -} - ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len) { - zend_constant *c = zend_get_constant_str_impl(name, name_len); - return c ? &c->value : NULL; -} + zend_constant *c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len); + if (c) { + return &c->value; + } -static inline zend_constant *zend_get_constant_impl(zend_string *name) -{ - zval *zv; - zend_constant *c; - ALLOCA_FLAG(use_heap) - - zv = zend_hash_find(EG(zend_constants), name); - if (zv == NULL) { - char *lcname = do_alloca(ZSTR_LEN(name) + 1, use_heap); - zend_str_tolower_copy(lcname, ZSTR_VAL(name), ZSTR_LEN(name)); - zv = zend_hash_str_find(EG(zend_constants), lcname, ZSTR_LEN(name)); - if (zv != NULL) { - c = Z_PTR_P(zv); - if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) { - c = NULL; - } - } else { - c = zend_get_special_constant(ZSTR_VAL(name), ZSTR_LEN(name)); - } - free_alloca(lcname, use_heap); - return c; - } else { - return (zend_constant *) Z_PTR_P(zv); + c = zend_get_halt_offset_constant(name, name_len); + if (c) { + return &c->value; } + + return zend_get_special_const(name, name_len); } ZEND_API zval *zend_get_constant(zend_string *name) { - zend_constant *c = zend_get_constant_impl(name); - return c ? &c->value : NULL; -} + zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name); + if (c) { + return &c->value; + } -static zend_bool is_access_deprecated(const zend_constant *c, const char *access_name) { - const char *ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name)); - if (ns_sep) { - /* Namespaces are always case-insensitive. Only compare shortname. */ - size_t shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1; - size_t shortname_len = ZSTR_LEN(c->name) - shortname_offset; - return memcmp( - access_name + shortname_offset, - ZSTR_VAL(c->name) + shortname_offset, - shortname_len - ) != 0; - } else { - /* No namespace, compare whole name */ - return memcmp(access_name, ZSTR_VAL(c->name), ZSTR_LEN(c->name)) != 0; + c = zend_get_halt_offset_constant(ZSTR_VAL(name), ZSTR_LEN(name)); + if (c) { + return &c->value; } + + return zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)); } ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) @@ -419,56 +409,34 @@ failure: size_t lcname_len; ALLOCA_FLAG(use_heap) + /* Lowercase the namespace portion */ lcname_len = prefix_len + 1 + const_name_len; lcname = do_alloca(lcname_len + 1, use_heap); zend_str_tolower_copy(lcname, name, prefix_len); - /* Check for namespace constant */ lcname[prefix_len] = '\\'; memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1); - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) { - /* try lowercase */ - zend_str_tolower(lcname + prefix_len + 1, const_name_len); - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) { - if ((ZEND_CONSTANT_FLAGS(c) & CONST_CS) != 0) { - c = NULL; - } - } - } + c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len); free_alloca(lcname, use_heap); - if (!c) { - if (!(flags & IS_CONSTANT_UNQUALIFIED)) { - return NULL; - } + if (c) { + return &c->value; + } - /* name requires runtime resolution, need to check non-namespaced name */ - c = zend_get_constant_str_impl(constant_name, const_name_len); - name = constant_name; + if (!(flags & IS_CONSTANT_UNQUALIFIED)) { + return NULL; } + + /* name requires runtime resolution, need to check non-namespaced name */ + return zend_get_constant_str(constant_name, const_name_len); } else { if (cname) { - c = zend_get_constant_impl(cname); + return zend_get_constant(cname); } else { - c = zend_get_constant_str_impl(name, name_len); - } - } - - if (!c) { - return NULL; - } - - if (!(flags & ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) { - if (!(ZEND_CONSTANT_FLAGS(c) & (CONST_CS|CONST_CT_SUBST)) && is_access_deprecated(c, name)) { - zend_error(E_DEPRECATED, - "Case-insensitive constants are deprecated. " - "The correct casing for this constant is \"%s\"", - ZSTR_VAL(c->name)); + return zend_get_constant_str(name, name_len); } } - - return &c->value; } static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c) @@ -489,38 +457,30 @@ ZEND_API int zend_register_constant(zend_constant *c) zend_string *lowercase_name = NULL; zend_string *name; int ret = SUCCESS; + zend_bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0; #if 0 printf("Registering constant for module %d\n", c->module_number); #endif - if (!(ZEND_CONSTANT_FLAGS(c) & CONST_CS)) { - lowercase_name = zend_string_tolower_ex(c->name, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); + char *slash = strrchr(ZSTR_VAL(c->name), '\\'); + if (slash) { + lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), persistent); + zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name)); lowercase_name = zend_new_interned_string(lowercase_name); name = lowercase_name; } else { - char *slash = strrchr(ZSTR_VAL(c->name), '\\'); - if (slash) { - lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); - zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name)); - lowercase_name = zend_new_interned_string(lowercase_name); - name = lowercase_name; - } else { - name = c->name; - } + name = c->name; } - /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */ + /* Check if the user is trying to define any special constant */ if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__") - || zend_hash_add_constant(EG(zend_constants), name, c) == NULL) { - - /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */ - if (ZSTR_VAL(c->name)[0] == '\0' && ZSTR_LEN(c->name) > sizeof("\0__COMPILER_HALT_OFFSET__")-1 - && memcmp(ZSTR_VAL(name), "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) { - } + || (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name))) + || zend_hash_add_constant(EG(zend_constants), name, c) == NULL + ) { zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name)); zend_string_release(c->name); - if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) { + if (!persistent) { zval_ptr_dtor_nogc(&c->value); } ret = FAILURE; diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index fec4f294e9..66c9e1c63c 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -22,16 +22,12 @@ #include "zend_globals.h" -#define CONST_CS (1<<0) /* Case Sensitive */ -#define CONST_PERSISTENT (1<<1) /* Persistent */ -#define CONST_CT_SUBST (1<<2) /* Allow compile-time substitution */ -#define CONST_NO_FILE_CACHE (1<<3) /* Can't be saved in file cache */ +#define CONST_CS 0 /* No longer used -- always case sensitive */ +#define CONST_PERSISTENT (1<<0) /* Persistent */ +#define CONST_NO_FILE_CACHE (1<<1) /* Can't be saved in file cache */ #define PHP_USER_CONSTANT 0x7fffff /* a constant defined in user space */ -/* Flag for zend_get_constant_ex(). Must not class with ZEND_FETCH_CLASS_* flags. */ -#define ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK 0x1000 - typedef struct _zend_constant { zval value; zend_string *name; @@ -89,6 +85,16 @@ ZEND_API int zend_register_constant(zend_constant *c); #ifdef ZTS void zend_copy_constants(HashTable *target, HashTable *sourc); #endif + +ZEND_API zval *_zend_get_special_const(const char *name, size_t name_len); + +static zend_always_inline zval *zend_get_special_const(const char *name, size_t name_len) { + if (name_len == 4 || name_len == 5) { + return _zend_get_special_const(name, name_len); + } + return NULL; +} + END_EXTERN_C() #define ZEND_CONSTANT_DTOR free_zend_constant diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index db47aaa9e5..39155e8827 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4147,31 +4147,17 @@ static zend_always_inline int _zend_quick_get_constant( const zval *key, uint32_t flags, int check_defined_only OPLINE_DC EXECUTE_DATA_DC) /* {{{ */ { zval *zv; - const zval *orig_key = key; zend_constant *c = NULL; + /* null/true/false are resolved during compilation, so don't check for them here. */ zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); if (zv) { c = (zend_constant*)Z_PTR_P(zv); - } else { + } else if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { key++; zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); - if (zv && (ZEND_CONSTANT_FLAGS((zend_constant*)Z_PTR_P(zv)) & CONST_CS) == 0) { + if (zv) { c = (zend_constant*)Z_PTR_P(zv); - } else { - if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { - key++; - zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); - if (zv) { - c = (zend_constant*)Z_PTR_P(zv); - } else { - key++; - zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); - if (zv && (ZEND_CONSTANT_FLAGS((zend_constant*)Z_PTR_P(zv)) & CONST_CS) == 0) { - c = (zend_constant*)Z_PTR_P(zv); - } - } - } } } @@ -4199,44 +4185,6 @@ static zend_always_inline int _zend_quick_get_constant( if (!check_defined_only) { ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); - if (!(ZEND_CONSTANT_FLAGS(c) & (CONST_CS|CONST_CT_SUBST))) { - const char *ns_sep; - size_t shortname_offset; - size_t shortname_len; - zend_bool is_deprecated; - - if (flags & IS_CONSTANT_UNQUALIFIED) { - const zval *access_key; - - if (!(flags & IS_CONSTANT_IN_NAMESPACE)) { - access_key = orig_key - 1; - } else { - if (key < orig_key + 2) { - goto check_short_name; - } else { - access_key = orig_key + 2; - } - } - is_deprecated = !zend_string_equals(c->name, Z_STR_P(access_key)); - } else { -check_short_name: - ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name)); - ZEND_ASSERT(ns_sep); - /* Namespaces are always case-insensitive. Only compare shortname. */ - shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1; - shortname_len = ZSTR_LEN(c->name) - shortname_offset; - - is_deprecated = memcmp(ZSTR_VAL(c->name) + shortname_offset, Z_STRVAL_P(orig_key - 1) + shortname_offset, shortname_len) != 0; - } - - if (is_deprecated) { - zend_error(E_DEPRECATED, - "Case-insensitive constants are deprecated. " - "The correct casing for this constant is \"%s\"", - ZSTR_VAL(c->name)); - return SUCCESS; - } - } } CACHE_PTR(opline->extended_value, c); diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 45fe55b1ed..84c5687212 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -33,27 +33,9 @@ /* Checks if a constant (like "true") may be replaced by its value */ int zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy) { - zend_constant *c; - char *lookup_name; - int retval = 1; - ALLOCA_FLAG(use_heap); - - if ((c = zend_hash_find_ptr(EG(zend_constants), name)) == NULL) { - lookup_name = do_alloca(ZSTR_LEN(name) + 1, use_heap); - memcpy(lookup_name, ZSTR_VAL(name), ZSTR_LEN(name) + 1); - zend_str_tolower(lookup_name, ZSTR_LEN(name)); - - if ((c = zend_hash_str_find_ptr(EG(zend_constants), lookup_name, ZSTR_LEN(name))) != NULL) { - if (!(ZEND_CONSTANT_FLAGS(c) & CONST_CT_SUBST) || (ZEND_CONSTANT_FLAGS(c) & CONST_CS)) { - retval = 0; - } - } else { - retval = 0; - } - free_alloca(lookup_name, use_heap); - } - - if (retval) { + zval *zv; + zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name); + if (c) { if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) && (!(ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE) || !(CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE))) { @@ -61,12 +43,19 @@ int zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int if (copy) { Z_TRY_ADDREF_P(result); } + return 1; } else { - retval = 0; + return 0; } } - return retval; + /* Special constants null/true/false can always be substituted. */ + zv = zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)); + if (zv) { + ZVAL_COPY_VALUE(result, zv); + return 1; + } + return 0; } /* CFG back references management */ diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 4504d47bcb..8cc83d2964 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -168,13 +168,13 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2); break; case ZEND_DEFINED: - LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 1); break; case ZEND_FETCH_CONSTANT: if ((opline->op1.num & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { - LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 5); - } else { LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 3); + } else { + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 2); } break; case ZEND_FETCH_CLASS_CONSTANT: |
