mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Implement internal operator overloading
As pre RFC https://wiki.php.net/rfc/operator_overloading_gmp
This commit is contained in:
parent
1143f58a70
commit
3823321c5c
@ -1651,6 +1651,8 @@ ZEND_API zend_object_handlers std_object_handlers = {
|
|||||||
NULL, /* get_debug_info */
|
NULL, /* get_debug_info */
|
||||||
zend_std_get_closure, /* get_closure */
|
zend_std_get_closure, /* get_closure */
|
||||||
zend_std_get_gc, /* get_gc */
|
zend_std_get_gc, /* get_gc */
|
||||||
|
NULL, /* do_operation */
|
||||||
|
NULL, /* compare */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -100,6 +100,7 @@ typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC);
|
|||||||
typedef zend_class_entry *(*zend_object_get_class_entry_t)(const zval *object TSRMLS_DC);
|
typedef zend_class_entry *(*zend_object_get_class_entry_t)(const zval *object TSRMLS_DC);
|
||||||
typedef int (*zend_object_get_class_name_t)(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC);
|
typedef int (*zend_object_get_class_name_t)(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC);
|
||||||
typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);
|
typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);
|
||||||
|
typedef int (*zend_object_compare_zvals_t)(zval *resul, zval *op1, zval *op2 TSRMLS_DC);
|
||||||
|
|
||||||
/* Cast an object to some other type
|
/* Cast an object to some other type
|
||||||
*/
|
*/
|
||||||
@ -113,6 +114,8 @@ typedef int (*zend_object_get_closure_t)(zval *obj, zend_class_entry **ce_ptr, u
|
|||||||
|
|
||||||
typedef HashTable *(*zend_object_get_gc_t)(zval *object, zval ***table, int *n TSRMLS_DC);
|
typedef HashTable *(*zend_object_get_gc_t)(zval *object, zval ***table, int *n TSRMLS_DC);
|
||||||
|
|
||||||
|
typedef int (*zend_object_do_operation_t)(zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC);
|
||||||
|
|
||||||
struct _zend_object_handlers {
|
struct _zend_object_handlers {
|
||||||
/* general object functions */
|
/* general object functions */
|
||||||
zend_object_add_ref_t add_ref;
|
zend_object_add_ref_t add_ref;
|
||||||
@ -142,6 +145,8 @@ struct _zend_object_handlers {
|
|||||||
zend_object_get_debug_info_t get_debug_info;
|
zend_object_get_debug_info_t get_debug_info;
|
||||||
zend_object_get_closure_t get_closure;
|
zend_object_get_closure_t get_closure;
|
||||||
zend_object_get_gc_t get_gc;
|
zend_object_get_gc_t get_gc;
|
||||||
|
zend_object_do_operation_t do_operation;
|
||||||
|
zend_object_compare_zvals_t compare;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ZEND_API zend_object_handlers std_object_handlers;
|
extern ZEND_API zend_object_handlers std_object_handlers;
|
||||||
|
@ -857,6 +857,8 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (!converted) {
|
if (!converted) {
|
||||||
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD);
|
||||||
|
|
||||||
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
||||||
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
||||||
converted = 1;
|
converted = 1;
|
||||||
@ -904,6 +906,8 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (!converted) {
|
if (!converted) {
|
||||||
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB);
|
||||||
|
|
||||||
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
||||||
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
||||||
converted = 1;
|
converted = 1;
|
||||||
@ -945,6 +949,8 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (!converted) {
|
if (!converted) {
|
||||||
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL);
|
||||||
|
|
||||||
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
||||||
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
||||||
converted = 1;
|
converted = 1;
|
||||||
@ -1010,6 +1016,8 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (!converted) {
|
if (!converted) {
|
||||||
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV);
|
||||||
|
|
||||||
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
||||||
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
||||||
converted = 1;
|
converted = 1;
|
||||||
@ -1027,9 +1035,15 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
|
|||||||
zval op1_copy, op2_copy;
|
zval op1_copy, op2_copy;
|
||||||
long op1_lval;
|
long op1_lval;
|
||||||
|
|
||||||
zendi_convert_to_long(op1, op1_copy, result);
|
if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
|
||||||
op1_lval = Z_LVAL_P(op1);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MOD);
|
||||||
zendi_convert_to_long(op2, op2_copy, result);
|
|
||||||
|
zendi_convert_to_long(op1, op1_copy, result);
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
zendi_convert_to_long(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
if (Z_LVAL_P(op2) == 0) {
|
if (Z_LVAL_P(op2) == 0) {
|
||||||
zend_error(E_WARNING, "Division by zero");
|
zend_error(E_WARNING, "Division by zero");
|
||||||
@ -1053,9 +1067,16 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||||||
zval op1_copy, op2_copy;
|
zval op1_copy, op2_copy;
|
||||||
long op1_lval;
|
long op1_lval;
|
||||||
|
|
||||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
|
||||||
op1_lval = Z_LVAL_P(op1);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_XOR);
|
||||||
zendi_convert_to_boolean(op2, op2_copy, result);
|
|
||||||
|
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
zendi_convert_to_boolean(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_BOOL(result, op1_lval ^ Z_LVAL_P(op2));
|
ZVAL_BOOL(result, op1_lval ^ Z_LVAL_P(op2));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1065,7 +1086,12 @@ ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
|
|||||||
{
|
{
|
||||||
zval op1_copy;
|
zval op1_copy;
|
||||||
|
|
||||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
if (Z_TYPE_P(op1) != IS_BOOL) {
|
||||||
|
ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
|
||||||
|
|
||||||
|
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_BOOL(result, !Z_LVAL_P(op1));
|
ZVAL_BOOL(result, !Z_LVAL_P(op1));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1073,29 +1099,32 @@ ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
|
|||||||
|
|
||||||
ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
|
ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
zval op1_copy = *op1;
|
|
||||||
|
|
||||||
op1 = &op1_copy;
|
switch (Z_TYPE_P(op1)) {
|
||||||
|
case IS_LONG:
|
||||||
|
ZVAL_LONG(result, ~Z_LVAL_P(op1));
|
||||||
|
return SUCCESS;
|
||||||
|
case IS_DOUBLE:
|
||||||
|
ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
|
||||||
|
return SUCCESS;
|
||||||
|
case IS_STRING: {
|
||||||
|
int i;
|
||||||
|
zval op1_copy = *op1;
|
||||||
|
|
||||||
if (Z_TYPE_P(op1) == IS_LONG) {
|
Z_TYPE_P(result) = IS_STRING;
|
||||||
ZVAL_LONG(result, ~Z_LVAL_P(op1));
|
Z_STRVAL_P(result) = estrndup(Z_STRVAL(op1_copy), Z_STRLEN(op1_copy));
|
||||||
return SUCCESS;
|
Z_STRLEN_P(result) = Z_STRLEN(op1_copy);
|
||||||
} else if (Z_TYPE_P(op1) == IS_DOUBLE) {
|
for (i = 0; i < Z_STRLEN(op1_copy); i++) {
|
||||||
ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
|
Z_STRVAL_P(result)[i] = ~Z_STRVAL(op1_copy)[i];
|
||||||
return SUCCESS;
|
}
|
||||||
} else if (Z_TYPE_P(op1) == IS_STRING) {
|
return SUCCESS;
|
||||||
int i;
|
|
||||||
|
|
||||||
Z_TYPE_P(result) = IS_STRING;
|
|
||||||
Z_STRVAL_P(result) = estrndup(Z_STRVAL_P(op1), Z_STRLEN_P(op1));
|
|
||||||
Z_STRLEN_P(result) = Z_STRLEN_P(op1);
|
|
||||||
for (i = 0; i < Z_STRLEN_P(op1); i++) {
|
|
||||||
Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
|
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
default:
|
||||||
|
ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
|
||||||
|
|
||||||
|
zend_error(E_ERROR, "Unsupported operand types");
|
||||||
|
return FAILURE;
|
||||||
}
|
}
|
||||||
zend_error(E_ERROR, "Unsupported operand types");
|
|
||||||
return FAILURE; /* unknown datatype */
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@ -1130,9 +1159,16 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
|
|||||||
Z_STRLEN_P(result) = result_len;
|
Z_STRLEN_P(result) = result_len;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
zendi_convert_to_long(op1, op1_copy, result);
|
|
||||||
op1_lval = Z_LVAL_P(op1);
|
if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
|
||||||
zendi_convert_to_long(op2, op2_copy, result);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_OR);
|
||||||
|
|
||||||
|
zendi_convert_to_long(op1, op1_copy, result);
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
zendi_convert_to_long(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
|
ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@ -1171,10 +1207,15 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
|
||||||
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_AND);
|
||||||
|
|
||||||
zendi_convert_to_long(op1, op1_copy, result);
|
zendi_convert_to_long(op1, op1_copy, result);
|
||||||
op1_lval = Z_LVAL_P(op1);
|
op1_lval = Z_LVAL_P(op1);
|
||||||
zendi_convert_to_long(op2, op2_copy, result);
|
zendi_convert_to_long(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
|
ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@ -1213,9 +1254,15 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
zendi_convert_to_long(op1, op1_copy, result);
|
if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
|
||||||
op1_lval = Z_LVAL_P(op1);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_XOR);
|
||||||
zendi_convert_to_long(op2, op2_copy, result);
|
|
||||||
|
zendi_convert_to_long(op1, op1_copy, result);
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
zendi_convert_to_long(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
|
ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@ -1227,9 +1274,16 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
|
|||||||
zval op1_copy, op2_copy;
|
zval op1_copy, op2_copy;
|
||||||
long op1_lval;
|
long op1_lval;
|
||||||
|
|
||||||
zendi_convert_to_long(op1, op1_copy, result);
|
if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
|
||||||
op1_lval = Z_LVAL_P(op1);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SL);
|
||||||
zendi_convert_to_long(op2, op2_copy, result);
|
|
||||||
|
zendi_convert_to_long(op1, op1_copy, result);
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
zendi_convert_to_long(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
|
ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1240,9 +1294,16 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||||||
zval op1_copy, op2_copy;
|
zval op1_copy, op2_copy;
|
||||||
long op1_lval;
|
long op1_lval;
|
||||||
|
|
||||||
zendi_convert_to_long(op1, op1_copy, result);
|
if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
|
||||||
op1_lval = Z_LVAL_P(op1);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SR);
|
||||||
zendi_convert_to_long(op2, op2_copy, result);
|
|
||||||
|
zendi_convert_to_long(op1, op1_copy, result);
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
zendi_convert_to_long(op2, op2_copy, result);
|
||||||
|
} else {
|
||||||
|
op1_lval = Z_LVAL_P(op1);
|
||||||
|
}
|
||||||
|
|
||||||
ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
|
ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1291,11 +1352,15 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
|
|||||||
zval op1_copy, op2_copy;
|
zval op1_copy, op2_copy;
|
||||||
int use_copy1 = 0, use_copy2 = 0;
|
int use_copy1 = 0, use_copy2 = 0;
|
||||||
|
|
||||||
if (Z_TYPE_P(op1) != IS_STRING) {
|
if (Z_TYPE_P(op1) != IS_STRING || Z_TYPE_P(op2) != IS_STRING) {
|
||||||
zend_make_printable_zval(op1, &op1_copy, &use_copy1);
|
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT);
|
||||||
}
|
|
||||||
if (Z_TYPE_P(op2) != IS_STRING) {
|
if (Z_TYPE_P(op1) != IS_STRING) {
|
||||||
zend_make_printable_zval(op2, &op2_copy, &use_copy2);
|
zend_make_printable_zval(op1, &op1_copy, &use_copy1);
|
||||||
|
}
|
||||||
|
if (Z_TYPE_P(op2) != IS_STRING) {
|
||||||
|
zend_make_printable_zval(op2, &op2_copy, &use_copy2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_copy1) {
|
if (use_copy1) {
|
||||||
@ -1526,20 +1591,24 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {
|
|||||||
ZVAL_LONG(result, -1);
|
ZVAL_LONG(result, -1);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
|
||||||
case TYPE_PAIR(IS_OBJECT, IS_OBJECT):
|
default:
|
||||||
/* If both are objects sharing the same comparision handler then use is */
|
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
|
||||||
if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) {
|
return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2 TSRMLS_CC);
|
||||||
|
} else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
|
||||||
|
return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2 TSRMLS_CC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
|
||||||
if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
|
if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
|
||||||
/* object handles are identical, apparently this is the same object */
|
/* object handles are identical, apparently this is the same object */
|
||||||
ZVAL_LONG(result, 0);
|
ZVAL_LONG(result, 0);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC));
|
if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
|
||||||
return SUCCESS;
|
ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2 TSRMLS_CC));
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* break missing intentionally */
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (Z_TYPE_P(op1) == IS_OBJECT) {
|
if (Z_TYPE_P(op1) == IS_OBJECT) {
|
||||||
if (Z_OBJ_HT_P(op1)->get) {
|
if (Z_OBJ_HT_P(op1)->get) {
|
||||||
op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
|
op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
|
||||||
@ -1890,6 +1959,20 @@ ZEND_API int increment_function(zval *op1) /* {{{ */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IS_OBJECT:
|
||||||
|
if (Z_OBJ_HANDLER_P(op1, do_operation)) {
|
||||||
|
zval *op2;
|
||||||
|
int res;
|
||||||
|
TSRMLS_FETCH();
|
||||||
|
|
||||||
|
MAKE_STD_ZVAL(op2);
|
||||||
|
ZVAL_LONG(op2, 1);
|
||||||
|
res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, op2 TSRMLS_CC);
|
||||||
|
zval_ptr_dtor(&op2);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return FAILURE;
|
||||||
default:
|
default:
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
@ -1936,6 +2019,20 @@ ZEND_API int decrement_function(zval *op1) /* {{{ */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IS_OBJECT:
|
||||||
|
if (Z_OBJ_HANDLER_P(op1, do_operation)) {
|
||||||
|
zval *op2;
|
||||||
|
int res;
|
||||||
|
TSRMLS_FETCH();
|
||||||
|
|
||||||
|
MAKE_STD_ZVAL(op2);
|
||||||
|
ZVAL_LONG(op2, 1);
|
||||||
|
res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, op2 TSRMLS_CC);
|
||||||
|
zval_ptr_dtor(&op2);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return FAILURE;
|
||||||
default:
|
default:
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -945,6 +945,24 @@ static zend_always_inline int fast_is_smaller_or_equal_function(zval *result, zv
|
|||||||
return Z_LVAL_P(result) <= 0;
|
return Z_LVAL_P(result) <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode) \
|
||||||
|
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation)) { \
|
||||||
|
if (SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) { \
|
||||||
|
return SUCCESS; \
|
||||||
|
} \
|
||||||
|
} else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation)) { \
|
||||||
|
if (SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) { \
|
||||||
|
return SUCCESS; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode) \
|
||||||
|
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation) \
|
||||||
|
&& SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL TSRMLS_CC) \
|
||||||
|
) { \
|
||||||
|
return SUCCESS; \
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user