@@ -6010,6 +6010,25 @@ 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 -> ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES ;
6022+ ce -> num_interfaces ++ ;
6023+ ce -> interface_names =
6024+ erealloc (ce -> interface_names , sizeof (zend_class_name ) * ce -> num_interfaces );
6025+ // TODO: Add known interned strings instead?
6026+ ce -> interface_names [ce -> num_interfaces - 1 ].name =
6027+ zend_string_init ("Stringable" , sizeof ("Stringable" ) - 1 , 0 );
6028+ ce -> interface_names [ce -> num_interfaces - 1 ].lc_name =
6029+ zend_string_init ("stringable" , sizeof ("stringable" ) - 1 , 0 );
6030+ }
6031+
60136032void zend_begin_method_decl (zend_op_array * op_array , zend_string * name , zend_bool has_body ) /* {{{ */
60146033{
60156034 zend_class_entry * ce = CG (active_class_entry );
@@ -6091,6 +6110,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
60916110 } else if (zend_string_equals_literal (lcname , ZEND_TOSTRING_FUNC_NAME )) {
60926111 zend_check_magic_method_attr (fn_flags , "__toString" , 0 );
60936112 ce -> __tostring = (zend_function * ) op_array ;
6113+ add_stringable_interface (ce );
60946114 } else if (zend_string_equals_literal (lcname , ZEND_INVOKE_FUNC_NAME )) {
60956115 zend_check_magic_method_attr (fn_flags , "__invoke" , 0 );
60966116 } else if (zend_string_equals_literal (lcname , ZEND_DEBUGINFO_FUNC_NAME )) {
@@ -6616,6 +6636,10 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
66166636
66176637 CG (active_class_entry ) = ce ;
66186638
6639+ if (implements_ast ) {
6640+ zend_compile_implements (implements_ast );
6641+ }
6642+
66196643 zend_compile_stmt (stmt_ast );
66206644
66216645 /* Reset lineno for final opcodes and errors */
@@ -6655,10 +6679,6 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
66556679 }
66566680 }
66576681
6658- if (implements_ast ) {
6659- zend_compile_implements (implements_ast );
6660- }
6661-
66626682 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 ) {
66636683 zend_verify_abstract_class (ce );
66646684 }
0 commit comments