Skip to content

Commit 7616901

Browse files
committed
Fix constant generation
1 parent a00d277 commit 7616901

8 files changed

+88
-31
lines changed

Zend/zend_constants.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "zend_operators.h"
2626
#include "zend_globals.h"
2727
#include "zend_API.h"
28+
#include "zend_constants_arginfo.h"
2829

2930
/* Protection from recursive self-referencing class constants */
3031
#define IS_CONSTANT_VISITED_MARK 0x80
@@ -108,10 +109,9 @@ void zend_startup_constants(void)
108109

109110
void zend_register_standard_constants(void)
110111
{
111-
REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);
112+
register_zend_constants_consts(0);
113+
112114
REGISTER_MAIN_LONG_CONSTANT("E_RECOVERABLE_ERROR", E_RECOVERABLE_ERROR, CONST_PERSISTENT | CONST_CS);
113-
REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);
114-
REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);
115115
REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);
116116
REGISTER_MAIN_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_CS);
117117
REGISTER_MAIN_LONG_CONSTANT("E_DEPRECATED", E_DEPRECATED, CONST_PERSISTENT | CONST_CS);

Zend/zend_constants.stub.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/** @generate-class-entries */
4+
5+
/** @cname E_ERROR */
6+
const E_ERROR = 1;
7+
/** @cname E_WARNING */
8+
const E_WARNING = 2;
9+
/** @cname E_PARSE */
10+
const E_PARSE = 4;
11+
const E_NOTICE = UNKNOWN;
12+
const E_CORE_ERROR = UNKNOWN;
13+
const E_CORE_WARNING = UNKNOWN;
14+
const E_COMPILE_ERROR = UNKNOWN;
15+
const E_COMPILE_WARNING = UNKNOWN;
16+
const E_USER_ERROR = UNKNOWN;
17+
const E_USER_WARNING = UNKNOWN;
18+
const E_USER_NOTICE = UNKNOWN;
19+
const E_STRICT = UNKNOWNN;
20+
const E_RECOVERABLE_ERROR = UNKNOWN;
21+
const E_DEPRECATED = UNKNOWN;
22+
const E_USER_DEPRECATED = UNKNOWN;

Zend/zend_constants_arginfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* This is a generated file, edit the .stub.php file instead.
2+
* Stub hash: 77f39014422633b26c62049152878f0df242b896 */
3+
4+
#include "zend_constants_consts.h"
5+
6+
7+
8+
static void register_zend_constants_consts(int module_number)
9+
{
10+
REGISTER_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_CS | CONST_PERSISTENT);
11+
REGISTER_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_CS | CONST_PERSISTENT);
12+
REGISTER_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_CS | CONST_PERSISTENT);
13+
}

Zend/zend_constants_consts.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* This is a generated file, edit the .stub.php file instead.
2+
* Stub hash: 77f39014422633b26c62049152878f0df242b896 */
3+
4+
#define E_ERROR 1
5+
#define E_WARNING 2
6+
#define E_PARSE 4

Zend/zend_errors.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
#ifndef ZEND_ERRORS_H
2121
#define ZEND_ERRORS_H
2222

23-
#define E_ERROR (1<<0L)
24-
#define E_WARNING (1<<1L)
25-
#define E_PARSE (1<<2L)
23+
#include "zend_constants_consts.h"
24+
2625
#define E_NOTICE (1<<3L)
2726
#define E_CORE_ERROR (1<<4L)
2827
#define E_CORE_WARNING (1<<5L)

Zend/zend_exceptions.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -753,11 +753,6 @@ void zend_register_default_exception(void) /* {{{ */
753753
zend_ce_error_exception = register_class_ErrorException(zend_ce_exception);
754754
zend_ce_error_exception->create_object = zend_error_exception_new;
755755

756-
/* Declared manually because it uses constant E_ERROR. */
757-
zval severity_default_value;
758-
ZVAL_LONG(&severity_default_value, E_ERROR);
759-
zend_declare_typed_property(zend_ce_error_exception, ZSTR_KNOWN(ZEND_STR_SEVERITY), &severity_default_value, ZEND_ACC_PROTECTED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
760-
761756
zend_ce_error = register_class_Error(zend_ce_throwable);
762757
zend_ce_error->create_object = zend_default_exception_new;
763758

Zend/zend_exceptions_arginfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ static zend_class_entry *register_class_ErrorException(zend_class_entry *class_e
259259
INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods);
260260
class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception);
261261

262+
zval property_severity_default_value;
263+
ZVAL_LONG(&property_severity_default_value, E_ERROR);
264+
zend_string *property_severity_name = zend_string_init("severity", sizeof("severity") - 1, 1);
265+
zend_declare_typed_property(class_entry, property_severity_name, &property_severity_default_value, ZEND_ACC_PROTECTED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
266+
zend_string_release(property_severity_name);
267+
262268
return class_entry;
263269
}
264270

build/gen_stub.php

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,11 @@ function processStubFile(string $stubFile, Context $context): ?FileInfo {
6666

6767
initPhpParser();
6868
$fileInfo = parseStubFile($stubCode);
69-
$allConstInfos = $fileInfo->getAllConstInfos();
69+
$constInfos = $fileInfo->getAllConstInfos();
70+
$context->allConstInfos = array_merge($context->allConstInfos, $constInfos);
7071

7172
$generatedConstCode = false;
72-
$constCode = generateConstCode($allConstInfos, $stubHash);
73+
$constCode = generateConstCode($constInfos, $stubHash);
7374
if (($context->forceRegeneration || $stubHash !== $oldStubHash) && $constCode !== "" && file_put_contents($constFile, $constCode)) {
7475
echo "Saved $constFile\n";
7576
$generatedConstCode = true;
@@ -78,7 +79,7 @@ function processStubFile(string $stubFile, Context $context): ?FileInfo {
7879
$arginfoCode = generateArgInfoCode(
7980
basename($stubFilenameWithoutExtension),
8081
$fileInfo,
81-
$allConstInfos,
82+
$context->allConstInfos,
8283
$generatedConstCode ? basename($constFile) : null,
8384
$stubHash
8485
);
@@ -99,7 +100,7 @@ function processStubFile(string $stubFile, Context $context): ?FileInfo {
99100
$arginfoCode = generateArgInfoCode(
100101
basename($stubFilenameWithoutExtension),
101102
$legacyFileInfo,
102-
$allConstInfos,
103+
$context->allConstInfos,
103104
$generatedConstCode ? basename($constFile) : null,
104105
$stubHash
105106
);
@@ -137,6 +138,8 @@ class Context {
137138
public $forceParse = false;
138139
/** @var bool */
139140
public $forceRegeneration = false;
141+
/** @var iterable<ConstInfo> */
142+
public iterable $allConstInfos = [];
140143
}
141144

142145
class ArrayType extends SimpleType {
@@ -1493,6 +1496,17 @@ function (Expr $expr) use ($allConstInfos, &$cConstName, &$originatingConst, &$i
14931496
);
14941497
}
14951498

1499+
public static function createFromExpressionRecursively(Expr $expr, ?string $cConstName, iterable $allConstInfos): EvaluatedValue
1500+
{
1501+
$result = self::createFromExpression($expr, $cConstName, $allConstInfos);
1502+
1503+
if ($result->originatingConst !== null) {
1504+
$result = self::createFromExpressionRecursively($result->originatingConst->value, $result->cConstName, $allConstInfos);
1505+
}
1506+
1507+
return $result;
1508+
}
1509+
14961510
public static function null(): EvaluatedValue
14971511
{
14981512
return new self(null, null, null, false);
@@ -1755,8 +1769,7 @@ public function getCDeclaration(iterable $allConstInfos): ?string
17551769
$code .= $value->cConstName;
17561770
} else {
17571771
if ($value->isUnknownConstValue) {
1758-
echo "Skipping C declaration generation for constant $this->name, because it has an unknown constant value\n";
1759-
return "";
1772+
throw new Exception("Cannot generate C declaration for constant $this->name, because it has an unknown constant value");
17601773
}
17611774

17621775
switch ($value->type) {
@@ -1788,7 +1801,6 @@ public function getDeclaration(iterable $allConstInfos): string
17881801
{
17891802
$value = EvaluatedValue::createFromExpression($this->value, $this->cname, $allConstInfos);
17901803
if ($value->isUnknownConstValue) {
1791-
echo "Skipping code generation for constant $this->name, because it has an unknown constant default value\n";
17921804
return "";
17931805
}
17941806

@@ -1817,24 +1829,29 @@ private function getConstDeclaration(string $code, EvaluatedValue $value): strin
18171829
$constName = str_replace('\\', '\\\\', $this->name->__toString());
18181830
$constValue = $value->value;
18191831

1832+
$flags = "CONST_CS | CONST_PERSISTENT";
1833+
if ($this->isDeprecated) {
1834+
$flags .= " | CONST_DEPRECATED";
1835+
}
1836+
18201837
switch ($value->type) {
18211838
case "NULL":
1822-
$code .= " REGISTER_NULL_CONSTANT(\"$constName\", CONST_CS | CONST_PERSISTENT);\n";
1839+
$code .= " REGISTER_NULL_CONSTANT(\"$constName\", $flags);\n";
18231840
break;
18241841
case "boolean":
1825-
$code .= " REGISTER_BOOL_CONSTANT(\"$constName\", " . ($cConstName ?: ($constValue ? "true" : "false")) . ", CONST_CS | CONST_PERSISTENT);\n";
1842+
$code .= " REGISTER_BOOL_CONSTANT(\"$constName\", " . ($cConstName ?: ($constValue ? "true" : "false")) . ", $flags);\n";
18261843
break;
18271844
case "integer":
1828-
$code .= " REGISTER_LONG_CONSTANT(\"$constName\", " . ($cConstName ?: (int) $constValue) . ", CONST_CS | CONST_PERSISTENT);\n";
1845+
$code .= " REGISTER_LONG_CONSTANT(\"$constName\", " . ($cConstName ?: (int) $constValue) . ", $flags);\n";
18291846
break;
18301847
case "double":
1831-
$code .= " REGISTER_DOUBLE_CONSTANT(\"$constName\", " . ($cConstName ?: (int) $constValue) . ", CONST_CS | CONST_PERSISTENT);\n";
1848+
$code .= " REGISTER_DOUBLE_CONSTANT(\"$constName\", " . ($cConstName ?: (int) $constValue) . ", $flags);\n";
18321849
break;
18331850
case "string":
1834-
$code .= " REGISTER_STRING_CONSTANT(\"$constName\", " . ($cConstName ?: '"' . addslashes($constValue) . '"') . ", CONST_CS | CONST_PERSISTENT);\n";
1851+
$code .= " REGISTER_STRING_CONSTANT(\"$constName\", " . ($cConstName ?: '"' . addslashes($constValue) . '"') . ", $flags);\n";
18351852
break;
18361853
default:
1837-
throw new Exception("Not implemented constant type");
1854+
throw new Exception("Unimplemented constant type");
18381855
}
18391856

18401857
return $code;
@@ -1966,13 +1983,16 @@ public function getDeclaration(iterable $allConstInfos): string {
19661983

19671984
$propertyName = $this->name->property;
19681985

1986+
$isUnknownConstValue = false;
19691987
if ($this->defaultValue === null) {
19701988
$defaultValue = EvaluatedValue::null();
19711989
} else {
19721990
$defaultValue = EvaluatedValue::createFromExpression($this->defaultValue, null, $allConstInfos);
1991+
$recursiveDefaultValue = EvaluatedValue::createFromExpressionRecursively($this->defaultValue, null, $allConstInfos);
1992+
$isUnknownConstValue = $recursiveDefaultValue->isUnknownConstValue;
19731993
}
19741994

1975-
if ($defaultValue->isUnknownConstValue) {
1995+
if ($isUnknownConstValue) {
19761996
echo "Skipping code generation for property $this->name, because it has an unknown constant default value\n";
19771997
return "";
19781998
}
@@ -4089,8 +4109,6 @@ function initPhpParser() {
40894109
$funcMap = [];
40904110
/** @var array<string, FuncInfo> $aliasMap */
40914111
$aliasMap = [];
4092-
/** @var iterable<ConstInfo> $constInfo */
4093-
$constInfos = [];
40944112

40954113
foreach ($fileInfos as $fileInfo) {
40964114
foreach ($fileInfo->getAllFuncInfos() as $funcInfo) {
@@ -4106,8 +4124,6 @@ function initPhpParser() {
41064124
foreach ($fileInfo->classInfos as $classInfo) {
41074125
$classMap[$classInfo->name->__toString()] = $classInfo;
41084126
}
4109-
4110-
$constInfos = array_merge($constInfos, $fileInfo->getAllConstInfos());
41114127
}
41124128

41134129
if ($verify) {
@@ -4198,7 +4214,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
41984214
if ($generateClassSynopses) {
41994215
$classSynopsesDirectory = getcwd() . "/classsynopses";
42004216

4201-
$classSynopses = generateClassSynopses($classMap, $constInfos);
4217+
$classSynopses = generateClassSynopses($classMap, $context->allConstInfos);
42024218
if (!empty($classSynopses)) {
42034219
if (!file_exists($classSynopsesDirectory)) {
42044220
mkdir($classSynopsesDirectory);
@@ -4213,7 +4229,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
42134229
}
42144230

42154231
if ($replaceClassSynopses) {
4216-
$classSynopses = replaceClassSynopses($targetSynopses, $classMap, $constInfos);
4232+
$classSynopses = replaceClassSynopses($targetSynopses, $classMap, $context->allConstInfos);
42174233

42184234
foreach ($classSynopses as $filename => $content) {
42194235
if (file_put_contents($filename, $content)) {

0 commit comments

Comments
 (0)