Skip to content

Add support for generating MAY_BE_ARRAY_OF_REF func info flag #7416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions Zend/Optimizer/zend_func_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,6 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa
}

static const func_info_t old_func_infos[] = {
/* zend */
F1("get_class_vars", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF),
F1("get_defined_vars", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF),

/* ext/standard */
F1("parse_ini_file", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_FALSE | MAY_BE_ARRAY_OF_TRUE | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
F1("parse_ini_string", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_FALSE | MAY_BE_ARRAY_OF_TRUE | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
Expand Down Expand Up @@ -165,18 +161,8 @@ static const func_info_t old_func_infos[] = {
F1("stream_bucket_new", MAY_BE_OBJECT),
F1("sys_get_temp_dir", MAY_BE_STRING),

/* ext/preg */
F1("preg_grep", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),

F1("utf8_encode", MAY_BE_STRING),
F1("utf8_decode", MAY_BE_STRING),

/* ext/filter */
F1("filter_var_array", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF),

/* ext/spl */
F1("iterator_to_array", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),

};

static HashTable func_info;
Expand Down
5 changes: 5 additions & 0 deletions Zend/Optimizer/zend_func_infos.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
static const func_info_t func_infos[] = {
F1("zend_version", MAY_BE_STRING),
FN("func_get_args", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY),
F1("get_class_vars", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF),
F1("get_class_methods", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("get_included_files", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
FN("set_error_handler", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_OBJECT|MAY_BE_NULL),
Expand All @@ -13,6 +14,7 @@ static const func_info_t func_infos[] = {
F1("get_declared_traits", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("get_declared_interfaces", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("get_defined_functions", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ARRAY),
F1("get_defined_vars", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF),
F1("get_resource_type", MAY_BE_STRING),
F1("get_loaded_extensions", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("get_defined_constants", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY),
Expand Down Expand Up @@ -81,6 +83,7 @@ static const func_info_t func_infos[] = {
F1("finfo_buffer", MAY_BE_STRING|MAY_BE_FALSE),
F1("mime_content_type", MAY_BE_STRING|MAY_BE_FALSE),
F1("filter_input_array", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE|MAY_BE_NULL),
F1("filter_var_array", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_FALSE|MAY_BE_NULL),
F1("filter_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("gd_info", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE),
F1("imagecreatetruecolor", MAY_BE_OBJECT|MAY_BE_FALSE),
Expand Down Expand Up @@ -328,6 +331,7 @@ static const func_info_t func_infos[] = {
FN("preg_filter", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL),
FN("preg_replace_callback", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL),
F1("preg_split", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
F1("preg_grep", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_FALSE),
F1("pg_dbname", MAY_BE_STRING),
F1("pg_options", MAY_BE_STRING),
F1("pg_port", MAY_BE_STRING),
Expand Down Expand Up @@ -387,6 +391,7 @@ static const func_info_t func_infos[] = {
F1("class_uses", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
F1("spl_classes", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING),
F1("spl_object_hash", MAY_BE_STRING),
F1("iterator_to_array", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF),
F1("base64_encode", MAY_BE_STRING),
F1("base64_decode", MAY_BE_STRING|MAY_BE_FALSE),
F1("long2ip", MAY_BE_STRING|MAY_BE_FALSE),
Expand Down
8 changes: 8 additions & 0 deletions Zend/zend_builtin_functions.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ function is_subclass_of(mixed $object_or_class, string $class, bool $allow_strin
/** @param object|string $object_or_class */
function is_a(mixed $object_or_class, string $class, bool $allow_string = false): bool {}

/**
* @return array<string, mixed|ref>
* @refcount 1
*/
function get_class_vars(string $class): array {}

function get_object_vars(object $object): array {}
Expand Down Expand Up @@ -127,6 +131,10 @@ function get_declared_interfaces(): array {}
*/
function get_defined_functions(bool $exclude_disabled = true): array {}

/**
* @return array<string, mixed|ref>
* @refcount 1
*/
function get_defined_vars(): array {}

/**
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_builtin_functions_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 830eee0780adba8fc87cd5aed7f755d4d85ed82b */
* Stub hash: f87d92c002674c431827895a8d8b3a5da3b95482 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_version, 0, 0, IS_STRING, 0)
ZEND_END_ARG_INFO()
Expand Down
51 changes: 33 additions & 18 deletions build/gen_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ public static function fromString(string $typeString): SimpleType
case "mixed":
case "static":
case "never":
case "ref":
return new SimpleType(strtolower($typeString), true);
case "array":
return ArrayType::createGenericArray();
Expand Down Expand Up @@ -358,6 +359,8 @@ public function toOptimizerTypeMaskForArrayValue(): string {
return "MAY_BE_ARRAY_OF_RESOURCE";
case "mixed":
return "MAY_BE_ARRAY_OF_ANY";
case "ref":
return "MAY_BE_ARRAY_OF_REF";
default:
throw new Exception("Type $this->name cannot be an array value");
}
Expand Down Expand Up @@ -397,24 +400,22 @@ class Type {
/** @var SimpleType[] */
public $types;

/**
* @param SimpleType[] $types
*/
public function __construct(array $types) {
$this->types = $types;
}

public static function fromNode(Node $node): Type {
if ($node instanceof Node\UnionType) {
return new Type(array_map(['SimpleType', 'fromNode'], $node->types));
return new Type(array_map(['SimpleType', 'fromNode'], $node->types), false);
}

if ($node instanceof Node\NullableType) {
return new Type([
SimpleType::fromNode($node->type),
SimpleType::null(),
]);
return new Type(
[
SimpleType::fromNode($node->type),
SimpleType::null(),
],
false
);
}
return new Type([SimpleType::fromNode($node)]);

return new Type([SimpleType::fromNode($node)], false);
}

public static function fromString(string $typeString): self {
Expand Down Expand Up @@ -443,6 +444,7 @@ public static function fromString(string $typeString): self {

if ($char === "|") {
$simpleTypeName = trim(substr($typeString, $simpleTypeOffset, $i - $simpleTypeOffset));

$simpleTypes[] = SimpleType::fromString($simpleTypeName);

$simpleTypeOffset = $i + 1;
Expand All @@ -452,6 +454,13 @@ public static function fromString(string $typeString): self {
return new Type($simpleTypes);
}

/**
* @param SimpleType[] $types
*/
private function __construct(array $types) {
$this->types = $types;
}

public function isScalar(): bool {
foreach ($this->types as $type) {
if (!$type->isScalar()) {
Expand All @@ -473,9 +482,15 @@ public function isNullable(): bool {
}

public function getWithoutNull(): Type {
return new Type(array_filter($this->types, function(SimpleType $type) {
return !$type->isNull();
}));
return new Type(
array_filter(
$this->types,
function(SimpleType $type) {
return !$type->isNull();
}
),
false
);
}

public function tryToSimpleType(): ?SimpleType {
Expand Down Expand Up @@ -2032,9 +2047,9 @@ public function getType(): string {
$matches = [];

if ($this->name === "param") {
preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)\s*\$\w+.*$/', $value, $matches);
preg_match('/^\s*([\w\|\\\\\[\]<>,\- ]+)\s*\$\w+.*$/', $value, $matches);
} elseif ($this->name === "return") {
preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)(\s+|$)/', $value, $matches);
preg_match('/^\s*([\w\|\\\\\[\]<>,\- ]+)(\s+|$)/', $value, $matches);
}

if (!isset($matches[1])) {
Expand Down
4 changes: 4 additions & 0 deletions ext/filter/filter.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ function filter_var(mixed $value, int $filter = FILTER_DEFAULT, array|int $optio
/** @refcount 1 */
function filter_input_array(int $type, array|int $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {}

/**
* @return array<int|string, mixed|ref>|false|null
* @refcount 1
*/
function filter_var_array(array $array, array|int $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {}

/**
Expand Down
2 changes: 1 addition & 1 deletion ext/filter/filter_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 28ff4549a3e25c103a172624b8e25c6cd1912379 */
* Stub hash: 34a64a7c42c7129146fac699c801fe0257fe0d6f */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_has_var, 0, 2, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, input_type, IS_LONG, 0)
Expand Down
4 changes: 4 additions & 0 deletions ext/pcre/php_pcre.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ function preg_split(string $pattern, string $subject, int $limit = -1, int $flag

function preg_quote(string $str, ?string $delimiter = null): string {}

/**
* @return array<int|string, mixed|ref>|false
* @refcount 1
*/
function preg_grep(string $pattern, array $array, int $flags = 0): array|false {}

function preg_last_error(): int {}
Expand Down
2 changes: 1 addition & 1 deletion ext/pcre/php_pcre_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 5d7958a9f83b19eef0bffdf631ddb47cae28733f */
* Stub hash: 18ea8e0fc49c4daab52d346ba68afc77cc3f1552 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0)
Expand Down
4 changes: 4 additions & 0 deletions ext/spl/php_spl.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@ function iterator_apply(Traversable $iterator, callable $callback, ?array $args

function iterator_count(Traversable $iterator): int {}

/**
* @return array<int|string, mixed|ref>
* @refcount 1
*/
function iterator_to_array(Traversable $iterator, bool $preserve_keys = true): array {}
2 changes: 1 addition & 1 deletion ext/spl/php_spl_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 20188120387b006ea0e5833ad20241b73d2e2327 */
* Stub hash: a3102a82fa37455c2a5941b6e4f56204baa43950 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_implements, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_INFO(0, object_or_class)
Expand Down