diff --git a/Zend/zend.c b/Zend/zend.c index 2d8a0f455f8b4..27a36f0cab5d4 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -38,6 +38,7 @@ #include "zend_call_stack.h" #include "zend_max_execution_timer.h" #include "zend_hrtime.h" +#include "zend_atom.h" #include "Optimizer/zend_optimizer.h" #include "php.h" #include "php_globals.h" @@ -1055,6 +1056,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ zend_interned_strings_init(); zend_startup_builtin_functions(); + zend_startup_atoms(); zend_register_standard_constants(); zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4c31fba5e506e..d9d1de81cb957 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -197,6 +197,8 @@ ZEND_API zend_string *zend_zval_get_legacy_type(const zval *arg) /* {{{ */ return ZSTR_KNOWN(ZEND_STR_STRING); case IS_ARRAY: return ZSTR_KNOWN(ZEND_STR_ARRAY); + case IS_ATOM: + return ZSTR_KNOWN(ZEND_STR_ATOM); case IS_OBJECT: return ZSTR_KNOWN(ZEND_STR_OBJECT); case IS_RESOURCE: diff --git a/Zend/zend_atom.c b/Zend/zend_atom.c new file mode 100644 index 0000000000000..83a36b27a41bd --- /dev/null +++ b/Zend/zend_atom.c @@ -0,0 +1,168 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: [Your Name] | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_atom.h" +#include "zend_hash.h" +#include "zend_string.h" +#include "zend_alloc.h" + +ZEND_API HashTable atom_table; +ZEND_API uint32_t next_atom_id = 1; /* Start from 1, 0 is reserved for invalid */ +static bool atoms_initialized = false; + +static void atom_dtor(zval *zv) +{ + zend_atom *atom = (zend_atom *)Z_PTR_P(zv); + zend_string_release(atom->name); + efree(atom); +} + +ZEND_API void zend_atoms_init(void) +{ + zend_hash_init(&atom_table, 64, NULL, atom_dtor, 0); + next_atom_id = 1; +} + +ZEND_API void zend_atoms_shutdown(void) +{ + zend_hash_destroy(&atom_table); +} + +ZEND_API bool zend_atom_name_is_valid(const char *name, size_t name_len) +{ + if (name_len == 0) { + return false; + } + + /* First character must be [a-zA-Z_\x80-\xff] */ + unsigned char c = (unsigned char)name[0]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c >= 0x80)) { + return false; + } + + /* Subsequent characters must be [a-zA-Z0-9_\x80-\xff] */ + for (size_t i = 1; i < name_len; i++) { + c = (unsigned char)name[i]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '_' || c >= 0x80)) { + return false; + } + } + + return true; +} + +ZEND_API uint32_t zend_atom_create(zend_string *name) +{ + zval *existing; + zend_atom *atom; + zval atom_zv; + + if (!atoms_initialized) { + zend_startup_atoms(); + } + + /* Check if atom already exists */ + existing = zend_hash_find(&atom_table, name); + if (existing) { + atom = (zend_atom *)Z_PTR_P(existing); + return atom->id; + } + + /* Validate atom name */ + if (!zend_atom_name_is_valid(ZSTR_VAL(name), ZSTR_LEN(name))) { + return ZEND_ATOM_INVALID_ID; + } + + /* Create new atom */ + atom = emalloc(sizeof(zend_atom)); + atom->name = zend_string_copy(name); + atom->id = next_atom_id++; + + ZVAL_PTR(&atom_zv, atom); + zend_hash_add(&atom_table, name, &atom_zv); + + return atom->id; +} + +ZEND_API uint32_t zend_atom_create_cstr(const char *name, size_t name_len) +{ + zend_string *str = zend_string_init(name, name_len, 0); + uint32_t result = zend_atom_create(str); + zend_string_release(str); + return result; +} + +ZEND_API uint32_t zend_atom_find(zend_string *name) +{ + if (!atoms_initialized) { + return ZEND_ATOM_INVALID_ID; + } + + zval *existing = zend_hash_find(&atom_table, name); + if (existing) { + zend_atom *atom = (zend_atom *)Z_PTR_P(existing); + return atom->id; + } + return ZEND_ATOM_INVALID_ID; +} + +ZEND_API uint32_t zend_atom_find_cstr(const char *name, size_t name_len) +{ + zend_string *str = zend_string_init(name, name_len, 0); + uint32_t result = zend_atom_find(str); + zend_string_release(str); + return result; +} + +ZEND_API zend_string *zend_atom_name(uint32_t atom_id) +{ + zval *entry; + zend_atom *atom; + + if (atom_id == ZEND_ATOM_INVALID_ID) { + return NULL; + } + + /* Linear search through atom table to find by ID */ + /* TODO: Consider maintaining a reverse lookup table for performance */ + ZEND_HASH_FOREACH_VAL(&atom_table, entry) { + atom = (zend_atom *)Z_PTR_P(entry); + if (atom->id == atom_id) { + return atom->name; + } + } ZEND_HASH_FOREACH_END(); + + return NULL; +} + +ZEND_API bool zend_atom_exists(zend_string *name) +{ + return zend_hash_exists(&atom_table, name); +} + +ZEND_API void zend_startup_atoms(void) +{ + if (atoms_initialized) { + return; + } + + zend_hash_init(&atom_table, 0, NULL, atom_dtor, 1); + atoms_initialized = true; +} \ No newline at end of file diff --git a/Zend/zend_atom.h b/Zend/zend_atom.h new file mode 100644 index 0000000000000..cecaa5f2eb3e4 --- /dev/null +++ b/Zend/zend_atom.h @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: [Your Name] | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_ATOM_H +#define ZEND_ATOM_H + +#include "zend_types.h" +#include "zend_hash.h" + +BEGIN_EXTERN_C() + +typedef struct _zend_atom { + zend_string *name; /* atom name */ + uint32_t id; /* unique atom ID */ +} zend_atom; + +/* Atom table globals */ +ZEND_API extern HashTable atom_table; +ZEND_API extern uint32_t next_atom_id; + +/* Core atom management functions */ +ZEND_API void zend_atoms_init(void); +ZEND_API void zend_atoms_shutdown(void); +ZEND_API uint32_t zend_atom_create(zend_string *name); +ZEND_API uint32_t zend_atom_find(zend_string *name); +ZEND_API zend_string *zend_atom_name(uint32_t atom_id); +ZEND_API bool zend_atom_exists(zend_string *name); +ZEND_API void zend_startup_atoms(void); + +/* Atom creation from C string (for internal use) */ +ZEND_API uint32_t zend_atom_create_cstr(const char *name, size_t name_len); +ZEND_API uint32_t zend_atom_find_cstr(const char *name, size_t name_len); + +/* Validation */ +ZEND_API bool zend_atom_name_is_valid(const char *name, size_t name_len); + +/* Utility macros */ +#define ZEND_ATOM_INVALID_ID 0 + +END_EXTERN_C() + +#endif /* ZEND_ATOM_H */ \ No newline at end of file diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 9483a83b4e955..67da496e3aefb 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -89,6 +89,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_LNUMBER "integer" %token T_DNUMBER "floating-point number" %token T_STRING "identifier" +%token T_ATOM "atom" %token T_NAME_FULLY_QUALIFIED "fully qualified name" %token T_NAME_RELATIVE "namespace-relative name" %token T_NAME_QUALIFIED "namespaced name" @@ -1443,6 +1444,7 @@ dereferenceable_scalar: scalar: T_LNUMBER { $$ = $1; } | T_DNUMBER { $$ = $1; } + | T_ATOM { $$ = $1; } | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; } | T_START_HEREDOC T_END_HEREDOC { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 4c883b81c5f7d..c4b857cec0e1a 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -2394,6 +2394,10 @@ inline_char_handler: RETURN_TOKEN(T_NS_SEPARATOR); } +":"{LABEL} { + RETURN_TOKEN_WITH_STR(T_ATOM, 1); +} + {LABEL} { RETURN_TOKEN_WITH_STR(T_STRING, 0); } diff --git a/Zend/zend_string.h b/Zend/zend_string.h index e9e2b947a6c91..bbe85bf3a18a4 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -606,6 +606,7 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_INTEGER, "integer") \ _(ZEND_STR_DOUBLE, "double") \ _(ZEND_STR_ARRAY, "array") \ + _(ZEND_STR_ATOM, "atom") \ _(ZEND_STR_RESOURCE, "resource") \ _(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \ _(ZEND_STR_NAME, "name") \ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index f839cec3b3667..b8a8a6eaedd02 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -326,6 +326,7 @@ typedef union _zend_value { void *ptr; zend_class_entry *ce; zend_function *func; + uint32_t atom_id; /* atom identifier */ struct { uint32_t w1; uint32_t w2; @@ -609,25 +610,26 @@ struct _zend_ast_ref { #define IS_RESOURCE 9 #define IS_REFERENCE 10 #define IS_CONSTANT_AST 11 /* Constant expressions */ +#define IS_ATOM 12 /* Atom type */ /* Fake types used only for type hinting. * These are allowed to overlap with the types below. */ -#define IS_CALLABLE 12 -#define IS_ITERABLE 13 -#define IS_VOID 14 -#define IS_STATIC 15 -#define IS_MIXED 16 -#define IS_NEVER 17 +#define IS_CALLABLE 13 +#define IS_ITERABLE 14 +#define IS_VOID 15 +#define IS_STATIC 16 +#define IS_MIXED 17 +#define IS_NEVER 18 /* internal types */ -#define IS_INDIRECT 12 -#define IS_PTR 13 -#define IS_ALIAS_PTR 14 -#define _IS_ERROR 15 +#define IS_INDIRECT 13 +#define IS_PTR 14 +#define IS_ALIAS_PTR 15 +#define _IS_ERROR 16 /* used for casts */ -#define _IS_BOOL 18 -#define _IS_NUMBER 19 +#define _IS_BOOL 19 +#define _IS_NUMBER 20 /* guard flags */ #define ZEND_GUARD_PROPERTY_GET (1<<0) @@ -1045,6 +1047,9 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define Z_PTR(zval) (zval).value.ptr #define Z_PTR_P(zval_p) Z_PTR(*(zval_p)) +#define Z_ATOM_ID(zval) (zval).value.atom_id +#define Z_ATOM_ID_P(zval_p) Z_ATOM_ID(*(zval_p)) + #define ZVAL_UNDEF(z) do { \ Z_TYPE_INFO_P(z) = IS_UNDEF; \ } while (0) @@ -1261,6 +1266,12 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { Z_TYPE_INFO_P(z) = IS_ALIAS_PTR; \ } while (0) +#define ZVAL_ATOM(z, id) do { \ + zval *__z = (z); \ + Z_ATOM_ID_P(__z) = (id); \ + Z_TYPE_INFO_P(__z) = IS_ATOM; \ + } while (0) + #define ZVAL_ERROR(z) do { \ Z_TYPE_INFO_P(z) = _IS_ERROR; \ } while (0) diff --git a/configure.ac b/configure.ac index 01d9ded69b920..32eae9a2dc17c 100644 --- a/configure.ac +++ b/configure.ac @@ -1711,6 +1711,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([ Optimizer/zend_optimizer.c Optimizer/zend_ssa.c zend_alloc.c + zend_atom.c zend_API.c zend_ast.c zend_atomic.c diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index b6533d8dc20e8..a785afc8c5e00 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -3597,6 +3597,14 @@ function gettype(mixed $value): string {} */ function get_debug_type(mixed $value): string {} +function atom(string $name): mixed {} + +function string(mixed $atom): string {} + +function get_defined_atoms(): array {} + +function atom_exists(string $name): bool {} + function settype(mixed &$var, string $type): bool {} /** diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index d35377c900735..73bec75dd7a0a 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 824ccb41163307bd0fad452b705a8222b6f42d09 */ + * Stub hash: b319a1197f131279574718e1308146a106dd55a2 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -2007,6 +2007,18 @@ ZEND_END_ARG_INFO() #define arginfo_get_debug_type arginfo_gettype +#define arginfo_atom arginfo_constant + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_string, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, atom, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +#define arginfo_get_defined_atoms arginfo_ob_list_handlers + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_atom_exists, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_settype, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(1, var, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, type, IS_STRING, 0) @@ -2823,6 +2835,10 @@ ZEND_FUNCTION(stream_set_timeout); #endif ZEND_FUNCTION(gettype); ZEND_FUNCTION(get_debug_type); +ZEND_FUNCTION(atom); +ZEND_FUNCTION(string); +ZEND_FUNCTION(get_defined_atoms); +ZEND_FUNCTION(atom_exists); ZEND_FUNCTION(settype); ZEND_FUNCTION(intval); ZEND_FUNCTION(floatval); @@ -3431,6 +3447,10 @@ static const zend_function_entry ext_functions[] = { #endif ZEND_RAW_FENTRY("gettype", zif_gettype, arginfo_gettype, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("get_debug_type", zif_get_debug_type, arginfo_get_debug_type, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) + ZEND_FE(atom, arginfo_atom) + ZEND_FE(string, arginfo_string) + ZEND_FE(get_defined_atoms, arginfo_get_defined_atoms) + ZEND_FE(atom_exists, arginfo_atom_exists) ZEND_FE(settype, arginfo_settype) ZEND_RAW_FENTRY("intval", zif_intval, arginfo_intval, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("floatval", zif_floatval, arginfo_floatval, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) diff --git a/ext/standard/type.c b/ext/standard/type.c index 4557014ff5a33..93ad9976e56ca 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -15,6 +15,7 @@ */ #include "php.h" +#include "zend_atom.h" /* {{{ Returns the type of the variable */ PHP_FUNCTION(gettype) @@ -59,6 +60,8 @@ PHP_FUNCTION(get_debug_type) RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_STRING)); case IS_ARRAY: RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_ARRAY)); + case IS_ATOM: + RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_ATOM)); case IS_OBJECT: if (Z_OBJ_P(arg)->ce->ce_flags & ZEND_ACC_ANON_CLASS) { name = ZSTR_VAL(Z_OBJ_P(arg)->ce->name); @@ -465,3 +468,78 @@ PHP_FUNCTION(is_countable) RETURN_BOOL(zend_is_countable(var)); } /* }}} */ + +/* {{{ Creates an atom from a string */ +PHP_FUNCTION(atom) +{ + zend_string *str; + uint32_t atom_id; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(str) + ZEND_PARSE_PARAMETERS_END(); + + atom_id = zend_atom_create(str); + if (atom_id == ZEND_ATOM_INVALID_ID) { + zend_argument_value_error(1, "must be a valid atom identifier"); + RETURN_THROWS(); + } + + ZVAL_ATOM(return_value, atom_id); +} +/* }}} */ + +/* {{{ Converts an atom to its string representation */ +PHP_FUNCTION(string) +{ + zval *arg; + zend_string *atom_name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(arg) + ZEND_PARSE_PARAMETERS_END(); + + if (Z_TYPE_P(arg) != IS_ATOM) { + zend_argument_type_error(1, "must be an atom, %s given", zend_zval_type_name(arg)); + RETURN_THROWS(); + } + + atom_name = zend_atom_name(Z_ATOM_ID_P(arg)); + if (!atom_name) { + zend_throw_error(NULL, "Invalid atom"); + RETURN_THROWS(); + } + + RETURN_STR_COPY(atom_name); +} +/* }}} */ + +/* {{{ Returns an array of all defined atoms */ +PHP_FUNCTION(get_defined_atoms) +{ + zval *entry; + zend_atom *atom; + + ZEND_PARSE_PARAMETERS_NONE(); + + array_init(return_value); + + ZEND_HASH_FOREACH_VAL(&atom_table, entry) { + atom = (zend_atom *)Z_PTR_P(entry); + add_next_index_str(return_value, zend_string_copy(atom->name)); + } ZEND_HASH_FOREACH_END(); +} +/* }}} */ + +/* {{{ Checks if an atom with the given name exists */ +PHP_FUNCTION(atom_exists) +{ + zend_string *name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_BOOL(zend_atom_exists(name)); +} +/* }}} */ diff --git a/ext/standard/var.c b/ext/standard/var.c index 1c2b0eb164a1c..73dfb8b15cd58 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -30,6 +30,7 @@ #include "zend_enum.h" #include "zend_exceptions.h" #include "zend_types.h" +#include "zend_atom.h" /* }}} */ struct php_serialize_data { @@ -136,6 +137,17 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ PHPWRITE(Z_STRVAL_P(struc), Z_STRLEN_P(struc)); PUTS("\"\n"); break; + case IS_ATOM: { + zend_string *atom_name = zend_atom_name(Z_ATOM_ID_P(struc)); + if (atom_name) { + php_printf("%satom(:", COMMON); + PHPWRITE(ZSTR_VAL(atom_name), ZSTR_LEN(atom_name)); + php_printf(")\n"); + } else { + php_printf("%satom(INVALID:%u)\n", COMMON, Z_ATOM_ID_P(struc)); + } + break; + } case IS_ARRAY: myht = Z_ARRVAL_P(struc); if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) { @@ -331,6 +343,17 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */ PUTS("\" interned\n"); } break; + case IS_ATOM: { + zend_string *atom_name = zend_atom_name(Z_ATOM_ID_P(struc)); + if (atom_name) { + php_printf("atom(:"); + PHPWRITE(ZSTR_VAL(atom_name), ZSTR_LEN(atom_name)); + php_printf(")\n"); + } else { + php_printf("atom(INVALID:%u)\n", Z_ATOM_ID_P(struc)); + } + break; + } case IS_ARRAY: myht = Z_ARRVAL_P(struc); if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) { diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index a1e131032bcfb..ed3c9a7177185 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -28,6 +28,7 @@ char *get_token_type_name(int token_type) case T_LNUMBER: return "T_LNUMBER"; case T_DNUMBER: return "T_DNUMBER"; case T_STRING: return "T_STRING"; + case T_ATOM: return "T_ATOM"; case T_NAME_FULLY_QUALIFIED: return "T_NAME_FULLY_QUALIFIED"; case T_NAME_RELATIVE: return "T_NAME_RELATIVE"; case T_NAME_QUALIFIED: return "T_NAME_QUALIFIED"; diff --git a/ext/tokenizer/tokenizer_data.stub.php b/ext/tokenizer/tokenizer_data.stub.php index c1e1fd254dfaa..26cad657ab567 100644 --- a/ext/tokenizer/tokenizer_data.stub.php +++ b/ext/tokenizer/tokenizer_data.stub.php @@ -17,6 +17,11 @@ * @cvalue T_STRING */ const T_STRING = UNKNOWN; +/** + * @var int + * @cvalue T_ATOM + */ +const T_ATOM = UNKNOWN; /** * @var int * @cvalue T_NAME_FULLY_QUALIFIED diff --git a/ext/tokenizer/tokenizer_data_arginfo.h b/ext/tokenizer/tokenizer_data_arginfo.h index 9c488d19f1890..1441c40133cf8 100644 --- a/ext/tokenizer/tokenizer_data_arginfo.h +++ b/ext/tokenizer/tokenizer_data_arginfo.h @@ -1,11 +1,12 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 19d25d22098f46283b517352cbb302db962b50fd */ + * Stub hash: e52d0aa7d19c83f08d0f86b14f505453fb03123e */ static void register_tokenizer_data_symbols(int module_number) { REGISTER_LONG_CONSTANT("T_LNUMBER", T_LNUMBER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_DNUMBER", T_DNUMBER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_STRING", T_STRING, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_ATOM", T_ATOM, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NAME_FULLY_QUALIFIED", T_NAME_FULLY_QUALIFIED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NAME_RELATIVE", T_NAME_RELATIVE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NAME_QUALIFIED", T_NAME_QUALIFIED, CONST_PERSISTENT);