diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 06c1d5282622..0c8e10e17f08 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -72,6 +72,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES zend_string* parameter. . EG(in_autoload) was renamed to EG(autoload_current_classnames) and no longer is a pointer, but a directly embedded HashTable struct. + . Added a C23_ENUM() helper macro to define forward-compatible fixed-size + enums. ======================== 2. Build system changes diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 587ae485ec82..41bbdde5a38d 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -497,6 +497,12 @@ typedef struct _zend_class_constant { #define ZEND_CLASS_CONST_FLAGS(c) Z_CONSTANT_FLAGS((c)->value) +C23_ENUM(zend_function_type, uint8_t) { + ZEND_INTERNAL_FUNCTION = 1, + ZEND_USER_FUNCTION = 2, + ZEND_EVAL_CODE = 4, +}; + /* arg_info for internal functions */ typedef struct _zend_internal_arg_info { const char *name; @@ -524,7 +530,7 @@ typedef struct _zend_internal_function_info { struct _zend_op_array { /* Common elements */ - uint8_t type; + zend_function_type type; uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string *function_name; @@ -584,7 +590,7 @@ typedef void (ZEND_FASTCALL *zif_handler)(INTERNAL_FUNCTION_PARAMETERS); typedef struct _zend_internal_function { /* Common elements */ - uint8_t type; + zend_function_type type; uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string* function_name; @@ -610,11 +616,11 @@ typedef struct _zend_internal_function { #define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? ZSTR_VAL((function)->common.scope->name) : "") union _zend_function { - uint8_t type; /* MUST be the first element of this struct! */ + zend_function_type type; /* MUST be the first element of this struct! */ uint32_t quick_arg_flags; struct { - uint8_t type; /* never used */ + zend_function_type type; /* never used */ uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string *function_name; @@ -956,7 +962,7 @@ ZEND_API zend_ast *zend_compile_string_to_ast( ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...); ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handle *file_handle); ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle); -ZEND_API void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size); +ZEND_API void init_op_array(zend_op_array *op_array, zend_function_type type, int initial_ops_size); ZEND_API void destroy_op_array(zend_op_array *op_array); ZEND_API void zend_destroy_static_vars(zend_op_array *op_array); ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle); @@ -1071,10 +1077,6 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define BP_VAR_FUNC_ARG 4 #define BP_VAR_UNSET 5 -#define ZEND_INTERNAL_FUNCTION 1 -#define ZEND_USER_FUNCTION 2 -#define ZEND_EVAL_CODE 4 - #define ZEND_USER_CODE(type) ((type) != ZEND_INTERNAL_FUNCTION) #define ZEND_INTERNAL_CLASS 1 diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 5a8a78cc3bd7..1c985189fd3c 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -591,7 +591,7 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle) return SUCCESS; } -static zend_op_array *zend_compile(int type) +static zend_op_array *zend_compile(zend_function_type type) { zend_op_array *op_array = NULL; bool original_in_compilation = CG(in_compilation); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index d874f566dc87..24b480ad71e6 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -45,7 +45,7 @@ static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend } } -void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size) +void init_op_array(zend_op_array *op_array, zend_function_type type, int initial_ops_size) { op_array->type = type; op_array->arg_flags[0] = 0; diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 6546ebfb5b79..c8a6dfa871b5 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -146,6 +146,19 @@ #define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__)) +/* Define an enum with a fixed underlying type as C23_ENUM(name, underlying_type) { }. */ +#if __STDC_VERSION__ >= 202311L || defined(__cplusplus) +# define C23_ENUM(name, underlying_type) \ + enum name: underlying_type; \ + typedef enum name name; \ + enum name: underlying_type +#else +# define C23_ENUM(name, underlying_type) \ + enum name; \ + typedef underlying_type name; \ + enum name +#endif + /* all HAVE_XXX test have to be after the include of zend_config above */ #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)