@@ -3069,19 +3069,26 @@ class StringBuilder {
30693069     * @param string $varName 
30703070     * @param string $strContent 
30713071     * @param ?int $minPHPCompatibility 
3072+      * @param bool $interned 
30723073     * @return string[] 
30733074     */ 
30743075    public  static  function  getString (
30753076        string  $ varName ,
30763077        string  $ content ,
3077-         ?int  $ minPHPCompatibility
3078+         ?int  $ minPHPCompatibility ,
3079+         bool  $ interned  = false 
30783080    ): array  {
30793081        // Generally strings will not be known 
3082+         $ initFn  = $ interned  ? 'zend_string_init_interned '  : 'zend_string_init ' ;
30803083        $ result  = [
3081-             "\tzend_string * $ varName = zend_string_init ( \"$ content \", sizeof( \"$ content \") - 1, 1); \n" ,
3084+             "\tzend_string * $ varName =  $ initFn ( \"$ content \", sizeof( \"$ content \") - 1, 1); \n" ,
30823085            $ varName ,
30833086            "\tzend_string_release( $ varName); \n" 
30843087        ];
3088+         // For attribute values that are not freed 
3089+         if  ($ varName  === '' ) {
3090+             $ result [0 ] = "$ initFn( \"$ content \", sizeof( \"$ content \") - 1, 1); \n" ;
3091+         }
30853092        // If not set, use the current latest version 
30863093        $ allVersions  = ALL_PHP_VERSION_IDS ;
30873094        $ minPhp  = $ minPHPCompatibility  ?? end ($ allVersions );
@@ -3338,40 +3345,36 @@ public function __construct(string $class, array $args) {
33383345
33393346    /** @param array<string, ConstInfo> $allConstInfos */ 
33403347    public  function  generateCode (string  $ invocation , string  $ nameSuffix , array  $ allConstInfos , ?int  $ phpVersionIdMinimumCompatibility ): string  {
3341-         $ php82MinimumCompatibility  = $ phpVersionIdMinimumCompatibility  === null  || $ phpVersionIdMinimumCompatibility  >= PHP_82_VERSION_ID ;
3342-         $ php84MinimumCompatibility  = $ phpVersionIdMinimumCompatibility  === null  || $ phpVersionIdMinimumCompatibility  >= PHP_84_VERSION_ID ;
3343-         /* see ZEND_KNOWN_STRINGS in Zend/strings.h */ 
3344-         $ knowns  = [
3345-             "message "  => "ZEND_STR_MESSAGE " ,
3346-         ];
3347-         if  ($ php82MinimumCompatibility ) {
3348-             $ knowns ["SensitiveParameter " ] = "ZEND_STR_SENSITIVEPARAMETER " ;
3349-         }
3350-         if  ($ php84MinimumCompatibility ) {
3351-             $ knowns ["Deprecated " ] = "ZEND_STR_DEPRECATED_CAPITALIZED " ;
3352-             $ knowns ["since " ] = "ZEND_STR_SINCE " ;
3353-         }
3354- 
3355-         $ code  = "\n" ;
33563348        $ escapedAttributeName  = strtr ($ this  ->class , '\\' , '_ ' );
3357-         if  (isset ($ knowns [$ escapedAttributeName ])) {
3358-             $ code  .= "\t"  . ($ this  ->args  ? "zend_attribute *attribute_ {$ escapedAttributeName }_ $ nameSuffix =  "  : "" ) . "$ invocation, ZSTR_KNOWN( {$ knowns [$ escapedAttributeName ]}),  "  . count ($ this  ->args ) . "); \n" ;
3359-         } else  {
3360-             $ code  .= "\tzend_string *attribute_name_ {$ escapedAttributeName }_ $ nameSuffix = zend_string_init_interned( \""  . addcslashes ($ this  ->class , "\\" ) . "\", sizeof( \""  . addcslashes ($ this  ->class , "\\" ) . "\") - 1, 1); \n" ;
3361-             $ code  .= "\t"  . ($ this  ->args  ? "zend_attribute *attribute_ {$ escapedAttributeName }_ $ nameSuffix =  "  : "" ) . "$ invocation, attribute_name_ {$ escapedAttributeName }_ $ nameSuffix,  "  . count ($ this  ->args ) . "); \n" ;
3362-             $ code  .= "\tzend_string_release(attribute_name_ {$ escapedAttributeName }_ $ nameSuffix); \n" ;
3363-         }
3349+         [$ stringInit , $ nameCode , $ stringRelease ] = StringBuilder::getString (
3350+             "attribute_name_ {$ escapedAttributeName }_ $ nameSuffix " ,
3351+             addcslashes ($ this  ->class , "\\" ),
3352+             $ phpVersionIdMinimumCompatibility ,
3353+             true 
3354+         );
3355+         $ code  = "\n" ;
3356+         $ code  .= $ stringInit ;
3357+         $ code  .= "\t"  . ($ this  ->args  ? "zend_attribute *attribute_ {$ escapedAttributeName }_ $ nameSuffix =  "  : "" ) . "$ invocation,  $ nameCode,  "  . count ($ this  ->args ) . "); \n" ;
3358+         $ code  .= $ stringRelease ;
3359+ 
33643360        foreach  ($ this  ->args  as  $ i  => $ arg ) {
33653361            $ value  = EvaluatedValue::createFromExpression ($ arg ->value , null , null , $ allConstInfos );
33663362            $ zvalName  = "attribute_ {$ escapedAttributeName }_ {$ nameSuffix }_arg $ i " ;
33673363            $ code  .= $ value ->initializeZval ($ zvalName );
33683364            $ code  .= "\tZVAL_COPY_VALUE(&attribute_ {$ escapedAttributeName }_ {$ nameSuffix }->args[ $ i].value, & $ zvalName); \n" ;
33693365            if  ($ arg ->name ) {
3370-                 if  (isset ($ knowns [$ arg ->name ->name ])) {
3371-                     $ code  .= "\tattribute_ {$ escapedAttributeName }_ {$ nameSuffix }->args[ $ i].name = ZSTR_KNOWN( {$ knowns [$ arg ->name ->name ]}); \n" ;
3366+                 [$ stringInit , $ nameCode , $ stringRelease ] = StringBuilder::getString (
3367+                     "" ,
3368+                     $ arg ->name ->name ,
3369+                     $ phpVersionIdMinimumCompatibility ,
3370+                     true 
3371+                 );
3372+                 if  ($ stringInit  === '' ) {
3373+                     $ nameCode  .= "; \n" ;
33723374                } else  {
3373-                     $ code  .=  "\t attribute_ { $ escapedAttributeName } _ { $ nameSuffix } ->args[ $ i ].name = zend_string_init_interned( \"{ $ arg -> name -> name }\" , sizeof( \"{ $ arg -> name -> name }\" ) - 1, 1); \n"  ;
3375+                     $ nameCode  =  $ stringInit  ;
33743376                }
3377+                 $ code  .= "\tattribute_ {$ escapedAttributeName }_ {$ nameSuffix }->args[ $ i].name =  $ nameCode " ;
33753378            }
33763379        }
33773380        return  $ code ;
0 commit comments