summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r--Zend/zend_operators.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index e8629291e5..8c083542f0 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1082,6 +1082,46 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
}
/* }}} */
+ZEND_API int boolean_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+ zval op1_copy, op2_copy;
+ long op1_lval;
+
+ if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_AND);
+
+ 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));
+ return SUCCESS;
+}
+/* }}} */
+
+ZEND_API int boolean_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+ zval op1_copy, op2_copy;
+ long op1_lval;
+
+ if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_OR);
+
+ 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));
+ return SUCCESS;
+}
+/* }}} */
+
ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
{
zval op1_copy;
@@ -2323,6 +2363,28 @@ ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
}
/* }}} */
+#define PREVENT_DTOR_IF_REFCOUNT_1_AND_ASSIGN_TO_RESULT(var) \
+ *result = *var; \
+ if (Z_REFCOUNT_P(var) == 1) { \
+ Z_TYPE_P(var) = IS_NULL; \
+ }
+
+ZEND_API int ternary_function(zval *result, zval *condition, zval *then, zval *if_not TSRMLS_DC) /* {{{ */
+{
+ if (i_zend_is_true(condition)) {
+ if (then) {
+ PREVENT_DTOR_IF_REFCOUNT_1_AND_ASSIGN_TO_RESULT(then);
+ } else {
+ PREVENT_DTOR_IF_REFCOUNT_1_AND_ASSIGN_TO_RESULT(condition);
+ }
+ } else {
+ PREVENT_DTOR_IF_REFCOUNT_1_AND_ASSIGN_TO_RESULT(if_not);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4