@@ -579,12 +579,11 @@ zend_result php_json_escape_string(
579579}
580580/* }}} */
581581
582- static zend_result php_json_encode_serializable_object (smart_str * buf , zval * val , int options , php_json_encoder * encoder ) /* {{{ */
582+ static zend_result php_json_encode_serializable_object (smart_str * buf , zend_object * obj , int options , php_json_encoder * encoder )
583583{
584- zend_class_entry * ce = Z_OBJCE_P (val );
585- zend_object * obj = Z_OBJ_P (val );
584+ zend_class_entry * ce = obj -> ce ;
586585 uint32_t * guard = zend_get_recursion_guard (obj );
587- zval retval , fname ;
586+ zval retval ;
588587 zend_result return_code ;
589588
590589 ZEND_ASSERT (guard != NULL );
@@ -599,35 +598,19 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val
599598
600599 ZEND_GUARD_PROTECT_RECURSION (guard , JSON );
601600
602- ZVAL_STRING (& fname , "jsonSerialize" );
603-
604- if (FAILURE == call_user_function (NULL , val , & fname , & retval , 0 , NULL ) || Z_TYPE (retval ) == IS_UNDEF ) {
605- if (!EG (exception )) {
606- zend_throw_exception_ex (NULL , 0 , "Failed calling %s::jsonSerialize()" , ZSTR_VAL (ce -> name ));
607- }
608- zval_ptr_dtor (& fname );
609-
601+ zend_function * json_serialize_method = zend_hash_str_find_ptr (& ce -> function_table , ZEND_STRL ("jsonserialize" ));
602+ ZEND_ASSERT (json_serialize_method != NULL && "This should be guaranteed prior to calling this function" );
603+ zend_call_known_function (json_serialize_method , obj , ce , & retval , 0 , NULL , NULL );
604+ /* An exception has occurred */
605+ if (Z_TYPE (retval ) == IS_UNDEF ) {
610606 if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR ) {
611607 smart_str_appendl (buf , "null" , 4 );
612608 }
613609 ZEND_GUARD_UNPROTECT_RECURSION (guard , JSON );
614610 return FAILURE ;
615611 }
616612
617- if (EG (exception )) {
618- /* Error already raised */
619- zval_ptr_dtor (& retval );
620- zval_ptr_dtor (& fname );
621-
622- if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR ) {
623- smart_str_appendl (buf , "null" , 4 );
624- }
625- ZEND_GUARD_UNPROTECT_RECURSION (guard , JSON );
626- return FAILURE ;
627- }
628-
629- if ((Z_TYPE (retval ) == IS_OBJECT ) &&
630- (Z_OBJ (retval ) == Z_OBJ_P (val ))) {
613+ if (Z_TYPE (retval ) == IS_OBJECT && Z_OBJ (retval ) == obj ) {
631614 /* Handle the case where jsonSerialize does: return $this; by going straight to encode array */
632615 ZEND_GUARD_UNPROTECT_RECURSION (guard , JSON );
633616 return_code = php_json_encode_array (buf , & retval , options , encoder );
@@ -638,11 +621,9 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val
638621 }
639622
640623 zval_ptr_dtor (& retval );
641- zval_ptr_dtor (& fname );
642624
643625 return return_code ;
644626}
645- /* }}} */
646627
647628static zend_result php_json_encode_serializable_enum (smart_str * buf , zval * val , int options , php_json_encoder * encoder )
648629{
@@ -691,7 +672,7 @@ zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_jso
691672
692673 case IS_OBJECT :
693674 if (instanceof_function (Z_OBJCE_P (val ), php_json_serializable_ce )) {
694- return php_json_encode_serializable_object (buf , val , options , encoder );
675+ return php_json_encode_serializable_object (buf , Z_OBJ_P ( val ) , options , encoder );
695676 }
696677 if (Z_OBJCE_P (val )-> ce_flags & ZEND_ACC_ENUM ) {
697678 return php_json_encode_serializable_enum (buf , val , options , encoder );
0 commit comments