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.c122
1 files changed, 49 insertions, 73 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 47e2562da8..d943ae739a 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -683,7 +683,7 @@ static void convert_scalar_to_array(zval *op, int type TSRMLS_DC) /* {{{ */
switch (type) {
case IS_ARRAY:
ZVAL_NEW_ARR(op);
- zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_index_update(Z_ARRVAL_P(op), 0, &entry);
break;
case IS_OBJECT:
@@ -707,7 +707,7 @@ ZEND_API void convert_to_array(zval *op) /* {{{ */
zval arr;
ZVAL_NEW_ARR(&arr);
- zend_hash_init(Z_ARRVAL(arr), 0, NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(Z_ARRVAL(arr), 8, NULL, ZVAL_PTR_DTOR, 0);
if (Z_OBJCE_P(op) == zend_ce_closure) {
convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
if (Z_TYPE_P(op) == IS_ARRAY) {
@@ -733,7 +733,7 @@ ZEND_API void convert_to_array(zval *op) /* {{{ */
break;
case IS_NULL:
ZVAL_NEW_ARR(op);
- zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
break;
default:
convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
@@ -875,7 +875,7 @@ ZEND_API double zval_get_double(zval *op TSRMLS_DC) /* {{{ */
{
zval tmp;
ZVAL_DUP(&tmp, op);
- convert_object_to_type(op, IS_DOUBLE, convert_to_double);
+ convert_object_to_type(&tmp, IS_DOUBLE, convert_to_double);
if (Z_TYPE(tmp) == IS_DOUBLE) {
return Z_DVAL(tmp);
@@ -893,32 +893,33 @@ ZEND_API double zval_get_double(zval *op TSRMLS_DC) /* {{{ */
}
/* }}} */
-ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC) /* {{{ */
+ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC) /* {{{ */
{
+try_again:
switch (Z_TYPE_P(op)) {
case IS_NULL:
return STR_EMPTY_ALLOC();
case IS_STRING:
return STR_COPY(Z_STR_P(op));
case IS_BOOL:
- if (Z_LVAL_P(op)) {
+ if (Z_BVAL_P(op)) {
return STR_INIT("1", 1, 0);
} else {
return STR_EMPTY_ALLOC();
}
case IS_RESOURCE: {
- char *str;
- int len = zend_spprintf(&str, 0, "Resource id #%ld", Z_RES_HANDLE_P(op));
- zend_string *retval = STR_INIT(str, len, 0);
- efree(str);
- return retval;
+ char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "Resource id #%ld", Z_RES_HANDLE_P(op));
+ return STR_INIT(buf, len, 0);
}
case IS_LONG: {
- char *str;
- int len = zend_spprintf(&str, 0, "%ld", Z_LVAL_P(op));
- zend_string *retval = STR_INIT(str, len, 0);
- efree(str);
- return retval;
+ char buf[MAX_LENGTH_OF_LONG + 1];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "%ld", Z_LVAL_P(op));
+ return STR_INIT(buf, len, 0);
}
case IS_DOUBLE: {
char *str;
@@ -932,17 +933,28 @@ ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC) /* {{{ */
return STR_INIT("Array", sizeof("Array")-1, 0);
case IS_OBJECT: {
zval tmp;
- ZVAL_DUP(&tmp, op);
- convert_object_to_type(op, IS_STRING, convert_to_string);
-
- if (Z_TYPE(tmp) == IS_STRING) {
- return Z_STR(tmp);
- } else {
- zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name->val);
- zval_dtor(&tmp);
- return STR_INIT("Object", sizeof("Object")-1, 0);
+ //???if (zend_std_cast_object_tostring(op, &tmp, IS_STRING TSRMLS_CC) == SUCCESS) {
+ //??? return Z_STR(tmp);
+ //???}
+ if (Z_OBJ_HT_P(op)->cast_object) {
+ if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING TSRMLS_CC) == SUCCESS) {
+ return Z_STR(tmp);
+ }
+ } else if (Z_OBJ_HT_P(op)->get) {
+ zval *z = Z_OBJ_HT_P(op)->get(op, &tmp TSRMLS_CC);
+ 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", Z_OBJCE_P(op)->name->val);
+ return STR_EMPTY_ALLOC();
}
+ case IS_REFERENCE:
+ op = Z_REFVAL_P(op);
+ goto try_again;
default:
//??? original code returns bool(0)
return STR_EMPTY_ALLOC();
@@ -1547,35 +1559,17 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
{
- zval op1_copy, op2_copy;
- int use_copy1 = 0, use_copy2 = 0;
-
- if (Z_TYPE_P(op1) != IS_STRING) {
- 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) {
- op1 = &op1_copy;
- }
- if (use_copy2) {
- op2 = &op2_copy;
- }
+ zend_string *str1 = zval_get_string(op1);
+ zend_string *str2 = zval_get_string(op2);
if (case_insensitive) {
- ZVAL_LONG(result, zend_binary_zval_strcasecmp(op1, op2));
+ ZVAL_LONG(result, zend_binary_strcasecmp_l(str1->val, str1->len, str2->val, str1->len));
} else {
- ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2));
+ ZVAL_LONG(result, zend_binary_strcmp(str1->val, str1->len, str2->val, str2->len));
}
- if (use_copy1) {
- zval_dtor(op1);
- }
- if (use_copy2) {
- zval_dtor(op2);
- }
+ STR_RELEASE(str1);
+ STR_RELEASE(str2);
return SUCCESS;
}
/* }}} */
@@ -1595,31 +1589,13 @@ ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSR
#if HAVE_STRCOLL
ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
{
- zval op1_copy, op2_copy;
- int use_copy1 = 0, use_copy2 = 0;
+ zend_string *str1 = zval_get_string(op1);
+ zend_string *str2 = zval_get_string(op2);
- if (Z_TYPE_P(op1) != IS_STRING) {
- 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);
- }
+ ZVAL_LONG(result, strcoll(str1->val, str2->val));
- if (use_copy1) {
- op1 = &op1_copy;
- }
- if (use_copy2) {
- op2 = &op2_copy;
- }
-
- ZVAL_LONG(result, strcoll(Z_STRVAL_P(op1), Z_STRVAL_P(op2)));
-
- if (use_copy1) {
- zval_dtor(op1);
- }
- if (use_copy2) {
- zval_dtor(op2);
- }
+ STR_RELEASE(str1);
+ STR_RELEASE(str2);
return SUCCESS;
}
/* }}} */
@@ -2424,7 +2400,7 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
}
} else {
string_cmp:
- Z_LVAL_P(result) = zend_binary_zval_strcmp(s1, s2);
+ Z_LVAL_P(result) = zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
}
}