mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
- 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.
This commit is contained in:
parent
ad31a021bc
commit
f7f49e4584
5 changed files with 34 additions and 7 deletions
|
@ -25,6 +25,7 @@
|
||||||
#include "zend_builtin_functions.h"
|
#include "zend_builtin_functions.h"
|
||||||
|
|
||||||
zend_class_entry *default_exception_ptr;
|
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)
|
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)
|
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);
|
INIT_CLASS_ENTRY(ce, "exception", default_exception_functions);
|
||||||
default_exception_ptr = zend_register_internal_class(&default_exception TSRMLS_CC);
|
default_exception_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
||||||
default_exception_ptr->create_object = zend_default_exception_new;
|
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);
|
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, "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, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
|
||||||
zend_declare_property_null(default_exception_ptr, "trace", sizeof("trace")-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)
|
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;
|
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, ...)
|
ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...)
|
||||||
{
|
{
|
||||||
zval *ex;
|
zval *ex;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
|
|
||||||
ZEND_API zend_class_entry *zend_exception_get_default(void);
|
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);
|
ZEND_API void zend_register_default_classes(TSRMLS_D);
|
||||||
|
|
||||||
/* exception_ce NULL or zend_exception_get_default() or a derived class
|
/* exception_ce NULL or zend_exception_get_default() or a derived class
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "zend_builtin_functions.h"
|
#include "zend_builtin_functions.h"
|
||||||
|
|
||||||
zend_class_entry *default_exception_ptr;
|
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)
|
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)
|
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);
|
INIT_CLASS_ENTRY(ce, "exception", default_exception_functions);
|
||||||
default_exception_ptr = zend_register_internal_class(&default_exception TSRMLS_CC);
|
default_exception_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
||||||
default_exception_ptr->create_object = zend_default_exception_new;
|
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);
|
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, "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, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
|
||||||
zend_declare_property_null(default_exception_ptr, "trace", sizeof("trace")-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)
|
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;
|
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, ...)
|
ZEND_API void zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...)
|
||||||
{
|
{
|
||||||
zval *ex;
|
zval *ex;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
|
|
||||||
ZEND_API zend_class_entry *zend_exception_get_default(void);
|
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);
|
ZEND_API void zend_register_default_classes(TSRMLS_D);
|
||||||
|
|
||||||
/* exception_ce NULL or zend_exception_get_default() or a derived class
|
/* exception_ce NULL or zend_exception_get_default() or a derived class
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "zend_extensions.h"
|
#include "zend_extensions.h"
|
||||||
#include "zend_fast_cache.h"
|
#include "zend_fast_cache.h"
|
||||||
#include "zend_ini.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(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)
|
#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;
|
zval *current_this;
|
||||||
int return_value_used = RETURN_VALUE_USED(EX(opline));
|
int return_value_used = RETURN_VALUE_USED(EX(opline));
|
||||||
zend_bool should_change_scope;
|
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);
|
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;
|
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);
|
EG(function_state_ptr) = &EX(function_state);
|
||||||
zend_ptr_stack_clear_multiple(TSRMLS_C);
|
zend_ptr_stack_clear_multiple(TSRMLS_C);
|
||||||
|
|
||||||
|
fcall_exception:
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
if (return_value_used && EX_T(EX(opline)->result.u.var).var.ptr) {
|
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);
|
zval_ptr_dtor(&EX_T(EX(opline)->result.u.var).var.ptr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue