Browse Source

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.
pull/3782/head
Nikita Popov 7 years ago
parent
commit
3d39479f4d
  1. 4
      Zend/tests/008.phpt
  2. 2
      Zend/zend_builtin_functions.c
  3. 43
      Zend/zend_compile.c
  4. 214
      Zend/zend_constants.c
  5. 20
      Zend/zend_constants.h
  6. 58
      Zend/zend_execute.c
  7. 35
      ext/opcache/Optimizer/block_pass.c
  8. 6
      ext/opcache/Optimizer/compact_literals.c

4
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

2
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;

43
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));
}

214
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;

20
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

58
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);

35
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 */

6
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:

Loading…
Cancel
Save