}
/* }}} */
+static zend_bool can_ct_eval_const(zend_constant *c) {
+ if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) {
+ return 0;
+ }
+ if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)
+ && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION)
+ && !((ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE)
+ && (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE))) {
+ return 1;
+ }
+ if (Z_TYPE(c->value) < IS_OBJECT
+ && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
+ return 1;
+ }
+ return 0;
+}
+
static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool is_fully_qualified) /* {{{ */
{
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)
- && !((ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE) && (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE)))
- || (Z_TYPE(c->value) < IS_OBJECT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION))
- )) {
+ if (c && can_ct_eval_const(c)) {
ZVAL_COPY_OR_DUP(zv, &c->value);
return 1;
}
/* 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);
}
- if ((val = zend_get_special_const(lookup_name, lookup_len))) {
- ZVAL_COPY_VALUE(zv, val);
+ if ((c = zend_get_special_const(lookup_name, lookup_len))) {
+ ZVAL_COPY_VALUE(zv, &c->value);
return 1;
}
#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;
+static zend_constant *null_const, *true_const, *false_const;
void free_zend_constant(zval *zv)
{
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);
+ true_const = zend_hash_str_find_ptr(EG(zend_constants), "TRUE", sizeof("TRUE")-1);
+ false_const = zend_hash_str_find_ptr(EG(zend_constants), "FALSE", sizeof("FALSE")-1);
+ null_const = zend_hash_str_find_ptr(EG(zend_constants), "NULL", sizeof("NULL")-1);
}
}
}
-ZEND_API zval *_zend_get_special_const(const char *name, size_t len) /* {{{ */
+ZEND_API zend_constant *_zend_get_special_const(const char *name, size_t len) /* {{{ */
{
if (len == 4) {
if ((name[0] == 'n' || name[0] == 'N') &&
(name[2] == 'l' || name[2] == 'L') &&
(name[3] == 'l' || name[3] == 'L')
) {
- return &null_value;
+ return null_const;
}
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;
+ return true_const;
}
} else {
if ((name[0] == 'f' || name[0] == 'F') &&
(name[3] == 's' || name[3] == 'S') &&
(name[4] == 'e' || name[4] == 'E')
) {
- return &false_value;
+ return false_const;
}
}
- return 0;
+ return NULL;
}
/* }}} */
}
/* }}} */
-ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
+static zend_constant *zend_get_constant_str_impl(const char *name, size_t name_len)
{
zend_constant *c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len);
if (c) {
- return &c->value;
+ return c;
}
c = zend_get_halt_offset_constant(name, name_len);
if (c) {
- return &c->value;
+ return c;
}
return zend_get_special_const(name, name_len);
}
-ZEND_API zval *zend_get_constant(zend_string *name)
+ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
{
- zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name);
+ zend_constant *c = zend_get_constant_str_impl(name, name_len);
if (c) {
return &c->value;
}
+ return NULL;
+}
+
+static zend_constant *zend_get_constant_impl(zend_string *name)
+{
+ zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name);
+ if (c) {
+ return c;
+ }
c = zend_get_halt_offset_constant(ZSTR_VAL(name), ZSTR_LEN(name));
if (c) {
- return &c->value;
+ return c;
}
return zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name));
}
+ZEND_API zval *zend_get_constant(zend_string *name)
+{
+ zend_constant *c = zend_get_constant_impl(name);
+ if (c) {
+ return &c->value;
+ }
+ return NULL;
+}
+
ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags)
{
zend_constant *c;
}
/* non-class constant */
- zval *value;
if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) {
/* compound constant name */
int prefix_len = colon - name;
c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len);
free_alloca(lcname, use_heap);
- if (c) {
- return &c->value;
- }
-
- if (flags & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) {
- /* name requires runtime resolution, need to check non-namespaced name */
- value = zend_get_constant_str(constant_name, const_name_len);
- } else {
- value = NULL;
+ if (!c) {
+ if (flags & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) {
+ /* name requires runtime resolution, need to check non-namespaced name */
+ c = zend_get_constant_str_impl(constant_name, const_name_len);
+ }
}
} else {
if (cname) {
- value = zend_get_constant(cname);
+ c = zend_get_constant_impl(cname);
} else {
- value = zend_get_constant_str(name, name_len);
+ c = zend_get_constant_str_impl(name, name_len);
}
}
- if (!value && !(flags & ZEND_FETCH_CLASS_SILENT)) {
- zend_throw_error(NULL, "Undefined constant '%s'", name);
+ if (!(flags & ZEND_FETCH_CLASS_SILENT)) {
+ if (!c) {
+ zend_throw_error(NULL, "Undefined constant '%s'", name);
+ } else if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) {
+ zend_error(E_DEPRECATED, "Constant %s is deprecated", name);
+ }
}
- return value;
+ return &c->value;
}
static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c)
#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 CONST_DEPRECATED (1<<2) /* Deprecated */
#define PHP_USER_CONSTANT 0x7fffff /* a constant defined in user space */
void zend_copy_constants(HashTable *target, HashTable *sourc);
#endif
-ZEND_API zval *_zend_get_special_const(const char *name, size_t name_len);
+ZEND_API zend_constant *_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) {
+static zend_always_inline zend_constant *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);
}
/* 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)
{
- 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_DEPRECATED)
&& (!(ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE)
|| !(CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE))) {
ZVAL_COPY_VALUE(result, &c->value);
}
/* 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);
+ c = zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name));
+ if (c) {
+ ZVAL_COPY_VALUE(result, &c->value);
return 1;
}
return 0;