Remove get() object handler

Now that set() is gone, there is little point in keeping get(), as
it is essentially just a different way of writing cast_object()
now.

Closes GH-4202.
This commit is contained in:
Nikita Popov 2019-05-29 11:52:55 +02:00
parent 693955c5c5
commit 45a0656e95
14 changed files with 22 additions and 190 deletions

View File

@ -4,7 +4,7 @@ PHP 8.0 INTERNALS UPGRADE NOTES
a. Object Handlers API
b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler
c. TSRM changes
d. set() object handler
d. get() and set() object handlers
2. Build system changes
a. Abstract
@ -40,9 +40,12 @@ PHP 8.0 INTERNALS UPGRADE NOTES
- tsrm_free_interpreter_context
- support for GNUPTH, SGI ST, and BETHREADS
d. The set() object handler, which allowed overloading the assignment
operator, has been removed. There is no direct replacement for this
functionality, though some use-cases may be replaced by do_operation().
d. The get() and set() object handlers have been removed. The get() handler
can generally be replaced with cast_object(). Some uses of set() may be
replaced by do_operation(). If set() was used to overload direct
assignments using "=", then this is no longer supported and the
functionality should be provided in some other way (for example, as
modification of an object property).
========================

View File

@ -438,22 +438,6 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest
*dest = Z_STR_P(arg);
return 1;
}
} else if (zobj->handlers->get) {
zval rv;
zval *z = zobj->handlers->get(zobj, &rv);
if (Z_TYPE_P(z) != IS_OBJECT) {
OBJ_RELEASE(zobj);
if (Z_TYPE_P(z) == IS_STRING) {
ZVAL_COPY_VALUE(arg, z);
} else {
ZVAL_STR(arg, zval_get_string_func(z));
zval_ptr_dtor(z);
}
*dest = Z_STR_P(arg);
return 1;
}
zval_ptr_dtor(z);
}
return 0;
} else {

View File

@ -789,7 +789,6 @@ ZEND_FUNCTION(define)
ZVAL_UNDEF(&val_free);
repeat:
switch (Z_TYPE_P(val)) {
case IS_LONG:
case IS_DOUBLE:
@ -810,17 +809,10 @@ repeat:
}
break;
case IS_OBJECT:
if (Z_TYPE(val_free) == IS_UNDEF) {
if (Z_OBJ_HT_P(val)->get) {
zval rv;
val = Z_OBJ_HT_P(val)->get(Z_OBJ_P(val), &rv);
ZVAL_COPY_VALUE(&val_free, val);
goto repeat;
} else if (Z_OBJ_HT_P(val)->cast_object) {
if (Z_OBJ_HT_P(val)->cast_object(Z_OBJ_P(val), &val_free, IS_STRING) == SUCCESS) {
val = &val_free;
break;
}
if (Z_OBJ_HT_P(val)->cast_object) {
if (Z_OBJ_HT_P(val)->cast_object(Z_OBJ_P(val), &val_free, IS_STRING) == SUCCESS) {
val = &val_free;
break;
}
}
/* no break */

View File

@ -1296,15 +1296,6 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *
if ((z = Z_OBJ_HT_P(object)->read_dimension(Z_OBJ_P(object), property, BP_VAR_R, &rv)) != NULL) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
zval rv2;
zval *value = Z_OBJ_HT_P(z)->get(Z_OBJ_P(z), &rv2);
if (z == &rv) {
zval_ptr_dtor(&rv);
}
ZVAL_COPY_VALUE(z, value);
}
if (binary_op(&res, z, value) == SUCCESS) {
Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), property, &res);
}
@ -1783,15 +1774,6 @@ static zend_never_inline void zend_post_incdec_overloaded_property(zend_object *
return;
}
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
zval rv2;
zval *value = Z_OBJ_HT_P(z)->get(Z_OBJ_P(z), &rv2);
if (z == &rv) {
zval_ptr_dtor(&rv);
}
ZVAL_COPY_VALUE(z, value);
}
ZVAL_COPY_DEREF(&z_copy, z);
ZVAL_COPY(EX_VAR(opline->result.var), &z_copy);
if (inc) {
@ -1821,15 +1803,6 @@ static zend_never_inline void zend_pre_incdec_overloaded_property(zend_object *o
return;
}
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
zval rv2;
zval *value = Z_OBJ_HT_P(z)->get(Z_OBJ_P(z), &rv2);
if (z == &rv) {
zval_ptr_dtor(&rv);
}
ZVAL_COPY_VALUE(z, value);
}
ZVAL_COPY_DEREF(&z_copy, z);
if (inc) {
increment_function(&z_copy);
@ -1859,15 +1832,6 @@ static zend_never_inline void zend_assign_op_overloaded_property(zend_object *ob
}
return;
}
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
zval rv2;
zval *value = Z_OBJ_HT_P(z)->get(Z_OBJ_P(z), &rv2);
if (z == &rv) {
zval_ptr_dtor(&rv);
}
ZVAL_COPY_VALUE(z, value);
}
if (binary_op(&res, z, value) == SUCCESS) {
object->handlers->write_property(object, name, &res, cache_slot);
}

View File

@ -36,7 +36,6 @@ static const zend_object_handlers iterator_object_handlers = {
NULL, /* read dim */
NULL, /* write dim */
NULL,
NULL, /* get */
NULL, /* has prop */
NULL, /* unset prop */
NULL, /* has dim */

View File

@ -1837,7 +1837,6 @@ ZEND_API const zend_object_handlers std_object_handlers = {
zend_std_read_dimension, /* read_dimension */
zend_std_write_dimension, /* write_dimension */
zend_std_get_property_ptr_ptr, /* get_property_ptr_ptr */
NULL, /* get */
zend_std_has_property, /* has_property */
zend_std_unset_property, /* unset_property */
zend_std_has_dimension, /* has_dimension */

View File

@ -63,11 +63,6 @@ typedef void (*zend_object_write_dimension_t)(zend_object *object, zval *offset,
/* Used to create pointer to the property of the object, for future direct r/w access */
typedef zval *(*zend_object_get_property_ptr_ptr_t)(zend_object *object, zend_string *member, int type, void **cache_slot);
/* Used to get object value. Can be used when converting object value to
* one of the basic types and when using scalar ops (like ++, +=) on the object
*/
typedef zval* (*zend_object_get_t)(zend_object *object, zval *rv);
/* Used to check if a property of the object exists */
/* param has_set_exists:
* 0 (has) whether property exists and is not NULL
@ -158,7 +153,6 @@ struct _zend_object_handlers {
zend_object_read_dimension_t read_dimension; /* required */
zend_object_write_dimension_t write_dimension; /* required */
zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; /* required */
zend_object_get_t get; /* optional */
zend_object_has_property_t has_property; /* required */
zend_object_unset_property_t unset_property; /* required */
zend_object_has_dimension_t has_dimension; /* required */

View File

@ -143,13 +143,6 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {
"Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name),\
zend_get_type_by_const(ctype)); \
} \
} else if (Z_OBJ_HT_P(op)->get) { \
zval *newop = Z_OBJ_HT_P(op)->get(Z_OBJ_P(op), dst); \
if (Z_TYPE_P(newop) != IS_OBJECT) { \
/* for safety - avoid loop */ \
ZVAL_COPY_VALUE(dst, newop); \
conv_func(dst); \
} \
}
/* }}} */
@ -866,14 +859,6 @@ try_again:
if (Z_OBJ_HT_P(op)->cast_object(Z_OBJ_P(op), &tmp, IS_STRING) == SUCCESS) {
return Z_STR(tmp);
}
} else if (Z_OBJ_HT_P(op)->get) {
zval *z = Z_OBJ_HT_P(op)->get(Z_OBJ_P(op), &tmp);
if (Z_TYPE_P(z) != IS_OBJECT) {
zend_string *str = zval_get_string(z);
zval_ptr_dtor(z);
return str;
}
zval_ptr_dtor(z);
}
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(op)->name));
return ZSTR_EMPTY_ALLOC();
@ -1969,8 +1954,7 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
{
int ret;
int converted = 0;
zval op1_copy, op2_copy;
zval *op_free, tmp_free;
zval op1_copy, op2_copy, tmp_free;
while (1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
@ -2076,13 +2060,7 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
}
}
if (Z_TYPE_P(op1) == IS_OBJECT) {
if (Z_OBJ_HT_P(op1)->get) {
zval rv;
op_free = Z_OBJ_HT_P(op1)->get(Z_OBJ_P(op1), &rv);
ret = compare_function(result, op_free, op2);
zend_free_obj_get_result(op_free);
return ret;
} else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
ZVAL_UNDEF(&tmp_free);
if (Z_OBJ_HT_P(op1)->cast_object(Z_OBJ_P(op1), &tmp_free, ((Z_TYPE_P(op2) == IS_FALSE || Z_TYPE_P(op2) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op2))) == FAILURE) {
ZVAL_LONG(result, 1);
@ -2095,13 +2073,7 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
}
}
if (Z_TYPE_P(op2) == IS_OBJECT) {
if (Z_OBJ_HT_P(op2)->get) {
zval rv;
op_free = Z_OBJ_HT_P(op2)->get(Z_OBJ_P(op2), &rv);
ret = compare_function(result, op1, op_free);
zend_free_obj_get_result(op_free);
return ret;
} else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
ZVAL_UNDEF(&tmp_free);
if (Z_OBJ_HT_P(op2)->cast_object(Z_OBJ_P(op2), &tmp_free, ((Z_TYPE_P(op1) == IS_FALSE || Z_TYPE_P(op1) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op1))) == FAILURE) {
ZVAL_LONG(result, -1);
@ -2549,17 +2521,6 @@ ZEND_API int ZEND_FASTCALL zend_object_is_true(zval *op) /* {{{ */
return Z_TYPE(tmp) == IS_TRUE;
}
zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to bool", ZSTR_VAL(zobj->ce->name));
} else if (zobj->handlers->get) {
int result;
zval rv;
zval *tmp = zobj->handlers->get(zobj, &rv);
if (Z_TYPE_P(tmp) != IS_OBJECT) {
/* for safety - avoid loop */
result = i_zend_is_true(tmp);
zval_ptr_dtor(tmp);
return result;
}
}
return 1;
}

View File

@ -174,14 +174,6 @@ static void com_write_dimension(zend_object *object, zval *offset, zval *value)
}
}
#if 0
static zval *com_object_get(zval *property)
{
/* Not yet implemented in the engine */
return NULL;
}
#endif
static int com_property_exists(zend_object *object, zend_string *member, int check_empty, void **cache_slot)
{
DISPID dispid;
@ -540,7 +532,6 @@ zend_object_handlers php_com_object_handlers = {
com_read_dimension,
com_write_dimension,
NULL,
NULL, /* com_object_get, */
com_property_exists,
com_property_delete,
com_dimension_exists,

View File

@ -274,14 +274,6 @@ static void saproxy_write_dimension(zend_object *object, zval *offset, zval *val
}
}
#if 0
static zval *saproxy_object_get(zval *property)
{
/* Not yet implemented in the engine */
return NULL;
}
#endif
static int saproxy_property_exists(zend_object *object, zend_string *member, int check_empty, void **cache_slot)
{
/* no properties */
@ -397,7 +389,6 @@ zend_object_handlers php_com_saproxy_handlers = {
saproxy_read_dimension,
saproxy_write_dimension,
NULL,
NULL, /* saproxy_object_get, */
saproxy_property_exists,
saproxy_property_delete,
saproxy_dimension_exists,

View File

@ -4610,13 +4610,6 @@ static ZEND_COLD void zend_ffi_free_unset_property(zend_object *obj, zend_string
}
/* }}} */
static zval* zend_ffi_free_get(zend_object *obj, zval *rv) /* {{{ */
{
zend_ffi_use_after_free();
return NULL;
}
/* }}} */
static HashTable *zend_ffi_free_get_debug_info(zend_object *obj, int *is_temp) /* {{{ */
{
zend_ffi_use_after_free();
@ -4767,7 +4760,6 @@ ZEND_MINIT_FUNCTION(ffi)
zend_ffi_cdata_free_handlers.read_dimension = zend_ffi_free_read_dimension;
zend_ffi_cdata_free_handlers.write_dimension = zend_ffi_free_write_dimension;
zend_ffi_cdata_free_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr;
zend_ffi_cdata_free_handlers.get = zend_ffi_free_get;
zend_ffi_cdata_free_handlers.has_property = zend_ffi_free_has_property;
zend_ffi_cdata_free_handlers.unset_property = zend_ffi_free_unset_property;
zend_ffi_cdata_free_handlers.has_dimension = zend_ffi_free_has_dimension;

View File

@ -226,29 +226,7 @@ zval* collator_convert_object_to_string( zval* obj, zval *rv )
}
/* Try object's handlers. */
if( Z_OBJ_HT_P(obj)->get )
{
zstr = Z_OBJ_HT_P(obj)->get( Z_OBJ_P(obj), rv );
switch( Z_TYPE_P( zstr ) )
{
case IS_OBJECT:
{
/* Bail out. */
zval_ptr_dtor( zstr );
COLLATOR_CONVERT_RETURN_FAILED( obj );
} break;
case IS_STRING:
break;
default:
{
convert_to_string( zstr );
} break;
}
}
else if( Z_OBJ_HT_P(obj)->cast_object )
if( Z_OBJ_HT_P(obj)->cast_object )
{
zstr = rv;

View File

@ -968,15 +968,6 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d
z = Z_OBJ_HT_P(object)->read_dimension(Z_OBJ_P(object), property, BP_VAR_R, &rv);
if (z != NULL) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
zval rv2;
zval *value = Z_OBJ_HT_P(z)->get(Z_OBJ_P(z), &rv2);
if (z == &rv) {
zval_ptr_dtor(&rv);
}
ZVAL_COPY_VALUE(z, value);
}
if (binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value) == SUCCESS) {
Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), property, &res);
}

View File

@ -50,13 +50,13 @@ PHP_SXE_API zend_class_entry *sxe_get_element_class_entry() /* {{{ */
static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, zend_function *fptr_count);
static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data);
static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data);
static zval *sxe_get_value(zend_object *z, zval *rv);
static void php_sxe_iterator_dtor(zend_object_iterator *iter);
static int php_sxe_iterator_valid(zend_object_iterator *iter);
static zval *php_sxe_iterator_current_data(zend_object_iterator *iter);
static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key);
static void php_sxe_iterator_move_forward(zend_object_iterator *iter);
static void php_sxe_iterator_rewind(zend_object_iterator *iter);
static int sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int type);
/* {{{ _node_as_zval()
*/
@ -519,7 +519,12 @@ long_dim:
break;
case IS_OBJECT:
if (Z_OBJCE_P(value) == sxe_class_entry) {
value = sxe_get_value(Z_OBJ_P(value), &zval_copy);
if (sxe_object_cast_ex(Z_OBJ_P(value), &zval_copy, IS_STRING) == FAILURE) {
zend_error(E_ERROR, "Unable to cast node to string");
/* FIXME: Should not be fatal */
}
value = &zval_copy;
new_value = 1;
break;
}
@ -1999,17 +2004,6 @@ SXE_METHOD(count)
}
/* }}} */
static zval *sxe_get_value(zend_object *zobj, zval *rv) /* {{{ */
{
if (sxe_object_cast_ex(zobj, rv, IS_STRING) == FAILURE) {
zend_error(E_ERROR, "Unable to cast node to string");
/* FIXME: Should not be fatal */
}
return rv;
}
/* }}} */
static zend_object_handlers sxe_object_handlers;
/* {{{ sxe_object_clone()
@ -2706,7 +2700,6 @@ PHP_MINIT_FUNCTION(simplexml)
sxe_object_handlers.read_dimension = sxe_dimension_read;
sxe_object_handlers.write_dimension = sxe_dimension_write;
sxe_object_handlers.get_property_ptr_ptr = sxe_property_get_adr;
sxe_object_handlers.get = sxe_get_value;
sxe_object_handlers.has_property = sxe_property_exists;
sxe_object_handlers.unset_property = sxe_property_delete;
sxe_object_handlers.has_dimension = sxe_dimension_exists;