v. php_add[c]slashes
w. zend_class_entry.iterator_funcs
x. Class declaration opcodes (DECLARE_INHERITED_CLASS ...)
+ y. zend_constant
2. Build system changes
a. Unix build system changes
- ADD_INTERFACE and ADD_TRAIT don't use run-time cache to keep interface or
trait. These instructions are executed once, and caching is useless.
+ y. zend_constant.flags and zend_constant.module_number are packed into
+ reserved space inside zend_constant.value. They should be accessed using
+ ZEND_CONTANT_FLAGS(), ZEND_CONSTANTS_MODULE_NUMBER() and
+ ZEND_CONTANT_SET_FLAGS() macros.
+
========================
2. Build system changes
========================
"define(): Declaration of case-insensitive constants is deprecated");
}
- c.flags = case_sensitive; /* non persistent */
+ /* non persistent */
+ ZEND_CONSTANT_SET_FLAGS(&c, case_sensitive, PHP_USER_CONSTANT);
c.name = zend_string_copy(name);
- c.module_number = PHP_USER_CONSTANT;
if (zend_register_constant(&c) == SUCCESS) {
RETURN_TRUE;
} else {
continue;
}
- if (val->module_number == PHP_USER_CONSTANT) {
+ if (ZEND_CONSTANT_MODULE_NUMBER(val) == PHP_USER_CONSTANT) {
module_number = i;
- } else if (val->module_number > i || val->module_number < 0) {
+ } else if (ZEND_CONSTANT_MODULE_NUMBER(val) > i) {
/* should not happen */
continue;
} else {
- module_number = val->module_number;
+ module_number = ZEND_CONSTANT_MODULE_NUMBER(val);
}
if (Z_TYPE(modules[module_number]) == IS_UNDEF) {
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 && !(c->flags & CONST_CS) && (c->flags & CONST_CT_SUBST)) {
+ if (c && !(ZEND_CONSTANT_FLAGS(c) & CONST_CS) && (ZEND_CONSTANT_FLAGS(c) & CONST_CT_SUBST)) {
return c;
}
return NULL;
/* Substitute case-sensitive (or lowercase) constants */
c = zend_hash_find_ptr(EG(zend_constants), name);
if (c && (
- ((c->flags & CONST_PERSISTENT)
+ ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)
&& !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION)
- && (!(c->flags & CONST_NO_FILE_CACHE) || !(CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE)))
+ && (!(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))
)) {
ZVAL_COPY_OR_DUP(zv, &c->value);
{
zend_constant *c = Z_PTR_P(zv);
- if (!(c->flags & CONST_PERSISTENT)) {
+ if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) {
zval_ptr_dtor_nogc(&c->value);
if (c->name) {
zend_string_release_ex(c->name, 0);
zend_constant *c = (zend_constant *)Z_PTR_P(el);
int module_number = *(int *)arg;
- if (c->module_number == module_number) {
+ if (ZEND_CONSTANT_MODULE_NUMBER(c) == module_number) {
return 1;
} else {
return 0;
zend_constant c;
ZVAL_NULL(&c.value);
- c.flags = flags;
+ ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
- c.module_number = module_number;
zend_register_constant(&c);
}
zend_constant c;
ZVAL_BOOL(&c.value, bval);
- c.flags = flags;
+ ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
- c.module_number = module_number;
zend_register_constant(&c);
}
zend_constant c;
ZVAL_LONG(&c.value, lval);
- c.flags = flags;
+ ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
- c.module_number = module_number;
zend_register_constant(&c);
}
zend_constant c;
ZVAL_DOUBLE(&c.value, dval);
- c.flags = flags;
+ ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
- c.module_number = module_number;
zend_register_constant(&c);
}
zend_constant c;
ZVAL_STR(&c.value, zend_string_init_interned(strval, strlen, flags & CONST_PERSISTENT));
- c.flags = flags;
+ ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
- c.module_number = module_number;
zend_register_constant(&c);
}
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 (c->flags & CONST_CS) {
+ if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) {
c = NULL;
}
} else {
zv = zend_hash_str_find(EG(zend_constants), lcname, ZSTR_LEN(name));
if (zv != NULL) {
c = Z_PTR_P(zv);
- if (c->flags & CONST_CS) {
+ if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) {
c = NULL;
}
} else {
/* 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 ((c->flags & CONST_CS) != 0) {
+ if ((ZEND_CONSTANT_FLAGS(c) & CONST_CS) != 0) {
c = NULL;
}
}
}
if (!(flags & ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) {
- if (!(c->flags & (CONST_CS|CONST_CT_SUBST)) && is_access_deprecated(c, name)) {
+ 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\"",
static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c)
{
void *ret;
- zend_constant *copy = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT);
+ zend_constant *copy = pemalloc(sizeof(zend_constant), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
memcpy(copy, c, sizeof(zend_constant));
ret = zend_hash_add_ptr(ht, key, copy);
if (!ret) {
- pefree(copy, c->flags & CONST_PERSISTENT);
+ pefree(copy, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
}
return ret;
}
printf("Registering constant for module %d\n", c->module_number);
#endif
- if (!(c->flags & CONST_CS)) {
- lowercase_name = zend_string_tolower_ex(c->name, c->flags & CONST_PERSISTENT);
+ if (!(ZEND_CONSTANT_FLAGS(c) & CONST_CS)) {
+ lowercase_name = zend_string_tolower_ex(c->name, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
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), c->flags & CONST_PERSISTENT);
+ 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;
}
zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name));
zend_string_release(c->name);
- if (!(c->flags & CONST_PERSISTENT)) {
+ if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) {
zval_ptr_dtor_nogc(&c->value);
}
ret = FAILURE;
#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 PHP_USER_CONSTANT INT_MAX /* a constant defined in user space */
+#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;
- int flags;
- int module_number;
} zend_constant;
+#define ZEND_CONSTANT_FLAGS(c) \
+ (Z_CONSTANT_FLAGS((c)->value) & 0xff)
+
+#define ZEND_CONSTANT_MODULE_NUMBER(c) \
+ (Z_CONSTANT_FLAGS((c)->value) >> 8)
+
+#define ZEND_CONSTANT_SET_FLAGS(c, _flags, _module_number) do { \
+ Z_CONSTANT_FLAGS((c)->value) = \
+ ((_flags) & 0xff) | ((_module_number) << 8); \
+ } while (0)
+
#define REGISTER_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name)-1, (flags), module_number)
#define REGISTER_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name)-1, (bval), (flags), module_number)
#define REGISTER_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name)-1, (lval), (flags), module_number)
} else {
key++;
zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
- if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) {
+ if (zv && (ZEND_CONSTANT_FLAGS((zend_constant*)Z_PTR_P(zv)) & CONST_CS) == 0) {
c = (zend_constant*)Z_PTR_P(zv);
} else {
if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
} else {
key++;
zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
- if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) {
+ if (zv && (ZEND_CONSTANT_FLAGS((zend_constant*)Z_PTR_P(zv)) & CONST_CS) == 0) {
c = (zend_constant*)Z_PTR_P(zv);
}
}
if (!check_defined_only) {
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
- if (!(c->flags & (CONST_CS|CONST_CT_SUBST))) {
+ if (!(ZEND_CONSTANT_FLAGS(c) & (CONST_CS|CONST_CT_SUBST))) {
const char *ns_sep;
size_t shortname_offset;
size_t shortname_len;
static int clean_non_persistent_constant_full(zval *zv) /* {{{ */
{
zend_constant *c = Z_PTR_P(zv);
- return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
+ return (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
}
/* }}} */
} else {
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
zend_constant *c = Z_PTR_P(zv);
- if (c->flags & CONST_PERSISTENT) {
+ if (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) {
break;
}
zval_ptr_dtor_nogc(&c->value);
uint32_t fe_iter_idx; /* foreach iterator index */
uint32_t access_flags; /* class constant access flags */
uint32_t property_guard; /* single property guard */
+ uint32_t constant_flags; /* constant flags */
uint32_t extra; /* not further specified */
} u2;
};
#define Z_PROPERTY_GUARD(zval) (zval).u2.property_guard
#define Z_PROPERTY_GUARD_P(zval_p) Z_PROPERTY_GUARD(*(zval_p))
+#define Z_CONSTANT_FLAGS(zval) (zval).u2.constant_flags
+#define Z_CONSTANT_FLAGS_P(zval_p) Z_CONSTANT_FLAGS(*(zval_p))
+
#define Z_EXTRA(zval) (zval).u2.extra
#define Z_EXTRA_P(zval_p) Z_EXTRA(*(zval_p))
HANDLE_EXCEPTION();
}
}
- c.flags = CONST_CS; /* non persistent, case sensitive */
+ /* non persistent, case sensitive */
+ ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, PHP_USER_CONSTANT);
c.name = zend_string_copy(Z_STR_P(name));
- c.module_number = PHP_USER_CONSTANT;
if (zend_register_constant(&c) == FAILURE) {
}
HANDLE_EXCEPTION();
}
}
- c.flags = CONST_CS; /* non persistent, case sensitive */
+ /* non persistent, case sensitive */
+ ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, PHP_USER_CONSTANT);
c.name = zend_string_copy(Z_STR_P(name));
- c.module_number = PHP_USER_CONSTANT;
if (zend_register_constant(&c) == FAILURE) {
}
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 (!(c->flags & CONST_CT_SUBST) || (c->flags & CONST_CS)) {
+ if (!(ZEND_CONSTANT_FLAGS(c) & CONST_CT_SUBST) || (ZEND_CONSTANT_FLAGS(c) & CONST_CS)) {
retval = 0;
}
} else {
}
if (retval) {
- if ((c->flags & CONST_PERSISTENT)
- && (!(c->flags & CONST_NO_FILE_CACHE)
+ if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)
+ && (!(ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE)
|| !(CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE))) {
ZVAL_COPY_VALUE(result, &c->value);
if (copy) {
struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
int *num_classes = va_arg(args, int*);
- if (constant->module_number == module->module_number) {
+ if (ZEND_CONSTANT_MODULE_NUMBER(constant) == module->module_number) {
_const_string(str, ZSTR_VAL(constant->name), &constant->value, indent);
(*num_classes)++;
}
zval *retval = va_arg(args, zval*);
int number = va_arg(args, int);
- if (number == constant->module_number) {
+ if (number == ZEND_CONSTANT_MODULE_NUMBER(constant)) {
ZVAL_COPY_OR_DUP(&const_val, &constant->value);
zend_hash_update(Z_ARRVAL_P(retval), constant->name, &const_val);
}
php_stream_to_zval(s_out, &oc.value);
php_stream_to_zval(s_err, &ec.value);
- ic.flags = CONST_CS;
+ ZEND_CONSTANT_SET_FLAGS(&ic, CONST_CS, 0);
ic.name = zend_string_init_interned("STDIN", sizeof("STDIN")-1, 0);
- ic.module_number = 0;
zend_register_constant(&ic);
- oc.flags = CONST_CS;
+ ZEND_CONSTANT_SET_FLAGS(&oc, CONST_CS, 0);
oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT")-1, 0);
- oc.module_number = 0;
zend_register_constant(&oc);
- ec.flags = CONST_CS;
+ ZEND_CONSTANT_SET_FLAGS(&ec, CONST_CS, 0);
ec.name = zend_string_init_interned("STDERR", sizeof("STDERR")-1, 0);
- ec.module_number = 0;
zend_register_constant(&ec);
}
/* }}} */
php_stream_to_zval(s_err, &zerr);
ic.value = zin;
- ic.flags = CONST_CS;
+ ZEND_CONSTANT_SET_FLAGS(&ic, CONST_CS, 0);
ic.name = zend_string_init(ZEND_STRL("STDIN"), 0);
- ic.module_number = 0;
zend_hash_del(EG(zend_constants), ic.name);
zend_register_constant(&ic);
oc.value = zout;
- oc.flags = CONST_CS;
+ ZEND_CONSTANT_SET_FLAGS(&oc, CONST_CS, 0);
oc.name = zend_string_init(ZEND_STRL("STDOUT"), 0);
- oc.module_number = 0;
zend_hash_del(EG(zend_constants), oc.name);
zend_register_constant(&oc);
ec.value = zerr;
- ec.flags = CONST_CS;
+ ZEND_CONSTANT_SET_FLAGS(&ec, CONST_CS, 0);
ec.name = zend_string_init(ZEND_STRL("STDERR"), 0);
- ec.module_number = 0;
zend_hash_del(EG(zend_constants), ec.name);
zend_register_constant(&ec);
}
if (EG(zend_constants)) {
phpdbg_try_access {
ZEND_HASH_FOREACH_PTR(EG(zend_constants), data) {
- if (data->module_number == PHP_USER_CONSTANT) {
+ if (ZEND_CONSTANT_MODULE_NUMBER(data) == PHP_USER_CONSTANT) {
zend_hash_update_ptr(&consts, data->name, data);
}
} ZEND_HASH_FOREACH_END();