diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 4ec7cc5271191..775119ba6ada4 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -42,6 +42,10 @@ PHP 8.3 INTERNALS UPGRADE NOTES * The order of members of zend_op_array, zend_ssa_var, zend_ssa_var_info, zend_executor_globals and php_core_globals have changed to improve struct packing which reduces their size. +* The name field have been removed from the zend_constant struct. Now, + constant names are only stored as keys of the global constants table. + That's why the `zend_register_constant()` function now expects the + constant name as its first parameter. ======================== 2. Build system changes diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c332f5a3220eb..b8cd96c480282 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -511,8 +511,7 @@ ZEND_FUNCTION(define) register_constant: /* non persistent */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); - c.name = zend_string_copy(name); - if (zend_register_constant(&c) == SUCCESS) { + if (zend_register_constant(name, &c) == SUCCESS) { RETURN_TRUE; } else { RETURN_FALSE; @@ -1480,6 +1479,7 @@ ZEND_FUNCTION(get_defined_constants) zend_constant *val; int module_number; zval *modules, const_val; + zend_string *const_name; char **module_names; zend_module_entry *module; int i = 1; @@ -1494,12 +1494,7 @@ ZEND_FUNCTION(get_defined_constants) } ZEND_HASH_FOREACH_END(); module_names[i] = "user"; - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), val) { - if (!val->name) { - /* skip special constants */ - continue; - } - + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), const_name, val) { if (ZEND_CONSTANT_MODULE_NUMBER(val) == PHP_USER_CONSTANT) { module_number = i; } else if (ZEND_CONSTANT_MODULE_NUMBER(val) > i) { @@ -1515,22 +1510,19 @@ ZEND_FUNCTION(get_defined_constants) } ZVAL_COPY_OR_DUP(&const_val, &val->value); - zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val); + zend_hash_add_new(Z_ARRVAL(modules[module_number]), const_name, &const_val); } ZEND_HASH_FOREACH_END(); efree(module_names); efree(modules); } else { zend_constant *constant; + zend_string *const_name; zval const_val; - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { - if (!constant->name) { - /* skip special constants */ - continue; - } + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), const_name, constant) { ZVAL_COPY_OR_DUP(&const_val, &constant->value); - zend_hash_add_new(Z_ARRVAL_P(return_value), constant->name, &const_val); + zend_hash_add_new(Z_ARRVAL_P(return_value), const_name, &const_val); } ZEND_HASH_FOREACH_END(); } } diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index f002e321d8b2b..f4ed521605968 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -43,15 +43,9 @@ void free_zend_constant(zval *zv) if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) { zval_ptr_dtor_nogc(&c->value); - if (c->name) { - zend_string_release_ex(c->name, 0); - } efree(c); } else { zval_internal_ptr_dtor(&c->value); - if (c->name) { - zend_string_release_ex(c->name, 1); - } free(c); } } @@ -67,7 +61,6 @@ static void copy_zend_constant(zval *zv) memcpy(Z_PTR_P(zv), c, sizeof(zend_constant)); c = Z_PTR_P(zv); - c->name = zend_string_copy(c->name); if (Z_TYPE(c->value) == IS_STRING) { Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1); } @@ -129,8 +122,7 @@ ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int ZVAL_NULL(&c.value); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + zend_register_internal_constant(name, name_len, &c); } ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number) @@ -139,8 +131,7 @@ ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, boo ZVAL_BOOL(&c.value, bval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + zend_register_internal_constant(name, name_len, &c); } ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number) @@ -149,8 +140,7 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen ZVAL_LONG(&c.value, lval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + zend_register_internal_constant(name, name_len, &c); } @@ -160,8 +150,7 @@ ZEND_API void zend_register_double_constant(const char *name, size_t name_len, d ZVAL_DOUBLE(&c.value, dval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + zend_register_internal_constant(name, name_len, &c); } @@ -171,8 +160,7 @@ ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, ZVAL_STR(&c.value, zend_string_init_interned(strval, strlen, flags & CONST_PERSISTENT)); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + zend_register_internal_constant(name, name_len, &c); } @@ -545,10 +533,9 @@ static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_consta return ret; } -ZEND_API zend_result zend_register_constant(zend_constant *c) +ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c) { zend_string *lowercase_name = NULL; - zend_string *name; zend_result ret = SUCCESS; bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0; @@ -556,14 +543,12 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) printf("Registering constant for module %d\n", c->module_number); #endif - const char *slash = strrchr(ZSTR_VAL(c->name), '\\'); + const char *slash = strrchr(ZSTR_VAL(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_string_init(ZSTR_VAL(name), ZSTR_LEN(name), persistent); + zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(name)); lowercase_name = zend_new_interned_string(lowercase_name); name = lowercase_name; - } else { - name = c->name; } /* Check if the user is trying to define any special constant */ @@ -572,7 +557,6 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) || zend_hash_add_constant(EG(zend_constants), name, c) == NULL ) { zend_error(E_WARNING, "Constant %s already defined", ZSTR_VAL(name)); - zend_string_release(c->name); if (!persistent) { zval_ptr_dtor_nogc(&c->value); } @@ -583,3 +567,13 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) } return ret; } + +ZEND_API zend_result zend_register_internal_constant(const char *name, size_t name_len, zend_constant *c) { + zend_string *name_str = zend_string_init_interned(name, name_len, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); + + zend_result result = zend_register_constant(name_str, c); + + zend_string_release(name_str); + + return result; +} diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 736dbb0091085..d0ad242143fb4 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -32,7 +32,6 @@ typedef struct _zend_constant { zval value; - zend_string *name; } zend_constant; #define ZEND_CONSTANT_FLAGS(c) \ @@ -84,7 +83,8 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number); ZEND_API void zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number); ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number); -ZEND_API zend_result zend_register_constant(zend_constant *c); +ZEND_API zend_result zend_register_internal_constant(const char *name, size_t name_len, zend_constant *c); +ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c); #ifdef ZTS void zend_copy_constants(HashTable *target, HashTable *source); #endif diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index abe3b8042c96e..d7894289c0d72 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4961,7 +4961,7 @@ static zend_always_inline zend_result _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_DEPRECATED) { - zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(c->name)); + zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(Z_STR_P(key))); return SUCCESS; } } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9efe205abe037..c1a5e31f7e6d9 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -294,9 +294,6 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) break; } zval_ptr_dtor_nogc(&c->value); - if (c->name) { - zend_string_release_ex(c->name, 0); - } efree(c); zend_string_release_ex(key, 0); } ZEND_HASH_MAP_FOREACH_END_DEL(); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 57d5cf887aca9..5dd6e20b53111 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8096,9 +8096,8 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) } /* non persistent, case sensitive */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); - c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == FAILURE) { + if (zend_register_constant(Z_STR_P(name), &c) == FAILURE) { } FREE_OP1(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 95e66b0cac3a7..79e0f5ba606bd 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7585,9 +7585,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST } /* non persistent, case sensitive */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); - c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == FAILURE) { + if (zend_register_constant(Z_STR_P(name), &c) == FAILURE) { } diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index ccdcc3ff7e8c8..bebbe2e2ad024 100644 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -197,7 +197,7 @@ PHP_COM_DOTNET_API zend_result php_com_import_typelib(ITypeLib *TL, int mode, in if (pTKind == TKIND_ENUM) { ITypeLib_GetTypeInfo(TL, i, &TypeInfo); for (j = 0; ; j++) { - zend_string *const_name; + zend_string *const_name, *name; if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) { break; @@ -228,12 +228,13 @@ PHP_COM_DOTNET_API zend_result php_com_import_typelib(ITypeLib *TL, int mode, in ZVAL_LONG(&c.value, Z_LVAL(value)); if (mode & CONST_PERSISTENT) { /* duplicate string in a persistent manner */ - c.name = zend_string_dup(const_name, /* persistent */ true); + name = zend_string_dup(const_name, /* persistent */ true); zend_string_release_ex(const_name, /* persistent */ false); } else { - c.name = const_name; + name = const_name; } - zend_register_constant(&c); + zend_register_constant(name, &c); + zend_string_release(name); } ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); } diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 9f5992831d1e9..9b64eb382c68c 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -731,9 +731,6 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int p->key = new_interned_string(p->key); } c = (zend_constant*)Z_PTR(p->val); - if (c->name) { - c->name = new_interned_string(c->name); - } if (Z_TYPE(c->value) == IS_STRING) { ZVAL_STR(&c->value, new_interned_string(Z_STR(c->value))); } diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 8e02fbbbfeac2..ea23b4b2ed815 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -282,7 +282,7 @@ static zend_always_inline zend_constant* _zend_quick_get_constant( if (!check_defined_only) { if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { - zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(c->name)); + zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(Z_STR_P(key))); if (EG(exception)) { return NULL; } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 09112b38b8eec..7cf4feae20ea8 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1040,11 +1040,13 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i { smart_str str_constants = {0}; zend_constant *constant; + zend_string *name; int num_constants = 0; - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), name, constant) { + if (ZEND_CONSTANT_MODULE_NUMBER(constant) == module->module_number) { - _const_string(&str_constants, ZSTR_VAL(constant->name), &constant->value, indent); + _const_string(&str_constants, ZSTR_VAL(name), &constant->value, indent); num_constants++; } } ZEND_HASH_FOREACH_END(); @@ -5992,6 +5994,7 @@ ZEND_METHOD(ReflectionExtension, getConstants) reflection_object *intern; zend_module_entry *module; zend_constant *constant; + zend_string *name; if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); @@ -5999,11 +6002,11 @@ ZEND_METHOD(ReflectionExtension, getConstants) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), name, constant) { if (module->module_number == ZEND_CONSTANT_MODULE_NUMBER(constant)) { zval const_val; ZVAL_COPY_OR_DUP(&const_val, &constant->value); - zend_hash_update(Z_ARRVAL_P(return_value), constant->name, &const_val); + zend_hash_update(Z_ARRVAL_P(return_value), name, &const_val); } } ZEND_HASH_FOREACH_END(); } diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 4766fac2537cd..2f936a39b714f 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -558,16 +558,13 @@ static void cli_register_file_handles(void) php_stream_to_zval(s_err, &ec.value); Z_CONSTANT_FLAGS(ic.value) = 0; - ic.name = zend_string_init_interned("STDIN", sizeof("STDIN")-1, 0); - zend_register_constant(&ic); + zend_register_internal_constant("STDIN", sizeof("STDIN")-1, &ic); Z_CONSTANT_FLAGS(oc.value) = 0; - oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT")-1, 0); - zend_register_constant(&oc); + zend_register_internal_constant("STDOUT", sizeof("STDOUT")-1, &oc); Z_CONSTANT_FLAGS(ec.value) = 0; - ec.name = zend_string_init_interned("STDERR", sizeof("STDERR")-1, 0); - zend_register_constant(&ec); + zend_register_internal_constant("STDERR", sizeof("STDERR")-1, &ec); } static const char *param_mode_conflict = "Either execute direct code, process stdin or use a file.\n"; diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index de9a73ea45412..ba70244c143f0 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -912,21 +912,24 @@ void phpdbg_register_file_handles(void) /* {{{ */ ic.value = zin; Z_CONSTANT_FLAGS(ic.value) = 0; - ic.name = zend_string_init(ZEND_STRL("STDIN"), 0); - zend_hash_del(EG(zend_constants), ic.name); - zend_register_constant(&ic); + zend_string *stdin_name = zend_string_init(ZEND_STRL("STDIN"), 0); + zend_hash_del(EG(zend_constants), stdin_name); + zend_register_constant(stdin_name, &ic); + zend_string_release(stdin_name); oc.value = zout; Z_CONSTANT_FLAGS(oc.value) = 0; - oc.name = zend_string_init(ZEND_STRL("STDOUT"), 0); - zend_hash_del(EG(zend_constants), oc.name); - zend_register_constant(&oc); + zend_string *stdout_name = zend_string_init(ZEND_STRL("STDOUT"), 0); + zend_hash_del(EG(zend_constants), stdout_name); + zend_register_constant(stdout_name, &oc); + zend_string_release(stdout_name); ec.value = zerr; Z_CONSTANT_FLAGS(ec.value) = 0; - ec.name = zend_string_init(ZEND_STRL("STDERR"), 0); - zend_hash_del(EG(zend_constants), ec.name); - zend_register_constant(&ec); + zend_string *stderr_name = zend_string_init(ZEND_STRL("STDERR"), 0); + zend_hash_del(EG(zend_constants), stderr_name); + zend_register_constant(stderr_name, &ec); + zend_string_release(stderr_name); } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c index 0a1e7570a493c..d6457ef805cf7 100644 --- a/sapi/phpdbg/phpdbg_info.c +++ b/sapi/phpdbg/phpdbg_info.c @@ -100,14 +100,15 @@ PHPDBG_INFO(constants) /* {{{ */ { HashTable consts; zend_constant *data; + zend_string *name; zend_hash_init(&consts, 8, NULL, NULL, 0); if (EG(zend_constants)) { phpdbg_try_access { - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), data) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), name, data) { if (ZEND_CONSTANT_MODULE_NUMBER(data) == PHP_USER_CONSTANT) { - zend_hash_update_ptr(&consts, data->name, data); + zend_hash_update_ptr(&consts, name, data); } } ZEND_HASH_FOREACH_END(); } phpdbg_catch_access { @@ -119,14 +120,14 @@ PHPDBG_INFO(constants) /* {{{ */ if (zend_hash_num_elements(&consts)) { phpdbg_out("Address Refs Type Constant\n"); - ZEND_HASH_MAP_FOREACH_PTR(&consts, data) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&consts, name, data) { #define VARIABLEINFO(msg, ...) \ phpdbg_writeln( \ "%-18p %-7d %-9s %.*s" msg, &data->value, \ Z_REFCOUNTED(data->value) ? Z_REFCOUNT(data->value) : 1, \ zend_get_type_by_const(Z_TYPE(data->value)), \ - (int) ZSTR_LEN(data->name), ZSTR_VAL(data->name), ##__VA_ARGS__) + (int) ZSTR_LEN(name), ZSTR_VAL(name), ##__VA_ARGS__) switch (Z_TYPE(data->value)) { case IS_STRING: