Browse Source

Replace ZEND_ACC_ANON_BOUND, ZEND_ACC_UNRESOLVED_PARENT and ZEND_ACC_UNRESOLVED_INTERFACES with single ZEND_ACC_LINKED.

pull/3532/merge
Dmitry Stogov 7 years ago
parent
commit
689c6fb188
  1. 3
      UPGRADING.INTERNALS
  2. 3
      Zend/zend.h
  3. 2
      Zend/zend_API.c
  4. 6
      Zend/zend_compile.c
  5. 18
      Zend/zend_compile.h
  6. 10
      Zend/zend_inheritance.c
  7. 4
      Zend/zend_interfaces.c
  8. 4
      Zend/zend_opcode.c
  9. 4
      Zend/zend_operators.c
  10. 6
      Zend/zend_vm_def.h
  11. 6
      Zend/zend_vm_execute.h
  12. 12
      ext/opcache/Optimizer/zend_inference.c
  13. 6
      ext/opcache/zend_accelerator_util_funcs.c
  14. 28
      ext/opcache/zend_file_cache.c
  15. 8
      ext/opcache/zend_persist.c
  16. 4
      ext/opcache/zend_persist_calc.c
  17. 6
      ext/reflection/php_reflection.c
  18. 2
      ext/spl/spl_functions.c

3
UPGRADING.INTERNALS

@ -35,6 +35,9 @@ PHP 7.4 INTERNALS UPGRADE NOTES
- ZEND_ACC_SHADOW property flag is removed. Instead of creating shadow
clone, now we use the same private property_info, and should also
check property_info->ce (in the same way as with methods).
- ZEND_ACC_ANON_BOUND is replaced with ZEND_ACC_LINKED. This flag is set
not only during anonymous classes declaration, but also during any
run-time or compile-time class declaration.
- ZEND_ACC_... flags are re-numbered.
d. zend_check_private() is removed. Use (func->common.scope == scope) instead.

3
Zend/zend.h

@ -115,6 +115,7 @@ typedef struct _zend_trait_alias {
struct _zend_class_entry {
char type;
zend_string *name;
/* class_entry or string depending on ZEND_ACC_LINKED */
union {
zend_class_entry *parent;
zend_string *parent_name;
@ -163,7 +164,7 @@ struct _zend_class_entry {
uint32_t num_interfaces;
uint32_t num_traits;
/* class_entry or string(s) depending on ZEND_ACC_UNRESOLVED_INTERFACES */
/* class_entry or string(s) depending on ZEND_ACC_LINKED */
union {
zend_class_entry **interfaces;
zend_class_name *interface_names;

2
Zend/zend_API.c

@ -2716,7 +2716,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
class_entry->type = ZEND_INTERNAL_CLASS;
zend_initialize_class_data(class_entry, 0);
class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED;
class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED | ZEND_ACC_LINKED;
class_entry->info.internal.module = EG(current_module);
if (class_entry->info.internal.builtin_functions) {

6
Zend/zend_compile.c

@ -6183,7 +6183,7 @@ void zend_compile_implements(zend_ast *ast) /* {{{ */
interface_names[i].lc_name = zend_string_tolower(interface_names[i].name);
}
ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES | ZEND_ACC_UNRESOLVED_INTERFACES;
ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES;
ce->num_interfaces = list->children;
ce->interface_names = interface_names;
}
@ -6280,7 +6280,7 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
ce->parent_name = zend_resolve_class_name(extends_name,
extends_ast->kind == ZEND_AST_ZVAL ? extends_ast->attr : ZEND_NAME_FQ);
zend_string_release_ex(extends_name, 0);
ce->ce_flags |= ZEND_ACC_INHERITED | ZEND_ACC_UNRESOLVED_PARENT;
ce->ce_flags |= ZEND_ACC_INHERITED;
}
CG(active_class_entry) = ce;
@ -6355,12 +6355,14 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
}
CG(zend_lineno) = ast->lineno;
zend_string_release(lcname);
ce->ce_flags |= ZEND_ACC_LINKED;
return;
}
}
} else {
if (EXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) != NULL)) {
zend_string_release(lcname);
ce->ce_flags |= ZEND_ACC_LINKED;
return;
}
}

18
Zend/zend_compile.h

@ -217,7 +217,7 @@ typedef struct _zend_oparray_context {
#define ZEND_ACC_ABSTRACT (1 << 6) /* X | X | | */
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS (1 << 6) /* X | | | */
/* | | | */
/* Class Flags (unused: 15...) | | | */
/* Class Flags (unused: 13...) | | | */
/* =========== | | | */
/* | | | */
/* Special class types | | | */
@ -225,8 +225,8 @@ typedef struct _zend_oparray_context {
#define ZEND_ACC_TRAIT (1 << 1) /* X | | | */
#define ZEND_ACC_ANON_CLASS (1 << 2) /* X | | | */
/* | | | */
/* Bound anonymous class | | | */
#define ZEND_ACC_ANON_BOUND (1 << 3) /* X | | | */
/* Class linked with parent, interfacs and traits | | | */
#define ZEND_ACC_LINKED (1 << 3) /* X | | | */
/* | | | */
/* class is abstarct, since it is set by any | | | */
/* abstract method | | | */
@ -242,20 +242,14 @@ typedef struct _zend_oparray_context {
/* Class extends another class | | | */
#define ZEND_ACC_INHERITED (1 << 9) /* X | | | */
/* | | | */
/* Class extends another class | | | */
#define ZEND_ACC_UNRESOLVED_PARENT (1 << 10) /* X | | | */
/* | | | */
/* Class implements interface(s) | | | */
#define ZEND_ACC_IMPLEMENT_INTERFACES (1 << 11) /* X | | | */
/* | | | */
/* Class implements interface(s) | | | */
#define ZEND_ACC_UNRESOLVED_INTERFACES (1 << 12) /* X | | | */
#define ZEND_ACC_IMPLEMENT_INTERFACES (1 << 10) /* X | | | */
/* | | | */
/* Class uses trait(s) | | | */
#define ZEND_ACC_IMPLEMENT_TRAITS (1 << 13) /* X | | | */
#define ZEND_ACC_IMPLEMENT_TRAITS (1 << 11) /* X | | | */
/* | | | */
/* User class has methods with static variables | | | */
#define ZEND_HAS_STATIC_IN_METHODS (1 << 14) /* X | | | */
#define ZEND_HAS_STATIC_IN_METHODS (1 << 12) /* X | | | */
/* | | | */
/* Function Flags (unused: 25...30) | | | */
/* ============== | | | */

10
Zend/zend_inheritance.c

@ -719,7 +719,6 @@ static void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_en
uint32_t i, ce_num, if_num = iface->num_interfaces;
zend_class_entry *entry;
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ce_num = ce->num_interfaces;
if (ce->type == ZEND_INTERNAL_CLASS) {
@ -798,9 +797,8 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
}
}
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) {
if (ce->parent_name) {
zend_string_release_ex(ce->parent_name, 0);
ce->ce_flags &= ~ZEND_ACC_UNRESOLVED_PARENT;
}
ce->parent = parent_ce;
@ -1032,7 +1030,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
zend_string *key;
zend_class_constant *c;
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED);
for (i = 0; i < ce->num_interfaces; i++) {
if (ce->interfaces[i] == NULL) {
@ -1090,8 +1088,6 @@ static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
zend_class_constant *c;
uint32_t i, j;
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES);
if (ce->parent && ce->parent->num_interfaces) {
interfaces = emalloc(sizeof(zend_class_entry*) * (ce->parent->num_interfaces + ce->num_interfaces));
memcpy(interfaces, ce->parent->interfaces, sizeof(zend_class_entry*) * ce->parent->num_interfaces);
@ -1141,7 +1137,6 @@ static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
ce->num_interfaces = num_interfaces;
ce->interfaces = interfaces;
ce->ce_flags &= ~ZEND_ACC_UNRESOLVED_INTERFACES;
i = ce->parent ? ce->parent->num_interfaces : 0;
for (; i < ce->num_interfaces; i++) {
@ -1912,6 +1907,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent) /* {{{ */
{
ce->ce_flags |= ZEND_ACC_LINKED;
if (parent) {
zend_do_inheritance(ce, parent);
}

4
Zend/zend_interfaces.c

@ -291,7 +291,7 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
return SUCCESS;
}
if (class_type->num_interfaces) {
ZEND_ASSERT(!(class_type->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_LINKED);
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;
@ -320,7 +320,7 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
} else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
/* c-level get_iterator cannot be changed (exception being only Traversable is implemented) */
if (class_type->num_interfaces) {
ZEND_ASSERT(!(class_type->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_LINKED);
for (i = 0; i < class_type->num_interfaces; i++) {
if (class_type->interfaces[i] == zend_ce_iterator) {
zend_error_noreturn(E_ERROR, "Class %s cannot implement both %s and %s at the same time",

4
Zend/zend_opcode.c

@ -218,7 +218,7 @@ ZEND_API void destroy_zend_class(zval *zv)
}
switch (ce->type) {
case ZEND_USER_CLASS:
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) {
if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
zend_string_release_ex(ce->parent_name, 0);
}
if (ce->default_properties_table) {
@ -266,7 +266,7 @@ ZEND_API void destroy_zend_class(zval *zv)
}
zend_hash_destroy(&ce->constants_table);
if (ce->num_interfaces > 0) {
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES) {
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
uint32_t i;
for (i = 0; i < ce->num_interfaces; i++) {

4
Zend/zend_operators.c

@ -2279,7 +2279,7 @@ static zend_bool ZEND_FASTCALL instanceof_interface_only(const zend_class_entry
uint32_t i;
if (instance_ce->num_interfaces) {
ZEND_ASSERT(!(instance_ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(instance_ce->ce_flags & ZEND_ACC_LINKED);
for (i = 0; i < instance_ce->num_interfaces; i++) {
if (instanceof_interface_only(instance_ce->interfaces[i], ce)) {
return 1;
@ -2307,7 +2307,7 @@ static zend_bool ZEND_FASTCALL instanceof_interface(const zend_class_entry *inst
uint32_t i;
if (instance_ce->num_interfaces) {
ZEND_ASSERT(!(instance_ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(instance_ce->ce_flags & ZEND_ACC_LINKED);
for (i = 0; i < instance_ce->num_interfaces; i++) {
if (instanceof_interface(instance_ce->interfaces[i], ce)) {
return 1;

6
Zend/zend_vm_def.h

@ -6692,12 +6692,11 @@ ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR)
ce = Z_CE_P(zv);
Z_CE_P(EX_VAR(opline->result.var)) = ce;
if (ce->ce_flags & ZEND_ACC_ANON_BOUND) {
if (ce->ce_flags & ZEND_ACC_LINKED) {
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
zend_do_link_class(ce, NULL);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@ -6713,7 +6712,7 @@ ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, CONST, CONST, JMP_ADDR)
ce = Z_CE_P(zv);
Z_CE_P(EX_VAR(opline->result.var)) = ce;
if (ce->ce_flags & ZEND_ACC_ANON_BOUND) {
if (ce->ce_flags & ZEND_ACC_LINKED) {
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
@ -6727,7 +6726,6 @@ ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, CONST, CONST, JMP_ADDR)
}
zend_do_link_class(ce, parent);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}

6
Zend/zend_vm_execute.h

@ -1596,12 +1596,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE
ce = Z_CE_P(zv);
Z_CE_P(EX_VAR(opline->result.var)) = ce;
if (ce->ce_flags & ZEND_ACC_ANON_BOUND) {
if (ce->ce_flags & ZEND_ACC_LINKED) {
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
zend_do_link_class(ce, NULL);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@ -5801,7 +5800,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_S
ce = Z_CE_P(zv);
Z_CE_P(EX_VAR(opline->result.var)) = ce;
if (ce->ce_flags & ZEND_ACC_ANON_BOUND) {
if (ce->ce_flags & ZEND_ACC_LINKED) {
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
@ -5815,7 +5814,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_S
}
zend_do_link_class(ce, parent);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}

12
ext/opcache/Optimizer/zend_inference.c

@ -2979,7 +2979,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
}
break;
case ZEND_FETCH_CLASS_PARENT:
if (op_array->scope && op_array->scope->parent && !(op_array->scope->ce_flags & ZEND_ACC_UNRESOLVED_PARENT)) {
if (op_array->scope && op_array->scope->parent && (op_array->scope->ce_flags & ZEND_ACC_LINKED)) {
UPDATE_SSA_OBJ_TYPE(op_array->scope->parent, 0, ssa_ops[i].result_def);
} else {
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_ops[i].result_def);
@ -3462,7 +3462,7 @@ unknown_opcode:
static uint32_t get_class_entry_rank(zend_class_entry *ce) {
uint32_t rank = 0;
if (!(ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT)) {
if (ce->ce_flags & ZEND_ACC_LINKED) {
while (ce->parent) {
rank++;
ce = ce->parent;
@ -3487,17 +3487,17 @@ static zend_class_entry *join_class_entries(
while (rank1 != rank2) {
if (rank1 > rank2) {
ce1 = (ce1->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) ? NULL : ce1->parent;
ce1 = !(ce1->ce_flags & ZEND_ACC_LINKED) ? NULL : ce1->parent;
rank1--;
} else {
ce2 = (ce2->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) ? NULL : ce2->parent;
ce2 = !(ce2->ce_flags & ZEND_ACC_LINKED) ? NULL : ce2->parent;
rank2--;
}
}
while (ce1 != ce2) {
ce1 = (ce1->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) ? NULL : ce1->parent;
ce2 = (ce2->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) ? NULL : ce2->parent;
ce1 = !(ce1->ce_flags & ZEND_ACC_LINKED) ? NULL : ce1->parent;
ce2 = !(ce2->ce_flags & ZEND_ACC_LINKED) ? NULL : ce2->parent;
}
if (ce1) {

6
ext/opcache/zend_accelerator_util_funcs.c

@ -292,7 +292,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
*pce = ce = ARENA_REALLOC(old_ce);
ce->refcount = 1;
if (ce->parent && !(ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT)) {
if (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) {
ce->parent = ARENA_REALLOC(ce->parent);
}
@ -312,7 +312,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
/* static members */
if (old_ce->default_static_members_table) {
int i, end;
zend_class_entry *parent = (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) ? NULL : ce->parent;
zend_class_entry *parent = !(ce->ce_flags & ZEND_ACC_LINKED) ? NULL : ce->parent;
ce->default_static_members_table = emalloc(sizeof(zval) * old_ce->default_static_members_count);
i = ce->default_static_members_count - 1;
@ -347,7 +347,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
if (ce->num_interfaces) {
zend_class_name *interface_names;
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES);
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
interface_names = emalloc(sizeof(zend_class_name) * ce->num_interfaces);
memcpy(interface_names, ce->interface_names, sizeof(zend_class_name) * ce->num_interfaces);
ce->interface_names = interface_names;

28
ext/opcache/zend_file_cache.c

@ -611,11 +611,13 @@ static void zend_file_cache_serialize_class(zval *zv,
UNSERIALIZE_PTR(ce);
SERIALIZE_STR(ce->name);
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) {
SERIALIZE_STR(ce->parent_name);
} else {
parent = ce->parent;
SERIALIZE_PTR(ce->parent);
if (ce->parent) {
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
SERIALIZE_STR(ce->parent_name);
} else {
parent = ce->parent;
SERIALIZE_PTR(ce->parent);
}
}
zend_file_cache_serialize_hash(&ce->function_table, script, info, buf, zend_file_cache_serialize_func);
if (ce->default_properties_table) {
@ -655,7 +657,7 @@ static void zend_file_cache_serialize_class(zval *zv,
uint32_t i;
zend_class_name *interface_names;
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES);
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
SERIALIZE_PTR(ce->interface_names);
interface_names = ce->interface_names;
@ -1250,11 +1252,13 @@ static void zend_file_cache_unserialize_class(zval *zv,
ce = Z_PTR_P(zv);
UNSERIALIZE_STR(ce->name);
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) {
UNSERIALIZE_STR(ce->parent_name);
} else {
UNSERIALIZE_PTR(ce->parent);
parent = ce->parent;
if (ce->parent) {
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
UNSERIALIZE_STR(ce->parent_name);
} else {
UNSERIALIZE_PTR(ce->parent);
parent = ce->parent;
}
}
zend_file_cache_unserialize_hash(&ce->function_table,
script, buf, zend_file_cache_unserialize_func, ZEND_FUNCTION_DTOR);
@ -1293,7 +1297,7 @@ static void zend_file_cache_unserialize_class(zval *zv,
if (ce->num_interfaces) {
uint32_t i;
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES);
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
UNSERIALIZE_PTR(ce->interface_names);
for (i = 0; i < ce->num_interfaces; i++) {

8
ext/opcache/zend_persist.c

@ -718,7 +718,7 @@ static void zend_persist_class_entry(zval *zv)
ce = Z_PTR_P(zv) = ZCG(arena_mem);
ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_class_entry)));
zend_accel_store_interned_string(ce->name);
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) {
if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
zend_accel_store_interned_string(ce->parent_name);
}
zend_hash_persist(&ce->function_table, zend_persist_class_method);
@ -736,7 +736,7 @@ static void zend_persist_class_entry(zval *zv)
/* Persist only static properties in this class.
* Static properties from parent classes will be handled in class_copy_ctor */
i = (ce->parent && !(ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT)) ? ce->parent->default_static_members_count : 0;
i = (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) ? ce->parent->default_static_members_count : 0;
for (; i < ce->default_static_members_count; i++) {
zend_persist_zval(&ce->default_static_members_table[i]);
}
@ -765,7 +765,7 @@ static void zend_persist_class_entry(zval *zv)
if (ce->num_interfaces) {
uint32_t i = 0;
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES);
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
for (i = 0; i < ce->num_interfaces; i++) {
zend_accel_store_interned_string(ce->interface_names[i].name);
zend_accel_store_interned_string(ce->interface_names[i].lc_name);
@ -837,7 +837,7 @@ static int zend_update_parent_ce(zval *zv)
{
zend_class_entry *ce = Z_PTR_P(zv);
if (ce->parent && !(ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT)) {
if (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) {
ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent);
}

4
ext/opcache/zend_persist_calc.c

@ -312,7 +312,7 @@ static void zend_persist_class_entry_calc(zval *zv)
if (ce->type == ZEND_USER_CLASS) {
ADD_ARENA_SIZE(sizeof(zend_class_entry));
ADD_INTERNED_STRING(ce->name, 0);
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_PARENT) {
if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
ADD_INTERNED_STRING(ce->parent_name, 0);
}
zend_hash_persist_calc(&ce->function_table, zend_persist_class_method_calc);
@ -348,7 +348,7 @@ static void zend_persist_class_entry_calc(zval *zv)
if (ce->num_interfaces) {
uint32_t i;
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES);
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
for (i = 0; i < ce->num_interfaces; i++) {
ADD_INTERNED_STRING(ce->interface_names[i].name, 0);
ADD_INTERNED_STRING(ce->interface_names[i].lc_name, 0);

6
ext/reflection/php_reflection.c

@ -325,7 +325,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
if (ce->num_interfaces) {
uint32_t i;
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED);
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name));
} else {
@ -4831,7 +4831,7 @@ ZEND_METHOD(reflection_class, getInterfaces)
if (ce->num_interfaces) {
uint32_t i;
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED);
array_init(return_value);
for (i=0; i < ce->num_interfaces; i++) {
zval interface;
@ -4863,7 +4863,7 @@ ZEND_METHOD(reflection_class, getInterfaceNames)
return;
}
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED);
array_init(return_value);
for (i=0; i < ce->num_interfaces; i++) {

2
ext/spl/spl_functions.c

@ -95,7 +95,7 @@ void spl_add_interfaces(zval *list, zend_class_entry * pce, int allow, int ce_fl
uint32_t num_interfaces;
if (pce->num_interfaces) {
ZEND_ASSERT(!(pce->ce_flags & ZEND_ACC_UNRESOLVED_INTERFACES));
ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED);
for (num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) {
spl_add_class_name(list, pce->interfaces[num_interfaces], allow, ce_flags);
}

Loading…
Cancel
Save