@@ -5717,89 +5717,81 @@ static zend_bool zend_is_valid_default_value(zend_type type, zval *value)
5717
5717
return 0 ;
5718
5718
}
5719
5719
5720
- static void zend_compile_attribute (zval * v , zend_ast * ast ) /* {{{ */
5720
+ static zend_attribute * zend_compile_attribute (zend_ast * ast , uint32_t offset ) /* {{{ */
5721
5721
{
5722
5722
ZEND_ASSERT (ast -> kind == ZEND_AST_ATTRIBUTE );
5723
5723
5724
- array_init_size ( v , 1 + ( ast -> child [1 ] ? zend_ast_get_list (ast -> child [1 ])-> children : 0 )) ;
5725
- add_next_index_str ( v , zend_resolve_class_name_ast ( ast -> child [ 0 ] ));
5724
+ zend_ast_list * list = ast -> child [1 ] ? zend_ast_get_list (ast -> child [1 ]) : NULL ;
5725
+ zend_attribute * attr = emalloc ( sizeof ( zend_attribute ) + sizeof ( zval ) * ( list ? list -> children : 0 ));
5726
5726
5727
- if (ast -> child [1 ]) {
5728
- zend_ast_list * list = zend_ast_get_list ( ast -> child [ 1 ] );
5729
- uint32_t i ;
5730
- zval tmp ;
5727
+ attr -> name = zend_resolve_class_name_ast (ast -> child [0 ]);
5728
+ attr -> lcname = zend_string_tolower ( attr -> name );
5729
+ attr -> offset = offset ;
5730
+ attr -> argc = list ? list -> children : 0 ;
5731
5731
5732
+ if (ast -> child [1 ]) {
5732
5733
ZEND_ASSERT (ast -> child [1 ]-> kind == ZEND_AST_ARG_LIST );
5733
5734
5734
- ZVAL_NULL ( & tmp ) ;
5735
+ uint32_t i ;
5735
5736
5736
5737
for (i = 0 ; i < list -> children ; i ++ ) {
5737
- zend_const_expr_to_zval (zend_hash_next_index_insert ( Z_ARRVAL_P ( v ), & tmp ) , list -> child [i ]);
5738
+ zend_const_expr_to_zval (& attr -> argv [ i ] , list -> child [i ]);
5738
5739
}
5739
5740
}
5741
+
5742
+ return attr ;
5740
5743
}
5741
5744
/* }}} */
5742
5745
5743
- static HashTable * zend_compile_attributes ( zend_ast * ast , int target ) /* {{{ */
5746
+ static void attribute_ptr_dtor ( zval * v ) /* {{{ */
5744
5747
{
5745
- HashTable * attr ;
5746
-
5747
- zend_ast_list * list = zend_ast_get_list (ast );
5748
+ zend_attribute * attr = Z_PTR_P (v );
5748
5749
uint32_t i ;
5749
5750
5750
- zval tmp ;
5751
-
5752
- ZVAL_NULL (& tmp );
5751
+ zend_string_release (attr -> name );
5752
+ zend_string_release (attr -> lcname );
5753
5753
5754
- ZEND_ASSERT (ast -> kind == ZEND_AST_ATTRIBUTE_LIST );
5755
-
5756
- ALLOC_HASHTABLE (attr );
5757
- zend_hash_init (attr , zend_ast_get_list (ast )-> children , NULL , ZVAL_PTR_DTOR , 0 );
5758
-
5759
- for (i = 0 ; i < list -> children ; i ++ ) {
5760
- zend_ast * el = list -> child [i ];
5761
- zend_string * name ;
5754
+ for (i = 0 ; i < attr -> argc ; i ++ ) {
5755
+ zval_ptr_dtor (& attr -> argv [i ]);
5756
+ }
5762
5757
5763
- zval a ;
5764
- zval * x ;
5758
+ efree (attr );
5759
+ }
5760
+ /* }}} */
5765
5761
5766
- zend_compile_attribute (& a , el );
5762
+ static zend_always_inline HashTable * create_attribute_array (uint32_t size ) /* {{{ */
5763
+ {
5764
+ HashTable * attributes ;
5767
5765
5768
- name = zend_string_tolower ( Z_STR_P ( zend_hash_index_find ( Z_ARRVAL ( a ), 0 )) );
5769
- x = zend_hash_find ( attr , name );
5766
+ ALLOC_HASHTABLE ( attributes );
5767
+ zend_hash_init ( attributes , size , NULL , attribute_ptr_dtor , 0 );
5770
5768
5771
- // Validate internal attribute
5772
- zend_attributes_internal_validator validator = zend_hash_find_ptr (& zend_attributes_internal_validators , name );
5769
+ return attributes ;
5770
+ }
5771
+ /* }}} */
5773
5772
5774
- if (validator != NULL ) {
5775
- validator (& a , target );
5776
- }
5773
+ static void zend_compile_attributes (HashTable * attributes , zend_ast * ast , uint32_t offset , int target ) /* {{{ */
5774
+ {
5775
+ zend_ast_list * list = zend_ast_get_list (ast );
5776
+ uint32_t i ;
5777
5777
5778
- if (x ) {
5779
- ZEND_ASSERT (Z_TYPE_P (x ) == IS_ARRAY );
5778
+ zval tmp ;
5780
5779
5781
- if (Z_TYPE_P (zend_hash_index_find (Z_ARRVAL_P (x ), 0 )) == IS_ARRAY ) {
5782
- add_next_index_zval (x , & a );
5783
- } else {
5784
- zval array ;
5780
+ ZEND_ASSERT (ast -> kind == ZEND_AST_ATTRIBUTE_LIST );
5785
5781
5786
- ZEND_ASSERT (Z_TYPE_P (zend_hash_index_find (Z_ARRVAL_P (x ), 0 )) == IS_STRING );
5782
+ for (i = 0 ; i < list -> children ; i ++ ) {
5783
+ zend_attribute * attr = zend_compile_attribute (list -> child [i ], 0 );
5787
5784
5788
- Z_ADDREF_P (x );
5785
+ // Validate internal attribute
5786
+ zend_attributes_internal_validator validator = zend_hash_find_ptr (& zend_attributes_internal_validators , attr -> lcname );
5789
5787
5790
- array_init (& array );
5791
- add_next_index_zval (& array , x );
5792
- add_next_index_zval (& array , & a );
5793
- zend_hash_update (attr , name , & array );
5794
- }
5795
- } else {
5796
- zend_hash_add (attr , name , & a );
5788
+ if (validator != NULL ) {
5789
+ validator (attr , target );
5797
5790
}
5798
5791
5799
- zend_string_release (name );
5792
+ ZVAL_PTR (& tmp , attr );
5793
+ zend_hash_next_index_insert (attributes , & tmp );
5800
5794
}
5801
-
5802
- return attr ;
5803
5795
}
5804
5796
/* }}} */
5805
5797
@@ -5908,15 +5900,11 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
5908
5900
arg_info -> type = (zend_type ) ZEND_TYPE_INIT_NONE (0 );
5909
5901
5910
5902
if (attributes_ast ) {
5911
- zval attr ;
5912
-
5913
5903
if (!op_array -> attributes ) {
5914
- ALLOC_HASHTABLE (op_array -> attributes );
5915
- zend_hash_init (op_array -> attributes , 8 , NULL , ZVAL_PTR_DTOR , 0 );
5904
+ op_array -> attributes = create_attribute_array (zend_ast_get_list (attributes_ast )-> children );
5916
5905
}
5917
5906
5918
- ZVAL_ARR (& attr , zend_compile_attributes (attributes_ast , ZEND_ATTRIBUTE_TARGET_PARAMETER ));
5919
- zend_hash_index_add (op_array -> attributes , i , & attr );
5907
+ zend_compile_attributes (op_array -> attributes , attributes_ast , i + 1 , ZEND_ATTRIBUTE_TARGET_PARAMETER );
5920
5908
}
5921
5909
5922
5910
if (type_ast ) {
@@ -6376,10 +6364,12 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
6376
6364
}
6377
6365
if (decl -> attributes ) {
6378
6366
int target = ZEND_ATTRIBUTE_TARGET_FUNCTION ;
6367
+
6379
6368
if (is_method ) {
6380
6369
target = ZEND_ATTRIBUTE_TARGET_METHOD ;
6381
6370
}
6382
- op_array -> attributes = zend_compile_attributes (decl -> attributes , target );
6371
+ op_array -> attributes = create_attribute_array (zend_ast_get_list (decl -> attributes )-> children );
6372
+ zend_compile_attributes (op_array -> attributes , decl -> attributes , 0 , target );
6383
6373
}
6384
6374
if (decl -> kind == ZEND_AST_CLOSURE || decl -> kind == ZEND_AST_ARROW_FUNC ) {
6385
6375
op_array -> fn_flags |= ZEND_ACC_CLOSURE ;
@@ -6548,12 +6538,15 @@ void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags, H
6548
6538
6549
6539
void zend_compile_prop_group (zend_ast * list ) /* {{{ */
6550
6540
{
6551
- HashTable * attributes ;
6541
+ HashTable * attributes = NULL ;
6552
6542
6553
6543
zend_ast * type_ast = list -> child [0 ];
6554
6544
zend_ast * prop_ast = list -> child [1 ];
6555
6545
6556
- attributes = list -> child [2 ] ? zend_compile_attributes (list -> child [2 ], ZEND_ATTRIBUTE_TARGET_PROPERTY ) : NULL ;
6546
+ if (list -> child [2 ]) {
6547
+ attributes = create_attribute_array (zend_ast_get_list (list -> child [2 ])-> children );
6548
+ zend_compile_attributes (attributes , list -> child [2 ], 0 , ZEND_ATTRIBUTE_TARGET_PROPERTY );
6549
+ }
6557
6550
6558
6551
zend_compile_prop_decl (prop_ast , type_ast , list -> attr , attributes );
6559
6552
@@ -6579,15 +6572,18 @@ void zend_compile_class_const_decl(zend_ast *ast, zend_ast *attr_ast) /* {{{ */
6579
6572
{
6580
6573
zend_ast_list * list = zend_ast_get_list (ast );
6581
6574
zend_class_entry * ce = CG (active_class_entry );
6582
- HashTable * attributes ;
6575
+ HashTable * attributes = NULL ;
6583
6576
uint32_t i ;
6584
6577
6585
6578
if ((ce -> ce_flags & ZEND_ACC_TRAIT ) != 0 ) {
6586
6579
zend_error_noreturn (E_COMPILE_ERROR , "Traits cannot have constants" );
6587
6580
return ;
6588
6581
}
6589
6582
6590
- attributes = attr_ast ? zend_compile_attributes (attr_ast , ZEND_ATTRIBUTE_TARGET_CLASS_CONST ) : NULL ;
6583
+ if (attr_ast ) {
6584
+ attributes = create_attribute_array (zend_ast_get_list (attr_ast )-> children );
6585
+ zend_compile_attributes (attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_CLASS_CONST );
6586
+ }
6591
6587
6592
6588
for (i = 0 ; i < list -> children ; ++ i ) {
6593
6589
zend_ast * const_ast = list -> child [i ];
@@ -6818,7 +6814,8 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
6818
6814
ce -> info .user .doc_comment = zend_string_copy (decl -> doc_comment );
6819
6815
}
6820
6816
if (decl -> attributes ) {
6821
- ce -> info .user .attributes = zend_compile_attributes (decl -> attributes , ZEND_ATTRIBUTE_TARGET_CLASS );
6817
+ ce -> info .user .attributes = create_attribute_array (zend_ast_get_list (decl -> attributes )-> children );
6818
+ zend_compile_attributes (ce -> info .user .attributes , decl -> attributes , 0 , ZEND_ATTRIBUTE_TARGET_CLASS );
6822
6819
}
6823
6820
6824
6821
if (UNEXPECTED ((decl -> flags & ZEND_ACC_ANON_CLASS ))) {
0 commit comments