Skip to content

Commit 9c900b6

Browse files
authored
zend_compile: Bundle function type constants into an zend_function_type enum (#21208)
* zend_compile: Bundle function type constants into an `zend_function_type` enum This clarifies the relationship between these constants and improves type safety a little. * Add C23_ENUM() helper macro * zend_portability: Rename `size` to `underlying_type` in `C23_ENUM()` * zend_portability: Include the leading `enum` in the `C23_ENUM` macro * Fix comment for C23_ENUM()
1 parent 45029f3 commit 9c900b6

5 files changed

Lines changed: 28 additions & 11 deletions

File tree

UPGRADING.INTERNALS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
7272
zend_string* parameter.
7373
. EG(in_autoload) was renamed to EG(autoload_current_classnames) and no
7474
longer is a pointer, but a directly embedded HashTable struct.
75+
. Added a C23_ENUM() helper macro to define forward-compatible fixed-size
76+
enums.
7577

7678
========================
7779
2. Build system changes

Zend/zend_compile.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,12 @@ typedef struct _zend_class_constant {
497497

498498
#define ZEND_CLASS_CONST_FLAGS(c) Z_CONSTANT_FLAGS((c)->value)
499499

500+
C23_ENUM(zend_function_type, uint8_t) {
501+
ZEND_INTERNAL_FUNCTION = 1,
502+
ZEND_USER_FUNCTION = 2,
503+
ZEND_EVAL_CODE = 4,
504+
};
505+
500506
/* arg_info for internal functions */
501507
typedef struct _zend_internal_arg_info {
502508
const char *name;
@@ -524,7 +530,7 @@ typedef struct _zend_internal_function_info {
524530

525531
struct _zend_op_array {
526532
/* Common elements */
527-
uint8_t type;
533+
zend_function_type type;
528534
uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */
529535
uint32_t fn_flags;
530536
zend_string *function_name;
@@ -584,7 +590,7 @@ typedef void (ZEND_FASTCALL *zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
584590

585591
typedef struct _zend_internal_function {
586592
/* Common elements */
587-
uint8_t type;
593+
zend_function_type type;
588594
uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */
589595
uint32_t fn_flags;
590596
zend_string* function_name;
@@ -610,11 +616,11 @@ typedef struct _zend_internal_function {
610616
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? ZSTR_VAL((function)->common.scope->name) : "")
611617

612618
union _zend_function {
613-
uint8_t type; /* MUST be the first element of this struct! */
619+
zend_function_type type; /* MUST be the first element of this struct! */
614620
uint32_t quick_arg_flags;
615621

616622
struct {
617-
uint8_t type; /* never used */
623+
zend_function_type type; /* never used */
618624
uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */
619625
uint32_t fn_flags;
620626
zend_string *function_name;
@@ -956,7 +962,7 @@ ZEND_API zend_ast *zend_compile_string_to_ast(
956962
ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...);
957963
ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handle *file_handle);
958964
ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle);
959-
ZEND_API void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size);
965+
ZEND_API void init_op_array(zend_op_array *op_array, zend_function_type type, int initial_ops_size);
960966
ZEND_API void destroy_op_array(zend_op_array *op_array);
961967
ZEND_API void zend_destroy_static_vars(zend_op_array *op_array);
962968
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);
10711077
#define BP_VAR_FUNC_ARG 4
10721078
#define BP_VAR_UNSET 5
10731079

1074-
#define ZEND_INTERNAL_FUNCTION 1
1075-
#define ZEND_USER_FUNCTION 2
1076-
#define ZEND_EVAL_CODE 4
1077-
10781080
#define ZEND_USER_CODE(type) ((type) != ZEND_INTERNAL_FUNCTION)
10791081

10801082
#define ZEND_INTERNAL_CLASS 1

Zend/zend_language_scanner.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
591591
return SUCCESS;
592592
}
593593

594-
static zend_op_array *zend_compile(int type)
594+
static zend_op_array *zend_compile(zend_function_type type)
595595
{
596596
zend_op_array *op_array = NULL;
597597
bool original_in_compilation = CG(in_compilation);

Zend/zend_opcode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend
4545
}
4646
}
4747

48-
void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size)
48+
void init_op_array(zend_op_array *op_array, zend_function_type type, int initial_ops_size)
4949
{
5050
op_array->type = type;
5151
op_array->arg_flags[0] = 0;

Zend/zend_portability.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@
146146

147147
#define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__))
148148

149+
/* Define an enum with a fixed underlying type as C23_ENUM(name, underlying_type) { }. */
150+
#if __STDC_VERSION__ >= 202311L || defined(__cplusplus)
151+
# define C23_ENUM(name, underlying_type) \
152+
enum name: underlying_type; \
153+
typedef enum name name; \
154+
enum name: underlying_type
155+
#else
156+
# define C23_ENUM(name, underlying_type) \
157+
enum name; \
158+
typedef underlying_type name; \
159+
enum name
160+
#endif
161+
149162
/* all HAVE_XXX test have to be after the include of zend_config above */
150163

151164
#if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)

0 commit comments

Comments
 (0)