summaryrefslogtreecommitdiff
path: root/Zend/zend_object_handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r--Zend/zend_object_handlers.c137
1 files changed, 81 insertions, 56 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index be1631f587..f10e2c58a6 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -63,47 +63,62 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
if (!zobj->properties) {
zend_property_info *prop_info;
zend_class_entry *ce = zobj->ce;
- uint32_t flags = 0;
+ int i;
zobj->properties = zend_new_array(ce->default_properties_count);
if (ce->default_properties_count) {
zend_hash_real_init_mixed(zobj->properties);
- ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
- if (!(prop_info->flags & ZEND_ACC_STATIC)) {
- flags |= prop_info->flags;
+ for (i = 0; i < ce->default_properties_count; i++) {
+ prop_info = ce->properties_info_table[i];
- if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) {
- HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
- }
-
- _zend_hash_append_ind(zobj->properties, prop_info->name,
- OBJ_PROP(zobj, prop_info->offset));
+ if (!prop_info) {
+ continue;
}
- } ZEND_HASH_FOREACH_END();
- if (flags & ZEND_ACC_CHANGED) {
- while (ce->parent && ce->parent->default_properties_count) {
- ce = ce->parent;
- ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
- if (prop_info->ce == ce &&
- !(prop_info->flags & ZEND_ACC_STATIC) &&
- (prop_info->flags & ZEND_ACC_PRIVATE)) {
- zval zv;
-
- if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) {
- HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
- }
-
- ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset));
- zend_hash_add(zobj->properties, prop_info->name, &zv);
- }
- } ZEND_HASH_FOREACH_END();
+
+ if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) {
+ HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
}
+
+ _zend_hash_append_ind(zobj->properties, prop_info->name,
+ OBJ_PROP(zobj, prop_info->offset));
}
}
}
}
/* }}} */
+ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* {{{ */
+{
+ zend_property_info *prop_info;
+ zend_class_entry *ce = zobj->ce;
+ HashTable *ht;
+ zval* prop;
+ int i;
+
+ ZEND_ASSERT(!zobj->properties);
+ ht = zend_new_array(ce->default_properties_count);
+ if (ce->default_properties_count) {
+ zend_hash_real_init_mixed(ht);
+ for (i = 0; i < ce->default_properties_count; i++) {
+ prop_info = ce->properties_info_table[i];
+
+ if (!prop_info) {
+ continue;
+ }
+
+ prop = OBJ_PROP(zobj, prop_info->offset);
+ if (UNEXPECTED(Z_TYPE_P(prop) == IS_UNDEF)) {
+ continue;
+ }
+
+ Z_TRY_ADDREF_P(prop);
+ _zend_hash_append(ht, prop_info->name, prop);
+ }
+ }
+ return ht;
+}
+/* }}} */
+
ZEND_API HashTable *zend_std_get_properties(zend_object *zobj) /* {{{ */
{
if (!zobj->properties) {
@@ -209,7 +224,7 @@ static void zend_std_call_issetter(zend_object *zobj, zend_string *prop_name, zv
/* }}} */
-static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */
+static zend_always_inline bool is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */
{
child_class = child_class->parent;
while (child_class) {
@@ -443,7 +458,7 @@ found:
}
/* }}} */
-ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_info_name, zend_bool is_dynamic) /* {{{ */
+ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_info_name, bool is_dynamic) /* {{{ */
{
zend_property_info *property_info;
const char *class_name = NULL;
@@ -691,7 +706,7 @@ exit:
}
/* }}} */
-static zend_always_inline zend_bool property_uses_strict_types() {
+static zend_always_inline bool property_uses_strict_types() {
zend_execute_data *execute_data = EG(current_execute_data);
return execute_data
&& execute_data->func
@@ -1263,11 +1278,29 @@ static zend_always_inline zend_function *zend_get_user_callstatic_function(zend_
}
/* }}} */
+static zend_always_inline zend_function *get_static_method_fallback(
+ zend_class_entry *ce, zend_string *function_name)
+{
+ zend_object *object;
+ if (ce->__call &&
+ (object = zend_get_this_object(EG(current_execute_data))) != NULL &&
+ instanceof_function(object->ce, ce)) {
+ /* Call the top-level defined __call().
+ * see: tests/classes/__call_004.phpt */
+
+ ZEND_ASSERT(object->ce->__call);
+ return zend_get_user_call_function(object->ce, function_name);
+ } else if (ce->__callstatic) {
+ return zend_get_user_callstatic_function(ce, function_name);
+ } else {
+ return NULL;
+ }
+}
+
ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name, const zval *key) /* {{{ */
{
zend_function *fbc = NULL;
zend_string *lc_function_name;
- zend_object *object;
zend_class_entry *scope;
if (EXPECTED(key != NULL)) {
@@ -1293,19 +1326,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
if (UNEXPECTED(!key)) {
zend_string_release_ex(lc_function_name, 0);
}
- if (ce->__call &&
- (object = zend_get_this_object(EG(current_execute_data))) != NULL &&
- instanceof_function(object->ce, ce)) {
- /* Call the top-level defined __call().
- * see: tests/classes/__call_004.phpt */
-
- ZEND_ASSERT(object->ce->__call);
- return zend_get_user_call_function(object->ce, function_name);
- } else if (ce->__callstatic) {
- return zend_get_user_callstatic_function(ce, function_name);
- } else {
- return NULL;
- }
+ return get_static_method_fallback(ce, function_name);
}
} while (0);
@@ -1321,12 +1342,11 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
if (UNEXPECTED(fbc->common.scope != scope)) {
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
- if (ce->__callstatic) {
- fbc = zend_get_user_callstatic_function(ce, function_name);
- } else {
+ zend_function *fallback_fbc = get_static_method_fallback(ce, function_name);
+ if (!fallback_fbc) {
zend_bad_method_call(fbc, function_name, scope);
- fbc = NULL;
}
+ fbc = fallback_fbc;
}
}
}
@@ -1440,7 +1460,7 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
return zend_std_get_static_property_with_info(ce, property_name, type, &prop_info);
}
-ZEND_API ZEND_COLD zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name) /* {{{ */
+ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name) /* {{{ */
{
zend_throw_error(NULL, "Attempt to unset static property %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(property_name));
return 0;
@@ -1550,6 +1570,7 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
}
if (!zobj1->properties && !zobj2->properties) {
zend_property_info *info;
+ int i;
if (!zobj1->ce->default_properties_count) {
return 0;
@@ -1565,14 +1586,18 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
}
Z_PROTECT_RECURSION_P(o1);
- ZEND_HASH_FOREACH_PTR(&zobj1->ce->properties_info, info) {
- zval *p1 = OBJ_PROP(zobj1, info->offset);
- zval *p2 = OBJ_PROP(zobj2, info->offset);
+ for (i = 0; i < zobj1->ce->default_properties_count; i++) {
+ zval *p1, *p2;
+
+ info = zobj1->ce->properties_info_table[i];
- if (info->flags & ZEND_ACC_STATIC) {
+ if (!info) {
continue;
}
+ p1 = OBJ_PROP(zobj1, info->offset);
+ p2 = OBJ_PROP(zobj2, info->offset);
+
if (Z_TYPE_P(p1) != IS_UNDEF) {
if (Z_TYPE_P(p2) != IS_UNDEF) {
int ret;
@@ -1592,7 +1617,7 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
return 1;
}
}
- } ZEND_HASH_FOREACH_END();
+ }
Z_UNPROTECT_RECURSION_P(o1);
return 0;
@@ -1751,7 +1776,7 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj,
}
/* }}} */
-ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, zend_bool check_only) /* {{{ */
+ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only) /* {{{ */
{
zval *func;
zend_class_entry *ce = obj->ce;