mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Simplified property name to string conversion
This commit is contained in:
parent
c42f0ba4f7
commit
57527455eb
1 changed files with 73 additions and 103 deletions
|
@ -173,12 +173,13 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ *
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void zend_std_call_getter(zend_object *zobj, zval *member, zval *retval) /* {{{ */
|
static void zend_std_call_getter(zend_object *zobj, zend_string *prop_name, zval *retval) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry *ce = zobj->ce;
|
zend_class_entry *ce = zobj->ce;
|
||||||
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
||||||
zend_fcall_info fci;
|
zend_fcall_info fci;
|
||||||
zend_fcall_info_cache fcic;
|
zend_fcall_info_cache fcic;
|
||||||
|
zval member;
|
||||||
|
|
||||||
EG(fake_scope) = NULL;
|
EG(fake_scope) = NULL;
|
||||||
|
|
||||||
|
@ -188,11 +189,13 @@ static void zend_std_call_getter(zend_object *zobj, zval *member, zval *retval)
|
||||||
it should return whether the call was successful or not
|
it should return whether the call was successful or not
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ZVAL_STR(&member, prop_name);
|
||||||
|
|
||||||
fci.size = sizeof(fci);
|
fci.size = sizeof(fci);
|
||||||
fci.object = zobj;
|
fci.object = zobj;
|
||||||
fci.retval = retval;
|
fci.retval = retval;
|
||||||
fci.param_count = 1;
|
fci.param_count = 1;
|
||||||
fci.params = member;
|
fci.params = &member;
|
||||||
fci.no_separation = 1;
|
fci.no_separation = 1;
|
||||||
ZVAL_UNDEF(&fci.function_name); /* Unused */
|
ZVAL_UNDEF(&fci.function_name); /* Unused */
|
||||||
|
|
||||||
|
@ -206,7 +209,7 @@ static void zend_std_call_getter(zend_object *zobj, zval *member, zval *retval)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void zend_std_call_setter(zend_object *zobj, zval *member, zval *value) /* {{{ */
|
static void zend_std_call_setter(zend_object *zobj, zend_string *prop_name, zval *value) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry *ce = zobj->ce;
|
zend_class_entry *ce = zobj->ce;
|
||||||
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
||||||
|
@ -221,7 +224,7 @@ static void zend_std_call_setter(zend_object *zobj, zval *member, zval *value) /
|
||||||
value to be set
|
value to be set
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZVAL_COPY_VALUE(&args[0], member);
|
ZVAL_STR(&args[0], prop_name);
|
||||||
ZVAL_COPY_VALUE(&args[1], value);
|
ZVAL_COPY_VALUE(&args[1], value);
|
||||||
ZVAL_UNDEF(&ret);
|
ZVAL_UNDEF(&ret);
|
||||||
|
|
||||||
|
@ -244,13 +247,13 @@ static void zend_std_call_setter(zend_object *zobj, zval *member, zval *value) /
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void zend_std_call_unsetter(zend_object *zobj, zval *member) /* {{{ */
|
static void zend_std_call_unsetter(zend_object *zobj, zend_string *prop_name) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry *ce = zobj->ce;
|
zend_class_entry *ce = zobj->ce;
|
||||||
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
||||||
zend_fcall_info fci;
|
zend_fcall_info fci;
|
||||||
zend_fcall_info_cache fcic;
|
zend_fcall_info_cache fcic;
|
||||||
zval ret;
|
zval ret, member;
|
||||||
|
|
||||||
EG(fake_scope) = NULL;
|
EG(fake_scope) = NULL;
|
||||||
|
|
||||||
|
@ -258,13 +261,14 @@ static void zend_std_call_unsetter(zend_object *zobj, zval *member) /* {{{ */
|
||||||
property name
|
property name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ZVAL_STR(&member, prop_name);
|
||||||
ZVAL_UNDEF(&ret);
|
ZVAL_UNDEF(&ret);
|
||||||
|
|
||||||
fci.size = sizeof(fci);
|
fci.size = sizeof(fci);
|
||||||
fci.object = zobj;
|
fci.object = zobj;
|
||||||
fci.retval = &ret;
|
fci.retval = &ret;
|
||||||
fci.param_count = 1;
|
fci.param_count = 1;
|
||||||
fci.params = member;
|
fci.params = &member;
|
||||||
fci.no_separation = 1;
|
fci.no_separation = 1;
|
||||||
ZVAL_UNDEF(&fci.function_name); /* Unused */
|
ZVAL_UNDEF(&fci.function_name); /* Unused */
|
||||||
|
|
||||||
|
@ -279,12 +283,13 @@ static void zend_std_call_unsetter(zend_object *zobj, zval *member) /* {{{ */
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void zend_std_call_issetter(zend_object *zobj, zval *member, zval *retval) /* {{{ */
|
static void zend_std_call_issetter(zend_object *zobj, zend_string *prop_name, zval *retval) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry *ce = zobj->ce;
|
zend_class_entry *ce = zobj->ce;
|
||||||
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
zend_class_entry *orig_fake_scope = EG(fake_scope);
|
||||||
zend_fcall_info fci;
|
zend_fcall_info fci;
|
||||||
zend_fcall_info_cache fcic;
|
zend_fcall_info_cache fcic;
|
||||||
|
zval member;
|
||||||
|
|
||||||
EG(fake_scope) = NULL;
|
EG(fake_scope) = NULL;
|
||||||
|
|
||||||
|
@ -294,11 +299,13 @@ static void zend_std_call_issetter(zend_object *zobj, zval *member, zval *retval
|
||||||
it should return whether the property is set or not
|
it should return whether the property is set or not
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ZVAL_STR(&member, prop_name);
|
||||||
|
|
||||||
fci.size = sizeof(fci);
|
fci.size = sizeof(fci);
|
||||||
fci.object = zobj;
|
fci.object = zobj;
|
||||||
fci.retval = retval;
|
fci.retval = retval;
|
||||||
fci.param_count = 1;
|
fci.param_count = 1;
|
||||||
fci.params = member;
|
fci.params = &member;
|
||||||
fci.no_separation = 1;
|
fci.no_separation = 1;
|
||||||
ZVAL_UNDEF(&fci.function_name); /* Unused */
|
ZVAL_UNDEF(&fci.function_name); /* Unused */
|
||||||
|
|
||||||
|
@ -603,26 +610,20 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe
|
||||||
ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */
|
ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_object *zobj;
|
zend_object *zobj;
|
||||||
zval tmp_member;
|
zend_string *name, *tmp_name;
|
||||||
zval *retval;
|
zval *retval;
|
||||||
uintptr_t property_offset;
|
uintptr_t property_offset;
|
||||||
uint32_t *guard = NULL;
|
uint32_t *guard = NULL;
|
||||||
|
|
||||||
zobj = Z_OBJ_P(object);
|
zobj = Z_OBJ_P(object);
|
||||||
|
name = zval_get_tmp_string(member, &tmp_name);
|
||||||
ZVAL_UNDEF(&tmp_member);
|
|
||||||
if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
|
|
||||||
ZVAL_STR(&tmp_member, zval_get_string_func(member));
|
|
||||||
member = &tmp_member;
|
|
||||||
cache_slot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG_OBJECT_HANDLERS
|
#if DEBUG_OBJECT_HANDLERS
|
||||||
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
|
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), ZSTR_VAL(name));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make zend_get_property_info silent if we have getter - we may want to use it */
|
/* make zend_get_property_info silent if we have getter - we may want to use it */
|
||||||
property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot);
|
property_offset = zend_get_property_offset(zobj->ce, name, (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot);
|
||||||
|
|
||||||
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
||||||
retval = OBJ_PROP(zobj, property_offset);
|
retval = OBJ_PROP(zobj, property_offset);
|
||||||
|
@ -638,17 +639,17 @@ ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void
|
||||||
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
||||||
|
|
||||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||||
(EXPECTED(p->key == Z_STR_P(member)) ||
|
(EXPECTED(p->key == name) ||
|
||||||
(EXPECTED(p->h == ZSTR_H(Z_STR_P(member))) &&
|
(EXPECTED(p->h == ZSTR_H(name)) &&
|
||||||
EXPECTED(p->key != NULL) &&
|
EXPECTED(p->key != NULL) &&
|
||||||
EXPECTED(zend_string_equal_content(p->key, Z_STR_P(member)))))) {
|
EXPECTED(zend_string_equal_content(p->key, name))))) {
|
||||||
retval = &p->val;
|
retval = &p->val;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||||
}
|
}
|
||||||
retval = zend_hash_find(zobj->properties, Z_STR_P(member));
|
retval = zend_hash_find(zobj->properties, name);
|
||||||
if (EXPECTED(retval)) {
|
if (EXPECTED(retval)) {
|
||||||
if (cache_slot) {
|
if (cache_slot) {
|
||||||
uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
|
uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
|
||||||
|
@ -665,18 +666,17 @@ ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void
|
||||||
/* magic isset */
|
/* magic isset */
|
||||||
if ((type == BP_VAR_IS) && zobj->ce->__isset) {
|
if ((type == BP_VAR_IS) && zobj->ce->__isset) {
|
||||||
zval tmp_result;
|
zval tmp_result;
|
||||||
guard = zend_get_property_guard(zobj, Z_STR_P(member));
|
guard = zend_get_property_guard(zobj, name);
|
||||||
|
|
||||||
if (!((*guard) & IN_ISSET)) {
|
if (!((*guard) & IN_ISSET)) {
|
||||||
if (Z_TYPE(tmp_member) == IS_UNDEF) {
|
if (!tmp_name && !ZSTR_IS_INTERNED(name)) {
|
||||||
ZVAL_COPY(&tmp_member, member);
|
tmp_name = zend_string_copy(name);
|
||||||
member = &tmp_member;
|
|
||||||
}
|
}
|
||||||
GC_ADDREF(zobj);
|
GC_ADDREF(zobj);
|
||||||
ZVAL_UNDEF(&tmp_result);
|
ZVAL_UNDEF(&tmp_result);
|
||||||
|
|
||||||
*guard |= IN_ISSET;
|
*guard |= IN_ISSET;
|
||||||
zend_std_call_issetter(zobj, member, &tmp_result);
|
zend_std_call_issetter(zobj, name, &tmp_result);
|
||||||
*guard &= ~IN_ISSET;
|
*guard &= ~IN_ISSET;
|
||||||
|
|
||||||
if (!zend_is_true(&tmp_result)) {
|
if (!zend_is_true(&tmp_result)) {
|
||||||
|
@ -696,14 +696,14 @@ ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void
|
||||||
}
|
}
|
||||||
} else if (zobj->ce->__get) {
|
} else if (zobj->ce->__get) {
|
||||||
/* magic get */
|
/* magic get */
|
||||||
guard = zend_get_property_guard(zobj, Z_STR_P(member));
|
guard = zend_get_property_guard(zobj, name);
|
||||||
if (!((*guard) & IN_GET)) {
|
if (!((*guard) & IN_GET)) {
|
||||||
/* have getter - try with it! */
|
/* have getter - try with it! */
|
||||||
call_getter_addref:
|
call_getter_addref:
|
||||||
GC_ADDREF(zobj);
|
GC_ADDREF(zobj);
|
||||||
call_getter:
|
call_getter:
|
||||||
*guard |= IN_GET; /* prevent circular getting */
|
*guard |= IN_GET; /* prevent circular getting */
|
||||||
zend_std_call_getter(zobj, member, rv);
|
zend_std_call_getter(zobj, name, rv);
|
||||||
*guard &= ~IN_GET;
|
*guard &= ~IN_GET;
|
||||||
|
|
||||||
if (Z_TYPE_P(rv) != IS_UNDEF) {
|
if (Z_TYPE_P(rv) != IS_UNDEF) {
|
||||||
|
@ -711,7 +711,7 @@ call_getter:
|
||||||
if (!Z_ISREF_P(rv) &&
|
if (!Z_ISREF_P(rv) &&
|
||||||
(type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) {
|
(type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) {
|
||||||
if (UNEXPECTED(Z_TYPE_P(rv) != IS_OBJECT)) {
|
if (UNEXPECTED(Z_TYPE_P(rv) != IS_OBJECT)) {
|
||||||
zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", ZSTR_VAL(zobj->ce->name), Z_STRVAL_P(member));
|
zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -719,7 +719,7 @@ call_getter:
|
||||||
}
|
}
|
||||||
OBJ_RELEASE(zobj);
|
OBJ_RELEASE(zobj);
|
||||||
goto exit;
|
goto exit;
|
||||||
} else if (Z_STRVAL_P(member)[0] == '\0' && Z_STRLEN_P(member) != 0) {
|
} else if (ZSTR_VAL(name)[0] == '\0' && ZSTR_LEN(name) != 0) {
|
||||||
zend_throw_error(NULL, "Cannot access property started with '\\0'");
|
zend_throw_error(NULL, "Cannot access property started with '\\0'");
|
||||||
retval = &EG(uninitialized_zval);
|
retval = &EG(uninitialized_zval);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -727,14 +727,12 @@ call_getter:
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type != BP_VAR_IS)) {
|
if ((type != BP_VAR_IS)) {
|
||||||
zend_error(E_NOTICE,"Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), Z_STRVAL_P(member));
|
zend_error(E_NOTICE,"Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
|
||||||
}
|
}
|
||||||
retval = &EG(uninitialized_zval);
|
retval = &EG(uninitialized_zval);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (UNEXPECTED(Z_REFCOUNTED(tmp_member))) {
|
zend_tmp_string_release(tmp_name);
|
||||||
zval_ptr_dtor(&tmp_member);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -743,20 +741,14 @@ exit:
|
||||||
ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, void **cache_slot) /* {{{ */
|
ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, void **cache_slot) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_object *zobj;
|
zend_object *zobj;
|
||||||
zval tmp_member;
|
zend_string *name, *tmp_name;
|
||||||
zval *variable_ptr;
|
zval *variable_ptr;
|
||||||
uintptr_t property_offset;
|
uintptr_t property_offset;
|
||||||
|
|
||||||
zobj = Z_OBJ_P(object);
|
zobj = Z_OBJ_P(object);
|
||||||
|
name = zval_get_tmp_string(member, &tmp_name);
|
||||||
|
|
||||||
ZVAL_UNDEF(&tmp_member);
|
property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__set != NULL), cache_slot);
|
||||||
if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
|
|
||||||
ZVAL_STR(&tmp_member, zval_get_string_func(member));
|
|
||||||
member = &tmp_member;
|
|
||||||
cache_slot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), cache_slot);
|
|
||||||
|
|
||||||
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
||||||
variable_ptr = OBJ_PROP(zobj, property_offset);
|
variable_ptr = OBJ_PROP(zobj, property_offset);
|
||||||
|
@ -771,7 +763,7 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v
|
||||||
}
|
}
|
||||||
zobj->properties = zend_array_dup(zobj->properties);
|
zobj->properties = zend_array_dup(zobj->properties);
|
||||||
}
|
}
|
||||||
if ((variable_ptr = zend_hash_find(zobj->properties, Z_STR_P(member))) != NULL) {
|
if ((variable_ptr = zend_hash_find(zobj->properties, name)) != NULL) {
|
||||||
found:
|
found:
|
||||||
zend_assign_to_variable(variable_ptr, value, IS_CV);
|
zend_assign_to_variable(variable_ptr, value, IS_CV);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -783,18 +775,18 @@ found:
|
||||||
|
|
||||||
/* magic set */
|
/* magic set */
|
||||||
if (zobj->ce->__set) {
|
if (zobj->ce->__set) {
|
||||||
uint32_t *guard = zend_get_property_guard(zobj, Z_STR_P(member));
|
uint32_t *guard = zend_get_property_guard(zobj, name);
|
||||||
|
|
||||||
if (!((*guard) & IN_SET)) {
|
if (!((*guard) & IN_SET)) {
|
||||||
GC_ADDREF(zobj);
|
GC_ADDREF(zobj);
|
||||||
(*guard) |= IN_SET; /* prevent circular setting */
|
(*guard) |= IN_SET; /* prevent circular setting */
|
||||||
zend_std_call_setter(zobj, member, value);
|
zend_std_call_setter(zobj, name, value);
|
||||||
(*guard) &= ~IN_SET;
|
(*guard) &= ~IN_SET;
|
||||||
OBJ_RELEASE(zobj);
|
OBJ_RELEASE(zobj);
|
||||||
} else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) {
|
} else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) {
|
||||||
goto write_std_property;
|
goto write_std_property;
|
||||||
} else {
|
} else {
|
||||||
if (Z_STRVAL_P(member)[0] == '\0' && Z_STRLEN_P(member) != 0) {
|
if (ZSTR_VAL(name)[0] == '\0' && ZSTR_LEN(name) != 0) {
|
||||||
zend_throw_error(NULL, "Cannot access property started with '\\0'");
|
zend_throw_error(NULL, "Cannot access property started with '\\0'");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -818,14 +810,12 @@ write_std_property:
|
||||||
if (!zobj->properties) {
|
if (!zobj->properties) {
|
||||||
rebuild_object_properties(zobj);
|
rebuild_object_properties(zobj);
|
||||||
}
|
}
|
||||||
zend_hash_add_new(zobj->properties, Z_STR_P(member), value);
|
zend_hash_add_new(zobj->properties, name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (UNEXPECTED(Z_REFCOUNTED(tmp_member))) {
|
zend_tmp_string_release(tmp_name);
|
||||||
zval_ptr_dtor(&tmp_member);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -993,19 +983,13 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int typ
|
||||||
ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_slot) /* {{{ */
|
ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_slot) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_object *zobj;
|
zend_object *zobj;
|
||||||
zval tmp_member;
|
zend_string *name, *tmp_name;
|
||||||
uintptr_t property_offset;
|
uintptr_t property_offset;
|
||||||
|
|
||||||
zobj = Z_OBJ_P(object);
|
zobj = Z_OBJ_P(object);
|
||||||
|
name = zval_get_tmp_string(member, &tmp_name);
|
||||||
|
|
||||||
ZVAL_UNDEF(&tmp_member);
|
property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__unset != NULL), cache_slot);
|
||||||
if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
|
|
||||||
ZVAL_STR(&tmp_member, zval_get_string_func(member));
|
|
||||||
member = &tmp_member;
|
|
||||||
cache_slot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), cache_slot);
|
|
||||||
|
|
||||||
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
||||||
zval *slot = OBJ_PROP(zobj, property_offset);
|
zval *slot = OBJ_PROP(zobj, property_offset);
|
||||||
|
@ -1026,7 +1010,7 @@ ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_s
|
||||||
}
|
}
|
||||||
zobj->properties = zend_array_dup(zobj->properties);
|
zobj->properties = zend_array_dup(zobj->properties);
|
||||||
}
|
}
|
||||||
if (EXPECTED(zend_hash_del(zobj->properties, Z_STR_P(member)) != FAILURE)) {
|
if (EXPECTED(zend_hash_del(zobj->properties, name) != FAILURE)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
} else if (UNEXPECTED(EG(exception))) {
|
} else if (UNEXPECTED(EG(exception))) {
|
||||||
|
@ -1035,14 +1019,14 @@ ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_s
|
||||||
|
|
||||||
/* magic unset */
|
/* magic unset */
|
||||||
if (zobj->ce->__unset) {
|
if (zobj->ce->__unset) {
|
||||||
uint32_t *guard = zend_get_property_guard(zobj, Z_STR_P(member));
|
uint32_t *guard = zend_get_property_guard(zobj, name);
|
||||||
if (!((*guard) & IN_UNSET)) {
|
if (!((*guard) & IN_UNSET)) {
|
||||||
/* have unseter - try with it! */
|
/* have unseter - try with it! */
|
||||||
(*guard) |= IN_UNSET; /* prevent circular unsetting */
|
(*guard) |= IN_UNSET; /* prevent circular unsetting */
|
||||||
zend_std_call_unsetter(zobj, member);
|
zend_std_call_unsetter(zobj, name);
|
||||||
(*guard) &= ~IN_UNSET;
|
(*guard) &= ~IN_UNSET;
|
||||||
} else {
|
} else {
|
||||||
if (Z_STRVAL_P(member)[0] == '\0' && Z_STRLEN_P(member) != 0) {
|
if (ZSTR_VAL(name)[0] == '\0' && ZSTR_LEN(name) != 0) {
|
||||||
zend_throw_error(NULL, "Cannot access property started with '\\0'");
|
zend_throw_error(NULL, "Cannot access property started with '\\0'");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -1050,9 +1034,7 @@ ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_s
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (UNEXPECTED(Z_REFCOUNTED(tmp_member))) {
|
zend_tmp_string_release(tmp_name);
|
||||||
zval_ptr_dtor(&tmp_member);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -1603,19 +1585,13 @@ ZEND_API int zend_std_has_property(zval *object, zval *member, int has_set_exist
|
||||||
zend_object *zobj;
|
zend_object *zobj;
|
||||||
int result;
|
int result;
|
||||||
zval *value = NULL;
|
zval *value = NULL;
|
||||||
zval tmp_member;
|
zend_string *name, *tmp_name;
|
||||||
uintptr_t property_offset;
|
uintptr_t property_offset;
|
||||||
|
|
||||||
zobj = Z_OBJ_P(object);
|
zobj = Z_OBJ_P(object);
|
||||||
|
name = zval_get_tmp_string(member, &tmp_name);
|
||||||
|
|
||||||
ZVAL_UNDEF(&tmp_member);
|
property_offset = zend_get_property_offset(zobj->ce, name, 1, cache_slot);
|
||||||
if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
|
|
||||||
ZVAL_STR(&tmp_member, zval_get_string_func(member));
|
|
||||||
member = &tmp_member;
|
|
||||||
cache_slot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), 1, cache_slot);
|
|
||||||
|
|
||||||
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
|
||||||
value = OBJ_PROP(zobj, property_offset);
|
value = OBJ_PROP(zobj, property_offset);
|
||||||
|
@ -1631,35 +1607,32 @@ ZEND_API int zend_std_has_property(zval *object, zval *member, int has_set_exist
|
||||||
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
||||||
|
|
||||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||||
(EXPECTED(p->key == Z_STR_P(member)) ||
|
(EXPECTED(p->key == name) ||
|
||||||
(EXPECTED(p->h == ZSTR_H(Z_STR_P(member))) &&
|
(EXPECTED(p->h == ZSTR_H(name)) &&
|
||||||
EXPECTED(p->key != NULL) &&
|
EXPECTED(p->key != NULL) &&
|
||||||
EXPECTED(zend_string_equal_content(p->key, Z_STR_P(member)))))) {
|
EXPECTED(zend_string_equal_content(p->key, name))))) {
|
||||||
value = &p->val;
|
value = &p->val;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||||
}
|
}
|
||||||
value = zend_hash_find(zobj->properties, Z_STR_P(member));
|
value = zend_hash_find(zobj->properties, name);
|
||||||
if (value) {
|
if (value) {
|
||||||
if (cache_slot) {
|
if (cache_slot) {
|
||||||
uintptr_t idx = (char*)value - (char*)zobj->properties->arData;
|
uintptr_t idx = (char*)value - (char*)zobj->properties->arData;
|
||||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||||
}
|
}
|
||||||
found:
|
found:
|
||||||
switch (has_set_exists) {
|
if (has_set_exists == ZEND_PROPERTY_NOT_EMPTY) {
|
||||||
case ZEND_PROPERTY_ISSET:
|
result = zend_is_true(value);
|
||||||
ZVAL_DEREF(value);
|
} else if (has_set_exists < ZEND_PROPERTY_NOT_EMPTY) {
|
||||||
result = (Z_TYPE_P(value) != IS_NULL);
|
ZEND_ASSERT(has_set_exists == ZEND_PROPERTY_ISSET);
|
||||||
break;
|
ZVAL_DEREF(value);
|
||||||
case ZEND_PROPERTY_EXISTS:
|
result = (Z_TYPE_P(value) != IS_NULL);
|
||||||
result = 1;
|
} else {
|
||||||
break;
|
ZEND_ASSERT(has_set_exists == ZEND_PROPERTY_EXISTS);
|
||||||
case ZEND_PROPERTY_NOT_EMPTY:
|
result = 1;
|
||||||
default:
|
|
||||||
result = zend_is_true(value);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -1671,25 +1644,24 @@ found:
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
if ((has_set_exists != ZEND_PROPERTY_EXISTS) && zobj->ce->__isset) {
|
if ((has_set_exists != ZEND_PROPERTY_EXISTS) && zobj->ce->__isset) {
|
||||||
uint32_t *guard = zend_get_property_guard(zobj, Z_STR_P(member));
|
uint32_t *guard = zend_get_property_guard(zobj, name);
|
||||||
|
|
||||||
if (!((*guard) & IN_ISSET)) {
|
if (!((*guard) & IN_ISSET)) {
|
||||||
zval rv;
|
zval rv;
|
||||||
|
|
||||||
/* have issetter - try with it! */
|
/* have issetter - try with it! */
|
||||||
if (Z_TYPE(tmp_member) == IS_UNDEF) {
|
if (!tmp_name && !ZSTR_IS_INTERNED(name)) {
|
||||||
ZVAL_COPY(&tmp_member, member);
|
tmp_name = zend_string_copy(name);
|
||||||
member = &tmp_member;
|
|
||||||
}
|
}
|
||||||
GC_ADDREF(zobj);
|
GC_ADDREF(zobj);
|
||||||
(*guard) |= IN_ISSET; /* prevent circular getting */
|
(*guard) |= IN_ISSET; /* prevent circular getting */
|
||||||
zend_std_call_issetter(zobj, member, &rv);
|
zend_std_call_issetter(zobj, name, &rv);
|
||||||
result = zend_is_true(&rv);
|
result = zend_is_true(&rv);
|
||||||
zval_ptr_dtor(&rv);
|
zval_ptr_dtor(&rv);
|
||||||
if (has_set_exists == ZEND_PROPERTY_NOT_EMPTY && result) {
|
if (has_set_exists == ZEND_PROPERTY_NOT_EMPTY && result) {
|
||||||
if (EXPECTED(!EG(exception)) && zobj->ce->__get && !((*guard) & IN_GET)) {
|
if (EXPECTED(!EG(exception)) && zobj->ce->__get && !((*guard) & IN_GET)) {
|
||||||
(*guard) |= IN_GET;
|
(*guard) |= IN_GET;
|
||||||
zend_std_call_getter(zobj, member, &rv);
|
zend_std_call_getter(zobj, name, &rv);
|
||||||
(*guard) &= ~IN_GET;
|
(*guard) &= ~IN_GET;
|
||||||
result = i_zend_is_true(&rv);
|
result = i_zend_is_true(&rv);
|
||||||
zval_ptr_dtor(&rv);
|
zval_ptr_dtor(&rv);
|
||||||
|
@ -1703,9 +1675,7 @@ found:
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (UNEXPECTED(Z_REFCOUNTED(tmp_member))) {
|
zend_tmp_string_release(tmp_name);
|
||||||
zval_ptr_dtor(&tmp_member);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue