#include "zend_dtrace.h"
#include "zend_smart_str.h"
+ZEND_API zend_class_entry *zend_ce_throwable;
+
static zend_class_entry *default_exception_ce;
static zend_class_entry *error_exception_ce;
static zend_class_entry *error_ce;
static zend_object_handlers default_exception_handlers;
ZEND_API void (*zend_throw_exception_hook)(zval *ex);
+/* {{{ zend_implement_throwable */
+static int zend_implement_throwable(zend_class_entry *interface, zend_class_entry *class_type)
+{
+ if (instanceof_function(class_type, default_exception_ce) || instanceof_function(class_type, error_ce)) {
+ return SUCCESS;
+ }
+ zend_error_noreturn(E_ERROR, "Class %s cannot implement interface %s, extend %s or %s instead",
+ class_type->name->val,
+ interface->name->val,
+ default_exception_ce->name->val,
+ error_ce->name->val);
+ return FAILURE;
+}
+/* }}} */
+
static inline zend_class_entry *zend_get_exception_base(zval *object)
{
return instanceof_function(Z_OBJCE_P(object), default_exception_ce) ? default_exception_ce : error_ce;
}
/* }}} */
+/** {{{ Throwable method definition */
+const zend_function_entry zend_funcs_throwable[] = {
+ ZEND_ABSTRACT_ME(throwable, getMessage, NULL)
+ ZEND_ABSTRACT_ME(throwable, getCode, NULL)
+ ZEND_ABSTRACT_ME(throwable, getFile, NULL)
+ ZEND_ABSTRACT_ME(throwable, getLine, NULL)
+ ZEND_ABSTRACT_ME(throwable, getTrace, NULL)
+ ZEND_ABSTRACT_ME(throwable, getPrevious, NULL)
+ ZEND_ABSTRACT_ME(throwable, getTraceAsString, NULL)
+ ZEND_ABSTRACT_ME(throwable, __toString, NULL)
+ ZEND_FE_END
+};
+/* }}} */
+
/* {{{ internal structs */
/* All functions that may be used in uncaught exception handlers must be final
* and must not throw exceptions. Otherwise we would need a facility to handle
{
zend_class_entry ce;
zend_property_info *prop;
+
+ REGISTER_INTERFACE(throwable, Throwable);
memcpy(&default_exception_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
default_exception_handlers.clone_obj = NULL;
BEGIN_EXTERN_C()
+extern ZEND_API zend_class_entry *zend_ce_throwable;
+
ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous);
ZEND_API void zend_exception_save(void);
ZEND_API void zend_exception_restore(void);
ZEND_API zend_class_entry *zend_ce_iterator;
ZEND_API zend_class_entry *zend_ce_arrayaccess;
ZEND_API zend_class_entry *zend_ce_serializable;
-ZEND_API zend_class_entry *zend_ce_throwable;
/* {{{ zend_call_method
Only returns the returned zval if retval_ptr != NULL */
}
/* }}}*/
-/* {{{ zend_implement_traversable */
-static int zend_implement_throwable(zend_class_entry *interface, zend_class_entry *class_type)
-{
- if (instanceof_function(class_type, zend_exception_get_default()) || instanceof_function(class_type, zend_get_error())) {
- return SUCCESS;
- }
- zend_error_noreturn(E_ERROR, "Class %s cannot implement interface %s, extend %s or %s instead",
- class_type->name->val,
- interface->name->val,
- zend_exception_get_default()->name->val,
- zend_get_error()->name->val);
- return FAILURE;
-}
-/* }}} */
-
/* {{{ function tables */
const zend_function_entry zend_funcs_aggregate[] = {
ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
};
/* }}} */
-const zend_function_entry zend_funcs_throwable[] = {
- ZEND_ABSTRACT_ME(throwable, getMessage, NULL)
- ZEND_ABSTRACT_ME(throwable, getCode, NULL)
- ZEND_ABSTRACT_ME(throwable, getFile, NULL)
- ZEND_ABSTRACT_ME(throwable, getLine, NULL)
- ZEND_ABSTRACT_ME(throwable, getTrace, NULL)
- ZEND_ABSTRACT_ME(throwable, getPrevious, NULL)
- ZEND_ABSTRACT_ME(throwable, getTraceAsString, NULL)
- ZEND_ABSTRACT_ME(throwable, __toString, NULL)
- ZEND_FE_END
-};
-
-#define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
- {\
- zend_class_entry ce;\
- INIT_CLASS_ENTRY(ce, # class_name_str, zend_funcs_ ## class_name) \
- zend_ce_ ## class_name = zend_register_internal_interface(&ce);\
- zend_ce_ ## class_name->interface_gets_implemented = zend_implement_ ## class_name;\
- }
-
#define REGISTER_ITERATOR_IMPLEMENT(class_name, interface_name) \
zend_class_implements(zend_ce_ ## class_name, 1, zend_ce_ ## interface_name)
/* {{{ zend_register_interfaces */
ZEND_API void zend_register_interfaces(void)
{
- REGISTER_ITERATOR_INTERFACE(traversable, Traversable);
+ REGISTER_INTERFACE(traversable, Traversable);
- REGISTER_ITERATOR_INTERFACE(aggregate, IteratorAggregate);
+ REGISTER_INTERFACE(aggregate, IteratorAggregate);
REGISTER_ITERATOR_IMPLEMENT(aggregate, traversable);
- REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
+ REGISTER_INTERFACE(iterator, Iterator);
REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
- REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
-
- REGISTER_ITERATOR_INTERFACE(serializable, Serializable);
+ REGISTER_INTERFACE(arrayaccess, ArrayAccess);
- REGISTER_ITERATOR_INTERFACE(throwable, Throwable);
+ REGISTER_INTERFACE(serializable, Serializable);
}
/* }}} */
extern ZEND_API zend_class_entry *zend_ce_iterator;
extern ZEND_API zend_class_entry *zend_ce_arrayaccess;
extern ZEND_API zend_class_entry *zend_ce_serializable;
-extern ZEND_API zend_class_entry *zend_ce_throwable;
typedef struct _zend_user_iterator {
zend_object_iterator it;
#define zend_call_method_with_2_params(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2) \
zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 2, arg1, arg2)
+#define REGISTER_INTERFACE(class_name, class_name_str) \
+ {\
+ zend_class_entry ce;\
+ INIT_CLASS_ENTRY(ce, # class_name_str, zend_funcs_ ## class_name) \
+ zend_ce_ ## class_name = zend_register_internal_interface(&ce);\
+ zend_ce_ ## class_name->interface_gets_implemented = zend_implement_ ## class_name;\
+ }
+
ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter);
ZEND_API int zend_user_it_valid(zend_object_iterator *_iter);
ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key);