[njs] Avoiding explicit length calculation for strings.

noreply at nginx.com noreply at nginx.com
Tue Jul 2 02:35:02 UTC 2024


details:   https://github.com/nginx/njs/commit/911cacd055e0f6e469edee086802f9be2cb4710c
branches:  master
commit:    911cacd055e0f6e469edee086802f9be2cb4710c
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed, 26 Jun 2024 22:33:57 -0700
description:
Avoiding explicit length calculation for strings.


---
 src/njs_error.c       |  8 +-----
 src/njs_extern.c      |  7 +----
 src/njs_generator.c   | 51 +++++++--------------------------
 src/njs_json.c        |  2 +-
 src/njs_regexp.c      | 24 ++--------------
 src/njs_string.c      | 78 ---------------------------------------------------
 src/njs_string.h      |  4 +--
 src/njs_typed_array.c | 41 ++++++++-------------------
 src/njs_typed_array.h |  2 +-
 src/njs_vm.c          | 10 ++-----
 10 files changed, 31 insertions(+), 196 deletions(-)

diff --git a/src/njs_error.c b/src/njs_error.c
index 5c2c6c3c..376205d7 100644
--- a/src/njs_error.c
+++ b/src/njs_error.c
@@ -31,17 +31,11 @@ void
 njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_t *proto,
     u_char *start, size_t size)
 {
-    ssize_t        length;
     njs_int_t     ret;
     njs_value_t   string;
     njs_object_t  *error;
 
-    length = njs_utf8_length(start, size);
-    if (njs_slow_path(length < 0)) {
-        length = 0;
-    }
-
-    ret = njs_string_new(vm, &string, start, size, length);
+    ret = njs_string_create(vm, &string, start, size);
     if (njs_slow_path(ret != NJS_OK)) {
         return;
     }
diff --git a/src/njs_extern.c b/src/njs_extern.c
index 9ec1c1c9..621cb76d 100644
--- a/src/njs_extern.c
+++ b/src/njs_extern.c
@@ -18,7 +18,6 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
     const njs_external_t *external, njs_uint_t n)
 {
     size_t                size;
-    ssize_t               length;
     njs_int_t             ret;
     njs_lvlhsh_t          *hash;
     const u_char          *start;
@@ -119,12 +118,8 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
             } else {
                 start = (u_char *) external->u.property.value;
                 size = njs_strlen(start);
-                length = njs_utf8_length(start, size);
-                if (njs_slow_path(length < 0)) {
-                    length = 0;
-                }
 
-                ret = njs_string_new(vm, &prop->u.value, start, size, length);
+                ret = njs_string_create(vm, &prop->u.value, start, size);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return NJS_ERROR;
                 }
diff --git a/src/njs_generator.c b/src/njs_generator.c
index 6846ec6b..2e81a407 100644
--- a/src/njs_generator.c
+++ b/src/njs_generator.c
@@ -1062,7 +1062,6 @@ static njs_int_t
 njs_generate_var_statement_after(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    ssize_t                  length;
     njs_int_t                ret;
     njs_variable_t           *var;
     njs_parser_node_t        *lvalue, *expr;
@@ -1104,14 +1103,8 @@ njs_generate_var_statement_after(njs_vm_t *vm, njs_generator_t *generator,
             return NJS_ERROR;
         }
 
-        length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
-        if (njs_slow_path(length < 0)) {
-            return NJS_ERROR;
-        }
-
-        ret = njs_string_new(vm, &expr->u.value.data.u.lambda->name,
-                             lex_entry->name.start, lex_entry->name.length,
-                             length);
+        ret = njs_string_create(vm, &expr->u.value.data.u.lambda->name,
+                                lex_entry->name.start, lex_entry->name.length);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -3030,7 +3023,6 @@ static njs_int_t
 njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node_dst, njs_parser_node_t *node_src)
 {
-    ssize_t                  length;
     njs_int_t                ret;
     njs_value_t              property;
     njs_variable_t           *var;
@@ -3050,13 +3042,8 @@ njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator,
             return NJS_ERROR;
         }
 
-        length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
-        if (njs_slow_path(length < 0)) {
-            return NJS_ERROR;
-        }
-
-        ret = njs_string_new(vm, &property, lex_entry->name.start,
-                         lex_entry->name.length, length);
+        ret = njs_string_create(vm, &property, lex_entry->name.start,
+                                lex_entry->name.length);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -3641,7 +3628,6 @@ static njs_int_t
 njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    ssize_t                  length;
     njs_int_t                ret;
     njs_variable_t           *var;
     njs_function_lambda_t    *lambda;
@@ -3671,13 +3657,8 @@ njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator,
         return ret;
     }
 
-    length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
-    if (njs_slow_path(length < 0)) {
-        return NJS_ERROR;
-    }
-
-    ret = njs_string_new(vm, &lambda->name, lex_entry->name.start,
-                         lex_entry->name.length, length);
+    ret = njs_string_create(vm, &lambda->name, lex_entry->name.start,
+                            lex_entry->name.length);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -4207,7 +4188,6 @@ static njs_int_t
 njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    ssize_t                  length;
     njs_int_t                ret;
     njs_bool_t               async;
     njs_variable_t           *var;
@@ -4232,13 +4212,8 @@ njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator,
         return NJS_ERROR;
     }
 
-    length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
-    if (njs_slow_path(length < 0)) {
-        return NJS_ERROR;
-    }
-
-    ret = njs_string_new(vm, &lambda->name, lex_entry->name.start,
-                         lex_entry->name.length, length);
+    ret = njs_string_create(vm, &lambda->name, lex_entry->name.start,
+                            lex_entry->name.length);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -5413,7 +5388,6 @@ static njs_int_t
 njs_generate_global_reference(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node, njs_bool_t exception)
 {
-    ssize_t                  length;
     njs_int_t                ret;
     njs_index_t              index;
     njs_value_t              property;
@@ -5441,13 +5415,8 @@ njs_generate_global_reference(njs_vm_t *vm, njs_generator_t *generator,
         return NJS_ERROR;
     }
 
-    length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
-    if (njs_slow_path(length < 0)) {
-        return NJS_ERROR;
-    }
-
-    ret = njs_string_new(vm, &property, lex_entry->name.start,
-                         lex_entry->name.length, length);
+    ret = njs_string_create(vm, &property, lex_entry->name.start,
+                            lex_entry->name.length);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
diff --git a/src/njs_json.c b/src/njs_json.c
index 2b73cd85..85c5d0e8 100644
--- a/src/njs_json.c
+++ b/src/njs_json.c
@@ -1798,7 +1798,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
 
         njs_chb_append_literal(chain, "[");
 
-        (void) njs_typed_array_to_chain(stringify->vm, chain, array, NULL);
+        njs_typed_array_to_chain(stringify->vm, chain, array, NULL);
 
         njs_chb_append_literal(chain, "]");
 
diff --git a/src/njs_regexp.c b/src/njs_regexp.c
index 74a4c23b..1c7cfe87 100644
--- a/src/njs_regexp.c
+++ b/src/njs_regexp.c
@@ -30,8 +30,6 @@ static njs_int_t njs_regexp_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s,
     unsigned flags, njs_value_t *retval);
 static njs_array_t *njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r,
     njs_utf8_t utf8, njs_string_prop_t *string, njs_regex_match_data_t *data);
-static njs_int_t njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value,
-    u_char *start, uint32_t size, int32_t length);
 
 
 const njs_value_t  njs_string_lindex = njs_string("lastIndex");
@@ -1016,7 +1014,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8,
 {
     u_char                *start;
     size_t                c;
-    int32_t               size, length;
+    int32_t               size;
     uint32_t              index;
     njs_int_t             ret;
     njs_uint_t            i, n;
@@ -1050,15 +1048,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8,
             start = &string->start[c];
             size = njs_regex_capture(match_data, n + 1) - c;
 
-            if (utf8 == NJS_STRING_UTF8) {
-                length = njs_max(njs_utf8_length(start, size), 0);
-
-            } else {
-                length = size;
-            }
-
-            ret = njs_regexp_string_create(vm, &array->start[i], start, size,
-                                           length);
+            ret = njs_string_create(vm, &array->start[i], start, size);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto fail;
             }
@@ -1316,16 +1306,6 @@ njs_regexp_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, unsigned flags,
 }
 
 
-static njs_int_t
-njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value, u_char *start,
-    uint32_t size, int32_t length)
-{
-    length = (length >= 0) ? length : 0;
-
-    return njs_string_new(vm, value, start, size, length);
-}
-
-
 njs_int_t
 njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
diff --git a/src/njs_string.c b/src/njs_string.c
index c07016b5..ea22755b 100644
--- a/src/njs_string.c
+++ b/src/njs_string.c
@@ -535,84 +535,6 @@ njs_string_copy(njs_value_t *dst, njs_value_t *src)
 }
 
 
-/*
- * njs_string_validate() validates an UTF-8 string, evaluates its length,
- * sets njs_string_prop_t struct.
- */
-
-njs_int_t
-njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value)
-{
-    u_char    *start;
-    size_t    new_size, map_offset;
-    ssize_t   size, length;
-    uint32_t  *map;
-
-    size = value->short_string.size;
-
-    if (size != NJS_STRING_LONG) {
-        string->start = value->short_string.start;
-        length = value->short_string.length;
-
-        if (length == 0 && length != size) {
-            length = njs_utf8_length(value->short_string.start, size);
-
-            if (njs_slow_path(length < 0)) {
-                /* Invalid UTF-8 string. */
-                return length;
-            }
-
-            value->short_string.length = length;
-        }
-
-    } else {
-        string->start = value->long_string.data->start;
-        size = value->long_string.size;
-        length = value->long_string.data->length;
-
-        if (length == 0 && length != size) {
-            length = njs_utf8_length(string->start, size);
-
-            if (length != size) {
-                if (njs_slow_path(length < 0)) {
-                    /* Invalid UTF-8 string. */
-                    return length;
-                }
-
-                if (length > NJS_STRING_MAP_STRIDE) {
-                    /*
-                     * Reallocate the long string with offset map
-                     * after the string.
-                     */
-                    map_offset = njs_string_map_offset(size);
-                    new_size = map_offset + njs_string_map_size(length);
-
-                    start = njs_mp_alloc(vm->mem_pool, new_size);
-                    if (njs_slow_path(start == NULL)) {
-                        njs_memory_error(vm);
-                        return NJS_ERROR;
-                    }
-
-                    memcpy(start, string->start, size);
-                    string->start = start;
-                    value->long_string.data->start = start;
-
-                    map = (uint32_t *) (start + map_offset);
-                    map[0] = 0;
-                }
-            }
-
-            value->long_string.data->length = length;
-        }
-    }
-
-    string->size = size;
-    string->length = length;
-
-    return length;
-}
-
-
 static njs_int_t
 njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
diff --git a/src/njs_string.h b/src/njs_string.h
index a83c406a..9b478875 100644
--- a/src/njs_string.h
+++ b/src/njs_string.h
@@ -149,8 +149,6 @@ void njs_string_truncate(njs_value_t *value, uint32_t size, uint32_t length);
 uint32_t njs_string_trim(const njs_value_t *value, njs_string_prop_t *string,
     unsigned mode);
 void njs_string_copy(njs_value_t *dst, njs_value_t *src);
-njs_int_t njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string,
-    njs_value_t *value);
 njs_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2);
 void njs_string_slice_string_prop(njs_string_prop_t *dst,
     const njs_string_prop_t *string, const njs_slice_prop_t *slice);
@@ -197,7 +195,7 @@ njs_string_calc_length(njs_utf8_t utf8, const u_char *start, size_t size)
     default:
         length = njs_utf8_length(start, size);
 
-        return (length >= 0) ? length : 0;
+        return length;
     }
 }
 
diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c
index 42426c06..2a485a19 100644
--- a/src/njs_typed_array.c
+++ b/src/njs_typed_array.c
@@ -2054,11 +2054,11 @@ njs_typed_array_prototype_sort(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-njs_int_t
+void
 njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
     njs_typed_array_t *array, njs_value_t *sep)
 {
-    size_t             size, length, arr_length;
+    size_t             length;
     uint32_t           i;
     njs_string_prop_t  separator;
 
@@ -2068,29 +2068,18 @@ njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
 
     (void) njs_string_prop(&separator, sep);
 
-    arr_length = njs_typed_array_length(array);
+    length = njs_typed_array_length(array);
 
-    if (arr_length == 0) {
-        return 0;
+    if (length == 0) {
+        return;
     }
 
-    for (i = 0; i < arr_length; i++) {
+    for (i = 0; i < length; i++) {
         njs_number_to_chain(vm, chain, njs_typed_array_prop(array, i));
         njs_chb_append(chain, separator.start, separator.size);
     }
 
     njs_chb_drop(chain, separator.size);
-
-    size = njs_chb_size(chain);
-
-    if (njs_utf8_length(separator.start, separator.size) >= 0) {
-        length = size - (separator.size - separator.length) * (arr_length - 1);
-
-    } else {
-        length = 0;
-    }
-
-    return length;
 }
 
 
@@ -2098,8 +2087,7 @@ static njs_int_t
 njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
-    u_char             *p;
-    size_t             size, length, arr_length;
+    size_t             length;
     njs_int_t          ret;
     njs_chb_t          chain;
     njs_value_t        *this, *separator;
@@ -2117,7 +2105,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    arr_length = njs_typed_array_length(array);
+    length = njs_typed_array_length(array);
 
     separator = njs_arg(args, nargs, 1);
 
@@ -2133,7 +2121,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    if (arr_length == 0) {
+    if (length == 0) {
         njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
@@ -2145,18 +2133,13 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
 
     NJS_CHB_MP_INIT(&chain, vm);
 
-    length = njs_typed_array_to_chain(vm, &chain, array, separator);
-    size = njs_chb_size(&chain);
+    njs_typed_array_to_chain(vm, &chain, array, separator);
 
-    p = njs_string_alloc(vm, retval, size, length);
-    if (njs_slow_path(p == NULL)) {
-        return NJS_ERROR;
-    }
+    ret = njs_string_create_chb(vm, retval, &chain);
 
-    njs_chb_join_to(&chain, p);
     njs_chb_destroy(&chain);
 
-    return NJS_OK;
+    return ret;
 }
 
 
diff --git a/src/njs_typed_array.h b/src/njs_typed_array.h
index 47177fad..0e3b2f4e 100644
--- a/src/njs_typed_array.h
+++ b/src/njs_typed_array.h
@@ -14,7 +14,7 @@ njs_array_buffer_t *njs_typed_array_writable(njs_vm_t *vm,
     njs_typed_array_t *array);
 njs_int_t njs_typed_array_set_value(njs_vm_t *vm, njs_typed_array_t *array,
     uint32_t index, njs_value_t *setval);
-njs_int_t njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
+void njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
     njs_typed_array_t *array, njs_value_t *sep);
 njs_int_t njs_typed_array_prototype_slice(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t copy, njs_value_t *retval);
diff --git a/src/njs_vm.c b/src/njs_vm.c
index b0fe353b..908c40c8 100644
--- a/src/njs_vm.c
+++ b/src/njs_vm.c
@@ -1103,7 +1103,6 @@ njs_value_t *
 njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
     njs_value_t *retval)
 {
-    ssize_t                  length;
     njs_int_t                ret;
     njs_value_t              *val;
     njs_array_t              *keys;
@@ -1143,18 +1142,13 @@ njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
             continue;
         }
 
-        length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
-        if (njs_slow_path(length < 0)) {
-            return NULL;
-        }
-
         val = njs_array_push(vm, keys);
         if (njs_slow_path(value == NULL)) {
             return NULL;
         }
 
-        ret = njs_string_new(vm, val, lex_entry->name.start,
-                             lex_entry->name.length, length);
+        ret = njs_string_create(vm, val, lex_entry->name.start,
+                                lex_entry->name.length);
         if (njs_slow_path(ret != NJS_OK)) {
             return NULL;
         }


More information about the nginx-devel mailing list