summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-11-15 17:33:37 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-11-15 17:33:37 +0100
commit292a1aeb59f348aabed58ac4fbc1d467dde3fcea (patch)
treed53c6bc68ba16c2e19e8ba9d1d863b0715bcb863
parent0cec268d15e5aded8692ee8076e93d2839725918 (diff)
downloadphp-git-292a1aeb59f348aabed58ac4fbc1d467dde3fcea.tar.gz
Support union types for args in gen stubs
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.
-rw-r--r--Zend/zend_API.h2
-rwxr-xr-xext/standard/basic_functions.stub.php44
-rwxr-xr-xext/standard/basic_functions_arginfo.h16
-rwxr-xr-xscripts/dev/gen_stub.php12
4 files changed, 32 insertions, 42 deletions
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 7f33d61f0c..08a5f2aa40 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -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) \
diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php
index b35b84fffa..ba7e17d7bc 100755
--- a/ext/standard/basic_functions.stub.php
+++ b/ext/standard/basic_functions.stub.php
@@ -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 {}
diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h
index f62df22dae..82d15731cb 100755
--- a/ext/standard/basic_functions_arginfo.h
+++ b/ext/standard/basic_functions_arginfo.h
@@ -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()
diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php
index c6f9557fb4..253c188b2a 100755
--- a/scripts/dev/gen_stub.php
+++ b/scripts/dev/gen_stub.php
@@ -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');
}