diff options
| -rw-r--r-- | Zend/zend_API.c | 7 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 9 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 21 | ||||
| -rw-r--r-- | Zend/zend_execute.c | 2 | ||||
| -rw-r--r-- | Zend/zend_execute_API.c | 2 | ||||
| -rwxr-xr-x | Zend/zend_interfaces.c | 2 | ||||
| -rw-r--r-- | Zend/zend_language_parser.y | 2 | ||||
| -rw-r--r-- | Zend/zend_reflection_api.c | 23 | ||||
| -rw-r--r-- | ext/reflection/php_reflection.c | 23 | ||||
| -rwxr-xr-x | ext/spl/spl_functions.c | 2 | ||||
| -rwxr-xr-x | ext/spl/spl_iterators.c | 2 |
11 files changed, 56 insertions, 39 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 1cf81d06b6..096a99bcf2 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1237,11 +1237,12 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr if (ptr->flags & ZEND_ACC_ABSTRACT) { if (scope) { /* This is a class that must be abstract itself. Here we set the check info. */ - scope->ce_flags |= ZEND_ACC_ABSTRACT; + scope->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; if (!(scope->ce_flags & ZEND_ACC_INTERFACE)) { /* Since the class is not an interface it needs to be declared as a abstract class. */ + /* Since here we are handling internal functions only we can add the keyword flag. */ /* This time we set the flag for the keyword 'abstratc'. */ - scope->ce_flags |= ZEND_ACC_ABSTRACT_CLASS; + scope->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; } } } else { @@ -1522,7 +1523,7 @@ ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_c ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC) { - return do_register_internal_class(orig_class_entry, ZEND_ACC_ABSTRACT|ZEND_ACC_INTERFACE TSRMLS_CC); + return do_register_internal_class(orig_class_entry, ZEND_ACC_INTERFACE TSRMLS_CC); } ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length, diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ed7cd0fe59..ddc8aca147 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -974,7 +974,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n } if (fn_flags & ZEND_ACC_ABSTRACT) { - CG(active_class_entry)->ce_flags |= ZEND_ACC_ABSTRACT; + CG(active_class_entry)->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; } if (!(fn_flags & ZEND_ACC_PPP_MASK)) { @@ -1749,8 +1749,8 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f TSRMLS_FETCH(); if (zend_hash_quick_find(child_function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child)==FAILURE) { - if (parent_flags & ZEND_ACC_ABSTRACT) { - child_ce->ce_flags |= ZEND_ACC_ABSTRACT; + if (parent_flags & (ZEND_ACC_ABSTRACT)) { + child_ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; } return 1; /* method doesn't exist in child, copy from parent */ } @@ -2537,8 +2537,7 @@ void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRML if (ce->num_interfaces > 0) { ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *)*ce->num_interfaces); } - if (!(ce->ce_flags & ZEND_ACC_INTERFACE) - && !(ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS) + if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) && ((parent_token->op_type != IS_UNUSED) || (ce->num_interfaces > 0))) { zend_verify_abstract_class(ce TSRMLS_CC); if (ce->parent || ce->num_interfaces) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f277d64b78..9f09c79b1b 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -99,18 +99,21 @@ typedef struct _zend_try_catch_element { } zend_try_catch_element; +/* method flags (types) */ #define ZEND_ACC_STATIC 0x01 #define ZEND_ACC_ABSTRACT 0x02 #define ZEND_ACC_FINAL 0x04 -#define ZEND_ACC_INTERFACE 0x08 -/* ZEND_ACC_ABSTRACT is used for abstract classes and methods. Abstract checks work only on this flag. */ -/* ZEND_ACC_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */ -#define ZEND_ACC_ABSTRACT_CLASS 0x10 -#define ZEND_ACC_FINAL_CLASS 0x20 -#define ZEND_ACC_IMPLEMENTED_ABSTRACT 0x40 +#define ZEND_ACC_IMPLEMENTED_ABSTRACT 0x08 -#define ZEND_ACC_ALLOW_STATIC 0x80 +/* class flags (types) */ +/* ZEND_ACC_IMPLICIT_ABSTRACT_CLASS is used for abstract classes (since it is set by any abstract method even interfaces MAY have it set, too). */ +/* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */ +#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS 0x10 +#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS 0x20 +#define ZEND_ACC_FINAL_CLASS 0x40 +#define ZEND_ACC_INTERFACE 0x80 +/* method flags (visibility) */ /* The order of those must be kept - public < protected < private */ #define ZEND_ACC_PUBLIC 0x100 #define ZEND_ACC_PROTECTED 0x200 @@ -120,10 +123,14 @@ typedef struct _zend_try_catch_element { #define ZEND_ACC_CHANGED 0x800 #define ZEND_ACC_IMPLICIT_PUBLIC 0x1000 +/* method flags (special method detection) */ #define ZEND_ACC_CTOR 0x2000 #define ZEND_ACC_DTOR 0x4000 #define ZEND_ACC_CLONE 0x8000 +/* method flag (bc only), any method that has this flag can be used statically and non statically. */ +#define ZEND_ACC_ALLOW_STATIC 0x10000 + char *zend_visibility_string(zend_uint fn_flags); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index badcdf5bc8..46f5efd173 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3169,7 +3169,7 @@ int zend_switch_free_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_new_handler(ZEND_OPCODE_HANDLER_ARGS) { - if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_ABSTRACT|ZEND_ACC_ABSTRACT_CLASS)) { + if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { char *class_type; if (EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 767583869a..4ec0fbda1c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1225,7 +1225,7 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) { zend_abstract_info ai; - if ((ce->ce_flags & ZEND_ACC_ABSTRACT) && !(ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS)) { + if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { memset(&ai, 0, sizeof(ai)); zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC); diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 96e994cc2f..dedbcb3129 100755 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -293,7 +293,7 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en if (class_type->get_iterator || (class_type->parent && class_type->parent->get_iterator)) { return SUCCESS; - } + } for (i = 0; i < class_type->num_interfaces; i++) { if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) { return SUCCESS; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 59b0262e20..9de80a096f 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -287,7 +287,7 @@ unticked_class_declaration_statement: class_entry_type: T_CLASS { $$.u.constant.value.lval = 0; } - | T_ABSTRACT T_CLASS { $$.u.constant.value.lval = ZEND_ACC_ABSTRACT_CLASS; } + | T_ABSTRACT T_CLASS { $$.u.constant.value.lval = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; } | T_FINAL T_CLASS { $$.u.constant.value.lval = ZEND_ACC_FINAL_CLASS; } ; diff --git a/Zend/zend_reflection_api.c b/Zend/zend_reflection_api.c index 89bd0a9282..97b71d5059 100644 --- a/Zend/zend_reflection_api.c +++ b/Zend/zend_reflection_api.c @@ -269,13 +269,17 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in if (ce->get_iterator != NULL) { string_printf(str, "<iterateable> "); } - if (ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS) { - string_printf(str, "abstract "); + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + string_printf(str, "interface "); + } else { + if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + string_printf(str, "abstract "); + } + if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) { + string_printf(str, "final "); + } + string_printf(str, "class "); } - if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) { - string_printf(str, "final "); - } - string_printf(str, (ce->ce_flags & ZEND_ACC_INTERFACE) ? "interface " : "class "); string_write(str, ce->name, ce->name_length); if (ce->parent) { string_printf(str, " extends %s", ce->parent->name); @@ -952,7 +956,7 @@ ZEND_METHOD(reflection, getModifierNames) array_init(return_value); - if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_ABSTRACT_CLASS)) { + if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { add_next_index_stringl(return_value, "abstract", sizeof("abstract"), 1); } if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) { @@ -2252,7 +2256,7 @@ ZEND_METHOD(reflection_class, isFinal) Returns whether this class is abstract */ ZEND_METHOD(reflection_class, isAbstract) { - _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT_CLASS); + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS); } /* }}} */ @@ -3192,7 +3196,8 @@ ZEND_API void zend_register_reflection_api(TSRMLS_D) { REGISTER_MAIN_LONG_CONSTANT("M_FINAL", ZEND_ACC_FINAL, CONST_PERSISTENT|CONST_CS); /* Class modifiers */ - REGISTER_MAIN_LONG_CONSTANT("C_ABSTRACT", ZEND_ACC_ABSTRACT_CLASS, CONST_PERSISTENT|CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("C_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, CONST_PERSISTENT|CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("C_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS, CONST_PERSISTENT|CONST_CS); REGISTER_MAIN_LONG_CONSTANT("C_FINAL", ZEND_ACC_FINAL_CLASS, CONST_PERSISTENT|CONST_CS); } /* }}} */ diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 89bd0a9282..97b71d5059 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -269,13 +269,17 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in if (ce->get_iterator != NULL) { string_printf(str, "<iterateable> "); } - if (ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS) { - string_printf(str, "abstract "); + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + string_printf(str, "interface "); + } else { + if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + string_printf(str, "abstract "); + } + if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) { + string_printf(str, "final "); + } + string_printf(str, "class "); } - if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) { - string_printf(str, "final "); - } - string_printf(str, (ce->ce_flags & ZEND_ACC_INTERFACE) ? "interface " : "class "); string_write(str, ce->name, ce->name_length); if (ce->parent) { string_printf(str, " extends %s", ce->parent->name); @@ -952,7 +956,7 @@ ZEND_METHOD(reflection, getModifierNames) array_init(return_value); - if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_ABSTRACT_CLASS)) { + if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { add_next_index_stringl(return_value, "abstract", sizeof("abstract"), 1); } if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) { @@ -2252,7 +2256,7 @@ ZEND_METHOD(reflection_class, isFinal) Returns whether this class is abstract */ ZEND_METHOD(reflection_class, isAbstract) { - _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT_CLASS); + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS); } /* }}} */ @@ -3192,7 +3196,8 @@ ZEND_API void zend_register_reflection_api(TSRMLS_D) { REGISTER_MAIN_LONG_CONSTANT("M_FINAL", ZEND_ACC_FINAL, CONST_PERSISTENT|CONST_CS); /* Class modifiers */ - REGISTER_MAIN_LONG_CONSTANT("C_ABSTRACT", ZEND_ACC_ABSTRACT_CLASS, CONST_PERSISTENT|CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("C_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, CONST_PERSISTENT|CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("C_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS, CONST_PERSISTENT|CONST_CS); REGISTER_MAIN_LONG_CONSTANT("C_FINAL", ZEND_ACC_FINAL_CLASS, CONST_PERSISTENT|CONST_CS); } /* }}} */ diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index b4fd7507cf..fc9c315ea6 100755 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -45,7 +45,7 @@ void spl_register_interface(zend_class_entry ** ppce, char * class_name, zend_fu *ppce = zend_register_internal_class(&ce TSRMLS_CC); /* entries changed by initialize */ - (*ppce)->ce_flags = ZEND_ACC_ABSTRACT | ZEND_ACC_INTERFACE; + (*ppce)->ce_flags = ZEND_ACC_INTERFACE; } /* }}} */ diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index d3973ed4b9..2168787987 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1204,7 +1204,7 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_STD_CLASS_EX(FilterIterator, spl_dual_it_new, spl_funcs_FilterIterator); REGISTER_SPL_ITERATOR(FilterIterator); - spl_ce_FilterIterator->ce_flags |= ZEND_ACC_ABSTRACT_CLASS; + spl_ce_FilterIterator->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; REGISTER_SPL_SUB_CLASS_EX(ParentIterator, FilterIterator, spl_dual_it_new, spl_funcs_ParentIterator); REGISTER_SPL_IMPLEMENTS(ParentIterator, RecursiveIterator); |
