@@ -3825,6 +3825,63 @@ static void preload_error_cb(int type, zend_string *error_filename, const uint32
3825
3825
}
3826
3826
}
3827
3827
3828
+ /* Remove DECLARE opcodes and dynamic defs. */
3829
+ static void preload_remove_declares (zend_op_array * op_array )
3830
+ {
3831
+ zend_op * opline = op_array -> opcodes ;
3832
+ zend_op * end = opline + op_array -> last ;
3833
+ uint32_t skip_dynamic_func_count = 0 ;
3834
+ zend_string * key ;
3835
+ zend_op_array * func ;
3836
+
3837
+ while (opline != end ) {
3838
+ switch (opline -> opcode ) {
3839
+ case ZEND_DECLARE_CLASS :
3840
+ case ZEND_DECLARE_CLASS_DELAYED :
3841
+ key = Z_STR_P (RT_CONSTANT (opline , opline -> op1 ) + 1 );
3842
+ if (!zend_hash_exists (CG (class_table ), key )) {
3843
+ MAKE_NOP (opline );
3844
+ }
3845
+ break ;
3846
+ case ZEND_DECLARE_FUNCTION :
3847
+ opline -> op2 .num -= skip_dynamic_func_count ;
3848
+ key = Z_STR_P (RT_CONSTANT (opline , opline -> op1 ));
3849
+ func = zend_hash_find_ptr (EG (function_table ), key );
3850
+ if (func && func == op_array -> dynamic_func_defs [opline -> op2 .num ]) {
3851
+ zend_op_array * * dynamic_func_defs ;
3852
+
3853
+ op_array -> num_dynamic_func_defs -- ;
3854
+ if (op_array -> num_dynamic_func_defs == 0 ) {
3855
+ dynamic_func_defs = NULL ;
3856
+ } else {
3857
+ dynamic_func_defs = emalloc (sizeof (zend_op_array * ) * op_array -> num_dynamic_func_defs );
3858
+ if (opline -> op2 .num > 0 ) {
3859
+ memcpy (
3860
+ dynamic_func_defs ,
3861
+ op_array -> dynamic_func_defs ,
3862
+ sizeof (zend_op_array * ) * opline -> op2 .num );
3863
+ }
3864
+ if (op_array -> num_dynamic_func_defs - opline -> op2 .num > 0 ) {
3865
+ memcpy (
3866
+ dynamic_func_defs + opline -> op2 .num ,
3867
+ op_array -> dynamic_func_defs + (opline -> op2 .num + 1 ),
3868
+ sizeof (zend_op_array * ) * (op_array -> num_dynamic_func_defs - opline -> op2 .num ));
3869
+ }
3870
+ }
3871
+ efree (op_array -> dynamic_func_defs );
3872
+ op_array -> dynamic_func_defs = dynamic_func_defs ;
3873
+ skip_dynamic_func_count ++ ;
3874
+ MAKE_NOP (opline );
3875
+ }
3876
+ break ;
3877
+ case ZEND_DECLARE_LAMBDA_FUNCTION :
3878
+ opline -> op2 .num -= skip_dynamic_func_count ;
3879
+ break ;
3880
+ }
3881
+ opline ++ ;
3882
+ }
3883
+ }
3884
+
3828
3885
static void preload_link (void )
3829
3886
{
3830
3887
zval * zv ;
@@ -3965,9 +4022,7 @@ static void preload_link(void)
3965
4022
ZEND_HASH_FOREACH_STR_KEY_VAL_FROM (
3966
4023
EG (class_table ), key , zv , EG (persistent_classes_count )) {
3967
4024
ce = Z_PTR_P (zv );
3968
- if (ce -> type == ZEND_INTERNAL_CLASS ) {
3969
- break ;
3970
- }
4025
+ ZEND_ASSERT (ce -> type != ZEND_INTERNAL_CLASS );
3971
4026
if ((ce -> ce_flags & (ZEND_ACC_TOP_LEVEL |ZEND_ACC_ANON_CLASS ))
3972
4027
&& !(ce -> ce_flags & ZEND_ACC_LINKED )) {
3973
4028
zend_string * lcname = zend_string_tolower (ce -> name );
@@ -3995,59 +4050,9 @@ static void preload_link(void)
3995
4050
3996
4051
zend_hash_destroy (& errors );
3997
4052
3998
- /* Remove DECLARE opcodes */
3999
4053
ZEND_HASH_FOREACH_PTR (preload_scripts , script ) {
4000
4054
zend_op_array * op_array = & script -> script .main_op_array ;
4001
- zend_op * opline = op_array -> opcodes ;
4002
- zend_op * end = opline + op_array -> last ;
4003
- uint32_t skip_dynamic_func_count = 0 ;
4004
-
4005
- while (opline != end ) {
4006
- switch (opline -> opcode ) {
4007
- case ZEND_DECLARE_CLASS :
4008
- case ZEND_DECLARE_CLASS_DELAYED :
4009
- key = Z_STR_P (RT_CONSTANT (opline , opline -> op1 ) + 1 );
4010
- if (!zend_hash_exists (CG (class_table ), key )) {
4011
- MAKE_NOP (opline );
4012
- }
4013
- break ;
4014
- case ZEND_DECLARE_FUNCTION :
4015
- opline -> op2 .num -= skip_dynamic_func_count ;
4016
- key = Z_STR_P (RT_CONSTANT (opline , opline -> op1 ));
4017
- zv = zend_hash_find (EG (function_table ), key );
4018
- if (zv && Z_PTR_P (zv ) == op_array -> dynamic_func_defs [opline -> op2 .num ]) {
4019
- zend_op_array * * dynamic_func_defs ;
4020
-
4021
- op_array -> num_dynamic_func_defs -- ;
4022
- if (op_array -> num_dynamic_func_defs == 0 ) {
4023
- dynamic_func_defs = NULL ;
4024
- } else {
4025
- dynamic_func_defs = emalloc (sizeof (zend_op_array * ) * op_array -> num_dynamic_func_defs );
4026
- if (opline -> op2 .num > 0 ) {
4027
- memcpy (
4028
- dynamic_func_defs ,
4029
- op_array -> dynamic_func_defs ,
4030
- sizeof (zend_op_array * ) * opline -> op2 .num );
4031
- }
4032
- if (op_array -> num_dynamic_func_defs - opline -> op2 .num > 0 ) {
4033
- memcpy (
4034
- dynamic_func_defs + opline -> op2 .num ,
4035
- op_array -> dynamic_func_defs + (opline -> op2 .num + 1 ),
4036
- sizeof (zend_op_array * ) * (op_array -> num_dynamic_func_defs - opline -> op2 .num ));
4037
- }
4038
- }
4039
- efree (op_array -> dynamic_func_defs );
4040
- op_array -> dynamic_func_defs = dynamic_func_defs ;
4041
- skip_dynamic_func_count ++ ;
4042
- MAKE_NOP (opline );
4043
- }
4044
- break ;
4045
- case ZEND_DECLARE_LAMBDA_FUNCTION :
4046
- opline -> op2 .num -= skip_dynamic_func_count ;
4047
- break ;
4048
- }
4049
- opline ++ ;
4050
- }
4055
+ preload_remove_declares (op_array );
4051
4056
4052
4057
if (op_array -> fn_flags & ZEND_ACC_EARLY_BINDING ) {
4053
4058
script -> script .first_early_binding_opline = zend_build_delayed_early_binding_list (op_array );
@@ -4056,6 +4061,16 @@ static void preload_link(void)
4056
4061
}
4057
4062
}
4058
4063
} ZEND_HASH_FOREACH_END ();
4064
+
4065
+ /* Dynamic defs inside methods need to be removed as well. */
4066
+ ZEND_HASH_FOREACH_PTR_FROM (EG (class_table ), ce , EG (persistent_classes_count )) {
4067
+ zend_op_array * op_array ;
4068
+ ZEND_HASH_FOREACH_PTR (& ce -> function_table , op_array ) {
4069
+ if (op_array -> type == ZEND_USER_FUNCTION ) {
4070
+ preload_remove_declares (op_array );
4071
+ }
4072
+ } ZEND_HASH_FOREACH_END ();
4073
+ } ZEND_HASH_FOREACH_END ();
4059
4074
}
4060
4075
4061
4076
static zend_string * preload_resolve_path (zend_string * filename )
0 commit comments