summaryrefslogtreecommitdiff
path: root/Zend/zend.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend.c')
-rw-r--r--Zend/zend.c342
1 files changed, 171 insertions, 171 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index b667514020..cbd5aef42b 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -32,6 +32,8 @@
#include "zend_smart_str.h"
#include "zend_smart_string.h"
#include "zend_cpuinfo.h"
+#include "zend_attributes.h"
+#include "zend_observer.h"
static size_t global_map_ptr_last = 0;
@@ -71,18 +73,19 @@ ZEND_API zend_class_entry *zend_standard_class_def = NULL;
ZEND_API size_t (*zend_printf)(const char *format, ...);
ZEND_API zend_write_func_t zend_write;
ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
-ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
+ZEND_API zend_result (*zend_stream_open_function)(const char *filename, 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, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args);
+ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
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)(char *name, size_t name_len);
+ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
-ZEND_API int (*zend_post_startup_cb)(void) = NULL;
+ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL;
ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
-ZEND_API int (*zend_preload_autoload)(zend_string *filename) = NULL;
+ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename) = NULL;
+/* This callback must be signal handler safe! */
void (*zend_on_timeout)(int seconds);
static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
@@ -95,7 +98,7 @@ ZEND_API zend_bool zend_rc_debug = 0;
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
{
if (!new_value) {
- EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
+ EG(error_reporting) = E_ALL;
} else {
EG(error_reporting) = atoi(ZSTR_VAL(new_value));
}
@@ -139,18 +142,9 @@ static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
{
- zend_long *p, val;
-#ifndef ZTS
- char *base = (char *) mh_arg2;
-#else
- char *base;
-
- base = (char *) ts_resource(*((int *) mh_arg2));
-#endif
-
- p = (zend_long *) (base+(size_t) mh_arg1);
+ zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
- val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
+ zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
if (stage != ZEND_INI_STAGE_STARTUP &&
stage != ZEND_INI_STAGE_SHUTDOWN &&
@@ -165,6 +159,20 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
}
/* }}} */
+static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
+{
+ zend_long i;
+
+ ZEND_ATOL(i, ZSTR_VAL(new_value));
+ if (i >= 0 && i <= 1000000) {
+ EG(exception_string_param_max_len) = i;
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+/* }}} */
+
#if ZEND_DEBUG
# define SIGNAL_CHECK_DEFAULT "1"
#else
@@ -182,6 +190,7 @@ ZEND_INI_BEGIN()
STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
#endif
STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
+ STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals)
ZEND_INI_END()
ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
@@ -355,7 +364,7 @@ static void print_flat_hash(HashTable *ht) /* {{{ */
}
/* }}} */
-ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
+ZEND_API bool zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
{
if (Z_TYPE_P(expr) == IS_STRING) {
return 0;
@@ -395,9 +404,7 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
}
print_flat_hash(Z_ARRVAL_P(expr));
ZEND_PUTS(")");
- if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
- }
+ GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
break;
case IS_OBJECT:
{
@@ -443,9 +450,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
}
print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
- if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
- }
+ GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
break;
case IS_OBJECT:
{
@@ -542,7 +547,7 @@ static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */
ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!GetVersionEx((OSVERSIONINFO *) osvi)) {
- ZEND_ASSERT(0); /* Should not happen as sizeof is used. */
+ ZEND_UNREACHABLE(); /* Should not happen as sizeof is used. */
}
}
/* }}} */
@@ -601,12 +606,20 @@ static void function_copy_ctor(zval *zv) /* {{{ */
new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, 1);
memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args);
for (i = 0 ; i < num_args; i++) {
- if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
+ if (ZEND_TYPE_HAS_LIST(arg_info[i].type)) {
+ zend_type_list *old_list = ZEND_TYPE_LIST(arg_info[i].type);
+ zend_type_list *new_list = pemalloc(ZEND_TYPE_LIST_SIZE(old_list->num_types), 1);
+ memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
+ ZEND_TYPE_SET_PTR(new_arg_info[i].type, new_list);
+
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
+ zend_string *name = zend_string_dup(ZEND_TYPE_NAME(*list_type), 1);
+ ZEND_TYPE_SET_PTR(*list_type, name);
+ } ZEND_TYPE_LIST_FOREACH_END();
+ } else if (ZEND_TYPE_HAS_NAME(arg_info[i].type)) {
zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
-
- new_arg_info[i].type =
- ZEND_TYPE_ENCODE_CLASS(
- name, ZEND_TYPE_ALLOW_NULL(arg_info[i].type));
+ ZEND_TYPE_SET_PTR(new_arg_info[i].type, name);
}
}
func->common.arg_info = new_arg_info + 1;
@@ -632,31 +645,33 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
compiler_globals->compiled_filename = NULL;
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
- zend_hash_init_ex(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
+ zend_hash_init(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1);
zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
- zend_hash_init_ex(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
+ zend_hash_init(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1);
zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
zend_set_default_compile_time_values();
compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
- zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0);
+ zend_hash_init(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1);
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
compiler_globals->script_encoding_list = NULL;
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
/* Map region is going to be created and resized at run-time. */
- compiler_globals->map_ptr_base = NULL;
+ ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
compiler_globals->map_ptr_size = 0;
compiler_globals->map_ptr_last = global_map_ptr_last;
if (compiler_globals->map_ptr_last) {
/* Allocate map_ptr table */
+ void *base;
compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096);
- compiler_globals->map_ptr_base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
- memset(compiler_globals->map_ptr_base, 0, compiler_globals->map_ptr_last * sizeof(void*));
+ base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
+ ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, base);
+ memset(base, 0, compiler_globals->map_ptr_last * sizeof(void*));
}
#else
# error "Unknown ZEND_MAP_PTR_KIND"
@@ -681,9 +696,9 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
if (compiler_globals->script_encoding_list) {
pefree((char*)compiler_globals->script_encoding_list, 1);
}
- if (compiler_globals->map_ptr_base) {
- free(compiler_globals->map_ptr_base);
- compiler_globals->map_ptr_base = NULL;
+ if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) {
+ free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base));
+ ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
compiler_globals->map_ptr_size = 0;
}
}
@@ -737,9 +752,8 @@ static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{
static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
{
- if (zend_copy_ini_directives() == SUCCESS) {
- zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
- }
+ zend_copy_ini_directives();
+ zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
}
/* }}} */
#endif
@@ -783,7 +797,7 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
}
/* }}} */
-int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
+void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
{
#ifdef ZTS
zend_compiler_globals *compiler_globals;
@@ -816,7 +830,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
/* Set up utility functions and values */
zend_error_cb = utility_functions->error_function;
zend_printf = utility_functions->printf_function;
- zend_write = (zend_write_func_t) utility_functions->write_function;
+ zend_write = utility_functions->write_function;
zend_fopen = utility_functions->fopen_function;
if (!zend_fopen) {
zend_fopen = zend_fopen_wrapper;
@@ -833,7 +847,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
zend_interrupt_function = NULL;
-#if HAVE_DTRACE
+#ifdef HAVE_DTRACE
/* build with dtrace support */
{
char *tmp = getenv("USE_ZEND_DTRACE");
@@ -843,6 +857,8 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
zend_compile_file = dtrace_compile_file;
zend_execute_ex = dtrace_execute_ex;
zend_execute_internal = dtrace_execute_internal;
+
+ zend_observer_error_register(dtrace_error_notify_cb);
} else {
zend_compile_file = compile_file;
zend_execute_ex = execute_ex;
@@ -871,12 +887,12 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
- zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
- zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
- zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0);
- zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0);
+ zend_hash_init(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1);
+ zend_hash_init(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1);
+ zend_hash_init(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1);
+ zend_hash_init(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1);
- zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0);
+ zend_hash_init(&module_registry, 32, NULL, module_destructor_zval, 1);
zend_init_rsrc_list_dtors();
#ifdef ZTS
@@ -912,10 +928,10 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
*/
CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ???
CG(map_ptr_last) = 0;
- CG(map_ptr_base) = pemalloc(CG(map_ptr_size) * sizeof(void*), 1);
+ ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), pemalloc(CG(map_ptr_size) * sizeof(void*), 1));
# elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
/* Map region is going to be created and resized at run-time. */
- CG(map_ptr_base) = NULL;
+ ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL);
CG(map_ptr_size) = 0;
CG(map_ptr_last) = 0;
# else
@@ -946,8 +962,6 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
tsrm_set_shutdown_handler(zend_interned_strings_dtor);
#endif
-
- return SUCCESS;
}
/* }}} */
@@ -959,6 +973,15 @@ void zend_register_standard_ini_entries(void) /* {{{ */
}
/* }}} */
+static zend_class_entry *resolve_type_name(zend_string *type_name) {
+ zend_string *lc_type_name = zend_string_tolower(type_name);
+ zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lc_type_name);
+
+ ZEND_ASSERT(ce && ce->type == ZEND_INTERNAL_CLASS);
+ zend_string_release(lc_type_name);
+ return ce;
+}
+
static void zend_resolve_property_types(void) /* {{{ */
{
zend_class_entry *ce;
@@ -971,16 +994,14 @@ static void zend_resolve_property_types(void) /* {{{ */
if (UNEXPECTED(ZEND_CLASS_HAS_TYPE_HINTS(ce))) {
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
- if (ZEND_TYPE_IS_NAME(prop_info->type)) {
- zend_string *type_name = ZEND_TYPE_NAME(prop_info->type);
- zend_string *lc_type_name = zend_string_tolower(type_name);
- zend_class_entry *prop_ce = zend_hash_find_ptr(CG(class_table), lc_type_name);
-
- ZEND_ASSERT(prop_ce && prop_ce->type == ZEND_INTERNAL_CLASS);
- prop_info->type = ZEND_TYPE_ENCODE_CE(prop_ce, ZEND_TYPE_ALLOW_NULL(prop_info->type));
- zend_string_release(lc_type_name);
- zend_string_release(type_name);
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(prop_info->type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
+ zend_string *type_name = ZEND_TYPE_NAME(*single_type);
+ ZEND_TYPE_SET_CE(*single_type, resolve_type_name(type_name));
+ zend_string_release(type_name);
+ }
+ } ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
@@ -991,7 +1012,7 @@ static void zend_resolve_property_types(void) /* {{{ */
/* Unlink the global (r/o) copies of the class, function and constant tables,
* and use a fresh r/w copy for the startup thread
*/
-int zend_post_startup(void) /* {{{ */
+zend_result zend_post_startup(void) /* {{{ */
{
#ifdef ZTS
zend_encoding **script_encoding_list;
@@ -1003,7 +1024,7 @@ int zend_post_startup(void) /* {{{ */
zend_resolve_property_types();
if (zend_post_startup_cb) {
- int (*cb)(void) = zend_post_startup_cb;
+ zend_result (*cb)(void) = zend_post_startup_cb;
zend_post_startup_cb = NULL;
if (cb() != SUCCESS) {
@@ -1025,8 +1046,10 @@ int zend_post_startup(void) /* {{{ */
compiler_globals->function_table = NULL;
free(compiler_globals->class_table);
compiler_globals->class_table = NULL;
- free(compiler_globals->map_ptr_base);
- compiler_globals->map_ptr_base = NULL;
+ if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) {
+ free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base));
+ }
+ ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
compiler_globals_ctor(compiler_globals);
compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
@@ -1072,6 +1095,7 @@ void zend_shutdown(void) /* {{{ */
zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
free(GLOBAL_CONSTANTS_TABLE);
zend_shutdown_strtod();
+ zend_attributes_shutdown();
#ifdef ZTS
GLOBAL_FUNCTION_TABLE = NULL;
@@ -1081,13 +1105,13 @@ void zend_shutdown(void) /* {{{ */
ts_free_id(executor_globals_id);
ts_free_id(compiler_globals_id);
#else
- if (CG(map_ptr_base)) {
- free(CG(map_ptr_base));
- CG(map_ptr_base) = NULL;
+ if (ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base))) {
+ free(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)));
+ ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL);
CG(map_ptr_size) = 0;
}
if (CG(script_encoding_list)) {
- free(CG(script_encoding_list));
+ free(ZEND_VOIDP(CG(script_encoding_list)));
CG(script_encoding_list) = NULL;
CG(script_encoding_list_size) = 0;
}
@@ -1156,7 +1180,7 @@ ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ *
}
/* }}} */
-ZEND_API char *get_zend_version(void) /* {{{ */
+ZEND_API const char *get_zend_version(void) /* {{{ */
{
return zend_version_info;
}
@@ -1172,8 +1196,9 @@ ZEND_API void zend_activate(void) /* {{{ */
init_executor();
startup_scanner();
if (CG(map_ptr_last)) {
- memset(CG(map_ptr_base), 0, CG(map_ptr_last) * sizeof(void*));
+ memset(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), 0, CG(map_ptr_last) * sizeof(void*));
}
+ zend_observer_activate();
}
/* }}} */
@@ -1190,6 +1215,8 @@ ZEND_API void zend_deactivate(void) /* {{{ */
/* we're no longer executing anything */
EG(current_execute_data) = NULL;
+ zend_observer_deactivate();
+
zend_try {
shutdown_scanner();
} zend_end_try();
@@ -1259,69 +1286,48 @@ ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
} \
} while (0)
-static ZEND_COLD void zend_error_va_list(
- int type, const char *error_filename, uint32_t error_lineno,
- const char *format, va_list args)
+static ZEND_COLD void zend_error_impl(
+ int orig_type, const char *error_filename, uint32_t error_lineno, zend_string *message)
{
- va_list usr_copy;
- zval params[5];
+ zval params[4];
zval retval;
zval orig_user_error_handler;
zend_bool in_compilation;
zend_class_entry *saved_class_entry;
zend_stack loop_var_stack;
zend_stack delayed_oplines_stack;
- zend_array *symbol_table;
- zend_class_entry *orig_fake_scope;
+ int type = orig_type & E_ALL;
/* Report about uncaught exception in case of fatal errors */
if (EG(exception)) {
zend_execute_data *ex;
const zend_op *opline;
- switch (type) {
- case E_CORE_ERROR:
- case E_ERROR:
- case E_RECOVERABLE_ERROR:
- case E_PARSE:
- case E_COMPILE_ERROR:
- case E_USER_ERROR:
- ex = EG(current_execute_data);
- opline = NULL;
- while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
- ex = ex->prev_execute_data;
- }
- if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
- EG(opline_before_exception)) {
- opline = EG(opline_before_exception);
- }
- zend_exception_error(EG(exception), E_WARNING);
- EG(exception) = NULL;
- if (opline) {
- ex->opline = opline;
- }
- break;
- default:
- break;
+ if (type & E_FATAL_ERRORS) {
+ ex = EG(current_execute_data);
+ opline = NULL;
+ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
+ ex = ex->prev_execute_data;
+ }
+ if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
+ EG(opline_before_exception)) {
+ opline = EG(opline_before_exception);
+ }
+ zend_exception_error(EG(exception), E_WARNING);
+ EG(exception) = NULL;
+ if (opline) {
+ ex->opline = opline;
+ }
}
}
-#ifdef HAVE_DTRACE
- if (DTRACE_ERROR_ENABLED()) {
- char *dtrace_error_buffer;
- va_copy(usr_copy, args);
- zend_vspprintf(&dtrace_error_buffer, 0, format, usr_copy);
- va_end(usr_copy);
- DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
- efree(dtrace_error_buffer);
- }
-#endif /* HAVE_DTRACE */
+ zend_observer_error_notify(type, error_filename, error_lineno, message);
/* if we don't have a user defined error handler */
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|| !(EG(user_error_handler_error_reporting) & type)
|| EG(error_handling) != EH_NORMAL) {
- zend_error_cb(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, message);
} else switch (type) {
case E_ERROR:
case E_PARSE:
@@ -1330,14 +1336,11 @@ static ZEND_COLD void zend_error_va_list(
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
/* The error may not be safe to handle in user-space */
- zend_error_cb(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, message);
break;
default:
/* Handle the error in user space */
- va_copy(usr_copy, args);
- ZVAL_STR(&params[1], zend_vstrpprintf(0, format, usr_copy));
- va_end(usr_copy);
-
+ ZVAL_STR_COPY(&params[1], message);
ZVAL_LONG(&params[0], type);
if (error_filename) {
@@ -1348,15 +1351,6 @@ static ZEND_COLD void zend_error_va_list(
ZVAL_LONG(&params[3], error_lineno);
- symbol_table = zend_rebuild_symbol_table();
-
- /* during shutdown the symbol table table can be still null */
- if (!symbol_table) {
- ZVAL_NULL(&params[4]);
- } else {
- ZVAL_ARR(&params[4], zend_array_dup(symbol_table));
- }
-
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
ZVAL_UNDEF(&EG(user_error_handler));
@@ -1374,23 +1368,18 @@ static ZEND_COLD void zend_error_va_list(
CG(in_compilation) = 0;
}
- orig_fake_scope = EG(fake_scope);
- EG(fake_scope) = NULL;
-
- if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params) == SUCCESS) {
+ if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) {
if (Z_TYPE(retval) != IS_UNDEF) {
if (Z_TYPE(retval) == IS_FALSE) {
- zend_error_cb(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, message);
}
zval_ptr_dtor(&retval);
}
} else if (!EG(exception)) {
/* The user error handler failed, use built-in error handler */
- zend_error_cb(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, message);
}
- EG(fake_scope) = orig_fake_scope;
-
if (in_compilation) {
CG(active_class_entry) = saved_class_entry;
RESTORE_STACK(loop_var_stack);
@@ -1398,7 +1387,6 @@ static ZEND_COLD void zend_error_va_list(
CG(in_compilation) = 1;
}
- zval_ptr_dtor(&params[4]);
zval_ptr_dtor(&params[2]);
zval_ptr_dtor(&params[1]);
@@ -1423,6 +1411,15 @@ static ZEND_COLD void zend_error_va_list(
}
/* }}} */
+static ZEND_COLD void zend_error_va_list(
+ int orig_type, const char *error_filename, uint32_t error_lineno,
+ const char *format, va_list args)
+{
+ zend_string *message = zend_vstrpprintf(0, format, args);
+ zend_error_impl(orig_type, error_filename, error_lineno, message);
+ zend_string_release(message);
+}
+
static ZEND_COLD void get_filename_lineno(int type, const char **filename, uint32_t *lineno) {
/* Obtain relevant filename and lineno */
switch (type) {
@@ -1511,7 +1508,6 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(
/* Should never reach this. */
abort();
}
-/* }}} */
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
{
@@ -1526,19 +1522,20 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *
/* Should never reach this. */
abort();
}
-/* }}} */
+
+ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) {
+ const char *filename;
+ uint32_t lineno;
+ get_filename_lineno(type, &filename, &lineno);
+ zend_error_impl(type, filename, lineno, message);
+}
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
{
va_list va;
char *message = NULL;
- if (exception_ce) {
- if (!instanceof_function(exception_ce, zend_ce_error)) {
- zend_error(E_NOTICE, "Error exceptions must be derived from Error");
- exception_ce = zend_ce_error;
- }
- } else {
+ if (!exception_ce) {
exception_ce = zend_ce_error;
}
@@ -1574,37 +1571,28 @@ ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
va_end(va);
} /* }}} */
-ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
+ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) /* {{{ */
{
va_list va;
char *message = NULL;
va_start(va, format);
zend_vspprintf(&message, 0, format, va);
- if (throw_exception) {
- zend_throw_exception(zend_ce_type_error, message, 0);
- } else {
- zend_error(E_WARNING, "%s", message);
- }
+ zend_throw_exception(zend_ce_argument_count_error, message, 0);
efree(message);
va_end(va);
} /* }}} */
-ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
+ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) /* {{{ */
{
va_list va;
char *message = NULL;
va_start(va, format);
zend_vspprintf(&message, 0, format, va);
- if (throw_exception) {
- zend_throw_exception(zend_ce_argument_count_error, message, 0);
- } else {
- zend_error(E_WARNING, "%s", message);
- }
+ zend_throw_exception(zend_ce_value_error, message, 0);
efree(message);
-
va_end(va);
} /* }}} */
@@ -1639,6 +1627,11 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */
zval orig_user_exception_handler;
zval params[1], retval2;
zend_object *old_exception;
+
+ if (zend_is_unwind_exit(EG(exception))) {
+ return;
+ }
+
old_exception = EG(exception);
EG(exception) = NULL;
ZVAL_OBJ(&params[0], old_exception);
@@ -1656,12 +1649,13 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */
}
} /* }}} */
-ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
+ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
{
va_list files;
int i;
zend_file_handle *file_handle;
zend_op_array *op_array;
+ zend_result ret = SUCCESS;
va_start(files, file_count);
for (i = 0; i < file_count; i++) {
@@ -1670,6 +1664,13 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
continue;
}
+ if (ret == FAILURE) {
+ /* If a failure occurred in one of the earlier files,
+ * only destroy the following file handles. */
+ zend_file_handle_dtor(file_handle);
+ continue;
+ }
+
op_array = zend_compile_file(file_handle, type);
if (file_handle->opened_path) {
zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
@@ -1683,19 +1684,18 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
zend_user_exception_handler();
}
if (EG(exception)) {
- zend_exception_error(EG(exception), E_ERROR);
+ ret = zend_exception_error(EG(exception), E_ERROR);
}
}
destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));
} else if (type==ZEND_REQUIRE) {
- va_end(files);
- return FAILURE;
+ ret = FAILURE;
}
}
va_end(files);
- return SUCCESS;
+ return ret;
}
/* }}} */
@@ -1741,16 +1741,16 @@ ZEND_API void *zend_map_ptr_new(void)
if (CG(map_ptr_last) >= CG(map_ptr_size)) {
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
// TODO: error ???
- ZEND_ASSERT(0);
+ ZEND_UNREACHABLE();
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
/* Grow map_ptr table */
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
- CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1);
+ ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
#else
# error "Unknown ZEND_MAP_PTR_KIND"
#endif
}
- ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last);
+ ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last);
*ptr = NULL;
CG(map_ptr_last)++;
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
@@ -1770,16 +1770,16 @@ ZEND_API void zend_map_ptr_extend(size_t last)
if (last >= CG(map_ptr_size)) {
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
/* This may never happen */
- ZEND_ASSERT(0);
+ ZEND_UNREACHABLE();
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
/* Grow map_ptr table */
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096);
- CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1);
+ ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
#else
# error "Unknown ZEND_MAP_PTR_KIND"
#endif
}
- ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last);
+ ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last);
memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*));
CG(map_ptr_last) = last;
}