@@ -1830,7 +1830,7 @@ protected function getFieldSynopsisValueString(iterable $allConstInfos): ?string
1830
1830
{
1831
1831
$ value = EvaluatedValue::createFromExpression ($ this ->value , null , $ this ->cname , $ allConstInfos );
1832
1832
if ($ value ->originatingConst ) {
1833
- return $ value ->originatingConst ->name -> __toString ( );
1833
+ return $ value ->originatingConst ->getFieldSynopsisValueString ( $ allConstInfos );
1834
1834
}
1835
1835
1836
1836
return $ this ->valueString ;
@@ -1846,11 +1846,6 @@ public function getDeclaration(iterable $allConstInfos): string
1846
1846
throw new Exception ("Constant " . $ this ->name ->__toString () . " must have a simple built-in type " );
1847
1847
}
1848
1848
1849
- $ value = EvaluatedValue::createFromExpression ($ this ->value , $ type , $ this ->cname , $ allConstInfos );
1850
- if (!$ value ->isUnknownConstValue && !$ value ->originatingConst ) {
1851
- throw new Exception ("Constant " . $ this ->name ->__toString () . " must have either UNKNOWN or a constant value " );
1852
- }
1853
-
1854
1849
$ value = EvaluatedValue::createFromExpression ($ this ->value , $ type , $ this ->cname , $ allConstInfos );
1855
1850
if ($ value ->isUnknownConstValue && !$ value ->cConstName ) {
1856
1851
throw new Exception ("Constant " . $ this ->name ->__toString () . " must have a @cname annotation " );
@@ -1863,10 +1858,11 @@ public function getDeclaration(iterable $allConstInfos): string
1863
1858
}
1864
1859
1865
1860
if ($ this ->name ->isClassConst ()) {
1866
- $ code .= $ this ->getClassConstDeclaration ($ code , $ value , $ allConstInfos );
1861
+ $ code .= $ this ->getClassConstDeclaration ($ value , $ allConstInfos );
1867
1862
} else {
1868
- $ code .= $ this ->getConstDeclaration ( $ code , $ value , $ allConstInfos );
1863
+ $ code .= $ this ->getGlobalConstDeclaration ( $ value , $ allConstInfos );
1869
1864
}
1865
+ $ code .= $ this ->getValueAssertion ($ value );
1870
1866
1871
1867
if ($ this ->cond ) {
1872
1868
$ code .= "#endif \n" ;
@@ -1878,7 +1874,7 @@ public function getDeclaration(iterable $allConstInfos): string
1878
1874
/**
1879
1875
* @param iterable<ConstInfo> $allConstInfos
1880
1876
*/
1881
- private function getConstDeclaration ( string $ code , EvaluatedValue $ value , iterable $ allConstInfos ): string
1877
+ private function getGlobalConstDeclaration ( EvaluatedValue $ value , iterable $ allConstInfos ): string
1882
1878
{
1883
1879
$ constName = str_replace ('\\' , '\\\\' , $ this ->name ->__toString ());
1884
1880
$ constValue = $ value ->value ;
@@ -1888,34 +1884,38 @@ private function getConstDeclaration(string $code, EvaluatedValue $value, iterab
1888
1884
if ($ this ->isDeprecated ) {
1889
1885
$ flags .= " | CONST_DEPRECATED " ;
1890
1886
}
1891
-
1892
1887
if ($ value ->type ->isNull ()) {
1893
- $ code .= " REGISTER_NULL_CONSTANT( \"$ constName \", $ flags); \n" ;
1894
- } elseif ($ value ->type ->isBool ()) {
1895
- $ code .= " REGISTER_BOOL_CONSTANT( \"$ constName \", " . ($ cConstValue ?: ($ constValue ? "true " : "false " )) . ", $ flags); \n" ;
1896
- } elseif ($ value ->type ->isInt ()) {
1897
- $ code .= " REGISTER_LONG_CONSTANT( \"$ constName \", " . ($ cConstValue ?: (int ) $ constValue ) . ", $ flags); \n" ;
1898
- } elseif ($ value ->type ->isFloat ()) {
1899
- $ code .= " REGISTER_DOUBLE_CONSTANT( \"$ constName \", " . ($ cConstValue ?: (int ) $ constValue ) . ", $ flags); \n" ;
1900
- } elseif ($ value ->type ->isString ()) {
1901
- $ code .= " REGISTER_STRING_CONSTANT( \"$ constName \", " . ($ cConstValue ?: '" ' . addslashes ($ constValue ) . '" ' ) . ", $ flags); \n" ;
1902
- } else {
1903
- throw new Exception ("Unimplemented constant type " );
1888
+ return " REGISTER_NULL_CONSTANT( \"$ constName \", $ flags); \n" ;
1904
1889
}
1905
1890
1906
- return $ code ;
1907
- }
1891
+ if ($ value ->type ->isBool ()) {
1892
+ return " REGISTER_BOOL_CONSTANT( \"$ constName \", " . ($ cConstValue ?: ($ constValue ? "true " : "false " )) . ", $ flags); \n" ;
1893
+ }
1894
+
1895
+ if ($ value ->type ->isInt ()) {
1896
+ return " REGISTER_LONG_CONSTANT( \"$ constName \", " . ($ cConstValue ?: (int ) $ constValue ) . ", $ flags); \n" ;
1897
+ }
1898
+
1899
+ if ($ value ->type ->isFloat ()) {
1900
+ return " REGISTER_DOUBLE_CONSTANT( \"$ constName \", " . ($ cConstValue ?: (float ) $ constValue ) . ", $ flags); \n" ;
1901
+ }
1902
+
1903
+ if ($ value ->type ->isString ()) {
1904
+ return " REGISTER_STRING_CONSTANT( \"$ constName \", " . ($ cConstValue ?: '" ' . addslashes ($ constValue ) . '" ' ) . ", $ flags); \n" ;
1905
+ }
1906
+
1907
+ throw new Exception ("Unimplemented constant type " );}
1908
1908
1909
1909
/**
1910
1910
* @param iterable<ConstInfo> $allConstInfos
1911
1911
*/
1912
- private function getClassConstDeclaration (string $ code , EvaluatedValue $ value , iterable $ allConstInfos ): string
1912
+ private function getClassConstDeclaration (EvaluatedValue $ value , iterable $ allConstInfos ): string
1913
1913
{
1914
1914
$ constName = $ this ->getVariableLikeName ();
1915
1915
1916
1916
$ zvalCode = $ value ->initializeZval ("const_ {$ constName }_value " , $ allConstInfos );
1917
1917
1918
- $ code . = "\n" . $ zvalCode ;
1918
+ $ code = "\n" . $ zvalCode ;
1919
1919
1920
1920
$ code .= "\tzend_string *const_ {$ constName }_name = zend_string_init_interned( \"$ constName \", sizeof( \"$ constName \") - 1, 1); \n" ;
1921
1921
$ nameCode = "const_ {$ constName }_name " ;
@@ -1926,6 +1926,42 @@ private function getClassConstDeclaration(string $code, EvaluatedValue $value, i
1926
1926
return $ code ;
1927
1927
}
1928
1928
1929
+ private function getValueAssertion (EvaluatedValue $ value ): string
1930
+ {
1931
+ if ($ value ->isUnknownConstValue || $ value ->originatingConst || $ value ->cConstName === null ) {
1932
+ return "" ;
1933
+ }
1934
+
1935
+ $ cName = $ value ->cConstName ;
1936
+ $ constValue = $ value ->value ;
1937
+
1938
+ if ($ value ->type ->isNull ()) {
1939
+ return " ZEND_ASSERT( $ cName == NULL); \n" ;
1940
+ }
1941
+
1942
+ if ($ value ->type ->isBool ()) {
1943
+ $ cValue = $ constValue ? "true " : "false " ;
1944
+ return " ZEND_ASSERT( $ cName == $ cValue); \n" ;
1945
+ }
1946
+
1947
+ if ($ value ->type ->isInt ()) {
1948
+ $ cValue = (int ) $ constValue ;
1949
+ return " ZEND_ASSERT( $ cName == $ cValue); \n" ;
1950
+ }
1951
+
1952
+ if ($ value ->type ->isFloat ()) {
1953
+ $ cValue = (float ) $ constValue ;
1954
+ return " ZEND_ASSERT( $ cName == $ cValue); \n" ;
1955
+ }
1956
+
1957
+ if ($ value ->type ->isString ()) {
1958
+ $ cValue = '" ' . addslashes ($ constValue ) . '" ' ;
1959
+ return " ZEND_ASSERT(strcmp( $ cName, $ cValue) == 0); \n" ;
1960
+ }
1961
+
1962
+ throw new Exception ("Unimplemented constant type " );
1963
+ }
1964
+
1929
1965
protected function getFlagsAsString (): string
1930
1966
{
1931
1967
$ flags = parent ::getFlagsAsString ();
0 commit comments