Skip to content

Commit d9630a5

Browse files
committed
Exceptions updates:
- Enforce exceptions to be derived from class Exception. This allows users to perform catch-all. It's not yet complete, so don't get comfortable with it just yet :) Updates are coming soon. - Implement zend_throw_exception() using zend_throw_exception_ex()
1 parent 559b146 commit d9630a5

File tree

6 files changed

+46
-63
lines changed

6 files changed

+46
-63
lines changed

Zend/zend_default_classes.c

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "zend_builtin_functions.h"
2626
#include "zend_interfaces.h"
2727

28-
static zend_class_entry *default_exception_ce;
28+
zend_class_entry *default_exception_ce;
2929
static zend_object_handlers default_exception_handlers;
3030
ZEND_API void zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
3131

@@ -452,36 +452,13 @@ ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code
452452
zend_throw_exception_internal(ex TSRMLS_CC);
453453
}
454454

455-
/* at the moment we can't use zend_throw_exception_ex because we don't have a protable
456-
* vsnprintf that tells us the number of characters needed nor do we have spprintf from
457-
* php or asprintf from glibc always.
458-
*/
455+
459456
ZEND_API void zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC)
460457
{
461-
zval *ex;
462-
463-
MAKE_STD_ZVAL(ex);
464-
if (exception_ce) {
465-
if (!instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
466-
zend_error(E_NOTICE, "Exceptions must be derived from exception");
467-
exception_ce = default_exception_ce;
468-
}
469-
} else {
470-
exception_ce = default_exception_ce;
471-
}
472-
object_init_ex(ex, exception_ce);
473-
474-
475-
if (message) {
476-
zend_update_property_string(default_exception_ce, ex, "message", sizeof("message")-1, message TSRMLS_CC);
477-
}
478-
if (code) {
479-
zend_update_property_long(default_exception_ce, ex, "code", sizeof("code")-1, code TSRMLS_CC);
480-
}
481-
482-
zend_throw_exception_internal(ex TSRMLS_CC);
458+
zend_throw_exception_ex(exception_ce, code TSRMLS_CC, "%s", message);
483459
}
484460

461+
485462
static void zend_error_va(int type, const char *file, uint lineno, const char *format, ...)
486463
{
487464
va_list args;
@@ -534,6 +511,24 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC)
534511
}
535512
}
536513

514+
515+
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC)
516+
{
517+
zend_class_entry *exception_ce;
518+
519+
if (exception == NULL || exception->type != IS_OBJECT) {
520+
zend_error(E_ERROR, "Need to supply an object when throwing an exception");
521+
}
522+
523+
exception_ce = Z_OBJCE_P(exception);
524+
525+
if (!exception_ce || !instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
526+
zend_error(E_ERROR, "Exceptions must valid objects that are derived from class Exception");
527+
}
528+
zend_throw_exception_internal(exception TSRMLS_CC);
529+
}
530+
531+
537532
ZEND_API void zend_register_default_classes(TSRMLS_D)
538533
{
539534
zend_register_interfaces(TSRMLS_C);

Zend/zend_default_classes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ ZEND_API void zend_register_default_classes(TSRMLS_D);
3131
* message NULL or the message of the exception */
3232
ZEND_API void zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
3333
ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...);
34+
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
3435

3536
/* show an exception using zend_error(E_ERROR,...) */
3637
ZEND_API void zend_exception_error(zval *exception TSRMLS_DC);

Zend/zend_exceptions.c

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "zend_builtin_functions.h"
2626
#include "zend_interfaces.h"
2727

28-
static zend_class_entry *default_exception_ce;
28+
zend_class_entry *default_exception_ce;
2929
static zend_object_handlers default_exception_handlers;
3030
ZEND_API void zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
3131

@@ -452,36 +452,13 @@ ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code
452452
zend_throw_exception_internal(ex TSRMLS_CC);
453453
}
454454

455-
/* at the moment we can't use zend_throw_exception_ex because we don't have a protable
456-
* vsnprintf that tells us the number of characters needed nor do we have spprintf from
457-
* php or asprintf from glibc always.
458-
*/
455+
459456
ZEND_API void zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC)
460457
{
461-
zval *ex;
462-
463-
MAKE_STD_ZVAL(ex);
464-
if (exception_ce) {
465-
if (!instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
466-
zend_error(E_NOTICE, "Exceptions must be derived from exception");
467-
exception_ce = default_exception_ce;
468-
}
469-
} else {
470-
exception_ce = default_exception_ce;
471-
}
472-
object_init_ex(ex, exception_ce);
473-
474-
475-
if (message) {
476-
zend_update_property_string(default_exception_ce, ex, "message", sizeof("message")-1, message TSRMLS_CC);
477-
}
478-
if (code) {
479-
zend_update_property_long(default_exception_ce, ex, "code", sizeof("code")-1, code TSRMLS_CC);
480-
}
481-
482-
zend_throw_exception_internal(ex TSRMLS_CC);
458+
zend_throw_exception_ex(exception_ce, code TSRMLS_CC, "%s", message);
483459
}
484460

461+
485462
static void zend_error_va(int type, const char *file, uint lineno, const char *format, ...)
486463
{
487464
va_list args;
@@ -534,6 +511,24 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC)
534511
}
535512
}
536513

514+
515+
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC)
516+
{
517+
zend_class_entry *exception_ce;
518+
519+
if (exception == NULL || exception->type != IS_OBJECT) {
520+
zend_error(E_ERROR, "Need to supply an object when throwing an exception");
521+
}
522+
523+
exception_ce = Z_OBJCE_P(exception);
524+
525+
if (!exception_ce || !instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
526+
zend_error(E_ERROR, "Exceptions must valid objects that are derived from class Exception");
527+
}
528+
zend_throw_exception_internal(exception TSRMLS_CC);
529+
}
530+
531+
537532
ZEND_API void zend_register_default_classes(TSRMLS_D)
538533
{
539534
zend_register_interfaces(TSRMLS_C);

Zend/zend_exceptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ ZEND_API void zend_register_default_classes(TSRMLS_D);
3131
* message NULL or the message of the exception */
3232
ZEND_API void zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
3333
ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...);
34+
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
3435

3536
/* show an exception using zend_error(E_ERROR,...) */
3637
ZEND_API void zend_exception_error(zval *exception TSRMLS_DC);

Zend/zend_execute.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
6565
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
6666
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
6767

68-
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
69-
7068
static inline int i_zend_is_true(zval *op)
7169
{
7270
int result;

Zend/zend_execute_API.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,13 +1221,6 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC)
12211221
EG(current_execute_data)->opline = &EG(active_op_array)->opcodes[EG(active_op_array)->last-1-1];
12221222
}
12231223

1224-
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC)
1225-
{
1226-
if (exception == NULL) {
1227-
zend_error(E_ERROR, "Need to supply object when throwing exception");
1228-
}
1229-
zend_throw_exception_internal(exception TSRMLS_CC);
1230-
}
12311224

12321225

12331226

0 commit comments

Comments
 (0)