@@ -53,14 +53,21 @@ static zend_object_handlers default_exception_handlers;
5353/* {{{ zend_implement_throwable */
5454static int zend_implement_throwable (zend_class_entry * interface , zend_class_entry * class_type )
5555{
56- if (instanceof_function (class_type , zend_ce_exception ) || instanceof_function (class_type , zend_ce_error )) {
56+ /* zend_ce_exception and zend_ce_error may not be initialized yet when this is caleld (e.g when
57+ * implementing Throwable for Exception itself). Perform a manual inheritance check. */
58+ zend_class_entry * root = class_type ;
59+ while (root -> parent ) {
60+ root = root -> parent ;
61+ }
62+ if (zend_string_equals_literal (root -> name , "Exception" )
63+ || zend_string_equals_literal (root -> name , "Error" )) {
5764 return SUCCESS ;
5865 }
59- zend_error_noreturn (E_ERROR , "Class %s cannot implement interface %s, extend %s or %s instead" ,
66+
67+ zend_error_noreturn (E_ERROR ,
68+ "Class %s cannot implement interface %s, extend Exception or Error instead" ,
6069 ZSTR_VAL (class_type -> name ),
61- ZSTR_VAL (interface -> name ),
62- ZSTR_VAL (zend_ce_exception -> name ),
63- ZSTR_VAL (zend_ce_error -> name ));
70+ ZSTR_VAL (interface -> name ));
6471 return FAILURE ;
6572}
6673/* }}} */
@@ -740,87 +747,50 @@ ZEND_METHOD(Exception, __toString)
740747}
741748/* }}} */
742749
743- static void declare_exception_properties (zend_class_entry * ce )
744- {
745- zval val ;
746-
747- zend_declare_property_string (ce , "message" , sizeof ("message" )- 1 , "" , ZEND_ACC_PROTECTED );
748- zend_declare_property_string (ce , "string" , sizeof ("string" )- 1 , "" , ZEND_ACC_PRIVATE );
749- zend_declare_property_long (ce , "code" , sizeof ("code" )- 1 , 0 , ZEND_ACC_PROTECTED );
750- zend_declare_property_null (ce , "file" , sizeof ("file" )- 1 , ZEND_ACC_PROTECTED );
751- zend_declare_property_null (ce , "line" , sizeof ("line" )- 1 , ZEND_ACC_PROTECTED );
752-
753- ZVAL_EMPTY_ARRAY (& val );
754- zend_declare_typed_property (
755- ce , ZSTR_KNOWN (ZEND_STR_TRACE ), & val , ZEND_ACC_PRIVATE , NULL ,
756- (zend_type ) ZEND_TYPE_INIT_MASK (MAY_BE_ARRAY ));
757-
758- ZVAL_NULL (& val );
759- zend_declare_typed_property (
760- ce , ZSTR_KNOWN (ZEND_STR_PREVIOUS ), & val , ZEND_ACC_PRIVATE , NULL ,
761- (zend_type ) ZEND_TYPE_INIT_CE (zend_ce_throwable , /* allow_null */ 1 , 0 ));
762- }
763-
764750void zend_register_default_exception (void ) /* {{{ */
765751{
766- zend_class_entry ce ;
767-
768- REGISTER_MAGIC_INTERFACE (throwable , Throwable );
769- zend_class_implements (zend_ce_throwable , 1 , zend_ce_stringable );
752+ zend_ce_throwable = register_class_Throwable (zend_ce_stringable );
753+ zend_ce_throwable -> interface_gets_implemented = zend_implement_throwable ;
770754
771755 memcpy (& default_exception_handlers , & std_object_handlers , sizeof (zend_object_handlers ));
772756 default_exception_handlers .clone_obj = NULL ;
773757
774- INIT_CLASS_ENTRY (ce , "Exception" , class_Exception_methods );
775- zend_ce_exception = zend_register_internal_class_ex (& ce , NULL );
758+ zend_ce_exception = register_class_Exception (zend_ce_throwable );
776759 zend_ce_exception -> create_object = zend_default_exception_new ;
777- zend_class_implements (zend_ce_exception , 1 , zend_ce_throwable );
778- declare_exception_properties (zend_ce_exception );
779760
780- INIT_CLASS_ENTRY (ce , "ErrorException" , class_ErrorException_methods );
781- zend_ce_error_exception = zend_register_internal_class_ex (& ce , zend_ce_exception );
761+ zend_ce_error_exception = register_class_ErrorException (zend_ce_exception );
782762 zend_ce_error_exception -> create_object = zend_error_exception_new ;
763+ /* Declared manually because it uses constant E_ERROR. */
783764 zend_declare_property_long (zend_ce_error_exception , "severity" , sizeof ("severity" )- 1 , E_ERROR , ZEND_ACC_PROTECTED );
784765
785- INIT_CLASS_ENTRY (ce , "Error" , class_Error_methods );
786- zend_ce_error = zend_register_internal_class_ex (& ce , NULL );
766+ zend_ce_error = register_class_Error (zend_ce_throwable );
787767 zend_ce_error -> create_object = zend_default_exception_new ;
788- zend_class_implements (zend_ce_error , 1 , zend_ce_throwable );
789- declare_exception_properties (zend_ce_error );
790768
791- INIT_CLASS_ENTRY (ce , "CompileError" , class_CompileError_methods );
792- zend_ce_compile_error = zend_register_internal_class_ex (& ce , zend_ce_error );
769+ zend_ce_compile_error = register_class_CompileError (zend_ce_error );
793770 zend_ce_compile_error -> create_object = zend_default_exception_new ;
794771
795- INIT_CLASS_ENTRY (ce , "ParseError" , class_ParseError_methods );
796- zend_ce_parse_error = zend_register_internal_class_ex (& ce , zend_ce_compile_error );
772+ zend_ce_parse_error = register_class_ParseError (zend_ce_compile_error );
797773 zend_ce_parse_error -> create_object = zend_default_exception_new ;
798774
799- INIT_CLASS_ENTRY (ce , "TypeError" , class_TypeError_methods );
800- zend_ce_type_error = zend_register_internal_class_ex (& ce , zend_ce_error );
775+ zend_ce_type_error = register_class_TypeError (zend_ce_error );
801776 zend_ce_type_error -> create_object = zend_default_exception_new ;
802777
803- INIT_CLASS_ENTRY (ce , "ArgumentCountError" , class_ArgumentCountError_methods );
804- zend_ce_argument_count_error = zend_register_internal_class_ex (& ce , zend_ce_type_error );
778+ zend_ce_argument_count_error = register_class_ArgumentCountError (zend_ce_type_error );
805779 zend_ce_argument_count_error -> create_object = zend_default_exception_new ;
806780
807- INIT_CLASS_ENTRY (ce , "ValueError" , class_ValueError_methods );
808- zend_ce_value_error = zend_register_internal_class_ex (& ce , zend_ce_error );
781+ zend_ce_value_error = register_class_ValueError (zend_ce_error );
809782 zend_ce_value_error -> create_object = zend_default_exception_new ;
810783
811- INIT_CLASS_ENTRY (ce , "ArithmeticError" , class_ArithmeticError_methods );
812- zend_ce_arithmetic_error = zend_register_internal_class_ex (& ce , zend_ce_error );
784+ zend_ce_arithmetic_error = register_class_ArithmeticError (zend_ce_error );
813785 zend_ce_arithmetic_error -> create_object = zend_default_exception_new ;
814786
815- INIT_CLASS_ENTRY (ce , "DivisionByZeroError" , class_DivisionByZeroError_methods );
816- zend_ce_division_by_zero_error = zend_register_internal_class_ex (& ce , zend_ce_arithmetic_error );
787+ zend_ce_division_by_zero_error = register_class_DivisionByZeroError (zend_ce_arithmetic_error );
817788 zend_ce_division_by_zero_error -> create_object = zend_default_exception_new ;
818789
819- INIT_CLASS_ENTRY (zend_ce_unwind_exit , "UnwindExit" , NULL );
820-
821- INIT_CLASS_ENTRY (ce , "UnhandledMatchError" , NULL );
822- zend_ce_unhandled_match_error = zend_register_internal_class_ex (& ce , zend_ce_error );
790+ zend_ce_unhandled_match_error = register_class_UnhandledMatchError (zend_ce_error );
823791 zend_ce_unhandled_match_error -> create_object = zend_default_exception_new ;
792+
793+ INIT_CLASS_ENTRY (zend_ce_unwind_exit , "UnwindExit" , NULL );
824794}
825795/* }}} */
826796
0 commit comments