- 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.
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;
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;
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) {
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;
}
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;
}
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;
}
}
#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 | | | */
#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 | | | */
/* 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) | | | */
/* ============== | | | */
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) {
}
}
- 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;
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) {
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);
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++) {
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);
}
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;
} 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",
}
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) {
}
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++) {
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;
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;
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();
}
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, parent);
- ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
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();
}
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, parent);
- ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
}
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);
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;
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) {
*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);
}
/* 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;
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;
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) {
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;
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);
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++) {
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);
/* 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]);
}
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);
{
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);
}
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);
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);
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 {
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;
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++) {
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);
}