@@ -674,69 +674,6 @@ static void auto_global_dtor(zval *zv) /* {{{ */
674674/* }}} */
675675
676676#ifdef ZTS
677- static void function_copy_ctor (zval * zv ) /* {{{ */
678- {
679- zend_function * old_func = Z_FUNC_P (zv );
680- zend_function * func ;
681-
682- if (old_func -> type == ZEND_USER_FUNCTION ) {
683- ZEND_ASSERT (old_func -> op_array .fn_flags & ZEND_ACC_IMMUTABLE );
684- return ;
685- }
686- func = pemalloc (sizeof (zend_internal_function ), 1 );
687- Z_FUNC_P (zv ) = func ;
688- memcpy (func , old_func , sizeof (zend_internal_function ));
689- function_add_ref (func );
690- if ((old_func -> common .fn_flags & (ZEND_ACC_HAS_RETURN_TYPE |ZEND_ACC_HAS_TYPE_HINTS ))
691- && old_func -> common .arg_info ) {
692- uint32_t i ;
693- uint32_t num_args = old_func -> common .num_args + 1 ;
694- zend_arg_info * arg_info = old_func -> common .arg_info - 1 ;
695- zend_arg_info * new_arg_info ;
696-
697- if (old_func -> common .fn_flags & ZEND_ACC_VARIADIC ) {
698- num_args ++ ;
699- }
700- new_arg_info = pemalloc (sizeof (zend_arg_info ) * num_args , 1 );
701- memcpy (new_arg_info , arg_info , sizeof (zend_arg_info ) * num_args );
702- for (i = 0 ; i < num_args ; i ++ ) {
703- if (ZEND_TYPE_HAS_LIST (arg_info [i ].type )) {
704- zend_type_list * old_list = ZEND_TYPE_LIST (arg_info [i ].type );
705- zend_type_list * new_list = pemalloc (ZEND_TYPE_LIST_SIZE (old_list -> num_types ), 1 );
706- memcpy (new_list , old_list , ZEND_TYPE_LIST_SIZE (old_list -> num_types ));
707- ZEND_TYPE_SET_PTR (new_arg_info [i ].type , new_list );
708-
709- zend_type * list_type ;
710- ZEND_TYPE_LIST_FOREACH (new_list , list_type ) {
711- zend_string * name = zend_string_dup (ZEND_TYPE_NAME (* list_type ), 1 );
712- ZEND_TYPE_SET_PTR (* list_type , name );
713- } ZEND_TYPE_LIST_FOREACH_END ();
714- } else if (ZEND_TYPE_HAS_NAME (arg_info [i ].type )) {
715- zend_string * name = zend_string_dup (ZEND_TYPE_NAME (arg_info [i ].type ), 1 );
716- ZEND_TYPE_SET_PTR (new_arg_info [i ].type , name );
717- }
718- }
719- func -> common .arg_info = new_arg_info + 1 ;
720- }
721- if (old_func -> common .attributes ) {
722- zend_attribute * old_attr ;
723-
724- func -> common .attributes = NULL ;
725-
726- ZEND_HASH_PACKED_FOREACH_PTR (old_func -> common .attributes , old_attr ) {
727- uint32_t i ;
728- zend_attribute * attr ;
729-
730- attr = zend_add_attribute (& func -> common .attributes , old_attr -> name , old_attr -> argc , old_attr -> flags , old_attr -> offset , old_attr -> lineno );
731-
732- for (i = 0 ; i < old_attr -> argc ; i ++ ) {
733- ZVAL_DUP (& attr -> args [i ].value , & old_attr -> args [i ].value );
734- }
735- } ZEND_HASH_FOREACH_END ();
736- }
737- }
738- /* }}} */
739-
740677static void auto_global_copy_ctor (zval * zv ) /* {{{ */
741678{
742679 zend_auto_global * old_ag = (zend_auto_global * ) Z_PTR_P (zv );
@@ -756,7 +693,8 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
756693
757694 compiler_globals -> function_table = (HashTable * ) malloc (sizeof (HashTable ));
758695 zend_hash_init (compiler_globals -> function_table , 1024 , NULL , ZEND_FUNCTION_DTOR , 1 );
759- zend_hash_copy (compiler_globals -> function_table , global_function_table , function_copy_ctor );
696+ zend_hash_copy (compiler_globals -> function_table , global_function_table , NULL );
697+ compiler_globals -> copied_functions_count = zend_hash_num_elements (compiler_globals -> function_table );
760698
761699 compiler_globals -> class_table = (HashTable * ) malloc (sizeof (HashTable ));
762700 zend_hash_init (compiler_globals -> class_table , 64 , NULL , ZEND_CLASS_DTOR , 1 );
@@ -790,6 +728,21 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
790728static void compiler_globals_dtor (zend_compiler_globals * compiler_globals ) /* {{{ */
791729{
792730 if (compiler_globals -> function_table != GLOBAL_FUNCTION_TABLE ) {
731+ uint32_t n = compiler_globals -> copied_functions_count ;
732+
733+ /* Prevent destruction of functions copied from the main process context */
734+ if (zend_hash_num_elements (compiler_globals -> function_table ) <= n ) {
735+ compiler_globals -> function_table -> nNumUsed = 0 ;
736+ } else {
737+ Bucket * p = compiler_globals -> function_table -> arData ;
738+
739+ compiler_globals -> function_table -> nNumOfElements -= n ;
740+ while (n != 0 ) {
741+ ZVAL_UNDEF (& p -> val );
742+ p ++ ;
743+ n -- ;
744+ }
745+ }
793746 zend_hash_destroy (compiler_globals -> function_table );
794747 free (compiler_globals -> function_table );
795748 }
0 commit comments