summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2003-02-05 14:27:30 +0000
committerZeev Suraski <zeev@php.net>2003-02-05 14:27:30 +0000
commitf660d28143cc105463082eb5e6612c5cc3d114e3 (patch)
treea411db8b02763b2c98e166a8f39c0c2b89e6ac08
parent17439aa9c4c3b33c757672f38f3a44d124f1c440 (diff)
downloadphp-git-f660d28143cc105463082eb5e6612c5cc3d114e3.tar.gz
- read_property cleanup
- Implement unset/isset/empty for PPP
-rw-r--r--Zend/zend_execute.c8
-rw-r--r--Zend/zend_object_handlers.c73
-rw-r--r--Zend/zend_object_handlers.h2
-rw-r--r--Zend/zend_objects_API.c2
4 files changed, 54 insertions, 31 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 8d32f44da6..b452b83fbc 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -391,7 +391,7 @@ static inline void zend_assign_to_object_op(znode *result, znode *op1, znode *op
}
if (!have_get_ptr) {
- zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC);
+ zval *z = Z_OBJ_HT_P(object)->read_property(object, property TSRMLS_CC);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
@@ -1013,7 +1013,7 @@ static void zend_fetch_property_address_read(znode *result, znode *op1, znode *o
}
/* here we are sure we are dealing with an object */
- *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+ *retval = Z_OBJ_HT_P(container)->read_property(container, offset TSRMLS_CC);
if (offset == &tmp) {
zval_dtor(offset);
}
@@ -1059,7 +1059,7 @@ static void zend_pre_incdec_property(znode *result, znode *op1, znode *op2, temp
}
if (!have_get_ptr) {
- zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC);
+ zval *z = Z_OBJ_HT_P(object)->read_property(object, property TSRMLS_CC);
SEPARATE_ZVAL_IF_NOT_REF(&z);
incdec_op(z);
Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
@@ -1106,7 +1106,7 @@ static void zend_post_incdec_property(znode *result, znode *op1, znode *op2, tem
}
if (!have_get_ptr) {
- zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC);
+ zval *z = Z_OBJ_HT_P(object)->read_property(object, property TSRMLS_CC);
SEPARATE_ZVAL_IF_NOT_REF(&z);
*retval = *z;
zendi_zval_copy_ctor(*retval);
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index b287e97f18..999db97fdb 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -178,7 +178,7 @@ inline int zend_verify_property_access(zend_property_info *property_info, zend_c
}
-zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC)
+zval *zend_std_read_property(zval *object, zval *member TSRMLS_DC)
{
zend_object *zobj;
zval tmp_member;
@@ -228,26 +228,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC)
retval = &EG(uninitialized_zval_ptr);
}
} else {
- switch (type) {
- case BP_VAR_R:
- zend_error(E_NOTICE,"Undefined property: %s", Z_STRVAL_P(member));
- /* break missing intentionally */
- case BP_VAR_IS:
- retval = &EG(uninitialized_zval_ptr);
- break;
- case BP_VAR_RW:
- zend_error(E_NOTICE,"Undefined property: %s", Z_STRVAL_P(member));
- /* break missing intentionally */
- case BP_VAR_W: {
- zval *new_zval = &EG(uninitialized_zval);
-
- new_zval->refcount++;
- zend_hash_update(zobj->properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, &new_zval, sizeof(zval *), (void **) &retval);
- }
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
-
- }
+ zend_error(E_NOTICE,"Undefined property: %s::$%s", zobj->ce->name, Z_STRVAL_P(member));
}
}
if (member == &tmp_member) {
@@ -391,6 +372,8 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC)
{
zend_object *zobj;
zval tmp_member;
+ zend_property_info *property_info;
+ zend_property_info std_property_info;
zobj = Z_OBJ_P(object);
@@ -400,7 +383,20 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC)
convert_to_string(&tmp_member);
member = &tmp_member;
}
- zend_hash_del(zobj->properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1);
+
+ if (zend_hash_find(&zobj->ce->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &property_info)==FAILURE) {
+ std_property_info.flags = ZEND_ACC_PUBLIC;
+ std_property_info.name = Z_STRVAL_P(member);
+ std_property_info.name_length = Z_STRLEN_P(member);
+ std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1);
+ property_info = &std_property_info;
+ }
+
+ if (!zend_verify_property_access(property_info, zobj->ce TSRMLS_CC)) {
+ zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), zobj->ce->name, Z_STRVAL_P(member));
+ }
+
+ zend_hash_del(zobj->properties, property_info->name, property_info->name_length+1);
if (member == &tmp_member) {
zval_dtor(member);
}
@@ -729,8 +725,10 @@ static union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC)
return constructor;
}
+
int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC);
+
static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC)
{
zend_object *zobj1, *zobj2;
@@ -744,6 +742,7 @@ static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC)
return zend_compare_symbol_tables_i(zobj1->properties, zobj2->properties TSRMLS_CC);
}
+
static int zend_std_has_property(zval *object, zval *member, int check_empty TSRMLS_DC)
{
zend_object *zobj;
@@ -751,16 +750,39 @@ static int zend_std_has_property(zval *object, zval *member, int check_empty TSR
zval **value;
zval tmp_member;
- zobj = Z_OBJ_P(object);
+ zend_property_info *property_info;
+ zend_property_info std_property_info;
+ zobj = Z_OBJ_P(object);
+
if (member->type != IS_STRING) {
tmp_member = *member;
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
member = &tmp_member;
}
-
- if (zend_hash_find(zobj->properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **)&value) == SUCCESS) {
+
+#if DEBUG_OBJECT_HANDLERS
+ fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
+#endif
+
+ if (zend_hash_find(&zobj->ce->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &property_info)==FAILURE) {
+ std_property_info.flags = ZEND_ACC_PUBLIC;
+ std_property_info.name = Z_STRVAL_P(member);
+ std_property_info.name_length = Z_STRLEN_P(member);
+ std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1);
+ property_info = &std_property_info;
+ }
+
+#if DEBUG_OBJECT_HANDLERS
+ zend_printf("Access type for %s::%s is %s\n", zobj->ce->name, Z_STRVAL_P(member), zend_visibility_string(property_info->flags));
+#endif
+ if (!zend_verify_property_access(property_info, zobj->ce TSRMLS_CC)) {
+ zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), zobj->ce->name, Z_STRVAL_P(member));
+ }
+
+
+ if (zend_hash_find(zobj->properties, property_info->name, property_info->name_length+1, (void **) &value) == SUCCESS) {
if (check_empty) {
result = zend_is_true(*value);
} else {
@@ -776,6 +798,7 @@ static int zend_std_has_property(zval *object, zval *member, int check_empty TSR
return result;
}
+
zend_class_entry *zend_std_object_get_class(zval *object TSRMLS_DC)
{
zend_object *zobj;
diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h
index 98857e3fac..442d92b72a 100644
--- a/Zend/zend_object_handlers.h
+++ b/Zend/zend_object_handlers.h
@@ -24,7 +24,7 @@
union _zend_function;
-typedef zval *(*zend_object_read_property_t)(zval *object, zval *member, int type TSRMLS_DC);
+typedef zval *(*zend_object_read_property_t)(zval *object, zval *member TSRMLS_DC);
/* Used to fetch property from the object, read-only */
typedef void (*zend_object_write_property_t)(zval *object, zval *member, zval *value TSRMLS_DC);
/* Used to set property of the object */
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index f317b1ef8a..7bc297b391 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -255,7 +255,7 @@ ZEND_API zval* zend_object_proxy_get(zval *property TSRMLS_DC)
zend_proxy_object *probj = zend_object_store_get_object(property TSRMLS_CC);
if (Z_OBJ_HT_P(probj->object) && Z_OBJ_HT_P(probj->object)->read_property) {
- return Z_OBJ_HT_P(probj->object)->read_property(probj->object, probj->property, BP_VAR_R TSRMLS_CC);
+ return Z_OBJ_HT_P(probj->object)->read_property(probj->object, probj->property TSRMLS_CC);
} else {
zend_error(E_WARNING, "Cannot read property of object - no read handler defined");
}