diff --git a/Zend/zend.c b/Zend/zend.c index b4fd4fd269c8a..75dc52d4fd8dd 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -88,6 +88,7 @@ ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle); ZEND_API void (*zend_ticks_function)(int ticks); ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data); ZEND_API void (*zend_error_cb)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message); +ZEND_API void (*zend_exit)(zend_string *str, zend_long status); void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap); void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap); ZEND_API char *(*zend_getenv)(const char *name, size_t name_len); @@ -994,6 +995,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ /* Set up the default garbage collection implementation. */ gc_collect_cycles = zend_gc_collect_cycles; + zend_exit = zend_exit_function_impl; zend_vm_init(); diff --git a/Zend/zend.h b/Zend/zend.h index 0cf1faeb653fe..3fefc6721de3b 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -356,6 +356,7 @@ extern ZEND_API void (*zend_ticks_function)(int ticks); * internal frame is still on top. */ extern ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data); +extern ZEND_API void (*zend_exit)(zend_string *str, zend_long status); extern ZEND_API void (*zend_error_cb)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message); extern ZEND_API void (*zend_on_timeout)(int seconds); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index bb8bb28bf6e4f..f0286ade1f532 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -73,27 +73,12 @@ ZEND_FUNCTION(exit) { zend_string *str = NULL; zend_long status = 0; - ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(str, status) ZEND_PARSE_PARAMETERS_END(); - if (str) { - size_t len = ZSTR_LEN(str); - if (len != 0) { - /* An exception might be emitted by an output handler */ - zend_write(ZSTR_VAL(str), len); - if (EG(exception)) { - RETURN_THROWS(); - } - } - } else { - EG(exit_status) = status; - } - - ZEND_ASSERT(!EG(exception)); - zend_throw_unwind_exit(); + zend_exit(str, status); } /* {{{ Get the version of the Zend Engine */ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index a11aca81e84c1..ec89a167cde9b 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -40,6 +40,7 @@ void init_executor(void); void shutdown_executor(void); void shutdown_destructors(void); ZEND_API void zend_shutdown_executor_values(bool fast_shutdown); +ZEND_API void zend_exit_function_impl(zend_string *str, zend_long status); ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value); ZEND_API void zend_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f42479cf745d2..90296639719fd 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -793,6 +793,26 @@ zend_result _call_user_function_impl(zval *object, zval *function_name, zval *re } /* }}} */ +ZEND_API void zend_exit_function_impl(zend_string *str, zend_long status) +{ + if (str) { + size_t len = ZSTR_LEN(str); + if (len != 0) { + /* An exception might be emitted by an output handler */ + zend_write(ZSTR_VAL(str), len); + if (EG(exception)) { + ZEND_ASSERT(EG(exception)); + return; + } + } + } else { + EG(exit_status) = status; + } + + ZEND_ASSERT(!EG(exception)); + zend_throw_unwind_exit(); +} + zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */ { uint32_t i;