@@ -6010,6 +6010,24 @@ static void zend_check_magic_method_attr(uint32_t attr, const char* method, zend
60106010}
60116011/* }}} */
60126012
6013+ static void add_stringable_interface (zend_class_entry * ce ) {
6014+ for (uint32_t i = 0 ; i < ce -> num_interfaces ; i ++ ) {
6015+ if (zend_string_equals_literal (ce -> interface_names [i ].lc_name , "stringable" )) {
6016+ /* Interface already explicitly implemented */
6017+ return ;
6018+ }
6019+ }
6020+
6021+ ce -> num_interfaces ++ ;
6022+ ce -> interface_names =
6023+ erealloc (ce -> interface_names , sizeof (zend_class_name ) * ce -> num_interfaces );
6024+ // TODO: Add known interned strings instead?
6025+ ce -> interface_names [ce -> num_interfaces - 1 ].name =
6026+ zend_string_init ("Stringable" , sizeof ("Stringable" ) - 1 , 0 );
6027+ ce -> interface_names [ce -> num_interfaces - 1 ].lc_name =
6028+ zend_string_init ("stringable" , sizeof ("stringable" ) - 1 , 0 );
6029+ }
6030+
60136031void zend_begin_method_decl (zend_op_array * op_array , zend_string * name , zend_bool has_body ) /* {{{ */
60146032{
60156033 zend_class_entry * ce = CG (active_class_entry );
@@ -6091,6 +6109,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
60916109 } else if (zend_string_equals_literal (lcname , ZEND_TOSTRING_FUNC_NAME )) {
60926110 zend_check_magic_method_attr (fn_flags , "__toString" , 0 );
60936111 ce -> __tostring = (zend_function * ) op_array ;
6112+ add_stringable_interface (ce );
60946113 } else if (zend_string_equals_literal (lcname , ZEND_INVOKE_FUNC_NAME )) {
60956114 zend_check_magic_method_attr (fn_flags , "__invoke" , 0 );
60966115 } else if (zend_string_equals_literal (lcname , ZEND_DEBUGINFO_FUNC_NAME )) {
@@ -6613,6 +6632,10 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
66136632
66146633 CG (active_class_entry ) = ce ;
66156634
6635+ if (implements_ast ) {
6636+ zend_compile_implements (implements_ast );
6637+ }
6638+
66166639 zend_compile_stmt (stmt_ast );
66176640
66186641 /* Reset lineno for final opcodes and errors */
@@ -6652,10 +6675,6 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
66526675 }
66536676 }
66546677
6655- if (implements_ast ) {
6656- zend_compile_implements (implements_ast );
6657- }
6658-
66596678 if ((ce -> ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |ZEND_ACC_INTERFACE |ZEND_ACC_TRAIT |ZEND_ACC_EXPLICIT_ABSTRACT_CLASS )) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ) {
66606679 zend_verify_abstract_class (ce );
66616680 }
0 commit comments