Skip to content

Fix arginfo generation from stubs for namespaced functions #9406

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ PHP 8.2 INTERNALS UPGRADE NOTES
2. Build system changes
========================

* Identifier names for namespaced functions generated from stub files through
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the conflict and slightly adjusted the wording. Feel free to change it should you find any issues with it.

gen_stub.php have been changed. This will require changes in extensions using
namespaced functions.

========================
3. Module changes
========================
Expand Down
49 changes: 28 additions & 21 deletions build/gen_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,10 @@ public function getNonNamespacedName(): string {
}

public function getDeclarationName(): string {
return implode('_', $this->name->parts);
}

public function getFunctionName(): string {
return $this->name->getLast();
}

Expand Down Expand Up @@ -1380,39 +1384,42 @@ public function getFunctionEntry(): string {
}
} else if ($this->name instanceof FunctionName) {
$namespace = $this->name->getNamespace();
$declarationName = $this->name->getDeclarationName();
$functionName = $this->name->getFunctionName();
$declarationName = $this->alias ? $this->alias->getNonNamespacedName() : $this->name->getDeclarationName();

if ($namespace) {
// Namespaced functions are always declared as aliases to avoid name conflicts when two functions with
// the same name exist in separate namespaces
$macro = $this->isDeprecated ? 'ZEND_NS_DEP_FALIAS' : 'ZEND_NS_FALIAS';

if ($this->alias && $this->isDeprecated) {
// Render A\B as "A\\B" in C strings for namespaces
return sprintf(
"\tZEND_DEP_FALIAS(%s, %s, %s)\n",
$declarationName, $this->alias->getNonNamespacedName(), $this->getArgInfoName()
"\t%s(\"%s\", %s, %s, %s)\n",
$macro, addslashes($namespace), $this->name->getFunctionName(), $declarationName, $this->getArgInfoName()
);
}

if ($this->alias) {
$macro = $this->isDeprecated ? 'ZEND_DEP_FALIAS' : 'ZEND_FALIAS';

return sprintf(
"\tZEND_FALIAS(%s, %s, %s)\n",
$declarationName, $this->alias->getNonNamespacedName(), $this->getArgInfoName()
"\t%s(%s, %s, %s)\n",
$macro, $functionName, $declarationName, $this->getArgInfoName()
);
}

if ($this->isDeprecated) {
return sprintf(
"\tZEND_DEP_FE(%s, %s)\n", $declarationName, $this->getArgInfoName());
switch (true) {
case $this->isDeprecated:
$macro = 'ZEND_DEP_FE';
break;
case $this->supportsCompileTimeEval:
$macro = 'ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE';
break;
default:
$macro = 'ZEND_FE';
}

if ($namespace) {
// Render A\B as "A\\B" in C strings for namespaces
return sprintf(
"\tZEND_NS_FE(\"%s\", %s, %s)\n",
addslashes($namespace), $declarationName, $this->getArgInfoName());
} else {
if ($this->supportsCompileTimeEval) {
return sprintf(
"\tZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(%s, %s)\n", $declarationName, $this->getArgInfoName());
}
return sprintf("\tZEND_FE(%s, %s)\n", $declarationName, $this->getArgInfoName());
}
return sprintf("\t%s(%s, %s)\n", $macro, $functionName, $this->getArgInfoName());
} else {
throw new Error("Cannot happen");
}
Expand Down
38 changes: 37 additions & 1 deletion ext/zend_test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ static ZEND_FUNCTION(zend_test_deprecated)
zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &arg1);
}

static ZEND_FUNCTION(zend_test_alias)
{
ZEND_PARSE_PARAMETERS_NONE();
}

static ZEND_FUNCTION(zend_test_deprecated_alias)
{
ZEND_PARSE_PARAMETERS_NONE();
}

/* Create a string without terminating null byte. Must be terminated with
* zend_terminate_string() before destruction, otherwise a warning is issued
* in debug builds. */
Expand Down Expand Up @@ -415,12 +425,38 @@ static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity)
}
}

static ZEND_FUNCTION(namespaced_func)
static ZEND_FUNCTION(ZendTestNS2_namespaced_func)
{
ZEND_PARSE_PARAMETERS_NONE();
RETURN_TRUE;
}

static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func)
{
ZEND_PARSE_PARAMETERS_NONE();
}

static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func)
{
ZEND_PARSE_PARAMETERS_NONE();
RETURN_TRUE;
}

static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_deprecated_func)
{
ZEND_PARSE_PARAMETERS_NONE();
}

static ZEND_FUNCTION(namespaced_alias_func)
{
ZEND_PARSE_PARAMETERS_NONE();
}

static ZEND_FUNCTION(namespaced_deprecated_alias_func)
{
ZEND_PARSE_PARAMETERS_NONE();
}

static ZEND_FUNCTION(zend_test_parameter_with_attribute)
{
zend_string *parameter;
Expand Down
35 changes: 35 additions & 0 deletions ext/zend_test/test.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ function zend_test_compile_string(string $source_string, string $filename, int $
/** @deprecated */
function zend_test_deprecated(mixed $arg = null): void {}

/** @alias zend_test_alias */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a problem with the aliases. If you run ./build/gen_stub.php --verify --force-regeneration then gen_stub.php complains about the inexistent alias functions (zend_test_alias, zend_test_deprecated_alias etc.). So I fixed them in ef21bbe

function zend_test_aliased(): void {}

/**
* @deprecated
* @alias zend_test_deprecated_alias
*/
function zend_test_deprecated_aliased(): void {}

function zend_create_unterminated_string(string $str): string {}

function zend_terminate_string(string &$str): void {}
Expand Down Expand Up @@ -168,6 +177,20 @@ class Foo {
public function method(): void {}
}

function namespaced_func(): bool {}

/** @deprecated */
function namespaced_deprecated_func(): void {}

/** @alias namespaced_alias_func */
function namespaced_aliased_func(): void {}

/**
* @deprecated
* @alias namespaced_deprecated_alias_func
*/
function namespaced_deprecated_aliased_func(): void {}

}

namespace ZendTestNS2\ZendSubNS {
Expand All @@ -178,4 +201,16 @@ public function method(): void {}

function namespaced_func(): bool {}

/** @deprecated */
function namespaced_deprecated_func(): void {}

/** @alias namespaced_alias_func */
function namespaced_aliased_func(): void {}

/**
* @deprecated
* @alias namespaced_deprecated_alias_func
*/
function namespaced_deprecated_aliased_func(): void {}

}
44 changes: 39 additions & 5 deletions ext/zend_test/test_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.