diff options
author | Marcus Boerger <helly@php.net> | 2003-08-30 11:40:37 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2003-08-30 11:40:37 +0000 |
commit | f7f49e4584ebed812fb37945c0b2d3f0ad4efbcc (patch) | |
tree | 6deb549831d0f2beeefb0f4e49dd396729cf9cfe | |
parent | ad31a021bc9e6b83243adabd6a0c5c52bcc6c9d8 (diff) | |
download | php-git-f7f49e4584ebed812fb37945c0b2d3f0ad4efbcc.tar.gz |
- The compiler can't detect all abstract function calls so we need to check.
# In this case throwing a dedicated exception is better than the error we
# show when the compiler can detect the abstract call because its run-time.
-rw-r--r-- | Zend/zend_default_classes.c | 15 | ||||
-rw-r--r-- | Zend/zend_default_classes.h | 1 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 15 | ||||
-rw-r--r-- | Zend/zend_exceptions.h | 1 | ||||
-rw-r--r-- | Zend/zend_execute.c | 9 |
5 files changed, 34 insertions, 7 deletions
diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 5c51ca1420..737bc604e5 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -25,6 +25,7 @@ #include "zend_builtin_functions.h" zend_class_entry *default_exception_ptr; +zend_class_entry *abstract_exception_ptr; static zend_object_value zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) { @@ -138,10 +139,10 @@ static zend_function_entry default_exception_functions[] = { static void zend_register_default_exception(TSRMLS_D) { - zend_class_entry default_exception; + zend_class_entry ce; - INIT_CLASS_ENTRY(default_exception, "exception", default_exception_functions); - default_exception_ptr = zend_register_internal_class(&default_exception TSRMLS_CC); + INIT_CLASS_ENTRY(ce, "exception", default_exception_functions); + default_exception_ptr = zend_register_internal_class(&ce TSRMLS_CC); default_exception_ptr->create_object = zend_default_exception_new; zend_declare_property_string(default_exception_ptr, "message", sizeof("message")-1, "Unknown exception", ZEND_ACC_PROTECTED); @@ -149,6 +150,9 @@ static void zend_register_default_exception(TSRMLS_D) zend_declare_property_null(default_exception_ptr, "file", sizeof("file")-1, ZEND_ACC_PROTECTED); zend_declare_property_null(default_exception_ptr, "line", sizeof("line")-1, ZEND_ACC_PROTECTED); zend_declare_property_null(default_exception_ptr, "trace", sizeof("trace")-1, ZEND_ACC_PROTECTED); + + INIT_CLASS_ENTRY(ce, "abstract_exception", NULL); + abstract_exception_ptr = zend_register_internal_class_ex(&ce, default_exception_ptr, NULL TSRMLS_CC); } ZEND_API zend_class_entry *zend_exception_get_default(void) @@ -156,6 +160,11 @@ ZEND_API zend_class_entry *zend_exception_get_default(void) return default_exception_ptr; } +ZEND_API zend_class_entry *zend_exception_get_abstract(void) +{ + return abstract_exception_ptr; +} + ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...) { zval *ex; diff --git a/Zend/zend_default_classes.h b/Zend/zend_default_classes.h index 9b6e17661c..c3e592df9f 100644 --- a/Zend/zend_default_classes.h +++ b/Zend/zend_default_classes.h @@ -25,6 +25,7 @@ BEGIN_EXTERN_C() ZEND_API zend_class_entry *zend_exception_get_default(void); +ZEND_API zend_class_entry *zend_exception_get_abstract(void); ZEND_API void zend_register_default_classes(TSRMLS_D); /* exception_ce NULL or zend_exception_get_default() or a derived class diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 5c51ca1420..737bc604e5 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -25,6 +25,7 @@ #include "zend_builtin_functions.h" zend_class_entry *default_exception_ptr; +zend_class_entry *abstract_exception_ptr; static zend_object_value zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) { @@ -138,10 +139,10 @@ static zend_function_entry default_exception_functions[] = { static void zend_register_default_exception(TSRMLS_D) { - zend_class_entry default_exception; + zend_class_entry ce; - INIT_CLASS_ENTRY(default_exception, "exception", default_exception_functions); - default_exception_ptr = zend_register_internal_class(&default_exception TSRMLS_CC); + INIT_CLASS_ENTRY(ce, "exception", default_exception_functions); + default_exception_ptr = zend_register_internal_class(&ce TSRMLS_CC); default_exception_ptr->create_object = zend_default_exception_new; zend_declare_property_string(default_exception_ptr, "message", sizeof("message")-1, "Unknown exception", ZEND_ACC_PROTECTED); @@ -149,6 +150,9 @@ static void zend_register_default_exception(TSRMLS_D) zend_declare_property_null(default_exception_ptr, "file", sizeof("file")-1, ZEND_ACC_PROTECTED); zend_declare_property_null(default_exception_ptr, "line", sizeof("line")-1, ZEND_ACC_PROTECTED); zend_declare_property_null(default_exception_ptr, "trace", sizeof("trace")-1, ZEND_ACC_PROTECTED); + + INIT_CLASS_ENTRY(ce, "abstract_exception", NULL); + abstract_exception_ptr = zend_register_internal_class_ex(&ce, default_exception_ptr, NULL TSRMLS_CC); } ZEND_API zend_class_entry *zend_exception_get_default(void) @@ -156,6 +160,11 @@ ZEND_API zend_class_entry *zend_exception_get_default(void) return default_exception_ptr; } +ZEND_API zend_class_entry *zend_exception_get_abstract(void) +{ + return abstract_exception_ptr; +} + ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...) { zval *ex; diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index 9b6e17661c..c3e592df9f 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -25,6 +25,7 @@ BEGIN_EXTERN_C() ZEND_API zend_class_entry *zend_exception_get_default(void); +ZEND_API zend_class_entry *zend_exception_get_abstract(void); ZEND_API void zend_register_default_classes(TSRMLS_D); /* exception_ce NULL or zend_exception_get_default() or a derived class diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3fed8b5264..4156717dbf 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -33,6 +33,7 @@ #include "zend_extensions.h" #include "zend_fast_cache.h" #include "zend_ini.h" +#include "zend_default_classes.h" #define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free TSRMLS_CC) #define get_zval_ptr_ptr(node, Ts, type) _get_zval_ptr_ptr(node, Ts TSRMLS_CC) @@ -2498,7 +2499,12 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS) zval *current_this; int return_value_used = RETURN_VALUE_USED(EX(opline)); zend_bool should_change_scope; - + + if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) { + zend_throw_exception_ex(zend_exception_get_abstract(), 0 TSRMLS_CC, "Abstract method %s::%s called", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name); + goto fcall_exception; + } + zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) EX(opline)->extended_value, NULL); EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; @@ -2629,6 +2635,7 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS) EG(function_state_ptr) = &EX(function_state); zend_ptr_stack_clear_multiple(TSRMLS_C); +fcall_exception: if (EG(exception)) { if (return_value_used && EX_T(EX(opline)->result.u.var).var.ptr) { zval_ptr_dtor(&EX_T(EX(opline)->result.u.var).var.ptr); |