Commit d16e6f52a43 for php.net
commit d16e6f52a432cc70fa8d54a3cd0c635ff403ec07
Author: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com>
Date: Tue Feb 3 12:38:04 2026 +0100
Generate C enums from internal enums, introduce Z_PARAM_ENUM() (#20917)
Update gen_stubs.php to generate C enums from internal enums, when the stub is annotated with @generate-c-enums. Enum values can be compared to the result of zend_enum_fetch_case_id(zend_object*).
The generated enums are added to separate files named {$extensionName}_decl.h, so that it's possible to include these from anywhere. _arginfo.h files would generate warnings if we tried to include them in a compilation unit that doesn't call the register_{$class} functions, for instance.
Introduce Z_PARAM_ENUM().
* Make ZEND_AST_CONST_ENUM_INIT a 4-children node
* Store enum case id in ZEND_AST_CONST_ENUM_INIT
* Store enum case id in instance
* Expose enum case_id internally
* Generate C enum for internal enums
* Introduce Z_PARAM_ENUM()
* Port extensions
diff --git a/.gitattributes b/.gitattributes
index 8dea3f8bbaf..74fd9f995e8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -21,6 +21,7 @@
# Collapse generated files within git and pull request diff.
**/*_arginfo.h linguist-generated -diff
+**/*_decl.h linguist-generated -diff
/main/debug_gdb_scripts.c linguist-generated -diff
/Zend/zend_vm_execute.h linguist-generated -diff
/Zend/zend_vm_handlers.h linguist-generated -diff
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index e35baa3df56..9e2b3ae4794 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -60,11 +60,20 @@ PHP 8.6 INTERNALS UPGRADE NOTES
automatically unwrap references when the result of the call is stored in an
IS_TMP_VAR variable. This may be achieved by calling the
zend_return_unwrap_ref() function.
+ . The php_math_round_mode_from_enum() function now takes a
+ zend_enum_RoundingMode parameter.
+ . Added Z_PARAM_ENUM().
+ . Added zend_enum_fetch_case_id().
========================
2. Build system changes
========================
+ . build/gen_stub.php may now generate a _decl.h file in addition to
+ the _arginfo.h file, if the stub declares enums and is annotated with
+ @generate-c-enums. For each enum the file will contain a C enum. Enum values
+ can be compared to the result of zend_enum_fetch_case_id(zend_object*).
+
========================
3. Module changes
========================
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index c1ccbf13666..d78ee6604e3 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -2009,6 +2009,13 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(dest_obj, _ce, dest_long, is_null) \
Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, 1)
+#define Z_PARAM_ENUM(dest, _ce) \
+ { \
+ zend_object *_tmp = NULL; \
+ Z_PARAM_OBJ_OF_CLASS(_tmp, _ce); \
+ dest = zend_enum_fetch_case_id(_tmp); \
+ }
+
/* old "p" */
#define Z_PARAM_PATH_EX(dest, dest_len, check_null, deref) \
Z_PARAM_PROLOGUE(deref, 0); \
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 54bf4c0bf2e..a6071d22841 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -995,10 +995,13 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
zend_ast *class_name_ast = ast->child[0];
zend_string *class_name = zend_ast_get_str(class_name_ast);
- zend_ast *case_name_ast = ast->child[1];
+ zend_ast *case_id_ast = ast->child[1];
+ int case_id = (int)Z_LVAL_P(zend_ast_get_zval(case_id_ast));
+
+ zend_ast *case_name_ast = ast->child[2];
zend_string *case_name = zend_ast_get_str(case_name_ast);
- zend_ast *case_value_ast = ast->child[2];
+ zend_ast *case_value_ast = ast->child[3];
zval case_value_zv;
ZVAL_UNDEF(&case_value_zv);
@@ -1009,7 +1012,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
}
zend_class_entry *ce = zend_lookup_class(class_name);
- zend_enum_new(result, ce, case_name, case_value_ast != NULL ? &case_value_zv : NULL);
+ zend_enum_new(result, ce, case_id, case_name, case_value_ast != NULL ? &case_value_zv : NULL);
zval_ptr_dtor_nogc(&case_value_zv);
break;
}
diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h
index c212cd8367a..a88efefd85b 100644
--- a/Zend/zend_ast.h
+++ b/Zend/zend_ast.h
@@ -168,15 +168,15 @@ enum _zend_ast_kind {
ZEND_AST_CONST_ELEM,
ZEND_AST_CLASS_CONST_GROUP,
- // Pseudo node for initializing enums
- ZEND_AST_CONST_ENUM_INIT,
-
/* 4 child nodes */
ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT,
ZEND_AST_FOREACH,
ZEND_AST_ENUM_CASE,
ZEND_AST_PROP_ELEM,
+ // Pseudo node for initializing enums
+ ZEND_AST_CONST_ENUM_INIT,
+
/* 5 child nodes */
/* 6 child nodes */
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 2b2235e5df1..688a50749a6 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -9756,6 +9756,11 @@ static void zend_compile_enum_case(zend_ast *ast)
ZVAL_STR_COPY(&class_name_zval, enum_class_name);
zend_ast *class_name_ast = zend_ast_create_zval(&class_name_zval);
+ zval case_id_zval;
+ int case_id = zend_enum_next_case_id(enum_class);
+ ZVAL_LONG(&case_id_zval, case_id);
+ zend_ast *case_id_ast = zend_ast_create_zval(&case_id_zval);
+
zval case_name_zval;
ZVAL_STR_COPY(&case_name_zval, enum_case_name);
zend_ast *case_name_ast = zend_ast_create_zval(&case_name_zval);
@@ -9773,7 +9778,8 @@ static void zend_compile_enum_case(zend_ast *ast)
ZSTR_VAL(enum_class_name));
}
- zend_ast *const_enum_init_ast = zend_ast_create(ZEND_AST_CONST_ENUM_INIT, class_name_ast, case_name_ast, case_value_ast);
+ zend_ast *const_enum_init_ast = zend_ast_create(ZEND_AST_CONST_ENUM_INIT,
+ class_name_ast, case_id_ast, case_name_ast, case_value_ast);
zval value_zv;
zend_const_expr_to_zval(&value_zv, &const_enum_init_ast, /* allow_dynamic */ false);
@@ -12669,7 +12675,7 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
zend_eval_const_expr(&ast->child[1]);
return;
case ZEND_AST_CONST_ENUM_INIT:
- zend_eval_const_expr(&ast->child[2]);
+ zend_eval_const_expr(&ast->child[3]);
return;
case ZEND_AST_PROP:
case ZEND_AST_NULLSAFE_PROP:
diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c
index 7c62c8a96d0..6e9c68810d4 100644
--- a/Zend/zend_enum.c
+++ b/Zend/zend_enum.c
@@ -40,9 +40,16 @@ static zend_arg_info zarginfo_class_UnitEnum_cases[sizeof(arginfo_class_UnitEnum
static zend_arg_info zarginfo_class_BackedEnum_from[sizeof(arginfo_class_BackedEnum_from)/sizeof(zend_internal_arg_info)];
static zend_arg_info zarginfo_class_BackedEnum_tryFrom[sizeof(arginfo_class_BackedEnum_tryFrom)/sizeof(zend_internal_arg_info)];
-zend_object *zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv)
+zend_object *zend_enum_new(zval *result, zend_class_entry *ce, int case_id, zend_string *case_name, zval *backing_value_zv)
{
- zend_object *zobj = zend_objects_new(ce);
+ zend_enum_obj *intern = zend_object_alloc(sizeof(*intern), ce);
+
+ zend_object_std_init(&intern->std, ce);
+ object_properties_init(&intern->std, ce);
+
+ intern->case_id = case_id;
+
+ zend_object *zobj = &intern->std;
GC_ADD_FLAGS(zobj, GC_NOT_COLLECTABLE);
ZVAL_OBJ(result, zobj);
@@ -170,6 +177,7 @@ void zend_register_enum_ce(void)
zend_ce_backed_enum->interface_gets_implemented = zend_implement_backed_enum;
memcpy(&zend_enum_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
+ zend_enum_object_handlers.offset = XtOffsetOf(zend_enum_obj, std);
zend_enum_object_handlers.clone_obj = NULL;
zend_enum_object_handlers.compare = zend_objects_not_comparable;
}
@@ -539,16 +547,18 @@ ZEND_API zend_class_entry *zend_register_internal_enum(
}
static zend_ast_ref *create_enum_case_ast(
- zend_string *class_name, zend_string *case_name, zval *value) {
+ zend_string *class_name, int case_id, zend_string *case_name,
+ zval *value) {
// TODO: Use custom node type for enum cases?
- size_t size = sizeof(zend_ast_ref) + zend_ast_size(3)
- + (value ? 3 : 2) * sizeof(zend_ast_zval);
+ const size_t num_children = ZEND_AST_CONST_ENUM_INIT >> ZEND_AST_NUM_CHILDREN_SHIFT;
+ size_t size = sizeof(zend_ast_ref) + zend_ast_size(num_children)
+ + (value ? num_children : num_children-1) * sizeof(zend_ast_zval);
char *p = pemalloc(size, 1);
zend_ast_ref *ref = (zend_ast_ref *) p; p += sizeof(zend_ast_ref);
GC_SET_REFCOUNT(ref, 1);
GC_TYPE_INFO(ref) = GC_CONSTANT_AST | GC_PERSISTENT | GC_IMMUTABLE;
- zend_ast *ast = (zend_ast *) p; p += zend_ast_size(3);
+ zend_ast *ast = (zend_ast *) p; p += zend_ast_size(num_children);
ast->kind = ZEND_AST_CONST_ENUM_INIT;
ast->attr = 0;
ast->lineno = 0;
@@ -563,24 +573,47 @@ static zend_ast_ref *create_enum_case_ast(
ast->child[1] = (zend_ast *) p; p += sizeof(zend_ast_zval);
ast->child[1]->kind = ZEND_AST_ZVAL;
ast->child[1]->attr = 0;
- ZEND_ASSERT(ZSTR_IS_INTERNED(case_name));
- ZVAL_STR(zend_ast_get_zval(ast->child[1]), case_name);
+ ZVAL_LONG(zend_ast_get_zval(ast->child[1]), case_id);
Z_LINENO_P(zend_ast_get_zval(ast->child[1])) = 0;
+ ast->child[2] = (zend_ast *) p; p += sizeof(zend_ast_zval);
+ ast->child[2]->kind = ZEND_AST_ZVAL;
+ ast->child[2]->attr = 0;
+ ZEND_ASSERT(ZSTR_IS_INTERNED(case_name));
+ ZVAL_STR(zend_ast_get_zval(ast->child[2]), case_name);
+ Z_LINENO_P(zend_ast_get_zval(ast->child[2])) = 0;
+
if (value) {
- ast->child[2] = (zend_ast *) p; p += sizeof(zend_ast_zval);
- ast->child[2]->kind = ZEND_AST_ZVAL;
- ast->child[2]->attr = 0;
+ ast->child[3] = (zend_ast *) p; p += sizeof(zend_ast_zval);
+ ast->child[3]->kind = ZEND_AST_ZVAL;
+ ast->child[3]->attr = 0;
ZEND_ASSERT(!Z_REFCOUNTED_P(value));
- ZVAL_COPY_VALUE(zend_ast_get_zval(ast->child[2]), value);
- Z_LINENO_P(zend_ast_get_zval(ast->child[2])) = 0;
+ ZVAL_COPY_VALUE(zend_ast_get_zval(ast->child[3]), value);
+ Z_LINENO_P(zend_ast_get_zval(ast->child[3])) = 0;
} else {
- ast->child[2] = NULL;
+ ast->child[3] = NULL;
}
return ref;
}
+int zend_enum_next_case_id(zend_class_entry *enum_class)
+{
+ ZEND_HASH_REVERSE_FOREACH_VAL(&enum_class->constants_table, zval *zv) {
+ zend_class_constant *c = Z_PTR_P(zv);
+ if (!(ZEND_CLASS_CONST_FLAGS(c) & ZEND_CLASS_CONST_IS_CASE)) {
+ continue;
+ }
+ ZEND_ASSERT(Z_TYPE(c->value) == IS_CONSTANT_AST);
+ zend_ast *ast = Z_ASTVAL(c->value);
+
+ ZEND_ASSERT(ast->kind == ZEND_AST_CONST_ENUM_INIT);
+ return Z_LVAL_P(zend_ast_get_zval(ast->child[1])) + 1;
+ } ZEND_HASH_FOREACH_END();
+
+ return 1;
+}
+
ZEND_API void zend_enum_add_case(zend_class_entry *ce, zend_string *case_name, zval *value)
{
if (value) {
@@ -602,9 +635,11 @@ ZEND_API void zend_enum_add_case(zend_class_entry *ce, zend_string *case_name, z
ZEND_ASSERT(ce->enum_backing_type == IS_UNDEF);
}
+ int case_id = zend_enum_next_case_id(ce);
+
zval ast_zv;
Z_TYPE_INFO(ast_zv) = IS_CONSTANT_AST;
- Z_AST(ast_zv) = create_enum_case_ast(ce->name, case_name, value);
+ Z_AST(ast_zv) = create_enum_case_ast(ce->name, case_id, case_name, value);
zend_class_constant *c = zend_declare_class_constant_ex(
ce, case_name, &ast_zv, ZEND_ACC_PUBLIC, NULL);
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_CLASS_CONST_IS_CASE;
diff --git a/Zend/zend_enum.h b/Zend/zend_enum.h
index 39743c73472..4d0799e4f0a 100644
--- a/Zend/zend_enum.h
+++ b/Zend/zend_enum.h
@@ -30,14 +30,25 @@ extern ZEND_API zend_class_entry *zend_ce_unit_enum;
extern ZEND_API zend_class_entry *zend_ce_backed_enum;
extern ZEND_API zend_object_handlers zend_enum_object_handlers;
+typedef struct zend_enum_obj {
+ int case_id;
+ zend_object std;
+} zend_enum_obj;
+
+static inline zend_enum_obj *zend_enum_obj_from_obj(zend_object *zobj) {
+ ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM);
+ return (zend_enum_obj*)((char*)(zobj) - XtOffsetOf(zend_enum_obj, std));
+}
+
void zend_enum_startup(void);
void zend_register_enum_ce(void);
void zend_enum_add_interfaces(zend_class_entry *ce);
zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce);
-zend_object *zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv);
+zend_object *zend_enum_new(zval *result, zend_class_entry *ce, int case_id, zend_string *case_name, zval *backing_value_zv);
void zend_verify_enum(const zend_class_entry *ce);
void zend_enum_register_funcs(zend_class_entry *ce);
void zend_enum_register_props(zend_class_entry *ce);
+int zend_enum_next_case_id(zend_class_entry *enum_class);
ZEND_API zend_class_entry *zend_register_internal_enum(
const char *name, uint8_t type, const zend_function_entry *functions);
@@ -47,6 +58,12 @@ ZEND_API zend_object *zend_enum_get_case(zend_class_entry *ce, zend_string *name
ZEND_API zend_object *zend_enum_get_case_cstr(zend_class_entry *ce, const char *name);
ZEND_API zend_result zend_enum_get_case_by_value(zend_object **result, zend_class_entry *ce, zend_long long_key, zend_string *string_key, bool try_from);
+static zend_always_inline int zend_enum_fetch_case_id(zend_object *zobj)
+{
+ ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM);
+ return zend_enum_obj_from_obj(zobj)->case_id;
+}
+
static zend_always_inline zval *zend_enum_fetch_case_name(zend_object *zobj)
{
ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM);
diff --git a/build/gen_stub.php b/build/gen_stub.php
index 2670e85458d..64273e24bd8 100755
--- a/build/gen_stub.php
+++ b/build/gen_stub.php
@@ -82,11 +82,22 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
$stubFilenameWithoutExtension = str_replace(".stub.php", "", $stubFile);
$arginfoFile = "{$stubFilenameWithoutExtension}_arginfo.h";
$legacyFile = "{$stubFilenameWithoutExtension}_legacy_arginfo.h";
-
+ $declFile = "{$stubFilenameWithoutExtension}_decl.h";
+
+ /* Check if the stub file changed, by checking that the hash stored
+ * in the generated arginfo.h matches.
+ * Also check that the decl.h file has the same hash. At this point
+ * we don't know if a decl.h file is supposed to exist, so extract
+ * this information (whether a decl file should exist) from the
+ * arginfo.h file. */
$stubCode = file_get_contents($stubFile);
$stubHash = sha1(str_replace("\r\n", "\n", $stubCode));
$oldStubHash = extractStubHash($arginfoFile);
- if ($stubHash === $oldStubHash && !$context->forceParse) {
+ $hasDeclHeader = extractHasDeclHeader($arginfoFile);
+ $oldStubHashDecl = extractStubHash($declFile);
+ $generatedFilesUpToDate = $stubHash === $oldStubHash
+ && ($hasDeclHeader ? $stubHash === $oldStubHashDecl : $oldStubHashDecl === null);
+ if ($generatedFilesUpToDate && !$context->forceParse) {
/* Stub file did not change, do not regenerate. */
return null;
}
@@ -122,26 +133,31 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
return $fileInfo;
}
- $arginfoCode = generateArgInfoCode(
+ [$arginfoCode, $declCode] = generateArgInfoCode(
basename($stubFilenameWithoutExtension),
$fileInfo,
$context->allConstInfos,
$stubHash
);
- if ($context->forceRegeneration || $stubHash !== $oldStubHash) {
+ if ($context->forceRegeneration || !$generatedFilesUpToDate) {
reportFilePutContents($arginfoFile, $arginfoCode);
+ if ($declCode !== '') {
+ reportFilePutContents($declFile, $declCode);
+ } else if (file_exists($declFile)) {
+ unlink($declFile);
+ }
}
if ($fileInfo->shouldGenerateLegacyArginfo()) {
$legacyFileInfo = $fileInfo->getLegacyVersion();
- $arginfoCode = generateArgInfoCode(
+ [$arginfoCode] = generateArgInfoCode(
basename($stubFilenameWithoutExtension),
$legacyFileInfo,
$context->allConstInfos,
$stubHash
);
- if ($context->forceRegeneration || $stubHash !== $oldStubHash) {
+ if ($context->forceRegeneration || !$generatedFilesUpToDate) {
reportFilePutContents($legacyFile, $arginfoCode);
}
}
@@ -159,13 +175,22 @@ function extractStubHash(string $arginfoFile): ?string {
}
$arginfoCode = file_get_contents($arginfoFile);
- if (!preg_match('/\* Stub hash: ([0-9a-f]+) \*/', $arginfoCode, $matches)) {
+ if (!preg_match('/\* Stub hash: ([0-9a-f]+)/', $arginfoCode, $matches)) {
return null;
}
return $matches[1];
}
+function extractHasDeclHeader(string $arginfoFile): bool {
+ if (!file_exists($arginfoFile)) {
+ return false;
+ }
+
+ $arginfoCode = file_get_contents($arginfoFile);
+ return str_contains($arginfoCode, '* Has decl header: yes *');
+}
+
class Context {
public bool $forceParse = false;
public bool $forceRegeneration = false;
@@ -3278,7 +3303,7 @@ protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fie
}
class EnumCaseInfo {
- private /* readonly */ string $name;
+ public /* readonly */ string $name;
private /* readonly */ ?Expr $value;
public function __construct(string $name, ?Expr $value) {
@@ -3661,6 +3686,38 @@ function (Name $item) {
return $code;
}
+ public function getCDeclarations(): string
+ {
+ if ($this->type !== "enum") {
+ return '';
+ }
+
+ $code = '';
+
+ if ($this->cond) {
+ $code .= "#if {$this->cond}\n";
+ }
+
+ $cEnumName = 'zend_enum_' . str_replace('\\', '_', $this->name->toString());
+
+ $code .= "typedef enum {$cEnumName} {\n";
+
+ $i = 1;
+ foreach ($this->enumCaseInfos as $case) {
+ $cName = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString()) . '_' . $case->name;
+ $code .= "\t{$cName} = {$i},\n";
+ $i++;
+ }
+
+ $code .= "} {$cEnumName};\n";
+
+ if ($this->cond) {
+ $code .= "#endif\n";
+ }
+
+ return $code;
+ }
+
private function getFlagsByPhpVersion(): VersionFlags
{
$php70Flags = [];
@@ -4192,6 +4249,7 @@ class FileInfo {
public bool $generateFunctionEntries = false;
public string $declarationPrefix = "";
public bool $generateClassEntries = false;
+ public bool $generateCEnums = false;
private bool $isUndocumentable = false;
private bool $legacyArginfoGeneration = false;
private ?int $minimumPhpVersionIdCompatibility = null;
@@ -4217,6 +4275,8 @@ public function __construct(array $fileTags) {
$this->declarationPrefix = $tag->value ? $tag->value . " " : "";
} else if ($tag->name === 'undocumentable') {
$this->isUndocumentable = true;
+ } else if ($tag->name === 'generate-c-enums') {
+ $this->generateCEnums = true;
}
}
@@ -4515,6 +4575,23 @@ public function generateClassEntryCode(array $allConstInfos): string {
return $code;
}
+
+ public function generateCDeclarations(): string {
+ $code = "";
+
+ if (!$this->generateCEnums) {
+ return $code;
+ }
+
+ foreach ($this->classInfos as $class) {
+ $cdecl = $class->getCDeclarations();
+ if ($cdecl !== '') {
+ $code .= "\n" . $cdecl;
+ }
+ }
+
+ return $code;
+ }
}
class DocCommentTag {
@@ -5150,15 +5227,15 @@ function generateCodeWithConditions(
/**
* @param array<string, ConstInfo> $allConstInfos
+ * @return array{string, string}
*/
function generateArgInfoCode(
string $stubFilenameWithoutExtension,
FileInfo $fileInfo,
array $allConstInfos,
string $stubHash
-): string {
- $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
- . " * Stub hash: $stubHash */\n";
+): array {
+ $code = "";
$generatedFuncInfos = [];
@@ -5250,7 +5327,26 @@ static function (FuncInfo $funcInfo) use ($fileInfo, &$generatedFunctionDeclarat
$code .= $fileInfo->generateClassEntryCode($allConstInfos);
}
- return $code;
+ $hasDeclFile = false;
+ $declCode = $fileInfo->generateCDeclarations();
+ if ($declCode !== '') {
+ $hasDeclFile = true;
+ $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
+ $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+ . " * Stub hash: $stubHash */\n"
+ . "\n"
+ . "#ifndef {$headerName}\n"
+ . "#define {$headerName}\n"
+ . $declCode . "\n"
+ . "#endif /* {$headerName} */\n";
+ }
+
+ $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+ . " * Stub hash: $stubHash"
+ . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
+ . $code;
+
+ return [$code, $declCode];
}
/** @param FuncInfo[] $funcInfos */
diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c
index df2b96e68a7..539fa9d9cf5 100644
--- a/ext/bcmath/bcmath.c
+++ b/ext/bcmath/bcmath.c
@@ -25,6 +25,7 @@
#include "php_ini.h"
#include "zend_exceptions.h"
#include "zend_interfaces.h"
+#include "zend_enum.h"
#include "bcmath_arginfo.h"
#include "ext/standard/info.h"
#include "php_bcmath.h"
@@ -787,30 +788,25 @@ PHP_FUNCTION(bcround)
{
zend_string *numstr;
zend_long precision = 0;
- zend_long mode = PHP_ROUND_HALF_UP;
- zend_object *mode_object = NULL;
+ zend_enum_RoundingMode rounding_mode = ZEND_ENUM_RoundingMode_HalfAwayFromZero;
bc_num num = NULL, result;
ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_STR(numstr)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(precision)
- Z_PARAM_OBJ_OF_CLASS(mode_object, rounding_mode_ce)
+ Z_PARAM_ENUM(rounding_mode, rounding_mode_ce)
ZEND_PARSE_PARAMETERS_END();
- if (mode_object != NULL) {
- mode = php_math_round_mode_from_enum(mode_object);
- }
-
- switch (mode) {
- case PHP_ROUND_HALF_UP:
- case PHP_ROUND_HALF_DOWN:
- case PHP_ROUND_HALF_EVEN:
- case PHP_ROUND_HALF_ODD:
- case PHP_ROUND_CEILING:
- case PHP_ROUND_FLOOR:
- case PHP_ROUND_TOWARD_ZERO:
- case PHP_ROUND_AWAY_FROM_ZERO:
+ switch (rounding_mode) {
+ case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
+ case ZEND_ENUM_RoundingMode_HalfTowardsZero:
+ case ZEND_ENUM_RoundingMode_HalfEven:
+ case ZEND_ENUM_RoundingMode_HalfOdd:
+ case ZEND_ENUM_RoundingMode_TowardsZero:
+ case ZEND_ENUM_RoundingMode_AwayFromZero:
+ case ZEND_ENUM_RoundingMode_NegativeInfinity:
+ case ZEND_ENUM_RoundingMode_PositiveInfinity:
break;
default:
/* This is currently unreachable, but might become reachable when new modes are added. */
@@ -827,7 +823,7 @@ PHP_FUNCTION(bcround)
goto cleanup;
}
- size_t scale = bc_round(num, precision, mode, &result);
+ size_t scale = bc_round(num, precision, rounding_mode, &result);
RETVAL_NEW_STR(bc_num2str_ex(result, scale));
cleanup: {
@@ -1796,30 +1792,26 @@ PHP_METHOD(BcMath_Number, ceil)
PHP_METHOD(BcMath_Number, round)
{
zend_long precision = 0;
- zend_long rounding_mode = PHP_ROUND_HALF_UP;
- zend_object *mode_object = NULL;
+ zend_enum_RoundingMode rounding_mode = ZEND_ENUM_RoundingMode_HalfAwayFromZero;
ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(precision);
- Z_PARAM_OBJ_OF_CLASS(mode_object, rounding_mode_ce);
+ Z_PARAM_ENUM(rounding_mode, rounding_mode_ce);
ZEND_PARSE_PARAMETERS_END();
- if (mode_object != NULL) {
- rounding_mode = php_math_round_mode_from_enum(mode_object);
- }
-
switch (rounding_mode) {
- case PHP_ROUND_HALF_UP:
- case PHP_ROUND_HALF_DOWN:
- case PHP_ROUND_HALF_EVEN:
- case PHP_ROUND_HALF_ODD:
- case PHP_ROUND_CEILING:
- case PHP_ROUND_FLOOR:
- case PHP_ROUND_TOWARD_ZERO:
- case PHP_ROUND_AWAY_FROM_ZERO:
+ case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
+ case ZEND_ENUM_RoundingMode_HalfTowardsZero:
+ case ZEND_ENUM_RoundingMode_HalfEven:
+ case ZEND_ENUM_RoundingMode_HalfOdd:
+ case ZEND_ENUM_RoundingMode_TowardsZero:
+ case ZEND_ENUM_RoundingMode_AwayFromZero:
+ case ZEND_ENUM_RoundingMode_NegativeInfinity:
+ case ZEND_ENUM_RoundingMode_PositiveInfinity:
break;
default:
+ /* This is currently unreachable, but might become reachable when new modes are added. */
zend_argument_value_error(2, "is an unsupported rounding mode");
RETURN_THROWS();
}
diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h
index fa335ae4048..970286b8a26 100644
--- a/ext/bcmath/libbcmath/src/bcmath.h
+++ b/ext/bcmath/libbcmath/src/bcmath.h
@@ -155,7 +155,7 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quo, bc_num *rem, size_t scale)
bc_num bc_floor_or_ceil(bc_num num, bool is_floor);
-size_t bc_round(bc_num num, zend_long places, zend_long mode, bc_num *result);
+size_t bc_round(bc_num num, zend_long places, zend_enum_RoundingMode mode, bc_num *result);
typedef enum {
BC_RAISE_STATUS_OK,
diff --git a/ext/bcmath/libbcmath/src/round.c b/ext/bcmath/libbcmath/src/round.c
index 44df6036cbe..ec0042a9f48 100644
--- a/ext/bcmath/libbcmath/src/round.c
+++ b/ext/bcmath/libbcmath/src/round.c
@@ -19,7 +19,7 @@
#include <stddef.h>
/* Returns the scale of the value after rounding. */
-size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
+size_t bc_round(bc_num num, zend_long precision, zend_enum_RoundingMode mode, bc_num *result)
{
/* clear result */
bc_free_num(result);
@@ -38,32 +38,30 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
/* e.g. value is 0.1 and precision is -3, ret is 0 or 1000 */
if (precision < 0 && num->n_len < (size_t) (-(precision + Z_L(1))) + 1) {
switch (mode) {
- case PHP_ROUND_HALF_UP:
- case PHP_ROUND_HALF_DOWN:
- case PHP_ROUND_HALF_EVEN:
- case PHP_ROUND_HALF_ODD:
- case PHP_ROUND_TOWARD_ZERO:
+ case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
+ case ZEND_ENUM_RoundingMode_HalfTowardsZero:
+ case ZEND_ENUM_RoundingMode_HalfEven:
+ case ZEND_ENUM_RoundingMode_HalfOdd:
+ case ZEND_ENUM_RoundingMode_TowardsZero:
*result = bc_copy_num(BCG(_zero_));
return 0;
- case PHP_ROUND_CEILING:
+ case ZEND_ENUM_RoundingMode_PositiveInfinity:
if (num->n_sign == MINUS) {
*result = bc_copy_num(BCG(_zero_));
return 0;
}
break;
- case PHP_ROUND_FLOOR:
+ case ZEND_ENUM_RoundingMode_NegativeInfinity:
if (num->n_sign == PLUS) {
*result = bc_copy_num(BCG(_zero_));
return 0;
}
break;
- case PHP_ROUND_AWAY_FROM_ZERO:
+ case ZEND_ENUM_RoundingMode_AwayFromZero:
break;
-
- EMPTY_SWITCH_DEFAULT_CASE()
}
if (bc_is_zero(num)) {
@@ -117,7 +115,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
/* Check cases that can be determined without looping. */
switch (mode) {
- case PHP_ROUND_HALF_UP:
+ case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
if (*nptr >= 5) {
goto up;
} else if (*nptr < 5) {
@@ -125,9 +123,9 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
}
break;
- case PHP_ROUND_HALF_DOWN:
- case PHP_ROUND_HALF_EVEN:
- case PHP_ROUND_HALF_ODD:
+ case ZEND_ENUM_RoundingMode_HalfTowardsZero:
+ case ZEND_ENUM_RoundingMode_HalfEven:
+ case ZEND_ENUM_RoundingMode_HalfOdd:
if (*nptr > 5) {
goto up;
} else if (*nptr < 5) {
@@ -136,7 +134,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
/* if *nptr == 5, we need to look-up further digits before making a decision. */
break;
- case PHP_ROUND_CEILING:
+ case ZEND_ENUM_RoundingMode_PositiveInfinity:
if (num->n_sign != PLUS) {
goto check_zero;
} else if (*nptr > 0) {
@@ -145,7 +143,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
/* if *nptr == 0, a loop is required for judgment. */
break;
- case PHP_ROUND_FLOOR:
+ case ZEND_ENUM_RoundingMode_NegativeInfinity:
if (num->n_sign != MINUS) {
goto check_zero;
} else if (*nptr > 0) {
@@ -154,17 +152,15 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
/* if *nptr == 0, a loop is required for judgment. */
break;
- case PHP_ROUND_TOWARD_ZERO:
+ case ZEND_ENUM_RoundingMode_TowardsZero:
goto check_zero;
- case PHP_ROUND_AWAY_FROM_ZERO:
+ case ZEND_ENUM_RoundingMode_AwayFromZero:
if (*nptr > 0) {
goto up;
}
/* if *nptr == 0, a loop is required for judgment. */
break;
-
- EMPTY_SWITCH_DEFAULT_CASE()
}
/* Loop through the remaining digits. */
@@ -180,19 +176,19 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
}
switch (mode) {
- case PHP_ROUND_HALF_DOWN:
- case PHP_ROUND_CEILING:
- case PHP_ROUND_FLOOR:
- case PHP_ROUND_AWAY_FROM_ZERO:
+ case ZEND_ENUM_RoundingMode_HalfTowardsZero:
+ case ZEND_ENUM_RoundingMode_PositiveInfinity:
+ case ZEND_ENUM_RoundingMode_NegativeInfinity:
+ case ZEND_ENUM_RoundingMode_AwayFromZero:
goto check_zero;
- case PHP_ROUND_HALF_EVEN:
+ case ZEND_ENUM_RoundingMode_HalfEven:
if (rounded_len == 0 || num->n_value[rounded_len - 1] % 2 == 0) {
goto check_zero;
}
break;
- case PHP_ROUND_HALF_ODD:
+ case ZEND_ENUM_RoundingMode_HalfOdd:
if (rounded_len != 0 && num->n_value[rounded_len - 1] % 2 == 1) {
goto check_zero;
}
diff --git a/ext/bcmath/php_bcmath.h b/ext/bcmath/php_bcmath.h
index 6b6098a2394..83894fd7ca6 100644
--- a/ext/bcmath/php_bcmath.h
+++ b/ext/bcmath/php_bcmath.h
@@ -17,9 +17,9 @@
#ifndef PHP_BCMATH_H
#define PHP_BCMATH_H
+#include "ext/standard/php_math_round_mode.h"
#include "libbcmath/src/bcmath.h"
#include "zend_API.h"
-#include "ext/standard/php_math_round_mode.h"
extern zend_module_entry bcmath_module_entry;
#define phpext_bcmath_ptr &bcmath_module_entry
diff --git a/ext/dom/element.c b/ext/dom/element.c
index 797f215e173..25bd306bcd8 100644
--- a/ext/dom/element.c
+++ b/ext/dom/element.c
@@ -1601,9 +1601,10 @@ PHP_METHOD(DOMElement, replaceChildren)
#define INSERT_ADJACENT_RES_SYNTAX_FAILED INSERT_ADJACENT_RES_ADOPT_FAILED
#define INSERT_ADJACENT_RES_PRE_INSERT_FAILED ((void*) -2)
-static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp, dom_object *this_intern, xmlNodePtr otherp)
+static xmlNodePtr dom_insert_adjacent(zend_enum_Dom_AdjacentPosition where, xmlNodePtr thisp, dom_object *this_intern, xmlNodePtr otherp)
{
- if (zend_string_equals_literal_ci(where, "beforebegin")) {
+ switch (where) {
+ case ZEND_ENUM_Dom_AdjacentPosition_BeforeBegin:
if (thisp->parent == NULL) {
return NULL;
}
@@ -1613,21 +1614,24 @@ static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp
if (!php_dom_pre_insert(this_intern->document, otherp, thisp->parent, thisp)) {
return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
- } else if (zend_string_equals_literal_ci(where, "afterbegin")) {
+ break;
+ case ZEND_ENUM_Dom_AdjacentPosition_AfterBegin:
if (!php_dom_adopt_node(otherp, this_intern, thisp->doc)) {
return INSERT_ADJACENT_RES_ADOPT_FAILED;
}
if (!php_dom_pre_insert(this_intern->document, otherp, thisp, thisp->children)) {
return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
- } else if (zend_string_equals_literal_ci(where, "beforeend")) {
+ break;
+ case ZEND_ENUM_Dom_AdjacentPosition_BeforeEnd:
if (!php_dom_adopt_node(otherp, this_intern, thisp->doc)) {
return INSERT_ADJACENT_RES_ADOPT_FAILED;
}
if (!php_dom_pre_insert(this_intern->document, otherp, thisp, NULL)) {
return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
- } else if (zend_string_equals_literal_ci(where, "afterend")) {
+ break;
+ case ZEND_ENUM_Dom_AdjacentPosition_AfterEnd:
if (thisp->parent == NULL) {
return NULL;
}
@@ -1637,9 +1641,7 @@ static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp
if (!php_dom_pre_insert(this_intern->document, otherp, thisp->parent, thisp->next)) {
return INSERT_ADJACENT_RES_PRE_INSERT_FAILED;
}
- } else {
- php_dom_throw_error(SYNTAX_ERR, dom_get_strict_error(this_intern->document));
- return INSERT_ADJACENT_RES_SYNTAX_FAILED;
+ break;
}
return otherp;
}
@@ -1647,7 +1649,7 @@ static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp
/* {{{ URL: https://dom.spec.whatwg.org/#dom-element-insertadjacentelement
Since:
*/
-static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, const zend_string *where, zval *element_zval)
+static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, zend_enum_Dom_AdjacentPosition where, zval *element_zval)
{
zval *id;
xmlNodePtr thisp, otherp;
@@ -1666,12 +1668,41 @@ static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, co
}
}
+static zend_result dom_adjacent_position_str_to_enum(zend_enum_Dom_AdjacentPosition *value, const zend_string *str)
+{
+ if (zend_string_equals_literal_ci(str, "beforebegin")) {
+ *value = ZEND_ENUM_Dom_AdjacentPosition_BeforeBegin;
+ } else if (zend_string_equals_literal_ci(str, "afterbegin")) {
+ *value = ZEND_ENUM_Dom_AdjacentPosition_AfterBegin;
+ } else if (zend_string_equals_literal_ci(str, "beforeend")) {
+ *value = ZEND_ENUM_Dom_AdjacentPosition_BeforeEnd;
+ } else if (zend_string_equals_literal_ci(str, "afterend")) {
+ *value = ZEND_ENUM_Dom_AdjacentPosition_AfterEnd;
+ } else {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
PHP_METHOD(DOMElement, insertAdjacentElement)
{
- zend_string *where;
+ zend_string *where_str;
+ zend_enum_Dom_AdjacentPosition where;
zval *element_zval;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "SO", &where, &element_zval, dom_element_class_entry) != SUCCESS) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "SO", &where_str, &element_zval, dom_element_class_entry) != SUCCESS) {
+ RETURN_THROWS();
+ }
+
+ if (dom_adjacent_position_str_to_enum(&where, where_str) != SUCCESS) {
+ zval *id;
+ xmlNodePtr p;
+ dom_object *intern;
+ DOM_GET_THIS_OBJ(p, id, xmlNodePtr, intern);
+ (void)p;
+
+ php_dom_throw_error(SYNTAX_ERR, dom_get_strict_error(intern->document));
RETURN_THROWS();
}
@@ -1680,14 +1711,14 @@ PHP_METHOD(DOMElement, insertAdjacentElement)
PHP_METHOD(Dom_Element, insertAdjacentElement)
{
- zval *element_zval, *where_zv;
+ zend_enum_Dom_AdjacentPosition where;
+ zval *element_zval;
ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_OBJECT_OF_CLASS(where_zv, dom_adjacent_position_class_entry)
+ Z_PARAM_ENUM(where, dom_adjacent_position_class_entry)
Z_PARAM_OBJECT_OF_CLASS(element_zval, dom_modern_element_class_entry)
ZEND_PARSE_PARAMETERS_END();
- const zend_string *where = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(where_zv)));
dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, where, element_zval);
}
/* }}} end DOMElement::insertAdjacentElement */
@@ -1695,7 +1726,7 @@ PHP_METHOD(Dom_Element, insertAdjacentElement)
/* {{{ URL: https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
Since:
*/
-static void dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAMETERS, const zend_string *where, const zend_string *data)
+static void dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAMETERS, zend_enum_Dom_AdjacentPosition where, const zend_string *data)
{
dom_object *this_intern;
zval *id;
@@ -1717,9 +1748,21 @@ static void dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAMETERS, const
PHP_METHOD(DOMElement, insertAdjacentText)
{
- zend_string *where, *data;
+ zend_string *where_str, *data;
+ zend_enum_Dom_AdjacentPosition where;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &where, &data) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &where_str, &data) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ if (dom_adjacent_position_str_to_enum(&where, where_str) != SUCCESS) {
+ zval *id;
+ xmlNodePtr p;
+ dom_object *intern;
+ DOM_GET_THIS_OBJ(p, id, xmlNodePtr, intern);
+ (void)p;
+
+ php_dom_throw_error(SYNTAX_ERR, dom_get_strict_error(intern->document));
RETURN_THROWS();
}
@@ -1728,15 +1771,14 @@ PHP_METHOD(DOMElement, insertAdjacentText)
PHP_METHOD(Dom_Element, insertAdjacentText)
{
- zval *where_zv;
+ zend_enum_Dom_AdjacentPosition where;
zend_string *data;
ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_OBJECT_OF_CLASS(where_zv, dom_adjacent_position_class_entry)
+ Z_PARAM_ENUM(where, dom_adjacent_position_class_entry)
Z_PARAM_STR(data)
ZEND_PARSE_PARAMETERS_END();
- const zend_string *where = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(where_zv)));
dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAM_PASSTHRU, where, data);
}
/* }}} end DOMElement::insertAdjacentText */
@@ -1744,7 +1786,7 @@ PHP_METHOD(Dom_Element, insertAdjacentText)
/* https://html.spec.whatwg.org/#dom-element-insertadjacenthtml */
PHP_METHOD(Dom_Element, insertAdjacentHTML)
{
- zval *where_zv;
+ zend_enum_Dom_AdjacentPosition where;
zend_string *string;
dom_object *this_intern;
@@ -1754,23 +1796,21 @@ PHP_METHOD(Dom_Element, insertAdjacentHTML)
bool created_context = false;
ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_OBJECT_OF_CLASS(where_zv, dom_adjacent_position_class_entry)
+ Z_PARAM_ENUM(where, dom_adjacent_position_class_entry)
Z_PARAM_STR(string)
ZEND_PARSE_PARAMETERS_END();
DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, this_intern);
- const zend_string *where = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(where_zv)));
-
/* 1. We don't do injection sinks. */
/* 2. Let context be NULL */
xmlNodePtr context = NULL;
/* 3. Use the first matching item from this list: (...) */
- switch (ZSTR_LEN(where) + ZSTR_VAL(where)[2]) {
- case sizeof("BeforeBegin") - 1 + 'f':
- case sizeof("AfterEnd") - 1 + 't':
+ switch (where) {
+ case ZEND_ENUM_Dom_AdjacentPosition_BeforeBegin:
+ case ZEND_ENUM_Dom_AdjacentPosition_AfterEnd:
/* 1. Set context to this's parent. */
context = thisp->parent;
@@ -1780,8 +1820,8 @@ PHP_METHOD(Dom_Element, insertAdjacentHTML)
RETURN_THROWS();
}
break;
- case sizeof("AfterBegin") - 1 + 't':
- case sizeof("BeforeEnd") - 1 + 'f':
+ case ZEND_ENUM_Dom_AdjacentPosition_AfterBegin:
+ case ZEND_ENUM_Dom_AdjacentPosition_BeforeEnd:
/* Set context to this. */
context = thisp;
break;
@@ -1811,17 +1851,17 @@ PHP_METHOD(Dom_Element, insertAdjacentHTML)
php_libxml_invalidate_node_list_cache(this_intern->document);
/* 6. Use the first matching item from this list: (...) */
- switch (ZSTR_LEN(where) + ZSTR_VAL(where)[2]) {
- case sizeof("BeforeBegin") - 1 + 'f':
+ switch (where) {
+ case ZEND_ENUM_Dom_AdjacentPosition_BeforeBegin:
php_dom_pre_insert(this_intern->document, fragment, thisp->parent, thisp);
break;
- case sizeof("AfterEnd") - 1 + 't':
+ case ZEND_ENUM_Dom_AdjacentPosition_AfterEnd:
php_dom_pre_insert(this_intern->document, fragment, thisp->parent, thisp->next);
break;
- case sizeof("AfterBegin") - 1 + 't':
+ case ZEND_ENUM_Dom_AdjacentPosition_AfterBegin:
php_dom_pre_insert(this_intern->document, fragment, thisp, thisp->children);
break;
- case sizeof("BeforeEnd") - 1 + 'f':
+ case ZEND_ENUM_Dom_AdjacentPosition_BeforeEnd:
php_dom_node_append(this_intern->document, fragment, thisp);
break;
EMPTY_SWITCH_DEFAULT_CASE();
diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h
index e44f74eadeb..e93000044f0 100644
--- a/ext/dom/php_dom.h
+++ b/ext/dom/php_dom.h
@@ -54,6 +54,7 @@ extern zend_module_entry dom_module_entry;
#include "xpath_callbacks.h"
#include "zend_exceptions.h"
#include "dom_ce.h"
+#include "php_dom_decl.h"
/* DOM API_VERSION, please bump it up, if you change anything in the API
therefore it's easier for the script-programmers to check, what's working how
diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php
index 37a1bea62b6..71aa5f4ec0f 100644
--- a/ext/dom/php_dom.stub.php
+++ b/ext/dom/php_dom.stub.php
@@ -1,6 +1,9 @@
<?php
-/** @generate-class-entries */
+/**
+ * @generate-class-entries
+ * @generate-c-enums
+ */
namespace
{
diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h
index 7a0ad88d7e5..1c90f920cdd 100644
Binary files a/ext/dom/php_dom_arginfo.h and b/ext/dom/php_dom_arginfo.h differ
diff --git a/ext/dom/php_dom_decl.h b/ext/dom/php_dom_decl.h
new file mode 100644
index 00000000000..f918637ab52
Binary files /dev/null and b/ext/dom/php_dom_decl.h differ
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 886a292ee29..ab8b638bdbd 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -1823,22 +1823,22 @@ PHP_FUNCTION(pcntl_getcpu)
#endif
#if defined(HAVE_PTHREAD_SET_QOS_CLASS_SELF_NP)
-static qos_class_t qos_zval_to_lval(const zval *qos_obj)
+static qos_class_t qos_enum_to_pthread(zend_enum_Pcntl_QosClass entry)
{
- qos_class_t qos_class = QOS_CLASS_DEFAULT;
- zend_string *entry = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(qos_obj)));
-
- if (zend_string_equals_literal(entry, "UserInteractive")) {
- qos_class = QOS_CLASS_USER_INTERACTIVE;
- } else if (zend_string_equals_literal(entry, "UserInitiated")) {
- qos_class = QOS_CLASS_USER_INITIATED;
- } else if (zend_string_equals_literal(entry, "Utility")) {
- qos_class = QOS_CLASS_UTILITY;
- } else if (zend_string_equals_literal(entry, "Background")) {
- qos_class = QOS_CLASS_BACKGROUND;
- }
-
- return qos_class;
+ switch (entry) {
+ case ZEND_ENUM_Pcntl_QosClass_UserInteractive:
+ return QOS_CLASS_USER_INTERACTIVE;
+ case ZEND_ENUM_Pcntl_QosClass_UserInitiated:
+ return QOS_CLASS_USER_INITIATED;
+ case ZEND_ENUM_Pcntl_QosClass_Utility:
+ return QOS_CLASS_UTILITY;
+ case ZEND_ENUM_Pcntl_QosClass_Background:
+ return QOS_CLASS_BACKGROUND;
+ case ZEND_ENUM_Pcntl_QosClass_Default:
+ return QOS_CLASS_DEFAULT;
+ }
+
+ ZEND_UNREACHABLE();
}
static zend_object *qos_lval_to_zval(qos_class_t qos_class)
@@ -1886,13 +1886,13 @@ PHP_FUNCTION(pcntl_getqos_class)
PHP_FUNCTION(pcntl_setqos_class)
{
- zval *qos_obj;
+ zend_enum_Pcntl_QosClass qos;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_OBJECT_OF_CLASS(qos_obj, QosClass_ce)
+ Z_PARAM_ENUM(qos, QosClass_ce)
ZEND_PARSE_PARAMETERS_END();
- qos_class_t qos_class = qos_zval_to_lval(qos_obj);
+ qos_class_t qos_class = qos_enum_to_pthread(qos);
if (UNEXPECTED(pthread_set_qos_class_self_np((qos_class_t)qos_class, 0) != 0))
{
diff --git a/ext/pcntl/pcntl.stub.php b/ext/pcntl/pcntl.stub.php
index 3f3800c50ab..2da540fa71e 100644
--- a/ext/pcntl/pcntl.stub.php
+++ b/ext/pcntl/pcntl.stub.php
@@ -1,6 +1,9 @@
<?php
-/** @generate-class-entries */
+/**
+ * @generate-class-entries
+ * @generate-c-enums
+ */
/* Wait Constants */
diff --git a/ext/pcntl/pcntl_arginfo.h b/ext/pcntl/pcntl_arginfo.h
index 808632fdabb..d9624a22605 100644
Binary files a/ext/pcntl/pcntl_arginfo.h and b/ext/pcntl/pcntl_arginfo.h differ
diff --git a/ext/pcntl/pcntl_decl.h b/ext/pcntl/pcntl_decl.h
new file mode 100644
index 00000000000..1059485bc93
Binary files /dev/null and b/ext/pcntl/pcntl_decl.h differ
diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h
index f2cc0d59195..fb151e207b9 100644
--- a/ext/pcntl/php_pcntl.h
+++ b/ext/pcntl/php_pcntl.h
@@ -17,6 +17,8 @@
#ifndef PHP_PCNTL_H
#define PHP_PCNTL_H
+#include "pcntl_decl.h"
+
#if defined(HAVE_DECL_WCONTINUED) && HAVE_DECL_WCONTINUED == 1 && defined(HAVE_WIFCONTINUED) && HAVE_WIFCONTINUED == 1
#define HAVE_WCONTINUED 1
#endif
diff --git a/ext/random/php_random.h b/ext/random/php_random.h
index 9db8c8ba190..e4d6b4bdf3d 100644
--- a/ext/random/php_random.h
+++ b/ext/random/php_random.h
@@ -34,6 +34,7 @@
# include "php.h"
# include "php_random_csprng.h"
# include "php_random_uint128.h"
+# include "random_decl.h"
PHPAPI double php_combined_lcg(void);
diff --git a/ext/random/random.stub.php b/ext/random/random.stub.php
index 2854bdd2c25..57a80bf645b 100644
--- a/ext/random/random.stub.php
+++ b/ext/random/random.stub.php
@@ -1,6 +1,9 @@
<?php
-/** @generate-class-entries */
+/**
+ * @generate-class-entries
+ * @generate-c-enums
+ */
namespace {
/**
diff --git a/ext/random/random_arginfo.h b/ext/random/random_arginfo.h
index fff5f1e9cd8..8332fdc41fd 100644
Binary files a/ext/random/random_arginfo.h and b/ext/random/random_arginfo.h differ
diff --git a/ext/random/random_decl.h b/ext/random/random_decl.h
new file mode 100644
index 00000000000..67b27f19824
Binary files /dev/null and b/ext/random/random_decl.h differ
diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c
index 2daf9866109..a576cd12955 100644
--- a/ext/random/randomizer.c
+++ b/ext/random/randomizer.c
@@ -131,14 +131,13 @@ PHP_METHOD(Random_Randomizer, getFloat)
{
php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS);
double min, max;
- zend_object *bounds = NULL;
- int bounds_type = 'C' + sizeof("ClosedOpen") - 1;
+ zend_enum_Random_IntervalBoundary bounds_type = ZEND_ENUM_Random_IntervalBoundary_ClosedOpen;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_DOUBLE(min)
Z_PARAM_DOUBLE(max)
Z_PARAM_OPTIONAL
- Z_PARAM_OBJ_OF_CLASS(bounds, random_ce_Random_IntervalBoundary);
+ Z_PARAM_ENUM(bounds_type, random_ce_Random_IntervalBoundary);
ZEND_PARSE_PARAMETERS_END();
if (!zend_finite(min)) {
@@ -151,36 +150,29 @@ PHP_METHOD(Random_Randomizer, getFloat)
RETURN_THROWS();
}
- if (bounds) {
- zval *case_name = zend_enum_fetch_case_name(bounds);
- zend_string *bounds_name = Z_STR_P(case_name);
-
- bounds_type = ZSTR_VAL(bounds_name)[0] + ZSTR_LEN(bounds_name);
- }
-
switch (bounds_type) {
- case 'C' + sizeof("ClosedOpen") - 1:
+ case ZEND_ENUM_Random_IntervalBoundary_ClosedOpen:
if (UNEXPECTED(max <= min)) {
zend_argument_value_error(2, "must be greater than argument #1 ($min)");
RETURN_THROWS();
}
RETURN_DOUBLE(php_random_gammasection_closed_open(randomizer->engine, min, max));
- case 'C' + sizeof("ClosedClosed") - 1:
+ case ZEND_ENUM_Random_IntervalBoundary_ClosedClosed:
if (UNEXPECTED(max < min)) {
zend_argument_value_error(2, "must be greater than or equal to argument #1 ($min)");
RETURN_THROWS();
}
RETURN_DOUBLE(php_random_gammasection_closed_closed(randomizer->engine, min, max));
- case 'O' + sizeof("OpenClosed") - 1:
+ case ZEND_ENUM_Random_IntervalBoundary_OpenClosed:
if (UNEXPECTED(max <= min)) {
zend_argument_value_error(2, "must be greater than argument #1 ($min)");
RETURN_THROWS();
}
RETURN_DOUBLE(php_random_gammasection_open_closed(randomizer->engine, min, max));
- case 'O' + sizeof("OpenOpen") - 1:
+ case ZEND_ENUM_Random_IntervalBoundary_OpenOpen:
if (UNEXPECTED(max <= min)) {
zend_argument_value_error(2, "must be greater than argument #1 ($min)");
RETURN_THROWS();
@@ -194,8 +186,6 @@ PHP_METHOD(Random_Randomizer, getFloat)
}
return;
- default:
- ZEND_UNREACHABLE();
}
}
/* }}} */
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 64e79651913..256468e39a4 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -6547,16 +6547,16 @@ ZEND_METHOD(ReflectionProperty, hasHook)
reflection_object *intern;
property_reference *ref;
- zend_object *type;
+ zend_enum_PropertyHookType type;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_OBJ_OF_CLASS(type, reflection_property_hook_type_ptr)
+ Z_PARAM_ENUM(type, reflection_property_hook_type_ptr)
ZEND_PARSE_PARAMETERS_END();
GET_REFLECTION_OBJECT_PTR(ref);
zend_property_hook_kind kind;
- if (zend_string_equals_literal(Z_STR_P(zend_enum_fetch_case_name(type)), "Get")) {
+ if (type == ZEND_ENUM_PropertyHookType_Get) {
kind = ZEND_PROPERTY_HOOK_GET;
} else {
kind = ZEND_PROPERTY_HOOK_SET;
@@ -6569,10 +6569,10 @@ ZEND_METHOD(ReflectionProperty, getHook)
{
reflection_object *intern;
property_reference *ref;
- zend_object *type;
+ zend_enum_PropertyHookType type;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_OBJ_OF_CLASS(type, reflection_property_hook_type_ptr)
+ Z_PARAM_ENUM(type, reflection_property_hook_type_ptr)
ZEND_PARSE_PARAMETERS_END();
GET_REFLECTION_OBJECT_PTR(ref);
@@ -6583,7 +6583,7 @@ ZEND_METHOD(ReflectionProperty, getHook)
}
zend_function *hook;
- if (zend_string_equals_literal(Z_STR_P(zend_enum_fetch_case_name(type)), "Get")) {
+ if (type == ZEND_ENUM_PropertyHookType_Get) {
hook = ref->prop->hooks[ZEND_PROPERTY_HOOK_GET];
} else {
hook = ref->prop->hooks[ZEND_PROPERTY_HOOK_SET];
diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h
index d676597fd0b..dc224073429 100644
--- a/ext/reflection/php_reflection.h
+++ b/ext/reflection/php_reflection.h
@@ -18,6 +18,7 @@
#define PHP_REFLECTION_H
#include "php.h"
+#include "php_reflection_decl.h"
extern zend_module_entry reflection_module_entry;
#define phpext_reflection_ptr &reflection_module_entry
diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php
index 91c70d6ffdb..147e2f18c9e 100644
--- a/ext/reflection/php_reflection.stub.php
+++ b/ext/reflection/php_reflection.stub.php
@@ -1,6 +1,9 @@
<?php
-/** @generate-class-entries */
+/**
+ * @generate-class-entries
+ * @generate-c-enums
+ */
class ReflectionException extends Exception
{
diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h
index 9e2b8b970eb..5d452451001 100644
Binary files a/ext/reflection/php_reflection_arginfo.h and b/ext/reflection/php_reflection_arginfo.h differ
diff --git a/ext/reflection/php_reflection_decl.h b/ext/reflection/php_reflection_decl.h
new file mode 100644
index 00000000000..7a458bccd1e
Binary files /dev/null and b/ext/reflection/php_reflection_decl.h differ
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index e5b85fbc2d5..004279b9d1a 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -27,6 +27,8 @@
#include "url_scanner_ex.h"
+#include "basic_functions_decl.h"
+
#if defined(_WIN32) && !defined(__clang__)
#include <intrin.h>
#endif
diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php
index 4f77cf9b7f8..6fa0d47c7bd 100644
--- a/ext/standard/basic_functions.stub.php
+++ b/ext/standard/basic_functions.stub.php
@@ -1,6 +1,9 @@
<?php
-/** @generate-class-entries */
+/**
+ * @generate-class-entries
+ * @generate-c-enums
+ */
/* array.c */
diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h
index d63ea5e4e48..e467710f72f 100644
Binary files a/ext/standard/basic_functions_arginfo.h and b/ext/standard/basic_functions_arginfo.h differ
diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h
new file mode 100644
index 00000000000..9e6fb0def44
Binary files /dev/null and b/ext/standard/basic_functions_decl.h differ
diff --git a/ext/standard/math.c b/ext/standard/math.c
index 95384c06588..6418a020f4f 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -304,30 +304,28 @@ PHP_FUNCTION(floor)
}
/* }}} */
-PHPAPI int php_math_round_mode_from_enum(zend_object *mode)
+PHPAPI int php_math_round_mode_from_enum(zend_enum_RoundingMode mode)
{
- zval *case_name = zend_enum_fetch_case_name(mode);
- zend_string *mode_name = Z_STR_P(case_name);
-
- switch (ZSTR_VAL(mode_name)[0] + ZSTR_VAL(mode_name)[4]) {
- case 'H' + 'A':
+ switch (mode) {
+ case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
return PHP_ROUND_HALF_UP;
- case 'H' + 'T':
+ case ZEND_ENUM_RoundingMode_HalfTowardsZero:
return PHP_ROUND_HALF_DOWN;
- case 'H' + 'E':
+ case ZEND_ENUM_RoundingMode_HalfEven:
return PHP_ROUND_HALF_EVEN;
- case 'H' + 'O':
+ case ZEND_ENUM_RoundingMode_HalfOdd:
return PHP_ROUND_HALF_ODD;
- case 'T' + 'r':
+ case ZEND_ENUM_RoundingMode_TowardsZero:
return PHP_ROUND_TOWARD_ZERO;
- case 'A' + 'F':
+ case ZEND_ENUM_RoundingMode_AwayFromZero:
return PHP_ROUND_AWAY_FROM_ZERO;
- case 'N' + 't':
+ case ZEND_ENUM_RoundingMode_NegativeInfinity:
return PHP_ROUND_FLOOR;
- case 'P' + 't':
+ case ZEND_ENUM_RoundingMode_PositiveInfinity:
return PHP_ROUND_CEILING;
- EMPTY_SWITCH_DEFAULT_CASE();
}
+
+ ZEND_UNREACHABLE();
}
/* {{{ Returns the number rounded to specified precision */
@@ -355,7 +353,7 @@ PHP_FUNCTION(round)
}
if (mode_object != NULL) {
- mode = php_math_round_mode_from_enum(mode_object);
+ mode = php_math_round_mode_from_enum(zend_enum_fetch_case_id(mode_object));
}
switch (mode) {
diff --git a/ext/standard/php_math_round_mode.h b/ext/standard/php_math_round_mode.h
index e8cbec64066..9ab02de2c36 100644
--- a/ext/standard/php_math_round_mode.h
+++ b/ext/standard/php_math_round_mode.h
@@ -16,6 +16,7 @@
*/
#include "php.h"
+#include "basic_functions_decl.h"
/* Define rounding modes (all are round-to-nearest) */
#ifndef PHP_ROUND_HALF_UP
@@ -52,4 +53,4 @@
extern PHPAPI zend_class_entry *rounding_mode_ce;
-PHPAPI int php_math_round_mode_from_enum(zend_object *mode);
+PHPAPI int php_math_round_mode_from_enum(zend_enum_RoundingMode mode);
diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c
index 77fc627b6a9..2adece12553 100644
--- a/ext/uri/php_uri.c
+++ b/ext/uri/php_uri.c
@@ -678,7 +678,7 @@ static void throw_cannot_recompose_uri_to_string(php_uri_object *object)
zend_throw_exception_ex(php_uri_ce_error, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->std.ce->name));
}
-static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, php_uri_object *that_object, zend_object *comparison_mode)
+static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, php_uri_object *that_object, zend_enum_Uri_UriComparisonMode comparison_mode)
{
php_uri_object *this_object = Z_URI_OBJECT_P(ZEND_THIS);
ZEND_ASSERT(this_object->uri != NULL);
@@ -691,11 +691,7 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, php_uri_object *that_object
RETURN_FALSE;
}
- bool exclude_fragment = true;
- if (comparison_mode) {
- zval *case_name = zend_enum_fetch_case_name(comparison_mode);
- exclude_fragment = zend_string_equals_literal(Z_STR_P(case_name), "ExcludeFragment");
- }
+ bool exclude_fragment = comparison_mode == ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment;
zend_string *this_str = this_object->parser->to_string(
this_object->uri, PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII, exclude_fragment);
@@ -721,12 +717,12 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, php_uri_object *that_object
PHP_METHOD(Uri_Rfc3986_Uri, equals)
{
zend_object *that_object;
- zend_object *comparison_mode = NULL;
+ zend_enum_Uri_UriComparisonMode comparison_mode = ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment;
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_OBJ_OF_CLASS(that_object, php_uri_ce_rfc3986_uri)
Z_PARAM_OPTIONAL
- Z_PARAM_OBJ_OF_CLASS(comparison_mode, php_uri_ce_comparison_mode)
+ Z_PARAM_ENUM(comparison_mode, php_uri_ce_comparison_mode)
ZEND_PARSE_PARAMETERS_END();
uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_uri_object_from_obj(that_object), comparison_mode);
@@ -917,12 +913,12 @@ PHP_METHOD(Uri_WhatWg_Url, getFragment)
PHP_METHOD(Uri_WhatWg_Url, equals)
{
zend_object *that_object;
- zend_object *comparison_mode = NULL;
+ zend_enum_Uri_UriComparisonMode comparison_mode = ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment;
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_OBJ_OF_CLASS(that_object, php_uri_ce_whatwg_url)
Z_PARAM_OPTIONAL
- Z_PARAM_OBJ_OF_CLASS(comparison_mode, php_uri_ce_comparison_mode)
+ Z_PARAM_ENUM(comparison_mode, php_uri_ce_comparison_mode)
ZEND_PARSE_PARAMETERS_END();
uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_uri_object_from_obj(that_object), comparison_mode);
diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php
index 9f12fbb1c07..6d4b2c3517a 100644
--- a/ext/uri/php_uri.stub.php
+++ b/ext/uri/php_uri.stub.php
@@ -1,6 +1,9 @@
<?php
-/** @generate-class-entries */
+/**
+ * @generate-class-entries
+ * @generate-c-enums
+ */
namespace Uri {
/** @strict-properties */
diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h
index 3bb73fb8d94..18d7f4adf78 100644
Binary files a/ext/uri/php_uri_arginfo.h and b/ext/uri/php_uri_arginfo.h differ
diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h
index 109236879ae..2ae76cb2ee4 100644
--- a/ext/uri/php_uri_common.h
+++ b/ext/uri/php_uri_common.h
@@ -17,6 +17,8 @@
#ifndef PHP_URI_COMMON_H
#define PHP_URI_COMMON_H
+#include "php_uri_decl.h"
+
extern zend_class_entry *php_uri_ce_rfc3986_uri;
extern zend_class_entry *php_uri_ce_whatwg_url;
extern zend_class_entry *php_uri_ce_comparison_mode;
diff --git a/ext/uri/php_uri_decl.h b/ext/uri/php_uri_decl.h
new file mode 100644
index 00000000000..3c069f3abe6
Binary files /dev/null and b/ext/uri/php_uri_decl.h differ
diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php
index e93362cebe0..63f9650f7ef 100644
--- a/ext/zend_test/test.stub.php
+++ b/ext/zend_test/test.stub.php
@@ -2,6 +2,7 @@
/**
* @generate-class-entries static
+ * @generate-c-enums
* @generate-legacy-arginfo 80000
* @undocumentable
*/
diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h
index e7d09d7da5f..6b5dfe9c256 100644
Binary files a/ext/zend_test/test_arginfo.h and b/ext/zend_test/test_arginfo.h differ
diff --git a/ext/zend_test/test_decl.h b/ext/zend_test/test_decl.h
new file mode 100644
index 00000000000..a6254865a87
Binary files /dev/null and b/ext/zend_test/test_decl.h differ