mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Improved object property access.
This commit is contained in:
parent
6b8328de74
commit
75041379a6
@ -1207,7 +1207,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC
|
||||
|
||||
for (i = 0; i < class_type->default_properties_count; i++) {
|
||||
if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) {
|
||||
zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC);
|
||||
zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1251,8 +1251,9 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti
|
||||
if (property_info != ZEND_WRONG_PROPERTY_INFO &&
|
||||
property_info &&
|
||||
(property_info->flags & ZEND_ACC_STATIC) == 0) {
|
||||
ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop);
|
||||
ZVAL_INDIRECT(prop, &object->properties_table[property_info->offset]);
|
||||
zval *slot = OBJ_PROP(object, property_info->offset);
|
||||
ZVAL_COPY_VALUE(slot, prop);
|
||||
ZVAL_INDIRECT(prop, slot);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
@ -1270,11 +1271,12 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties
|
||||
if (property_info != ZEND_WRONG_PROPERTY_INFO &&
|
||||
property_info &&
|
||||
(property_info->flags & ZEND_ACC_STATIC) == 0) {
|
||||
zval_ptr_dtor(&object->properties_table[property_info->offset]);
|
||||
ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop);
|
||||
zval_add_ref(&object->properties_table[property_info->offset]);
|
||||
zval *slot = OBJ_PROP(object, property_info->offset);
|
||||
zval_ptr_dtor(slot);
|
||||
ZVAL_COPY_VALUE(slot, prop);
|
||||
zval_add_ref(slot);
|
||||
if (object->properties) {
|
||||
ZVAL_INDIRECT(&tmp, &object->properties_table[property_info->offset]);
|
||||
ZVAL_INDIRECT(&tmp, slot);
|
||||
zend_hash_update(object->properties, key, &tmp);
|
||||
}
|
||||
} else {
|
||||
@ -3618,13 +3620,14 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
||||
if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
|
||||
(property_info_ptr->flags & ZEND_ACC_STATIC) == 0) {
|
||||
property_info->offset = property_info_ptr->offset;
|
||||
zval_ptr_dtor(&ce->default_properties_table[property_info->offset]);
|
||||
zval_ptr_dtor(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]);
|
||||
zend_hash_del(&ce->properties_info, name);
|
||||
} else {
|
||||
property_info->offset = ce->default_properties_count++;
|
||||
property_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count);
|
||||
ce->default_properties_count++;
|
||||
ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS);
|
||||
}
|
||||
ZVAL_COPY_VALUE(&ce->default_properties_table[property_info->offset], property);
|
||||
ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property);
|
||||
}
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
switch(Z_TYPE_P(property)) {
|
||||
|
@ -954,12 +954,10 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
|
||||
continue;
|
||||
}
|
||||
prop = NULL;
|
||||
if (prop_info->offset >= 0) {
|
||||
if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
|
||||
prop = &ce->default_static_members_table[prop_info->offset];
|
||||
} else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
|
||||
prop = &ce->default_properties_table[prop_info->offset];
|
||||
}
|
||||
if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
|
||||
prop = &ce->default_static_members_table[prop_info->offset];
|
||||
} else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
|
||||
prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
|
||||
}
|
||||
if (!prop || Z_TYPE_P(prop) == IS_UNDEF) {
|
||||
continue;
|
||||
|
@ -227,13 +227,23 @@ typedef struct _zend_try_catch_element {
|
||||
char *zend_visibility_string(uint32_t fn_flags);
|
||||
|
||||
typedef struct _zend_property_info {
|
||||
uint32_t offset; /* property offset for object properties or
|
||||
property index for static properties */
|
||||
uint32_t flags;
|
||||
int offset;
|
||||
zend_string *name;
|
||||
zend_string *doc_comment;
|
||||
zend_class_entry *ce;
|
||||
} zend_property_info;
|
||||
|
||||
#define OBJ_PROP(obj, offset) \
|
||||
((zval*)((char*)(obj) + offset))
|
||||
#define OBJ_PROP_NUM(obj, num) \
|
||||
(&(obj)->properties_table[(num)])
|
||||
#define OBJ_PROP_TO_OFFSET(num) \
|
||||
((uint32_t)(zend_uintptr_t)OBJ_PROP_NUM(((zend_object*)NULL), num))
|
||||
#define OBJ_PROP_TO_NUM(offset) \
|
||||
((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval))
|
||||
|
||||
typedef struct _zend_arg_info {
|
||||
const char *name; // TODO: convert into zend_string ???
|
||||
uint32_t name_len;
|
||||
|
@ -1292,7 +1292,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
|
||||
zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC);
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type TSRMLS_DC)
|
||||
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type TSRMLS_DC)
|
||||
{
|
||||
if (container_op_type != IS_UNUSED) {
|
||||
ZVAL_DEREF(container);
|
||||
@ -1316,6 +1316,26 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prop_op_type == IS_CONST &&
|
||||
EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) {
|
||||
zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 1);
|
||||
zend_object *zobj = Z_OBJ_P(container);
|
||||
zval *retval;
|
||||
|
||||
if (EXPECTED(prop_info)) {
|
||||
retval = OBJ_PROP(zobj, prop_info->offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
ZVAL_INDIRECT(result, retval);
|
||||
return;
|
||||
}
|
||||
} else if (EXPECTED(zobj->properties != NULL)) {
|
||||
retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
|
||||
if (EXPECTED(retval)) {
|
||||
ZVAL_INDIRECT(result, retval);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
|
||||
zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC);
|
||||
if (NULL == ptr) {
|
||||
|
@ -602,9 +602,12 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro
|
||||
if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name->val, key->val, zend_visibility_string(parent_info->flags), parent_ce->name->val, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
|
||||
} else if ((child_info->flags & ZEND_ACC_STATIC) == 0) {
|
||||
zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset]));
|
||||
ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset];
|
||||
ZVAL_UNDEF(&ce->default_properties_table[child_info->offset]);
|
||||
int parent_num = OBJ_PROP_TO_NUM(parent_info->offset);
|
||||
int child_num = OBJ_PROP_TO_NUM(child_info->offset);
|
||||
|
||||
zval_ptr_dtor(&(ce->default_properties_table[parent_num]));
|
||||
ce->default_properties_table[parent_num] = ce->default_properties_table[child_num];
|
||||
ZVAL_UNDEF(&ce->default_properties_table[child_num]);
|
||||
child_info->offset = parent_info->offset;
|
||||
}
|
||||
return 0; /* Don't copy from parent */
|
||||
@ -797,7 +800,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
||||
if (property_info->flags & ZEND_ACC_STATIC) {
|
||||
property_info->offset += parent_ce->default_static_members_count;
|
||||
} else {
|
||||
property_info->offset += parent_ce->default_properties_count;
|
||||
property_info->offset += parent_ce->default_properties_count * sizeof(zval);
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
@ -1421,8 +1424,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
|
||||
|| (Z_LVAL(compare_result) != 0);
|
||||
} else {
|
||||
not_compatible = (FAILURE == compare_function(&compare_result,
|
||||
&ce->default_properties_table[coliding_prop->offset],
|
||||
&ce->traits[i]->default_properties_table[property_info->offset] TSRMLS_CC))
|
||||
&ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)],
|
||||
&ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)] TSRMLS_CC))
|
||||
|| (Z_LVAL(compare_result) != 0);
|
||||
}
|
||||
} else {
|
||||
@ -1454,7 +1457,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
|
||||
if (flags & ZEND_ACC_STATIC) {
|
||||
prop_value = &ce->traits[i]->default_static_members_table[property_info->offset];
|
||||
} else {
|
||||
prop_value = &ce->traits[i]->default_properties_table[property_info->offset];
|
||||
prop_value = &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)];
|
||||
}
|
||||
if (Z_REFCOUNTED_P(prop_value)) Z_ADDREF_P(prop_value);
|
||||
|
||||
|
@ -80,11 +80,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
|
||||
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
|
||||
if (/*prop_info->ce == ce &&*/
|
||||
(prop_info->flags & ZEND_ACC_STATIC) == 0 &&
|
||||
prop_info->offset >= 0 &&
|
||||
Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) {
|
||||
Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) {
|
||||
zval zv;
|
||||
|
||||
ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]);
|
||||
ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset));
|
||||
zend_hash_add_new(zobj->properties, prop_info->name, &zv);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
@ -94,11 +93,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
|
||||
if (prop_info->ce == ce &&
|
||||
(prop_info->flags & ZEND_ACC_STATIC) == 0 &&
|
||||
(prop_info->flags & ZEND_ACC_PRIVATE) != 0 &&
|
||||
prop_info->offset >= 0 &&
|
||||
Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) {
|
||||
Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) {
|
||||
zval zv;
|
||||
|
||||
ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]);
|
||||
ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset));
|
||||
zend_hash_add(zobj->properties, prop_info->name, &zv);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
@ -288,7 +286,7 @@ static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_cla
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot TSRMLS_DC) /* {{{ */
|
||||
static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, int allow_static, void **cache_slot TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *zv;
|
||||
zend_property_info *property_info = NULL;
|
||||
@ -324,8 +322,13 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_
|
||||
if (EXPECTED(zend_verify_property_access(property_info, ce TSRMLS_CC) != 0)) {
|
||||
if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
|
||||
|| UNEXPECTED((flags & ZEND_ACC_PRIVATE))) {
|
||||
if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0) && !silent) {
|
||||
zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val);
|
||||
if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
|
||||
if (!silent) {
|
||||
zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val);
|
||||
}
|
||||
if (!allow_static) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
@ -342,7 +345,9 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_
|
||||
&& (zv = zend_hash_find(&EG(scope)->properties_info, member)) != NULL
|
||||
&& ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
|
||||
property_info = (zend_property_info*)Z_PTR_P(zv);
|
||||
goto exit;
|
||||
if (!allow_static && UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (UNEXPECTED(property_info == NULL)) {
|
||||
exit_dynamic:
|
||||
if (cache_slot) {
|
||||
@ -354,9 +359,6 @@ exit_dynamic:
|
||||
if (!silent) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(flags), ce->name->val, member->val);
|
||||
}
|
||||
if (cache_slot) {
|
||||
CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, ZEND_WRONG_PROPERTY_INFO);
|
||||
}
|
||||
return ZEND_WRONG_PROPERTY_INFO;
|
||||
}
|
||||
|
||||
@ -370,7 +372,7 @@ exit:
|
||||
|
||||
ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_string *member, int silent TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return zend_get_property_info_quick(ce, member, silent, NULL TSRMLS_CC);
|
||||
return zend_get_property_info_quick(ce, member, silent, 1, NULL TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -388,7 +390,7 @@ ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_inf
|
||||
} else {
|
||||
member = zend_string_copy(prop_info_name);
|
||||
}
|
||||
property_info = zend_get_property_info_quick(zobj->ce, member, 1, NULL TSRMLS_CC);
|
||||
property_info = zend_get_property_info_quick(zobj->ce, member, 1, 1, NULL TSRMLS_CC);
|
||||
zend_string_release(member);
|
||||
if (property_info == NULL) {
|
||||
/* undefined public property */
|
||||
@ -451,13 +453,11 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
|
||||
#endif
|
||||
|
||||
/* make zend_get_property_info silent if we have getter - we may want to use it */
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot TSRMLS_CC);
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), 0, cache_slot TSRMLS_CC);
|
||||
|
||||
if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) {
|
||||
if (EXPECTED(property_info != NULL) &&
|
||||
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
|
||||
|
||||
retval = &zobj->properties_table[property_info->offset];
|
||||
if (EXPECTED(property_info != NULL)) {
|
||||
retval = OBJ_PROP(zobj, property_info->offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
goto exit;
|
||||
}
|
||||
@ -534,13 +534,11 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v
|
||||
cache_slot = NULL;
|
||||
}
|
||||
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), cache_slot TSRMLS_CC);
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), 0, cache_slot TSRMLS_CC);
|
||||
|
||||
if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) {
|
||||
if (EXPECTED(property_info != NULL) &&
|
||||
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
|
||||
|
||||
variable_ptr = &zobj->properties_table[property_info->offset];
|
||||
if (EXPECTED(property_info != NULL)) {
|
||||
variable_ptr = OBJ_PROP(zobj, property_info->offset);
|
||||
if (Z_TYPE_P(variable_ptr) != IS_UNDEF) {
|
||||
goto found;
|
||||
}
|
||||
@ -638,7 +636,7 @@ write_std_property:
|
||||
if (EXPECTED(property_info != NULL) &&
|
||||
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
|
||||
|
||||
ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value);
|
||||
ZVAL_COPY_VALUE(OBJ_PROP(zobj, property_info->offset), value);
|
||||
} else {
|
||||
if (!zobj->properties) {
|
||||
rebuild_object_properties(zobj);
|
||||
@ -754,13 +752,11 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type,
|
||||
fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), name->val);
|
||||
#endif
|
||||
|
||||
property_info = zend_get_property_info_quick(zobj->ce, name, (zobj->ce->__get != NULL), cache_slot TSRMLS_CC);
|
||||
property_info = zend_get_property_info_quick(zobj->ce, name, (zobj->ce->__get != NULL), 0, cache_slot TSRMLS_CC);
|
||||
|
||||
if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) {
|
||||
if (EXPECTED(property_info != NULL) &&
|
||||
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
|
||||
|
||||
retval = &zobj->properties_table[property_info->offset];
|
||||
if (EXPECTED(property_info != NULL)) {
|
||||
retval = OBJ_PROP(zobj, property_info->offset);
|
||||
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
|
||||
if (EXPECTED(!zobj->ce->__get) ||
|
||||
UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
|
||||
@ -816,15 +812,15 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo
|
||||
cache_slot = NULL;
|
||||
}
|
||||
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), cache_slot TSRMLS_CC);
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), 0, cache_slot TSRMLS_CC);
|
||||
|
||||
if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) {
|
||||
if (EXPECTED(property_info != NULL) &&
|
||||
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
|
||||
if (EXPECTED(property_info != NULL)) {
|
||||
zval *slot = OBJ_PROP(zobj, property_info->offset);
|
||||
|
||||
if (Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
|
||||
zval_ptr_dtor(&zobj->properties_table[property_info->offset]);
|
||||
ZVAL_UNDEF(&zobj->properties_table[property_info->offset]);
|
||||
if (Z_TYPE_P(slot) != IS_UNDEF) {
|
||||
zval_ptr_dtor(slot);
|
||||
ZVAL_UNDEF(slot);
|
||||
goto exit;
|
||||
}
|
||||
} else if (EXPECTED(zobj->properties != NULL) &&
|
||||
@ -1413,13 +1409,11 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
|
||||
cache_slot = NULL;
|
||||
}
|
||||
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), 1, cache_slot TSRMLS_CC);
|
||||
property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), 1, 0, cache_slot TSRMLS_CC);
|
||||
|
||||
if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) {
|
||||
if (EXPECTED(property_info != NULL) &&
|
||||
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
|
||||
|
||||
value = &zobj->properties_table[property_info->offset];
|
||||
if (EXPECTED(property_info != NULL)) {
|
||||
value = OBJ_PROP(zobj, property_info->offset);
|
||||
if (Z_TYPE_P(value) != IS_UNDEF) {
|
||||
goto found;
|
||||
}
|
||||
|
@ -1324,11 +1324,33 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
zval *retval;
|
||||
|
||||
/* here we are sure we are dealing with an object */
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
do {
|
||||
if (OP2_TYPE == IS_CONST &&
|
||||
EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
|
||||
zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
|
||||
zend_object *zobj = Z_OBJ_P(container);
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
}
|
||||
if (EXPECTED(prop_info)) {
|
||||
retval = OBJ_PROP(zobj, prop_info->offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
break;
|
||||
}
|
||||
} else if (EXPECTED(zobj->properties != NULL)) {
|
||||
retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
|
||||
if (EXPECTED(retval)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
FREE_OP2();
|
||||
@ -1352,7 +1374,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1376,7 +1398,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1393,6 +1415,8 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV
|
||||
zval *container;
|
||||
zend_free_op free_op2;
|
||||
zval *offset;
|
||||
zval *retval;
|
||||
zend_property_info *prop_info;
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
|
||||
@ -1405,11 +1429,33 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV
|
||||
zval *retval;
|
||||
|
||||
/* here we are sure we are dealing with an object */
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
do {
|
||||
if (OP2_TYPE == IS_CONST &&
|
||||
EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
|
||||
zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
|
||||
zend_object *zobj = Z_OBJ_P(container);
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
}
|
||||
if (EXPECTED(prop_info)) {
|
||||
retval = OBJ_PROP(zobj, prop_info->offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
break;
|
||||
}
|
||||
} else if (EXPECTED(zobj->properties != NULL)) {
|
||||
retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
|
||||
if (EXPECTED(retval)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
FREE_OP2();
|
||||
@ -1438,7 +1484,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1464,7 +1510,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3363,7 +3363,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
|
||||
if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
|
||||
prop = &ce->default_static_members_table[prop_info->offset];
|
||||
} else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
|
||||
prop = &ce->default_properties_table[prop_info->offset];
|
||||
prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
|
||||
}
|
||||
}
|
||||
if (!prop) {
|
||||
|
Loading…
Reference in New Issue
Block a user