summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-12-24 15:04:51 +0300
committerDmitry Stogov <dmitry@zend.com>2014-12-24 15:04:51 +0300
commitc42ac09518d7ec121abb86fc57805e7db56d28ed (patch)
tree02e4c294ad86c7ad7767d21f2081b165809350fb
parent288b6d78b0ed89216e660bd645c98172d39ba021 (diff)
downloadphp-git-c42ac09518d7ec121abb86fc57805e7db56d28ed.tar.gz
Added new API function 'zend_string* zend_string_tolower(zend_string*)'.
It simplifies code and avoids unnecessary allocation and copying if string is already in lower case.
-rw-r--r--Zend/zend_API.c5
-rw-r--r--Zend/zend_builtin_functions.c87
-rw-r--r--Zend/zend_closures.c7
-rw-r--r--Zend/zend_compile.c39
-rw-r--r--Zend/zend_execute_API.c15
-rw-r--r--Zend/zend_inheritance.c46
-rw-r--r--Zend/zend_object_handlers.c7
-rw-r--r--Zend/zend_operators.c28
-rw-r--r--Zend/zend_operators.h1
-rw-r--r--Zend/zend_vm_def.h5
-rw-r--r--Zend/zend_vm_execute.h15
-rw-r--r--ext/opcache/Optimizer/pass1_5.c20
-rw-r--r--ext/standard/var.c3
13 files changed, 134 insertions, 144 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 4f19e48033..1b2c311fda 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2988,8 +2988,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
return 0;
}
- lmname = zend_string_alloc(mlen, 0);
- zend_str_tolower_copy(lmname->val, mname->val, mlen);
+ lmname = zend_string_tolower(mname);
if (strict_class &&
fcc->calling_scope &&
zend_string_equals_literal(lmname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
@@ -3154,7 +3153,7 @@ get_function_via_handler:
if (error) zend_spprintf(error, 0, "function '%s' does not exist", mname->val);
}
}
- zend_string_free(lmname);
+ zend_string_release(lmname);
zend_string_release(mname);
if (fcc->object) {
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 6ba0965ede..67d0bcff73 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1136,11 +1136,19 @@ ZEND_FUNCTION(get_object_vars)
}
/* }}} */
-static int same_name(const char *key, const char *name, size_t name_len) /* {{{ */
+static int same_name(zend_string *key, zend_string *name) /* {{{ */
{
- char *lcname = zend_str_tolower_dup(name, name_len);
- int ret = memcmp(lcname, key, name_len) == 0;
- efree(lcname);
+ zend_string *lcname;
+
+ if (key == name) {
+ return 1;
+ }
+ if (key->len != name->len) {
+ return 0;
+ }
+ lcname = zend_string_tolower(name);
+ int ret = memcmp(lcname->val, key->val, key->len) == 0;
+ zend_string_release(lcname);
return ret;
}
/* }}} */
@@ -1191,8 +1199,7 @@ ZEND_FUNCTION(get_class_methods)
if (mptr->type == ZEND_USER_FUNCTION &&
*mptr->op_array.refcount > 1 &&
- (len != key->len ||
- !same_name(key->val, mptr->common.function_name->val, len))) {
+ !same_name(key, mptr->common.function_name)) {
ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key));
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
} else {
@@ -1234,10 +1241,9 @@ ZEND_FUNCTION(method_exists)
RETURN_FALSE;
}
- lcname = zend_string_alloc(method_name->len, 0);
- zend_str_tolower_copy(lcname->val, method_name->val, method_name->len);
+ lcname = zend_string_tolower(method_name);
if (zend_hash_exists(&ce->function_table, lcname)) {
- zend_string_free(lcname);
+ zend_string_release(lcname);
RETURN_TRUE;
} else {
union _zend_function *func = NULL;
@@ -1253,16 +1259,16 @@ ZEND_FUNCTION(method_exists)
RETVAL_BOOL(func->common.scope == zend_ce_closure
&& zend_string_equals_literal(method_name, ZEND_INVOKE_FUNC_NAME));
- zend_string_free(lcname);
+ zend_string_release(lcname);
zend_string_release(func->common.function_name);
efree(func);
return;
}
- efree(lcname);
+ zend_string_release(lcname);
RETURN_TRUE;
}
}
- efree(lcname);
+ zend_string_release(lcname);
RETURN_FALSE;
}
/* }}} */
@@ -1340,11 +1346,10 @@ ZEND_FUNCTION(class_exists)
lc_name = zend_string_alloc(class_name->len - 1, 0);
zend_str_tolower_copy(lc_name->val, class_name->val + 1, class_name->len - 1);
} else {
- lc_name = zend_string_alloc(class_name->len, 0);
- zend_str_tolower_copy(lc_name->val, class_name->val, class_name->len);
+ lc_name = zend_string_tolower(class_name);
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
RETURN_BOOL(ce && !((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
}
@@ -1383,11 +1388,10 @@ ZEND_FUNCTION(interface_exists)
lc_name = zend_string_alloc(iface_name->len - 1, 0);
zend_str_tolower_copy(lc_name->val, iface_name->val + 1, iface_name->len - 1);
} else {
- lc_name = zend_string_alloc(iface_name->len, 0);
- zend_str_tolower_copy(lc_name->val, iface_name->val, iface_name->len);
+ lc_name = zend_string_tolower(iface_name);
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
RETURN_BOOL(ce && ce->ce_flags & ZEND_ACC_INTERFACE);
}
@@ -1426,11 +1430,10 @@ ZEND_FUNCTION(trait_exists)
lc_name = zend_string_alloc(trait_name->len - 1, 0);
zend_str_tolower_copy(lc_name->val, trait_name->val + 1, trait_name->len - 1);
} else {
- lc_name = zend_string_alloc(trait_name->len, 0);
- zend_str_tolower_copy(lc_name->val, trait_name->val, trait_name->len);
+ lc_name = zend_string_tolower(trait_name);
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
RETURN_BOOL(ce && ((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
}
@@ -1447,32 +1450,30 @@ ZEND_FUNCTION(trait_exists)
Checks if the function exists */
ZEND_FUNCTION(function_exists)
{
- char *name;
- size_t name_len;
+ zend_string *name;
zend_function *func;
zend_string *lcname;
#ifndef FAST_ZPP
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STRING(name, name_len)
+ Z_PARAM_STR(name)
ZEND_PARSE_PARAMETERS_END();
#endif
- if (name[0] == '\\') {
+ if (name->val[0] == '\\') {
/* Ignore leading "\" */
- lcname = zend_string_alloc(name_len - 1, 0);
- zend_str_tolower_copy(lcname->val, name + 1, name_len - 1);
+ lcname = zend_string_alloc(name->len - 1, 0);
+ zend_str_tolower_copy(lcname->val, name->val + 1, name->len - 1);
} else {
- lcname = zend_string_alloc(name_len, 0);
- zend_str_tolower_copy(lcname->val, name, name_len);
+ lcname = zend_string_tolower(name);
}
func = zend_hash_find_ptr(EG(function_table), lcname);
- zend_string_free(lcname);
+ zend_string_release(lcname);
/*
* A bit of a hack, but not a bad one: we see if the handler of the function
@@ -1745,8 +1746,7 @@ static int copy_class_or_interface_name(zval *el, int num_args, va_list args, ze
if ((hash_key->key && hash_key->key->val[0] != 0)
&& (comply_mask == (ce->ce_flags & mask))) {
if (ce->refcount > 1 &&
- (ce->name->len != hash_key->key->len ||
- !same_name(hash_key->key->val, ce->name->val, ce->name->len))) {
+ !same_name(hash_key->key, ce->name)) {
add_next_index_str(array, zend_string_copy(hash_key->key));
} else {
add_next_index_str(array, zend_string_copy(ce->name));
@@ -2589,22 +2589,20 @@ ZEND_FUNCTION(debug_backtrace)
Returns true if the named extension is loaded */
ZEND_FUNCTION(extension_loaded)
{
- char *extension_name;
- size_t extension_name_len;
+ zend_string *extension_name;
zend_string *lcname;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &extension_name, &extension_name_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
return;
}
- lcname = zend_string_alloc(extension_name_len, 0);
- zend_str_tolower_copy(lcname->val, extension_name, extension_name_len);
+ lcname = zend_string_tolower(extension_name);
if (zend_hash_exists(&module_registry, lcname)) {
RETVAL_TRUE;
} else {
RETVAL_FALSE;
}
- zend_string_free(lcname);
+ zend_string_release(lcname);
}
/* }}} */
@@ -2612,24 +2610,23 @@ ZEND_FUNCTION(extension_loaded)
Returns an array with the names of functions belonging to the named extension */
ZEND_FUNCTION(get_extension_funcs)
{
- char *extension_name;
+ zend_string *extension_name;
zend_string *lcname;
size_t extension_name_len;
int array;
zend_module_entry *module;
zend_function *zif;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &extension_name, &extension_name_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
return;
}
- if (strncasecmp(extension_name, "zend", sizeof("zend"))) {
- lcname = zend_string_alloc(extension_name_len, 0);
- zend_str_tolower_copy(lcname->val, extension_name, extension_name_len);
+ if (strncasecmp(extension_name->val, "zend", sizeof("zend"))) {
+ lcname = zend_string_tolower(extension_name);
} else {
lcname = zend_string_init("core", sizeof("core")-1, 0);
}
module = zend_hash_find_ptr(&module_registry, lcname);
- zend_string_free(lcname);
+ zend_string_release(lcname);
if (!module) {
RETURN_FALSE;
}
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index 51585fec91..21982914a9 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -211,13 +211,12 @@ static zend_function *zend_closure_get_method(zend_object **object, zend_string
{
zend_string *lc_name;
- lc_name = zend_string_alloc(method->len, 0);
- zend_str_tolower_copy(lc_name->val, method->val, method->len);
+ lc_name = zend_string_tolower(method);
if (zend_string_equals_literal(method, ZEND_INVOKE_FUNC_NAME)) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
return zend_get_closure_invoke_method(*object);
}
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
return std_object_handlers.get_method(object, method, key);
}
/* }}} */
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 7c323def84..8deefaefea 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -343,8 +343,7 @@ static int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name
int ret = zend_add_literal_string(op_array, &name);
/* Lowercased name */
- zend_string *lc_name = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lc_name->val, name->val, name->len);
+ zend_string *lc_name = zend_string_tolower(name);
zend_add_literal_string(op_array, &lc_name);
return ret;
@@ -360,8 +359,7 @@ static int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *n
int ret = zend_add_literal_string(op_array, &name);
/* Lowercased name */
- zend_string *lc_name = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lc_name->val, name->val, name->len);
+ zend_string *lc_name = zend_string_tolower(name);
zend_add_literal_string(op_array, &lc_name);
/* Lowercased unqualfied name */
@@ -381,8 +379,7 @@ static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *nam
int ret = zend_add_literal_string(op_array, &name);
/* Lowercased name */
- zend_string *lc_name = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lc_name->val, name->val, name->len);
+ zend_string *lc_name = zend_string_tolower(name);
zend_add_literal_string(op_array, &lc_name);
zend_alloc_cache_slot(ret);
@@ -410,8 +407,7 @@ static int zend_add_const_name_literal(zend_op_array *op_array, zend_string *nam
zend_add_literal_string(op_array, &tmp_name);
/* lowercased namespace name & lowercased constant name */
- tmp_name = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(tmp_name->val, name->val, name->len);
+ tmp_name = zend_string_tolower(name);
zend_add_literal_string(op_array, &tmp_name);
if (!unqualified) {
@@ -2628,8 +2624,7 @@ int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */
/* Lowercase constant name in a separate literal */
{
zval c;
- zend_string *lcname = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lcname->val, name->val, name->len);
+ zend_string *lcname = zend_string_tolower(name);
ZVAL_NEW_STR(&c, lcname);
zend_add_literal(CG(active_op_array), &c);
}
@@ -2648,14 +2643,13 @@ static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t
}
name = zend_ast_get_str(name_ast);
- lcname = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lcname->val, name->val, name->len);
+ lcname = zend_string_tolower(name);
fbc = zend_hash_find_ptr(CG(function_table), lcname);
if (!fbc || (fbc->type == ZEND_INTERNAL_FUNCTION &&
(CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
) {
- zend_string_free(lcname);
+ zend_string_release(lcname);
return FAILURE;
}
@@ -2808,11 +2802,11 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
{
zval *name = &name_node.u.constant;
- zend_string *lcname = zend_string_alloc(Z_STRLEN_P(name), 0);
+ zend_string *lcname;
zend_function *fbc;
zend_op *opline;
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(name), Z_STRLEN_P(name));
+ lcname = zend_string_tolower(Z_STR_P(name));
fbc = zend_hash_find_ptr(CG(function_table), lcname);
if (!fbc || (fbc->type == ZEND_INTERNAL_FUNCTION &&
@@ -3956,8 +3950,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
op_array->scope = ce;
op_array->function_name = zend_string_copy(name);
- lcname = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lcname->val, name->val, name->len);
+ lcname = zend_string_tolower(name);
lcname = zend_new_interned_string(lcname);
if (zend_hash_add_ptr(&ce->function_table, lcname, op_array) == NULL) {
@@ -4097,8 +4090,7 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
op_array->function_name = name = zend_prefix_with_ns(name);
- lcname = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lcname->val, name->val, name->len);
+ lcname = zend_string_tolower(name);
if (CG(current_import_function)) {
zend_string *import_name = zend_hash_find_ptr(CG(current_import_function), lcname);
@@ -4486,8 +4478,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
name->val);
}
- lcname = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lcname->val, name->val, name->len);
+ lcname = zend_string_tolower(name);
if (CG(current_import)) {
import_name = zend_hash_find_ptr(CG(current_import), lcname);
@@ -4497,8 +4488,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
name = zend_prefix_with_ns(name);
zend_string_release(lcname);
- lcname = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lcname->val, name->val, name->len);
+ lcname = zend_string_tolower(name);
} else {
zend_string_addref(name);
}
@@ -4725,8 +4715,7 @@ void zend_compile_use(zend_ast *ast) /* {{{ */
if (case_sensitive) {
lookup_name = zend_string_copy(new_name);
} else {
- lookup_name = zend_string_alloc(new_name->len, 0);
- zend_str_tolower_copy(lookup_name->val, new_name->val, new_name->len);
+ lookup_name = zend_string_tolower(new_name);
}
if (type == T_CLASS && (zend_string_equals_literal(lookup_name, "self")
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 10238e0396..14be7d4813 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -934,15 +934,14 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
lc_name = zend_string_alloc(name->len - 1, 0);
zend_str_tolower_copy(lc_name->val, name->val + 1, name->len - 1);
} else {
- lc_name = zend_string_alloc(name->len, 0);
- zend_str_tolower_copy(lc_name->val, name->val, name->len);
+ lc_name = zend_string_tolower(name);
}
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
if (ce) {
if (!key) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
}
return ce;
}
@@ -952,7 +951,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
*/
if (!use_autoload || zend_is_compiling()) {
if (!key) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
}
return NULL;
}
@@ -963,7 +962,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
EG(autoload_func) = func;
} else {
if (!key) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
}
return NULL;
}
@@ -973,7 +972,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
/* Verify class name before passing it to __autoload() */
if (strspn(name->val, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name->len) {
if (!key) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
}
return NULL;
}
@@ -985,7 +984,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) {
if (!key) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
}
return NULL;
}
@@ -1029,7 +1028,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
ce = zend_hash_find_ptr(EG(class_table), lc_name);
}
if (!key) {
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
}
return ce;
}
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index b7730be8f0..c140a18ec2 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -138,11 +138,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
zend_string *lc_class_name;
zend_string *lc_parent_class_name;
- lc_class_name = zend_string_alloc(ce->name->len, 0);
- zend_str_tolower_copy(lc_class_name->val, ce->name->val, ce->name->len);
+ lc_class_name = zend_string_tolower(ce->name);
if (!zend_hash_exists(&ce->function_table, lc_class_name)) {
- lc_parent_class_name = zend_string_alloc(ce->parent->name->len, 0);
- zend_str_tolower_copy(lc_parent_class_name->val, ce->parent->name->val, ce->parent->name->len);
+ lc_parent_class_name = zend_string_tolower(ce->parent->name);
if (!zend_hash_exists(&ce->function_table, lc_parent_class_name) &&
(function = zend_hash_find_ptr(&ce->parent->function_table, lc_parent_class_name)) != NULL) {
if (function->common.fn_flags & ZEND_ACC_CTOR) {
@@ -166,7 +164,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
}
zend_string_release(lc_parent_class_name);
}
- zend_string_free(lc_class_name);
+ zend_string_release(lc_class_name);
}
ce->constructor = ce->parent->constructor;
}
@@ -1023,8 +1021,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen
} else if (!strncmp(mname->val, ZEND_DEBUGINFO_FUNC_NAME, mname->len)) {
ce->__debugInfo = fe;
} else if (ce->name->len == mname->len) {
- zend_string *lowercase_name = zend_string_alloc(ce->name->len, 0);
- zend_str_tolower_copy(lowercase_name->val, ce->name->val, ce->name->len);
+ zend_string *lowercase_name = zend_string_tolower(ce->name);
lowercase_name = zend_new_interned_string(lowercase_name);
if (!memcmp(mname->val, lowercase_name->val, mname->len)) {
if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) {
@@ -1152,8 +1149,7 @@ static int zend_traits_copy_functions(zend_string *fnname, zend_function *fn, ze
fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
}
- lcname = zend_string_alloc(alias->alias->len, 0);
- zend_str_tolower_copy(lcname->val, alias->alias->val, alias->alias->len);
+ lcname = zend_string_tolower(alias->alias);
zend_add_trait_method(ce, alias->alias->val, lcname, &fn_copy, overriden);
zend_string_release(lcname);
@@ -1240,13 +1236,10 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce) /* {{{ */
zend_check_trait_usage(ce, cur_precedence->trait_method->ce);
/** Ensure that the preferred method is actually available. */
- lcname = zend_string_alloc(cur_method_ref->method_name->len, 0);
- zend_str_tolower_copy(lcname->val,
- cur_method_ref->method_name->val,
- cur_method_ref->method_name->len);
+ lcname = zend_string_tolower(cur_method_ref->method_name);
method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
lcname);
- zend_string_free(lcname);
+ zend_string_release(lcname);
if (!method_exists) {
zend_error_noreturn(E_COMPILE_ERROR,
"A precedence rule was defined for %s::%s but this method does not exist",
@@ -1300,13 +1293,10 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce) /* {{{ */
zend_check_trait_usage(ce, cur_method_ref->ce);
/** And, ensure that the referenced method is resolvable, too. */
- lcname = zend_string_alloc(cur_method_ref->method_name->len, 0);
- zend_str_tolower_copy(lcname->val,
- cur_method_ref->method_name->val,
- cur_method_ref->method_name->len);
+ lcname = zend_string_tolower(cur_method_ref->method_name);
method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
lcname);
- zend_string_free(lcname);
+ zend_string_release(lcname);
if (!method_exists) {
zend_error_noreturn(E_COMPILE_ERROR, "An alias was defined for %s::%s but this method does not exist", cur_method_ref->ce->name->val, cur_method_ref->method_name->val);
@@ -1330,11 +1320,8 @@ static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_tra
j = 0;
while (precedences[i]->exclude_from_classes[j].ce) {
if (precedences[i]->exclude_from_classes[j].ce == trait) {
- zend_string *lcname = zend_string_alloc(precedences[i]->trait_method->method_name->len, 0);
-
- zend_str_tolower_copy(lcname->val,
- precedences[i]->trait_method->method_name->val,
- precedences[i]->trait_method->method_name->len);
+ zend_string *lcname =
+ zend_string_tolower(precedences[i]->trait_method->method_name);
if (zend_hash_add_empty_element(exclude_table, lcname) == NULL) {
zend_string_release(lcname);
zend_error_noreturn(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name->val, trait->name->val);
@@ -1531,19 +1518,16 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce)
2) it is just a plain old inconsitency/typo/bug
as in the case where alias is set. */
- lc_method_name = zend_string_alloc(cur_alias->trait_method->method_name->len, 0);
- zend_str_tolower_copy(
- lc_method_name->val,
- cur_alias->trait_method->method_name->val,
- cur_alias->trait_method->method_name->len);
+ lc_method_name = zend_string_tolower(
+ cur_alias->trait_method->method_name);
if (zend_hash_exists(&ce->function_table,
lc_method_name)) {
- zend_string_free(lc_method_name);
+ zend_string_release(lc_method_name);
zend_error_noreturn(E_COMPILE_ERROR,
"The modifiers for the trait alias %s() need to be changed in the same statement in which the alias is defined. Error",
cur_alias->trait_method->method_name->val);
} else {
- zend_string_free(lc_method_name);
+ zend_string_release(lc_method_name);
zend_error_noreturn(E_COMPILE_ERROR,
"The modifiers of the trait method %s() are changed, but this method does not exist. Error",
cur_alias->trait_method->method_name->val);
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 644edfd61f..852d2d01dd 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1117,8 +1117,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
if (EXPECTED(key != NULL)) {
lc_function_name = Z_STR_P(key);
} else {
- lc_function_name = zend_string_alloc(function_name->len, 0);
- zend_str_tolower_copy(lc_function_name->val, function_name->val, function_name->len);
+ lc_function_name = zend_string_tolower(function_name);
}
if (function_name->len == ce->name->len && ce->constructor) {
@@ -1138,7 +1137,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
fbc = Z_FUNC_P(func);
} else {
if (UNEXPECTED(!key)) {
- zend_string_free(lc_function_name);
+ zend_string_release(lc_function_name);
}
if (ce->__call &&
Z_OBJ(EG(current_execute_data)->This) &&
@@ -1189,7 +1188,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
}
if (UNEXPECTED(!key)) {
- zend_string_free(lc_function_name);
+ zend_string_release(lc_function_name);
}
return fbc;
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 0101795d3f..14a85123c1 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -2342,6 +2342,34 @@ ZEND_API void zend_str_tolower(char *str, size_t length) /* {{{ */
}
/* }}} */
+ZEND_API zend_string *zend_string_tolower(zend_string *str) /* {{{ */
+{
+ register unsigned char *p = (unsigned char*)str->val;
+ register unsigned char *end = p + str->len;
+
+ while (p < end) {
+ if (*p != zend_tolower_ascii(*p)) {
+ zend_string *res = zend_string_alloc(str->len, 0);
+ register unsigned char *r;
+
+ if (p != (unsigned char*)str->val) {
+ memcpy(res->val, str->val, p - (unsigned char*)str->val);
+ }
+ r = p + (res->val - str->val);
+ while (p < end) {
+ *r = zend_tolower_ascii(*p);
+ p++;
+ r++;
+ }
+ *r = '\0';
+ return res;
+ }
+ p++;
+ }
+ return zend_string_copy(str);
+}
+/* }}} */
+
ZEND_API int zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
{
int retval;
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 83a70d5c47..1426fe919a 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -325,6 +325,7 @@ ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2);
ZEND_API void zend_str_tolower(char *str, size_t length);
ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, size_t length);
ZEND_API char *zend_str_tolower_dup(const char *source, size_t length);
+ZEND_API zend_string *zend_string_tolower(zend_string *str);
ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index c3f3546b57..964a4995f3 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2519,13 +2519,12 @@ ZEND_VM_C_LABEL(try_function_name):
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
} else {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name), 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
+ lcname = zend_string_tolower(Z_STR_P(function_name));
}
if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
}
- zend_string_free(lcname);
+ zend_string_release(lcname);
FREE_OP2();
fbc = Z_FUNC_P(func);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 5e67528f87..435eaf3bb4 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1578,13 +1578,12 @@ try_function_name:
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
} else {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name), 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
+ lcname = zend_string_tolower(Z_STR_P(function_name));
}
if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
}
- zend_string_free(lcname);
+ zend_string_release(lcname);
fbc = Z_FUNC_P(func);
called_scope = NULL;
@@ -1962,13 +1961,12 @@ try_function_name:
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
} else {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name), 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
+ lcname = zend_string_tolower(Z_STR_P(function_name));
}
if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
}
- zend_string_free(lcname);
+ zend_string_release(lcname);
fbc = Z_FUNC_P(func);
called_scope = NULL;
@@ -2152,13 +2150,12 @@ try_function_name:
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
} else {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name), 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
+ lcname = zend_string_tolower(Z_STR_P(function_name));
}
if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
}
- zend_string_free(lcname);
+ zend_string_release(lcname);
zval_ptr_dtor_nogc(free_op2);
fbc = Z_FUNC_P(func);
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index 5d6a8de7de..2a2e304b55 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -428,10 +428,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
"is_callable", sizeof("is_callable")))) {
zend_internal_function *func;
- char *lc_name = zend_str_tolower_dup(
- Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)));
+ zend_string *lc_name = zend_string_tolower(
+ Z_STR(ZEND_OP1_LITERAL(send1_opline)));
- if ((func = zend_hash_str_find_ptr(EG(function_table), lc_name, Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) != NULL &&
+ if ((func = zend_hash_find_ptr(EG(function_table), lc_name)) != NULL &&
func->type == ZEND_INTERNAL_FUNCTION &&
func->module->type == MODULE_PERSISTENT) {
zval t;
@@ -442,21 +442,21 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
literal_dtor(&ZEND_OP1_LITERAL(send1_opline));
MAKE_NOP(send1_opline);
MAKE_NOP(opline);
- efree(lc_name);
+ zend_string_release(lc_name);
break;
}
}
- efree(lc_name);
+ zend_string_release(lc_name);
} else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("extension_loaded")-1 &&
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
"extension_loaded", sizeof("extension_loaded")-1)) {
zval t;
- char *lc_name = zend_str_tolower_dup(
- Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)));
- zend_module_entry *m = zend_hash_str_find_ptr(&module_registry,
- lc_name, Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)));
+ zend_string *lc_name = zend_string_tolower(
+ Z_STR(ZEND_OP1_LITERAL(send1_opline)));
+ zend_module_entry *m = zend_hash_find_ptr(&module_registry,
+ lc_name);
- efree(lc_name);
+ zend_string_release(lc_name);
if (!m) {
if (!PG(enable_dl)) {
break;
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 94b43ca399..1342b13b47 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -1023,8 +1023,7 @@ PHP_FUNCTION(unserialize)
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(classes), entry) {
convert_to_string_ex(entry);
- lcname = zend_string_alloc(Z_STRLEN_P(entry), 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(entry), Z_STRLEN_P(entry));
+ lcname = zend_string_tolower(Z_STR_P(entry));
zend_hash_add_empty_element(class_hash, lcname);
zend_string_release(lcname);
} ZEND_HASH_FOREACH_END();