@@ -619,34 +619,34 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
619
619
620
620
static zend_bool do_inherit_method_check (HashTable * child_function_table , zend_function * parent , zend_string * key , zend_class_entry * child_ce ) /* {{{ */
621
621
{
622
- uint32_t parent_flags = parent -> common .fn_flags ;
623
- zend_function * child ;
622
+ zval * child = zend_hash_find (child_function_table , key );
624
623
625
- if (( child = zend_hash_find_ptr ( child_function_table , key )) == NULL ) {
626
- if (parent_flags & (ZEND_ACC_ABSTRACT )) {
624
+ if (child == NULL ) {
625
+ if (parent -> common . fn_flags & (ZEND_ACC_ABSTRACT )) {
627
626
child_ce -> ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ;
628
627
}
629
628
return 1 ; /* method doesn't exist in child, copy from parent */
630
629
}
631
630
632
- do_inheritance_check_on_method (child , parent );
631
+ do_inheritance_check_on_method (( zend_function * ) Z_PTR_P ( child ) , parent );
633
632
634
633
return 0 ;
635
634
}
636
635
/* }}} */
637
636
638
637
static void do_inherit_property (zend_property_info * parent_info , zend_string * key , zend_class_entry * ce ) /* {{{ */
639
638
{
640
- zend_property_info * child_info = zend_hash_find_ptr (& ce -> properties_info , key );
641
- zend_class_entry * parent_ce = ce -> parent ;
639
+ zval * child = zend_hash_find (& ce -> properties_info , key );
640
+ zend_property_info * child_info ;
642
641
643
- if (UNEXPECTED (child_info )) {
642
+ if (UNEXPECTED (child )) {
643
+ child_info = Z_PTR_P (child );
644
644
if (parent_info -> flags & (ZEND_ACC_PRIVATE |ZEND_ACC_SHADOW )) {
645
645
child_info -> flags |= ZEND_ACC_CHANGED ;
646
646
} else {
647
647
if ((parent_info -> flags & ZEND_ACC_STATIC ) != (child_info -> flags & ZEND_ACC_STATIC )) {
648
648
zend_error_noreturn (E_COMPILE_ERROR , "Cannot redeclare %s%s::$%s as %s%s::$%s" ,
649
- (parent_info -> flags & ZEND_ACC_STATIC ) ? "static " : "non static " , parent_ce -> name -> val , key -> val ,
649
+ (parent_info -> flags & ZEND_ACC_STATIC ) ? "static " : "non static " , ce -> parent -> name -> val , key -> val ,
650
650
(child_info -> flags & ZEND_ACC_STATIC ) ? "static " : "non static " , ce -> name -> val , key -> val );
651
651
}
652
652
@@ -655,7 +655,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
655
655
}
656
656
657
657
if ((child_info -> flags & ZEND_ACC_PPP_MASK ) > (parent_info -> flags & ZEND_ACC_PPP_MASK )) {
658
- zend_error_noreturn (E_COMPILE_ERROR , "Access level to %s::$%s must be %s (as in class %s)%s" , ce -> name -> val , key -> val , zend_visibility_string (parent_info -> flags ), parent_ce -> name -> val , (parent_info -> flags & ZEND_ACC_PUBLIC ) ? "" : " or weaker" );
658
+ zend_error_noreturn (E_COMPILE_ERROR , "Access level to %s::$%s must be %s (as in class %s)%s" , ce -> name -> val , key -> val , zend_visibility_string (parent_info -> flags ), ce -> parent -> name -> val , (parent_info -> flags & ZEND_ACC_PUBLIC ) ? "" : " or weaker" );
659
659
} else if ((child_info -> flags & ZEND_ACC_STATIC ) == 0 ) {
660
660
int parent_num = OBJ_PROP_TO_NUM (parent_info -> offset );
661
661
int child_num = OBJ_PROP_TO_NUM (child_info -> offset );
@@ -736,28 +736,22 @@ ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_
736
736
}
737
737
/* }}} */
738
738
739
- #ifdef ZTS
740
- # define zval_property_ctor (parent_ce , ce ) \
741
- (((parent_ce)->type != (ce)->type) ? ZVAL_COPY_CTOR : zval_add_ref)
742
- #else
743
- # define zval_property_ctor (parent_ce , ce ) \
744
- zval_add_ref
745
- #endif
746
-
747
739
static void do_inherit_class_constant (zend_string * name , zval * zv , zend_class_entry * ce , zend_class_entry * parent_ce ) /* {{{ */
748
740
{
749
- if (!Z_ISREF_P (zv )) {
750
- if (parent_ce -> type == ZEND_INTERNAL_CLASS ) {
751
- ZVAL_NEW_PERSISTENT_REF (zv , zv );
752
- } else {
753
- ZVAL_NEW_REF (zv , zv );
741
+ if (!zend_hash_exists (& ce -> constants_table , name )) {
742
+ if (!Z_ISREF_P (zv )) {
743
+ if (parent_ce -> type == ZEND_INTERNAL_CLASS ) {
744
+ ZVAL_NEW_PERSISTENT_REF (zv , zv );
745
+ } else {
746
+ ZVAL_NEW_REF (zv , zv );
747
+ }
748
+ }
749
+ if (Z_CONSTANT_P (Z_REFVAL_P (zv ))) {
750
+ ce -> ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED ;
754
751
}
755
- }
756
- if (Z_CONSTANT_P (Z_REFVAL_P (zv ))) {
757
- ce -> ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED ;
758
- }
759
- if (zend_hash_add (& ce -> constants_table , name , zv )) {
760
752
Z_ADDREF_P (zv );
753
+ zend_string_addref (name );
754
+ _zend_hash_append (& ce -> constants_table , name , zv );
761
755
}
762
756
}
763
757
/* }}} */
@@ -774,7 +768,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
774
768
if (!(parent_ce -> ce_flags & ZEND_ACC_INTERFACE )) {
775
769
zend_error_noreturn (E_COMPILE_ERROR , "Interface %s may not inherit from class (%s)" , ce -> name -> val , parent_ce -> name -> val );
776
770
}
777
- } else {
771
+ } else if ( UNEXPECTED ( parent_ce -> ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_FINAL ))) {
778
772
/* Class declaration must not extend traits or interfaces */
779
773
if (parent_ce -> ce_flags & ZEND_ACC_INTERFACE ) {
780
774
zend_error_noreturn (E_COMPILE_ERROR , "Class %s cannot extend from interface %s" , ce -> name -> val , parent_ce -> name -> val );
@@ -888,24 +882,39 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
888
882
}
889
883
} ZEND_HASH_FOREACH_END ();
890
884
891
- zend_hash_extend (& ce -> properties_info ,
892
- zend_hash_num_elements (& ce -> properties_info ) +
893
- zend_hash_num_elements (& parent_ce -> properties_info ), 0 );
885
+ if (zend_hash_num_elements (& parent_ce -> properties_info )) {
886
+ zend_hash_extend (& ce -> properties_info ,
887
+ zend_hash_num_elements (& ce -> properties_info ) +
888
+ zend_hash_num_elements (& parent_ce -> properties_info ), 0 );
894
889
895
- ZEND_HASH_FOREACH_STR_KEY_PTR (& parent_ce -> properties_info , key , property_info ) {
896
- do_inherit_property (property_info , key , ce );
897
- } ZEND_HASH_FOREACH_END ();
890
+ ZEND_HASH_FOREACH_STR_KEY_PTR (& parent_ce -> properties_info , key , property_info ) {
891
+ do_inherit_property (property_info , key , ce );
892
+ } ZEND_HASH_FOREACH_END ();
893
+ }
898
894
899
- ZEND_HASH_FOREACH_STR_KEY_VAL (& parent_ce -> constants_table , key , zv ) {
900
- do_inherit_class_constant (key , zv , ce , parent_ce );
901
- } ZEND_HASH_FOREACH_END ();
895
+ if (zend_hash_num_elements (& parent_ce -> constants_table )) {
896
+ zend_hash_extend (& ce -> constants_table ,
897
+ zend_hash_num_elements (& ce -> constants_table ) +
898
+ zend_hash_num_elements (& parent_ce -> constants_table ), 0 );
902
899
903
- ZEND_HASH_FOREACH_STR_KEY_PTR (& parent_ce -> function_table , key , func ) {
904
- if (do_inherit_method_check (& ce -> function_table , func , key , ce )) {
905
- zend_function * new_func = do_inherit_method (func , ce );
906
- zend_hash_add_new_ptr (& ce -> function_table , key , new_func );
907
- }
908
- } ZEND_HASH_FOREACH_END ();
900
+ ZEND_HASH_FOREACH_STR_KEY_VAL (& parent_ce -> constants_table , key , zv ) {
901
+ do_inherit_class_constant (key , zv , ce , parent_ce );
902
+ } ZEND_HASH_FOREACH_END ();
903
+ }
904
+
905
+ if (zend_hash_num_elements (& parent_ce -> function_table )) {
906
+ zend_hash_extend (& ce -> function_table ,
907
+ zend_hash_num_elements (& ce -> function_table ) +
908
+ zend_hash_num_elements (& parent_ce -> function_table ), 0 );
909
+
910
+ ZEND_HASH_FOREACH_STR_KEY_PTR (& parent_ce -> function_table , key , func ) {
911
+ if (do_inherit_method_check (& ce -> function_table , func , key , ce )) {
912
+ zend_function * new_func = do_inherit_method (func , ce );
913
+ zend_string_addref (key );
914
+ _zend_hash_append_ptr (& ce -> function_table , key , new_func );
915
+ }
916
+ } ZEND_HASH_FOREACH_END ();
917
+ }
909
918
910
919
do_inherit_parent_constructor (ce );
911
920
0 commit comments