summaryrefslogtreecommitdiff
path: root/Zend/zend_exceptions.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_exceptions.c')
-rw-r--r--Zend/zend_exceptions.c96
1 files changed, 33 insertions, 63 deletions
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index b52b1ab113..af71ac7a65 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -53,14 +53,21 @@ static zend_object_handlers default_exception_handlers;
/* {{{ zend_implement_throwable */
static int zend_implement_throwable(zend_class_entry *interface, zend_class_entry *class_type)
{
- if (instanceof_function(class_type, zend_ce_exception) || instanceof_function(class_type, zend_ce_error)) {
+ /* zend_ce_exception and zend_ce_error may not be initialized yet when this is caleld (e.g when
+ * implementing Throwable for Exception itself). Perform a manual inheritance check. */
+ zend_class_entry *root = class_type;
+ while (root->parent) {
+ root = root->parent;
+ }
+ if (zend_string_equals_literal(root->name, "Exception")
+ || zend_string_equals_literal(root->name, "Error")) {
return SUCCESS;
}
- zend_error_noreturn(E_ERROR, "Class %s cannot implement interface %s, extend %s or %s instead",
+
+ zend_error_noreturn(E_ERROR,
+ "Class %s cannot implement interface %s, extend Exception or Error instead",
ZSTR_VAL(class_type->name),
- ZSTR_VAL(interface->name),
- ZSTR_VAL(zend_ce_exception->name),
- ZSTR_VAL(zend_ce_error->name));
+ ZSTR_VAL(interface->name));
return FAILURE;
}
/* }}} */
@@ -93,7 +100,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
}
ZEND_ASSERT(instanceof_function(add_previous->ce, zend_ce_throwable)
- && "Previous execption must implement Throwable");
+ && "Previous exception must implement Throwable");
ZVAL_OBJ(&pv, add_previous);
ZVAL_OBJ(&zv, exception);
@@ -144,7 +151,7 @@ void zend_exception_restore(void) /* {{{ */
}
/* }}} */
-static zend_always_inline zend_bool is_handle_exception_set() {
+static zend_always_inline bool is_handle_exception_set() {
zend_execute_data *execute_data = EG(current_execute_data);
return !execute_data->func
|| !ZEND_USER_CODE(execute_data->func->common.type)
@@ -339,7 +346,7 @@ ZEND_METHOD(ErrorException, __construct)
{
zend_string *message = NULL, *filename = NULL;
zend_long code = 0, severity = E_ERROR, lineno;
- zend_bool lineno_is_null = 1;
+ bool lineno_is_null = 1;
zval tmp, *object, *previous = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|SllS!l!O!", &message, &code, &severity, &filename, &lineno, &lineno_is_null, &previous, zend_ce_throwable) == FAILURE) {
@@ -478,7 +485,7 @@ ZEND_METHOD(ErrorException, getSeverity)
static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */
{
/* the trivial way would be to do
- * convert_to_string_ex(arg);
+ * convert_to_string(arg);
* append it and kill the now tmp arg.
* but that could cause some E_NOTICE and also damn long lines.
*/
@@ -740,87 +747,50 @@ ZEND_METHOD(Exception, __toString)
}
/* }}} */
-static void declare_exception_properties(zend_class_entry *ce)
-{
- zval val;
-
- zend_declare_property_string(ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
- zend_declare_property_string(ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
- zend_declare_property_long(ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
- zend_declare_property_null(ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
- zend_declare_property_null(ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
-
- ZVAL_EMPTY_ARRAY(&val);
- zend_declare_typed_property(
- ce, ZSTR_KNOWN(ZEND_STR_TRACE), &val, ZEND_ACC_PRIVATE, NULL,
- (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
-
- ZVAL_NULL(&val);
- zend_declare_typed_property(
- ce, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &val, ZEND_ACC_PRIVATE, NULL,
- (zend_type) ZEND_TYPE_INIT_CE(zend_ce_throwable, /* allow_null */ 1, 0));
-}
-
void zend_register_default_exception(void) /* {{{ */
{
- zend_class_entry ce;
-
- REGISTER_MAGIC_INTERFACE(throwable, Throwable);
- zend_class_implements(zend_ce_throwable, 1, zend_ce_stringable);
+ zend_ce_throwable = register_class_Throwable(zend_ce_stringable);
+ zend_ce_throwable->interface_gets_implemented = zend_implement_throwable;
memcpy(&default_exception_handlers, &std_object_handlers, sizeof(zend_object_handlers));
default_exception_handlers.clone_obj = NULL;
- INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods);
- zend_ce_exception = zend_register_internal_class_ex(&ce, NULL);
+ zend_ce_exception = register_class_Exception(zend_ce_throwable);
zend_ce_exception->create_object = zend_default_exception_new;
- zend_class_implements(zend_ce_exception, 1, zend_ce_throwable);
- declare_exception_properties(zend_ce_exception);
- INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods);
- zend_ce_error_exception = zend_register_internal_class_ex(&ce, zend_ce_exception);
+ zend_ce_error_exception = register_class_ErrorException(zend_ce_exception);
zend_ce_error_exception->create_object = zend_error_exception_new;
+ /* Declared manually because it uses constant E_ERROR. */
zend_declare_property_long(zend_ce_error_exception, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED);
- INIT_CLASS_ENTRY(ce, "Error", class_Error_methods);
- zend_ce_error = zend_register_internal_class_ex(&ce, NULL);
+ zend_ce_error = register_class_Error(zend_ce_throwable);
zend_ce_error->create_object = zend_default_exception_new;
- zend_class_implements(zend_ce_error, 1, zend_ce_throwable);
- declare_exception_properties(zend_ce_error);
- INIT_CLASS_ENTRY(ce, "CompileError", class_CompileError_methods);
- zend_ce_compile_error = zend_register_internal_class_ex(&ce, zend_ce_error);
+ zend_ce_compile_error = register_class_CompileError(zend_ce_error);
zend_ce_compile_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(ce, "ParseError", class_ParseError_methods);
- zend_ce_parse_error = zend_register_internal_class_ex(&ce, zend_ce_compile_error);
+ zend_ce_parse_error = register_class_ParseError(zend_ce_compile_error);
zend_ce_parse_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(ce, "TypeError", class_TypeError_methods);
- zend_ce_type_error = zend_register_internal_class_ex(&ce, zend_ce_error);
+ zend_ce_type_error = register_class_TypeError(zend_ce_error);
zend_ce_type_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(ce, "ArgumentCountError", class_ArgumentCountError_methods);
- zend_ce_argument_count_error = zend_register_internal_class_ex(&ce, zend_ce_type_error);
+ zend_ce_argument_count_error = register_class_ArgumentCountError(zend_ce_type_error);
zend_ce_argument_count_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(ce, "ValueError", class_ValueError_methods);
- zend_ce_value_error = zend_register_internal_class_ex(&ce, zend_ce_error);
+ zend_ce_value_error = register_class_ValueError(zend_ce_error);
zend_ce_value_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(ce, "ArithmeticError", class_ArithmeticError_methods);
- zend_ce_arithmetic_error = zend_register_internal_class_ex(&ce, zend_ce_error);
+ zend_ce_arithmetic_error = register_class_ArithmeticError(zend_ce_error);
zend_ce_arithmetic_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(ce, "DivisionByZeroError", class_DivisionByZeroError_methods);
- zend_ce_division_by_zero_error = zend_register_internal_class_ex(&ce, zend_ce_arithmetic_error);
+ zend_ce_division_by_zero_error = register_class_DivisionByZeroError(zend_ce_arithmetic_error);
zend_ce_division_by_zero_error->create_object = zend_default_exception_new;
- INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL);
-
- INIT_CLASS_ENTRY(ce, "UnhandledMatchError", NULL);
- zend_ce_unhandled_match_error = zend_register_internal_class_ex(&ce, zend_ce_error);
+ zend_ce_unhandled_match_error = register_class_UnhandledMatchError(zend_ce_error);
zend_ce_unhandled_match_error->create_object = zend_default_exception_new;
+
+ INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL);
}
/* }}} */
@@ -1017,7 +987,7 @@ ZEND_API ZEND_COLD void zend_throw_unwind_exit(void)
EG(current_execute_data)->opline = EG(exception_op);
}
-ZEND_API zend_bool zend_is_unwind_exit(zend_object *ex)
+ZEND_API bool zend_is_unwind_exit(zend_object *ex)
{
return ex->ce == &zend_ce_unwind_exit;
}