summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.h
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-10-21 03:24:20 +0400
committerDmitry Stogov <dmitry@zend.com>2014-10-21 03:24:20 +0400
commit089f4967997462bdc9eb92ff3e604861e947cb23 (patch)
tree545991b20cfda6d3e3ce3d331d01b346204ea109 /Zend/zend_operators.h
parentae127faf5bcafc64a8dfdba6baad5f86ef5f94b0 (diff)
downloadphp-git-089f4967997462bdc9eb92ff3e604861e947cb23.tar.gz
Moved proxy object support in ASSIGN_ADD (and family) from VM to slow paths of corresponding operators
Diffstat (limited to 'Zend/zend_operators.h')
-rw-r--r--Zend/zend_operators.h49
1 files changed, 35 insertions, 14 deletions
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 8075edf939..f95e856e68 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -887,22 +887,43 @@ static zend_always_inline void fast_is_not_identical_function(zval *result, zval
ZVAL_BOOL(result, Z_TYPE_P(result) != IS_TRUE);
}
-#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_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \
+ if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
+ && op1 == result \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, get)) \
+ && EXPECTED(Z_OBJ_HANDLER_P(op1, set))) { \
+ int ret; \
+ zval rv; \
+ zval *objval = Z_OBJ_HANDLER_P(op1, get)(op1, &rv TSRMLS_CC); \
+ Z_ADDREF_P(objval); \
+ ret = binary_op(objval, objval, op2 TSRMLS_CC); \
+ Z_OBJ_HANDLER_P(op1, set)(op1, objval TSRMLS_CC); \
+ zval_ptr_dtor(objval); \
+ return ret; \
+ } else if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) { \
+ if (EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, 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; \
+#define ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode) \
+ if (UNEXPECTED(Z_TYPE_P(op2) == IS_OBJECT) \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op2, do_operation)) \
+ && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC))) { \
+ return SUCCESS; \
+ }
+
+#define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode, binary_op) \
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \
+ else \
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)
+
+#define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode) \
+ if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation)) \
+ && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL TSRMLS_CC))) { \
+ return SUCCESS; \
}
/* buf points to the END of the buffer */