summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-05-30 14:03:48 +0300
committerDmitry Stogov <dmitry@zend.com>2018-05-30 14:03:48 +0300
commitff58d7054899015a7871ff4ae23ae025abc94629 (patch)
treea46e2f585840bc7556902344a2fce73683bf6dc6 /Zend/zend_operators.c
parent84aab1d4e1a6394cd3fb89d027c0b7890ca49ab2 (diff)
downloadphp-git-ff58d7054899015a7871ff4ae23ae025abc94629.tar.gz
Avoid agressive inlining in rarely used paths
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r--Zend/zend_operators.c185
1 files changed, 114 insertions, 71 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 70ea7e5404..cd0e7047d0 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -156,7 +156,7 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {
/* }}} */
-void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */
+static void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent, zend_bool check) /* {{{ */
{
try_again:
switch (Z_TYPE_P(op)) {
@@ -196,6 +196,9 @@ try_again:
zval dst;
convert_object_to_type(op, &dst, _IS_NUMBER, convert_scalar_to_number);
+ if (check && UNEXPECTED(EG(exception))) {
+ return;
+ }
zval_dtor(op);
if (Z_TYPE(dst) == IS_LONG || Z_TYPE(dst) == IS_DOUBLE) {
@@ -211,63 +214,67 @@ try_again:
ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
{
- _convert_scalar_to_number(op, 1);
-}
-/* }}} */
-
-/* {{{ zendi_convert_scalar_to_number */
-#define zendi_convert_scalar_to_number(op, holder, result, silent) \
- if (Z_TYPE_P(op) != IS_LONG) { \
- if (op==result && Z_TYPE_P(op) != IS_OBJECT) { \
- _convert_scalar_to_number(op, silent); \
- } else { \
- switch (Z_TYPE_P(op)) { \
- case IS_STRING: \
- if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), silent ? 1 : -1)) == 0) { \
- ZVAL_LONG(&(holder), 0); \
- if (!silent) { \
- zend_error(E_WARNING, "A non-numeric value encountered"); \
- } \
- } \
- (op) = &(holder); \
- break; \
- case IS_NULL: \
- case IS_FALSE: \
- ZVAL_LONG(&(holder), 0); \
- (op) = &(holder); \
- break; \
- case IS_TRUE: \
- ZVAL_LONG(&(holder), 1); \
- (op) = &(holder); \
- break; \
- case IS_RESOURCE: \
- ZVAL_LONG(&(holder), Z_RES_HANDLE_P(op)); \
- (op) = &(holder); \
- break; \
- case IS_OBJECT: \
- ZVAL_COPY(&(holder), op); \
- _convert_scalar_to_number(&(holder), silent); \
- if (UNEXPECTED(EG(exception))) { \
- if (result != op1) { \
- ZVAL_UNDEF(result); \
- } \
- return FAILURE; \
- } \
- if (Z_TYPE(holder) == IS_LONG || Z_TYPE(holder) == IS_DOUBLE) { \
- if (op == result) { \
- zval_ptr_dtor(op); \
- ZVAL_COPY(op, &(holder)); \
- } else { \
- (op) = &(holder); \
- } \
- } \
- break; \
- } \
- } \
+ _convert_scalar_to_number(op, 1, 0);
+}
+/* }}} */
+
+/* {{{ _zendi_convert_scalar_to_number_ex */
+static zend_always_inline zval* _zendi_convert_scalar_to_number_ex(zval *op, zval *holder, zend_bool silent) /* {{{ */
+{
+ switch (Z_TYPE_P(op)) {
+ case IS_NULL:
+ case IS_FALSE:
+ ZVAL_LONG(holder, 0);
+ return holder;
+ case IS_TRUE:
+ ZVAL_LONG(holder, 1);
+ return holder;
+ case IS_STRING:
+ if ((Z_TYPE_INFO_P(holder) = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL_P(holder), &Z_DVAL_P(holder), silent ? 1 : -1)) == 0) {
+ ZVAL_LONG(holder, 0);
+ if (!silent) {
+ zend_error(E_WARNING, "A non-numeric value encountered");
+ }
+ }
+ return holder;
+ case IS_RESOURCE:
+ ZVAL_LONG(holder, Z_RES_HANDLE_P(op));
+ return holder;
+ case IS_OBJECT:
+ convert_object_to_type(op, holder, _IS_NUMBER, convert_scalar_to_number);
+ if (UNEXPECTED(EG(exception)) ||
+ UNEXPECTED(Z_TYPE_P(holder) != IS_LONG && Z_TYPE_P(holder) != IS_DOUBLE)) {
+ ZVAL_LONG(holder, 1);
+ }
+ return holder;
+ case IS_LONG:
+ case IS_DOUBLE:
+ default:
+ return op;
}
+}
+/* }}} */
+
+/* {{{ _zendi_convert_scalar_to_number */
+static zend_never_inline zval* ZEND_FASTCALL _zendi_convert_scalar_to_number(zval *op, zval *holder) /* {{{ */
+{
+ return _zendi_convert_scalar_to_number_ex(op, holder, 1);
+}
+/* }}} */
+/* {{{ _zendi_convert_scalar_to_number_noisy */
+static zend_never_inline zval* ZEND_FASTCALL _zendi_convert_scalar_to_number_noisy(zval *op, zval *holder) /* {{{ */
+{
+ return _zendi_convert_scalar_to_number_ex(op, holder, 0);
+}
/* }}} */
+#define zendi_convert_scalar_to_number(op, holder, result, silent) \
+ ((Z_TYPE_P(op) == IS_LONG || Z_TYPE_P(op) == IS_DOUBLE) ? (op) : \
+ (((op) == result) ? (_convert_scalar_to_number((op), silent, 1), (op)) : \
+ (silent ? _zendi_convert_scalar_to_number((op), holder) : \
+ _zendi_convert_scalar_to_number_noisy((op), holder))))
+
#define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, op, op_func) \
do { \
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { \
@@ -946,12 +953,18 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
if (EXPECTED(op1 != op2)) {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
- zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
+ op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0);
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
op2 = op1;
}
+ if (EG(exception)) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
+ return FAILURE;
+ }
converted = 1;
} else {
if (result != op1) {
@@ -998,12 +1011,18 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
if (EXPECTED(op1 != op2)) {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
- zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
+ op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0);
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
op2 = op1;
}
+ if (EG(exception)) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
+ return FAILURE;
+ }
converted = 1;
} else {
if (result != op1) {
@@ -1053,12 +1072,18 @@ ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* {
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
if (EXPECTED(op1 != op2)) {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
- zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
+ op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0);
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
op2 = op1;
}
+ if (EG(exception)) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
+ return FAILURE;
+ }
converted = 1;
} else {
if (result != op1) {
@@ -1144,23 +1169,29 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {
ZVAL_LONG(result, 0);
return SUCCESS;
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
}
if (Z_TYPE_P(op2) == IS_ARRAY) {
ZVAL_LONG(result, 1L);
return SUCCESS;
} else {
- zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
+ op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0);
}
} else {
if (Z_TYPE_P(op1) == IS_ARRAY) {
ZVAL_LONG(result, 0);
return SUCCESS;
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
}
op2 = op1;
}
+ if (EG(exception)) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
+ return FAILURE;
+ }
converted = 1;
} else {
if (result != op1) {
@@ -1229,12 +1260,18 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
if (EXPECTED(op1 != op2)) {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
- zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
+ op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0);
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
op2 = op1;
}
+ if (EG(exception)) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
+ return FAILURE;
+ }
converted = 1;
} else {
if (result != op1) {
@@ -2095,8 +2132,14 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
return SUCCESS;
} else {
- zendi_convert_scalar_to_number(op1, op1_copy, result, 1);
- zendi_convert_scalar_to_number(op2, op2_copy, result, 1);
+ op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 1);
+ op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 1);
+ if (EG(exception)) {
+ if (result != op1) {
+ ZVAL_UNDEF(result);
+ }
+ return FAILURE;
+ }
converted = 1;
}
} else if (Z_TYPE_P(op1)==IS_ARRAY) {