]> granicus.if.org Git - php/commitdiff
Support union types for args in gen stubs
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 15 Nov 2019 16:33:37 +0000 (17:33 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 15 Nov 2019 16:33:37 +0000 (17:33 +0100)
Using this requires care! The zpp implementation for this union
must be consistent with the arginfo implementation!

Apart from array|object, this is probably only the case for
int|float right now.

Zend/zend_API.h
ext/standard/basic_functions.stub.php
ext/standard/basic_functions_arginfo.h
scripts/dev/gen_stub.php

index 7f33d61f0c2824235af1fec3a28da0571575d342..08a5f2aa40f40745e29b9a3dde9a88a97af4d01c 100644 (file)
@@ -109,6 +109,8 @@ typedef struct _zend_fcall_info_cache {
        { #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
 #define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
        { #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
+#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask) \
+       { #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
 #define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
        { #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
 #define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
index b35b84fffa40a4c7072e0f2d49282a847df15c50..ba7e17d7bc2542f89aa65e70fe2cdff60425a3f6 100755 (executable)
@@ -80,38 +80,22 @@ function uasort(array &$arg, callable $cmp_function): bool {}
 
 function uksort(array &$arg, callable $cmp_function): bool {}
 
-/**
- * @param array|object $arg
- * @return mixed
- */
-function end(array &$arg) {}
+/** @return mixed */
+function end(array|object &$arg) {}
 
-/**
- * @param array|object $arg
- * @return mixed
- */
-function prev(&$arg) {}
+/** @return mixed */
+function prev(array|object &$arg) {}
 
-/**
- * @param array|object $arg
- * @return mixed
- */
-function next(&$arg) {}
+/** @return mixed */
+function next(array|object &$arg) {}
 
-/**
- * @param array|object $arg
- * @return mixed
- */
-function reset(&$arg) {}
+/** @return mixed */
+function reset(array|object &$arg) {}
 
-/**
- * @param array|object $arg
- * @return mixed
- */
-function current($arg) {}
+/** @return mixed */
+function current(array|object $arg) {}
 
-/** @param array|object $arg */
-function key($arg): int|string|null {}
+function key(array|object $arg): int|string|null {}
 
 /** @return mixed */
 function min($arg, ...$args) {}
@@ -119,11 +103,9 @@ function min($arg, ...$args) {}
 /** @return mixed */
 function max($arg, ...$args) {}
 
-/** @param array|object $input */
-function array_walk(&$input, callable $funcname, $userdata = null): bool {}
+function array_walk(array|object &$input, callable $funcname, $userdata = null): bool {}
 
-/** @param array|object $input */
-function array_walk_recursive(&$input, callable $funcname, $userdata = null): bool {}
+function array_walk_recursive(array|object &$input, callable $funcname, $userdata = null): bool {}
 
 function in_array($needle, array $haystack, bool $strict = false): bool {}
 
index f62df22daea54a0518d576d79fa572775aa2bb30..82d15731cbba293f60cfcf7f8854aa18f2fa5394 100755 (executable)
@@ -107,23 +107,21 @@ ZEND_END_ARG_INFO()
 #define arginfo_uksort arginfo_usort
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_end, 0, 0, 1)
-       ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0)
+       ZEND_ARG_TYPE_MASK(1, arg, MAY_BE_ARRAY|MAY_BE_OBJECT)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_prev, 0, 0, 1)
-       ZEND_ARG_INFO(1, arg)
-ZEND_END_ARG_INFO()
+#define arginfo_prev arginfo_end
 
-#define arginfo_next arginfo_prev
+#define arginfo_next arginfo_end
 
-#define arginfo_reset arginfo_prev
+#define arginfo_reset arginfo_end
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_current, 0, 0, 1)
-       ZEND_ARG_INFO(0, arg)
+       ZEND_ARG_TYPE_MASK(0, arg, MAY_BE_ARRAY|MAY_BE_OBJECT)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_key, 0, 1, MAY_BE_LONG|MAY_BE_STRING|MAY_BE_NULL)
-       ZEND_ARG_INFO(0, arg)
+       ZEND_ARG_TYPE_MASK(0, arg, MAY_BE_ARRAY|MAY_BE_OBJECT)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 1)
@@ -134,7 +132,7 @@ ZEND_END_ARG_INFO()
 #define arginfo_max arginfo_min
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk, 0, 2, _IS_BOOL, 0)
-       ZEND_ARG_INFO(1, input)
+       ZEND_ARG_TYPE_MASK(1, input, MAY_BE_ARRAY|MAY_BE_OBJECT)
        ZEND_ARG_TYPE_INFO(0, funcname, IS_CALLABLE, 0)
        ZEND_ARG_INFO(0, userdata)
 ZEND_END_ARG_INFO()
index c6f9557fb48b44a5a82cd6fcd2b8b996b33f53dd..253c188b2ac977b0ac91119f6aafecfbdfefb5d9 100755 (executable)
@@ -532,8 +532,7 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
         $argKind = $argInfo->isVariadic ? "ARG_VARIADIC" : "ARG";
         $argType = $argInfo->type;
         if ($argType !== null) {
-            $simpleArgType = $argType->tryToSimpleType();
-            if ($simpleArgType !== null) {
+            if (null !== $simpleArgType = $argType->tryToSimpleType()) {
                 if ($simpleArgType->isBuiltin) {
                     $code .= sprintf(
                         "\tZEND_%s_TYPE_INFO(%s, %s, %s, %d)\n",
@@ -547,6 +546,15 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
                         $simpleArgType->toEscapedName(), $argType->isNullable()
                     );
                 }
+            } else if (null !== $representableType = $argType->tryToRepresentableType()) {
+                if ($representableType->classType !== null) {
+                    throw new Exception('Unimplemented');
+                }
+                $code .= sprintf(
+                    "\tZEND_%s_TYPE_MASK(%s, %s, %s)\n",
+                    $argKind, $argInfo->getSendByString(), $argInfo->name,
+                    $representableType->toTypeMask()
+                );
             } else {
                 throw new Exception('Unimplemented');
             }