Skip to content

Commit d4238df

Browse files
committed
Zend: Exception::__toString() no need to allocate the method name
We can create the FCI/FCC pair ourself outside of the loop as the method getTraceAsString is final
1 parent f61ae00 commit d4238df

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

Zend/zend_exceptions.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -695,32 +695,41 @@ ZEND_METHOD(Exception, __toString)
695695
zval trace, *exception;
696696
zend_class_entry *base_ce;
697697
zend_string *str;
698-
zend_fcall_info fci;
699698
zval rv, tmp;
700-
zend_string *fname;
701699

702700
ZEND_PARSE_PARAMETERS_NONE();
703701

704702
str = ZSTR_EMPTY_ALLOC();
705703

706704
exception = ZEND_THIS;
707-
fname = ZSTR_INIT_LITERAL("gettraceasstring", 0);
705+
/* As getTraceAsString method is final we can grab it once */
706+
zend_function *getTraceAsString = zend_hash_str_find_ptr(&zend_ce_exception->function_table, ZEND_STRS("gettraceasstring"));
707+
ZEND_ASSERT(getTraceAsString && "Method getTraceAsString must exist");
708+
709+
zend_fcall_info fci = {
710+
.size = sizeof(fci),
711+
.function_name = {0},
712+
.retval = &trace,
713+
.param_count = 0,
714+
.params = NULL,
715+
.object = Z_OBJ_P(exception),
716+
.named_params = NULL,
717+
};
718+
zend_fcall_info_cache fcc = {
719+
.function_handler = getTraceAsString,
720+
.calling_scope = Z_OBJCE_P(exception),
721+
.called_scope = zend_ce_exception,
722+
.object = Z_OBJ_P(exception),
723+
.closure = NULL,
724+
};
708725

709726
while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) {
710727
zend_string *prev_str = str;
711728
zend_string *message = zval_get_string(GET_PROPERTY(exception, ZEND_STR_MESSAGE));
712729
zend_string *file = zval_get_string(GET_PROPERTY(exception, ZEND_STR_FILE));
713730
zend_long line = zval_get_long(GET_PROPERTY(exception, ZEND_STR_LINE));
714731

715-
fci.size = sizeof(fci);
716-
ZVAL_STR(&fci.function_name, fname);
717-
fci.object = Z_OBJ_P(exception);
718-
fci.retval = &trace;
719-
fci.param_count = 0;
720-
fci.params = NULL;
721-
fci.named_params = NULL;
722-
723-
zend_call_function(&fci, NULL);
732+
zend_call_function(&fci, &fcc);
724733

725734
if (Z_TYPE(trace) != IS_STRING) {
726735
zval_ptr_dtor(&trace);
@@ -765,7 +774,6 @@ ZEND_METHOD(Exception, __toString)
765774
break;
766775
}
767776
}
768-
zend_string_release_ex(fname, 0);
769777

770778
exception = ZEND_THIS;
771779
/* Reset apply counts */

0 commit comments

Comments
 (0)