From noreply at nginx.com Wed Jul 2 20:02:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Wed, 2 Jul 2025 20:02:02 +0000 (UTC) Subject: [njs] Modules: fixed qjs engine after bellard/quickjs@458c34d2. Message-ID: <20250702200202.4385A476CD@pubserv1.nginx> details: https://github.com/nginx/njs/commit/c367f7e2fd2bf0147e950131f4b7887d178110f6 branches: master commit: c367f7e2fd2bf0147e950131f4b7887d178110f6 user: Dmitry Volyntsev date: Tue, 1 Jul 2025 23:01:57 -0700 description: Modules: fixed qjs engine after bellard/quickjs at 458c34d2. Object leaks: ADDRESS REFS SHRF PROTO CONTENT 0x512000007fc0 1 [module] nginx: quickjs.c:1967: JS_FreeRuntime: Assertion `list_empty(&rt->gc_obj_list)' failed. After bellard/quickjs at 458c34d2 modules are treated as GC objects and tracked in rt->gc_obj_list. Intermediary module object loaded in ngx_qjs_clone() using JS_ReadObject() needed to be freed for proper ref_count accounting. --- nginx/ngx_js.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 448073b9..01d4bb2a 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -978,6 +978,11 @@ ngx_qjs_clone(ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *cf, void *external) "js load module exception: %V", &exception); goto destroy; } + + if (i != length - 1) { + /* JS_EvalFunction() does JS_FreeValue(cx, rv) for the last rv. */ + JS_FreeValue(cx, rv); + } } if (JS_ResolveModule(cx, rv) < 0) { From noreply at nginx.com Wed Jul 2 20:02:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Wed, 2 Jul 2025 20:02:02 +0000 (UTC) Subject: [njs] Fixed regexp compilation of patterns with escaped '[' characters. Message-ID: <20250702200202.4FBBB490A7@pubserv1.nginx> details: https://github.com/nginx/njs/commit/17124c81d84cfed13e47791893aa301681994db4 branches: master commit: 17124c81d84cfed13e47791893aa301681994db4 user: Dmitry Volyntsev date: Mon, 30 Jun 2025 18:30:03 -0700 description: Fixed regexp compilation of patterns with escaped '[' characters. This fixes #934 issue on Github. --- external/njs_regex.c | 27 +++++++++++++++++++++++++++ src/test/njs_unit_test.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/external/njs_regex.c b/external/njs_regex.c index a118666b..a0decefd 100644 --- a/external/njs_regex.c +++ b/external/njs_regex.c @@ -114,6 +114,11 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text) for (p = start; p < end; p++) { switch (*p) { + case '\\': + p += 1; + + break; + case '[': if (p + 1 < end && p[1] == ']') { p += 1; @@ -122,6 +127,11 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text) } else if (p + 2 < end && p[1] == '^' && p[2] == ']') { p += 2; anychars += 1; + + } else { + while (p < end && *p != ']') { + p += 1; + } } break; @@ -146,6 +156,15 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text) for (p = start; p < end; p++) { switch (*p) { + case '\\': + *dst++ = *p; + if (p + 1 < end) { + p += 1; + *dst++ = *p; + } + + continue; + case '[': if (p + 1 < end && p[1] == ']') { p += 1; @@ -156,6 +175,14 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text) p += 2; dst = njs_cpymem(dst, "[\\s\\S]", 6); continue; + + } else { + *dst++ = *p; + while (p < end && *p != ']') { + *dst++ = *p++; + } + + continue; } } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 3d466b96..01ff08d4 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -11969,6 +11969,48 @@ static njs_unit_test_t njs_test[] = { njs_str("/[]a/.test('a')"), njs_str("false") }, + { njs_str("/[#[]/.test('[')"), + njs_str("true") }, + + { njs_str("/[\\s[]/.test('[')"), + njs_str("true") }, + + { njs_str("/[#[^]/.test('[')"), + njs_str("true") }, + + { njs_str("/[#\\[]/.test('[')"), + njs_str("true") }, + + { njs_str("/[\\[^]/.test('[')"), + njs_str("true") }, + + { njs_str("/[^]abc]/.test('#abc]')"), + njs_str("true") }, + + { njs_str("/[[^]abc]/.test('[abc]')"), + njs_str("true") }, + + { njs_str("/[[^]abc]/.test('^abc]')"), + njs_str("true") }, + + { njs_str("/[]/.test('[]')"), + njs_str("false") }, + + { njs_str("/[[]/.test('[')"), + njs_str("true") }, + + { njs_str("/\\[]/.test('[]')"), + njs_str("true") }, + + { njs_str("/[]abc]/.test('abc]')"), + njs_str("false") }, + + { njs_str("/abc]/.test('abc]')"), + njs_str("true") }, + + { njs_str("/\\\\\\[]/.test('\\\\[]')"), + njs_str("true") }, + #ifdef NJS_HAVE_PCRE2 { njs_str("/[]*a/.test('a')"), njs_str("true") }, From noreply at nginx.com Thu Jul 3 05:51:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 05:51:02 +0000 (UTC) Subject: [njs] Fixed invalid link in README.md. Message-ID: <20250703055102.37D47490A5@pubserv1.nginx> details: https://github.com/nginx/njs/commit/873664f3453908f84cf5421e17f093666c0d2b41 branches: master commit: 873664f3453908f84cf5421e17f093666c0d2b41 user: Xiaobo Liu date: Tue, 1 Jul 2025 17:31:16 +0800 description: Fixed invalid link in README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f81075ce..d196510c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ NGINX JavaScript, also known as [NJS](https://nginx.org/en/docs/njs/), is a dyna - [Enabling the NGINX JavaScript modules](#enabling-the-nginx-javascipt-modules) - [Basics of writing .js script files](#basics-of-writing-js-script-files) - [Reference of custom objects, methods, and properties](#reference-of-custom-objects-methods-and-properties) - - [Example: Hello World](#hello-world) + - [Example: Hello World](#example-hello-world) - [The NJS command line interface (CLI)](#the-njs-command-line-interface-cli) - [Building from source](#building-from-source) - [Installing dependencies](#installing-dependencies) From noreply at nginx.com Thu Jul 3 16:35:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:02 +0000 (UTC) Subject: [njs] Improved memory consumption for concatenation of numbers and strings. Message-ID: <20250703163502.E7E45490A5@pubserv1.nginx> details: https://github.com/nginx/njs/commit/de00a558699b1fb234dd0328aa084a39ea788355 branches: master commit: de00a558699b1fb234dd0328aa084a39ea788355 user: Vadim Zhestikov date: Mon, 23 Jun 2025 12:33:18 -0700 description: Improved memory consumption for concatenation of numbers and strings. --- src/njs_vmcode.c | 52 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index c7adf63f..ebca15e3 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -667,14 +667,52 @@ NEXT_LBL; src = value1; } - ret = njs_primitive_value_to_string(vm, &dst, src); - if (njs_slow_path(ret != NJS_OK)) { - goto error; - } + if (njs_is_number(src)) { + size_t size; + njs_string_t sp; + char buf[64]; - ret = njs_string_concat(vm, s1, s2, &name); - if (njs_slow_path(ret == NJS_ERROR)) { - goto error; + /* Alloc free path for "str" + int or int + "str" concatenation. */ + + num = njs_number(src); + + if (isnan(num)) { + njs_atom_to_value(vm, &dst, NJS_ATOM_STRING_NaN); + + } else if (isinf(num)) { + + if (num < 0) { + njs_atom_to_value(vm, &dst, NJS_ATOM_STRING__Infinity); + + } else { + njs_atom_to_value(vm, &dst, NJS_ATOM_STRING_Infinity); + } + + } else { + size = njs_dtoa(num, buf); + + sp.start = (u_char *) buf; + sp.size = size; + sp.length = size; + + dst.string.data = &sp; + } + + ret = njs_string_concat(vm, s1, s2, &name); + if (njs_slow_path(ret == NJS_ERROR)) { + goto error; + } + + } else { + ret = njs_primitive_value_to_string(vm, &dst, src); + if (njs_slow_path(ret != NJS_OK)) { + goto error; + } + + ret = njs_string_concat(vm, s1, s2, &name); + if (njs_slow_path(ret == NJS_ERROR)) { + goto error; + } } njs_value_assign(retval, &name); From noreply at nginx.com Thu Jul 3 16:35:03 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:03 +0000 (UTC) Subject: [njs] Ignoring previous value in njs_flathsh_insert(). Message-ID: <20250703163503.0D6EE490AF@pubserv1.nginx> details: https://github.com/nginx/njs/commit/fee06cb2fe461a277b804f72bcef4f9ae89cafdd branches: master commit: fee06cb2fe461a277b804f72bcef4f9ae89cafdd user: Vadim Zhestikov date: Thu, 12 Jun 2025 08:34:17 -0700 description: Ignoring previous value in njs_flathsh_insert(). Previously, fhq->value was set to a previous value if the value existed. This is not used anymore in the code. --- src/njs_flathsh.c | 7 +------ src/njs_flathsh.h | 13 ++++++------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c index a9ef6e69..5a4efaa5 100644 --- a/src/njs_flathsh.c +++ b/src/njs_flathsh.c @@ -376,7 +376,6 @@ njs_flathsh_unique_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq) njs_int_t njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) { - void *tmp; njs_int_t cell_num, elt_num; njs_flathsh_elt_t *elt, *elts; njs_flathsh_descr_t *h; @@ -403,15 +402,11 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) fhq->proto->test(fhq, elt->value) == NJS_OK) { if (fhq->replace) { - tmp = fhq->value; - fhq->value = elt->value; - elt->value = tmp; + elt->value = fhq->value; return NJS_OK; } else { - fhq->value = elt->value; - return NJS_DECLINED; } } diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index 985bdab1..e15162d6 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -91,14 +91,13 @@ NJS_EXPORT njs_int_t njs_flathsh_unique_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq); /* - * njs_flathsh_insert() adds a hash element. If the element is already - * present in flathsh and the fhq->replace flag is zero, then fhq->value - * is updated with the old element and NJS_DECLINED is returned. - * If the element is already present in flathsh and the fhq->replace flag - * is non-zero, then the old element is replaced with the new element. - * fhq->value is updated with the old element, and NJS_OK is returned. + * njs_flathsh_insert() adds a hash element. If the element is already present + * in flathsh and the fhq->replace flag is zero, then NJS_DECLINED is returned. + * If the element is already present in flathsh and the fhq->replace flag is + * non-zero, then the old element is replaced with the new element and NJS_OK is + * returned. * If the element is not present in flathsh, then it is inserted and - * NJS_OK is returned. The fhq->value is not changed. + * NJS_OK is returned. * On memory allocation failure NJS_ERROR is returned. * * The required njs_flathsh_query_t fields: key_hash, key, proto, replace, From noreply at nginx.com Thu Jul 3 16:35:03 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:03 +0000 (UTC) Subject: [njs] Removed useless njs_value_assign() call. Message-ID: <20250703163503.1A904490B1@pubserv1.nginx> details: https://github.com/nginx/njs/commit/fe8a0e58d7bafe5a55705b30da5ac9722fa07e17 branches: master commit: fe8a0e58d7bafe5a55705b30da5ac9722fa07e17 user: Vadim Zhestikov date: Mon, 16 Jun 2025 14:33:05 -0700 description: Removed useless njs_value_assign() call. --- src/njs_object.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/njs_object.c b/src/njs_object.c index dec312c5..b842b1ab 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -2431,7 +2431,6 @@ njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash, return NULL; } - njs_value_assign(njs_prop_value(prop), constructor); prop->enumerable = 0; lhq.value = prop; From noreply at nginx.com Thu Jul 3 16:35:03 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:03 +0000 (UTC) Subject: [njs] Removed not used njs_scope_create_index_value(). Message-ID: <20250703163503.1FE7B490B2@pubserv1.nginx> details: https://github.com/nginx/njs/commit/d63a9d4b1de36c8279f505bc75d13e304726a8ac branches: master commit: d63a9d4b1de36c8279f505bc75d13e304726a8ac user: Vadim Zhestikov date: Fri, 27 Jun 2025 09:45:48 -0700 description: Removed not used njs_scope_create_index_value(). --- src/njs_scope.c | 16 ---------------- src/njs_scope.h | 1 - 2 files changed, 17 deletions(-) diff --git a/src/njs_scope.c b/src/njs_scope.c index 304e4e33..b95d3979 100644 --- a/src/njs_scope.c +++ b/src/njs_scope.c @@ -25,22 +25,6 @@ njs_scope_temp_index(njs_parser_scope_t *scope) } -njs_value_t * -njs_scope_create_index_value(njs_vm_t *vm, njs_index_t index) -{ - njs_value_t *value; - - value = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t)); - if (njs_slow_path(value == NULL)) { - return NULL; - } - - njs_scope_value_set(vm, index, value); - - return value; -} - - njs_value_t ** njs_scope_make(njs_vm_t *vm, uint32_t count) { diff --git a/src/njs_scope.h b/src/njs_scope.h index 16a47d98..32e44c6c 100644 --- a/src/njs_scope.h +++ b/src/njs_scope.h @@ -27,7 +27,6 @@ njs_index_t njs_scope_temp_index(njs_parser_scope_t *scope); -njs_value_t *njs_scope_create_index_value(njs_vm_t *vm, njs_index_t index); njs_value_t **njs_scope_make(njs_vm_t *vm, uint32_t count); njs_index_t njs_scope_global_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime); From noreply at nginx.com Thu Jul 3 16:35:03 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:03 +0000 (UTC) Subject: [njs] Simplified njs_object_prop_t. Message-ID: <20250703163503.14DFE490B0@pubserv1.nginx> details: https://github.com/nginx/njs/commit/a9adadb4f2b3e1ebfe2814feb4f5d943e13d149e branches: master commit: a9adadb4f2b3e1ebfe2814feb4f5d943e13d149e user: Vadim Zhestikov date: Fri, 6 Jun 2025 16:45:15 -0700 description: Simplified njs_object_prop_t. Removed enum_in_object_hash which is only set when prop->type is NJS_WHITEOUT and this check can be used instead. --- src/njs_object.c | 11 ++--------- src/njs_object_prop.c | 1 - src/njs_value.c | 1 - src/njs_value.h | 1 - 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/njs_object.c b/src/njs_object.c index 63273628..dec312c5 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -993,13 +993,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, njs_object_prop_t *hash_prop = lhq.value; - /* select names of prop which are not deleted and - * not deleted and created again i.e., - * they are replaced shared hash props - */ - if (hash_prop->type != NJS_WHITEOUT && - !(hash_prop->enum_in_object_hash)) - { + if (hash_prop->type != NJS_WHITEOUT) { njs_process_prop(vm, &prop_name, flags, items_string, items_symbol); } @@ -1060,8 +1054,7 @@ local_hash: } else { /* prop is: in_hash && in_shared_hash */ - /* select names of not deleted and created again */ - if (prop->enum_in_object_hash) { + if (prop->type == NJS_WHITEOUT) { njs_process_prop(vm, &prop_name, flags, items_string, items_symbol); } diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index d7c55d3a..275cd9ac 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -58,7 +58,6 @@ njs_object_prop_alloc2(njs_vm_t *vm, } prop->type = type; - prop->enum_in_object_hash = 0; if (flags != NJS_OBJECT_PROP_UNSET) { prop->enumerable = !!(flags & NJS_OBJECT_PROP_ENUMERABLE); diff --git a/src/njs_value.c b/src/njs_value.c index fe64afe6..92c87e85 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -1452,7 +1452,6 @@ slow_path: } prop->type = NJS_WHITEOUT; - prop->enum_in_object_hash = 1; return NJS_OK; } diff --git a/src/njs_value.h b/src/njs_value.h index 7bc9eff3..da53f158 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -339,7 +339,6 @@ struct njs_object_prop_s { #define njs_prop_setter(_p) (_p)->u.accessor.setter njs_object_prop_type_t type:8; /* 3 bits */ - njs_object_prop_type_t enum_in_object_hash:8; /* 3 bits */ njs_object_attribute_t writable:8; /* 2 bits */ njs_object_attribute_t enumerable:8; /* 2 bits */ From noreply at nginx.com Thu Jul 3 16:35:03 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:03 +0000 (UTC) Subject: [njs] Improved memory consumption of String.prototype.concat() with numbers. Message-ID: <20250703163503.02173490A8@pubserv1.nginx> details: https://github.com/nginx/njs/commit/853bf75366488af34e6d2db338bc0c8bfb850ea2 branches: master commit: 853bf75366488af34e6d2db338bc0c8bfb850ea2 user: Vadim Zhestikov date: Mon, 23 Jun 2025 17:44:57 -0700 description: Improved memory consumption of String.prototype.concat() with numbers. --- src/njs_dtoa.h | 2 + src/njs_string.c | 110 ++++++++++++++++++++++++++++++++++++----------- src/test/njs_unit_test.c | 9 ++++ 3 files changed, 95 insertions(+), 26 deletions(-) diff --git a/src/njs_dtoa.h b/src/njs_dtoa.h index 35ff09a5..4dcfc098 100644 --- a/src/njs_dtoa.h +++ b/src/njs_dtoa.h @@ -7,6 +7,8 @@ #ifndef _NJS_DTOA_H_INCLUDED_ #define _NJS_DTOA_H_INCLUDED_ +#define NJS_DTOA_MAX_LEN njs_length("-1.7976931348623157e+308") + NJS_EXPORT size_t njs_dtoa(double value, char *start); NJS_EXPORT size_t njs_dtoa_precision(double value, char *start, size_t prec); NJS_EXPORT size_t njs_dtoa_exponential(double value, char *start, diff --git a/src/njs_string.c b/src/njs_string.c index 6d7c464d..d3991451 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -601,56 +601,114 @@ njs_int_t njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - u_char *p, *start; - uint64_t size, length, mask; + char *np, *np_end; + double num; + u_char *p; + uint64_t sz, size, length; njs_int_t ret; njs_uint_t i; njs_string_prop_t string; + char buf[512], tmp[NJS_DTOA_MAX_LEN]; if (njs_is_null_or_undefined(&args[0])) { njs_type_error(vm, "\"this\" argument is null or undefined"); return NJS_ERROR; } + size = 0; + length = 0; + + np = buf; + np_end = buf + sizeof(buf); + for (i = 0; i < nargs; i++) { - if (!njs_is_string(&args[i])) { - ret = njs_value_to_string(vm, &args[i], &args[i]); - if (ret != NJS_OK) { - return ret; + if (njs_is_number(&args[i])) { + num = njs_number(&args[i]); + + if (isnan(num)) { + size += njs_length("NaN"); + length += njs_length("NaN"); + + } else if (isinf(num)) { + if (num < 0) { + size += njs_length("-Infinity"); + length += njs_length("-Infinity"); + + } else { + size += njs_length("Infinity"); + length += njs_length("Infinity"); + } + + } else { + if (njs_fast_path(np < np_end - NJS_DTOA_MAX_LEN)) { + sz = njs_dtoa(num, np + sizeof(uint8_t)); + + *np = (uint8_t) sz; + np += sizeof(uint8_t) + sz; + + } else { + sz = njs_dtoa(num, tmp); + } + + size += sz; + length += sz; + } + + } else { + if (!njs_is_string(&args[i])) { + ret = njs_value_to_string(vm, &args[i], &args[i]); + if (ret != NJS_OK) { + return ret; + } + } + + njs_string_prop(vm, &string, &args[i]); + + size += string.size; + length += string.length; } } - if (nargs == 1) { - njs_string_copy(retval, &args[0]); - return NJS_OK; + p = njs_string_alloc(vm, retval, size, length); + if (njs_slow_path(p == NULL)) { + return NJS_ERROR; } - size = 0; - length = 0; - mask = -1; + np = buf; for (i = 0; i < nargs; i++) { - (void) njs_string_prop(vm, &string, &args[i]); + if (njs_is_number(&args[i])) { + num = njs_number(&args[i]); - size += string.size; - length += string.length; - } + if (isnan(num)) { + p = njs_cpymem(p, "NaN", njs_length("NaN")); - length &= mask; + } else if (isinf(num)) { + if (num < 0) { + p = njs_cpymem(p, "-Infinity", njs_length("-Infinity")); - start = njs_string_alloc(vm, retval, size, length); - if (njs_slow_path(start == NULL)) { - return NJS_ERROR; - } + } else { + p = njs_cpymem(p, "Infinity", njs_length("Infinity")); + } - p = start; + } else { + if (njs_fast_path(np < np_end - NJS_DTOA_MAX_LEN)) { + length = *np++; + p = njs_cpymem(p, np, length); + np += length; - for (i = 0; i < nargs; i++) { - (void) njs_string_prop(vm, &string, &args[i]); + } else { + sz = njs_dtoa(num, (char *) p); + p += sz; + } + } - p = memcpy(p, string.start, string.size); - p += string.size; + } else { + njs_string_prop(vm, &string, &args[i]); + + p = njs_cpymem(p, string.start, string.size); + } } return NJS_OK; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 01ff08d4..33472f24 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -11036,6 +11036,15 @@ static njs_unit_test_t njs_test[] = { njs_str("''.concat.apply('a', [ 'b', 'c' ], 'd')"), njs_str("abc") }, + { njs_str("''.concat.apply('', Array(128).fill(1.23456789123e14)) == '123456789123000'.repeat(128)"), + njs_str("true") }, + + { njs_str("''.concat.apply('', Array(128).fill(0).map((v,i)=>Math.log2(i))).startsWith('-Infinity')"), + njs_str("true") }, + + { njs_str("''.concat.apply('', Array(256).fill(0).map((v,i)=> !(i % 2) ? Math.exp(i) : 'α'.repeat(Math.log2(i)))).endsWith('110ααααααα')"), + njs_str("true") }, + { njs_str("[].join.call([1,2,3])"), njs_str("1,2,3") }, From noreply at nginx.com Thu Jul 3 16:35:03 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 16:35:03 +0000 (UTC) Subject: [njs] Released temporary template literal memory. Message-ID: <20250703163503.07F77490AC@pubserv1.nginx> details: https://github.com/nginx/njs/commit/4edf28c49a3a71ba0c09532cbe4b5739918668ee branches: master commit: 4edf28c49a3a71ba0c09532cbe4b5739918668ee user: Vadim Zhestikov date: Wed, 25 Jun 2025 11:50:25 -0700 description: Released temporary template literal memory. --- src/njs_vmcode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index ebca15e3..ba6df7d8 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -2048,6 +2048,8 @@ njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *retval) return ret; } + njs_array_destroy(vm, array); + return sizeof(njs_vmcode_template_literal_t); } From noreply at nginx.com Thu Jul 3 18:51:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 3 Jul 2025 18:51:02 +0000 (UTC) Subject: [nginx] QUIC: adjusted OpenSSL 3.5 QUIC API feature test. Message-ID: <20250703185102.A4811490A8@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/0bb7489cb2fcc60ce24fae2d5581c7441bfa0931 branches: master commit: 0bb7489cb2fcc60ce24fae2d5581c7441bfa0931 user: Sergey Kandaurov date: Sun, 22 Jun 2025 20:40:05 +0400 description: QUIC: adjusted OpenSSL 3.5 QUIC API feature test. A bug with the "quic_transport_parameters" extension and SNI described in cedb855d7 is now fixed in the OpenSSL 3.5.1 release, as requested in https://github.com/openssl/openssl/pull/27706. --- src/event/quic/ngx_event_quic.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/event/quic/ngx_event_quic.h b/src/event/quic/ngx_event_quic.h index 335d87191..bab085f46 100644 --- a/src/event/quic/ngx_event_quic.h +++ b/src/event/quic/ngx_event_quic.h @@ -12,11 +12,8 @@ #include -#ifdef OSSL_RECORD_PROTECTION_LEVEL_NONE -#ifndef NGX_QUIC_OPENSSL_API -#define NGX_QUIC_BORINGSSL_API 1 -#define NGX_QUIC_OPENSSL_COMPAT 1 -#endif +#if (OPENSSL_VERSION_NUMBER >= 0x30500010L) +#define NGX_QUIC_OPENSSL_API 1 #elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION) #define NGX_QUIC_QUICTLS_API 1 From noreply at nginx.com Fri Jul 4 02:07:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Fri, 4 Jul 2025 02:07:02 +0000 (UTC) Subject: [njs] Fixed RegExp compilation after 17124c81. Message-ID: <20250704020702.240754837F@pubserv1.nginx> details: https://github.com/nginx/njs/commit/ecc237b079a699537351ddc3dd1ade2f96918451 branches: master commit: ecc237b079a699537351ddc3dd1ade2f96918451 user: Dmitry Volyntsev date: Thu, 3 Jul 2025 16:53:33 -0700 description: Fixed RegExp compilation after 17124c81. Previously, heap-buffer-overflow happened due to incorrect copying of [...] regexp parts. Found by OSS-Fuzz. --- external/njs_regex.c | 9 ++++++++- src/test/njs_unit_test.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/external/njs_regex.c b/external/njs_regex.c index a0decefd..cd45afc0 100644 --- a/external/njs_regex.c +++ b/external/njs_regex.c @@ -177,11 +177,16 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text) continue; } else { - *dst++ = *p; + *dst++ = *p++; /* Copy '['. */ + while (p < end && *p != ']') { *dst++ = *p++; } + if (p < end) { + *dst++ = *p; /* Copy ']'. */ + } + continue; } } @@ -189,6 +194,8 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text) *dst++ = *p; } + njs_assert(dst == text->start + text->length); + return NJS_OK; #else diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 33472f24..541e3327 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -9556,6 +9556,9 @@ static njs_unit_test_t njs_test[] = { njs_str("/["), njs_str("SyntaxError: Unterminated RegExp \"/[\" in 1") }, + { njs_str("/[][a"), + njs_str("SyntaxError: Unterminated RegExp \"/[][a\" in 1") }, + { njs_str("/[\\"), njs_str("SyntaxError: Unterminated RegExp \"/[\\\" in 1") }, @@ -9591,11 +9594,24 @@ static njs_unit_test_t njs_test[] = njs_str("/\\]cd/") }, #endif + { njs_str("RegExp('[][a')"), + njs_str("SyntaxError: " + njs_pcre_var("pcre_compile2(\"(?!)[a\") failed: missing terminating ] for character class at \"\"", + "pcre_compile(\"[][a\") failed: missing terminating ] for character class")) }, + + { njs_str("RegExp('[][a][a')"), + njs_str("SyntaxError: " + njs_pcre_var("pcre_compile2(\"(?!)[a][a\") failed: missing terminating ] for character class at \"\"", + "pcre_compile(\"[][a][a\") failed: missing terminating ] for character class")) }, + { njs_str("RegExp('[\\\\')"), njs_str("SyntaxError: " njs_pcre_var("pcre_compile2(\"[\\\") failed: \\ at end of pattern at \"\"", "pcre_compile(\"[\\\") failed: \\ at end of pattern")) }, + { njs_str("RegExp('[][a]')"), + njs_str(njs_pcre_var("/(?!)[a]/", "/[][a]/")) }, + { njs_str("RegExp('\\\\0').source[1]"), njs_str("0") }, From noreply at nginx.com Tue Jul 8 22:27:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Tue, 8 Jul 2025 22:27:02 +0000 (UTC) Subject: [njs] Fixed NULL pointer dereference when processing If-* headers. Message-ID: <20250708222702.094A647E71@pubserv1.nginx> details: https://github.com/nginx/njs/commit/a4addc9b3145313f74de31b592e3b36714987ea0 branches: master commit: a4addc9b3145313f74de31b592e3b36714987ea0 user: Dmitry Volyntsev date: Mon, 7 Jul 2025 22:40:45 -0700 description: Fixed NULL pointer dereference when processing If-* headers. Previously, when processing requests with If-Match and If-Unmodified-Since headers worker process crashed. For example with the following code: try { r.return(200) } catch (e) { r.internalRedirect() } The fix is to disable not_modified filter as it was done in nginx perl module nginx/nginx at d9887ee2. --- nginx/ngx_http_js_module.c | 8 ++++++++ nginx/t/js_internal_redirect.t | 29 ++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index 1e0a927f..45ddf17e 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -2455,6 +2455,8 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } + r->disable_not_modified = 1; + if (ngx_http_send_header(r) == NGX_ERROR) { return NJS_ERROR; } @@ -2738,6 +2740,8 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, cv.value.data = text.start; cv.value.len = text.length; + r->disable_not_modified = 1; + ctx->status = ngx_http_send_response(r, status, NULL, &cv); if (ctx->status == NGX_ERROR) { @@ -5445,6 +5449,8 @@ ngx_http_qjs_ext_return(JSContext *cx, JSValueConst this_val, cv.value.data = body.data; cv.value.len = body.len; + r->disable_not_modified = 1; + ctx->status = ngx_http_send_response(r, status, NULL, &cv); if (ctx->status == NGX_ERROR) { @@ -5670,6 +5676,8 @@ ngx_http_qjs_ext_send_header(JSContext *cx, JSValueConst this_val, return JS_ThrowInternalError(cx, "failed to set content type"); } + r->disable_not_modified = 1; + if (ngx_http_send_header(r) == NGX_ERROR) { return JS_ThrowInternalError(cx, "failed to send header"); } diff --git a/nginx/t/js_internal_redirect.t b/nginx/t/js_internal_redirect.t index abfe79f9..721113bb 100644 --- a/nginx/t/js_internal_redirect.t +++ b/nginx/t/js_internal_redirect.t @@ -11,6 +11,7 @@ use warnings; use strict; use Test::More; +use Socket qw/ CRLF /; BEGIN { use FindBin; chdir($FindBin::Bin); } @@ -54,6 +55,10 @@ http { return 200 redirect$arg_b; } + location /destroyed_ctx { + js_content test.destroyed_ctx; + } + location @named { return 200 named; } @@ -87,7 +92,16 @@ $t->write_file('test.js', < details: https://github.com/nginx/njs/commit/82d76e7a28104f24235ba93c7d277ff724d3feae branches: master commit: 82d76e7a28104f24235ba93c7d277ff724d3feae user: Vadim Zhestikov date: Thu, 3 Jul 2025 14:14:43 -0700 description: Improved String.prototype.concat() with scalar values. --- src/njs_string.c | 64 ++++++++++++++++++++++++++++++++++++++---------- src/test/njs_unit_test.c | 24 ++++++++++++++++++ 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/njs_string.c b/src/njs_string.c index d3991451..1a2b2333 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -608,7 +608,9 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_int_t ret; njs_uint_t i; njs_string_prop_t string; - char buf[512], tmp[NJS_DTOA_MAX_LEN]; + char buf[512]; + +#define NJS_SZ_LAST 64 if (njs_is_null_or_undefined(&args[0])) { njs_type_error(vm, "\"this\" argument is null or undefined"); @@ -620,6 +622,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, np = buf; np_end = buf + sizeof(buf); + *np = 0; for (i = 0; i < nargs; i++) { if (njs_is_number(&args[i])) { @@ -640,20 +643,42 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } else { - if (njs_fast_path(np < np_end - NJS_DTOA_MAX_LEN)) { - sz = njs_dtoa(num, np + sizeof(uint8_t)); - - *np = (uint8_t) sz; - np += sizeof(uint8_t) + sz; - - } else { - sz = njs_dtoa(num, tmp); + sz = njs_dtoa(num, np + sizeof(uint8_t)); + + if (*np == 0) { + if (np + sizeof(uint8_t) + sz + < np_end - NJS_DTOA_MAX_LEN - sizeof(uint8_t)) + { + *np = (uint8_t) sz; + np += sizeof(uint8_t) + sz; + *np = 0; + + } else { + *np = NJS_SZ_LAST; + } } size += sz; length += sz; } + } else if (njs_is_boolean(&args[i])) { + if (njs_is_true(&args[i])) { + size += njs_length("true"); + length += njs_length("true"); + } else { + size += njs_length("false"); + length += njs_length("false"); + } + + } else if (njs_is_null(&args[i])) { + size += njs_length("null"); + length += njs_length("null"); + + } else if (njs_is_undefined(&args[i])) { + size += njs_length("undefined"); + length += njs_length("undefined"); + } else { if (!njs_is_string(&args[i])) { ret = njs_value_to_string(vm, &args[i], &args[i]); @@ -693,10 +718,10 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } else { - if (njs_fast_path(np < np_end - NJS_DTOA_MAX_LEN)) { - length = *np++; - p = njs_cpymem(p, np, length); - np += length; + if (*np != NJS_SZ_LAST) { + sz = *np++; + p = njs_cpymem(p, np, sz); + np += sz; } else { sz = njs_dtoa(num, (char *) p); @@ -704,6 +729,19 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } + } else if (njs_is_boolean(&args[i])) { + if (njs_is_true(&args[i])) { + p = njs_cpymem(p, "true", njs_length("true")); + } else { + p = njs_cpymem(p, "false", njs_length("false")); + } + + } else if (njs_is_null(&args[i])) { + p = njs_cpymem(p, "null", njs_length("null")); + + } else if (njs_is_undefined(&args[i])) { + p = njs_cpymem(p, "undefined", njs_length("undefined")); + } else { njs_string_prop(vm, &string, &args[i]); diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 541e3327..fd98dbb5 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -11003,6 +11003,30 @@ static njs_unit_test_t njs_test[] = "f.apply(123, {})"), njs_str("123") }, + { njs_str("'Hello'.concat(' ', 'World')"), + njs_str("Hello World") }, + + { njs_str("'Value: '.concat(42, ' and ', 3.14)"), + njs_str("Value: 42 and 3.14") }, + + { njs_str("'Flags: '.concat(true, ' and ', false)"), + njs_str("Flags: true and false") }, + + { njs_str("'Values: '.concat(null, ' and ', undefined)"), + njs_str("Values: null and undefined") }, + + { njs_str("'Mixed: '.concat(123, ' ', true, ' ', null, ' ', undefined)"), + njs_str("Mixed: 123 true null undefined") }, + + { njs_str("'Special: '.concat(NaN, ' ', Infinity, ' ', -Infinity)"), + njs_str("Special: NaN Infinity -Infinity") }, + + { njs_str("'Numbers: '.concat(1234567890, ' ', 0.123456789, ' ', 1.23e-10)"), + njs_str("Numbers: 1234567890 0.123456789 1.23e-10") }, + + { njs_str("'Zero: '.concat(0, ' ', -0)"), + njs_str("Zero: 0 0") }, + { njs_str("(function(index, ...rest){ return rest[index];})" ".apply({}, [1022].concat(Array(1023).fill(1).map((v,i)=>i.toString(16))))"), njs_str("3fe") }, From noreply at nginx.com Wed Jul 9 19:18:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Wed, 9 Jul 2025 19:18:02 +0000 (UTC) Subject: [njs] Replaced constant by sizeof value. Message-ID: <20250709191802.9B4443F3B9@pubserv1.nginx> details: https://github.com/nginx/njs/commit/97603051707f7b4a8aac17e733fc8bbf20c933cf branches: master commit: 97603051707f7b4a8aac17e733fc8bbf20c933cf user: Vadim Zhestikov date: Sun, 6 Jul 2025 11:30:38 -0700 description: Replaced constant by sizeof value. --- src/njs_flathsh.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index e15162d6..38a9c56e 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -72,7 +72,7 @@ struct njs_flathsh_query_s { #define njs_hash_elts(h) \ - ((njs_flathsh_elt_t *) ((char *) (h) + 16 /* njs_flathsh_descr_t size */)) + ((njs_flathsh_elt_t *) ((char *) (h) + sizeof(njs_flathsh_descr_t))) /* From noreply at nginx.com Wed Jul 9 19:18:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Wed, 9 Jul 2025 19:18:02 +0000 (UTC) Subject: [njs] Optimized memory consumption by object hash. Message-ID: <20250709191802.ABEBC48F11@pubserv1.nginx> details: https://github.com/nginx/njs/commit/2f288a9c6f5db62e34709ad9380cd2f27bbf07c5 branches: master commit: 2f288a9c6f5db62e34709ad9380cd2f27bbf07c5 user: Vadim Zhestikov date: Fri, 6 Jun 2025 16:52:57 -0700 description: Optimized memory consumption by object hash. The new hash takes 42% less memory per element. --- src/njs_array.c | 6 +- src/njs_atom.c | 78 +++++++--- src/njs_buffer.c | 8 +- src/njs_builtin.c | 150 ++++++++++--------- src/njs_error.c | 47 +++--- src/njs_extern.c | 49 +++---- src/njs_flathsh.c | 38 ++--- src/njs_flathsh.h | 17 ++- src/njs_function.c | 68 ++++----- src/njs_json.c | 28 ++-- src/njs_module.c | 25 +++- src/njs_object.c | 113 ++++++++------ src/njs_object.h | 19 +-- src/njs_object_prop.c | 334 ++++++++++++++++++++---------------------- src/njs_object_prop_declare.h | 8 +- src/njs_regexp.c | 86 +++++------ src/njs_scope.c | 11 +- src/njs_value.c | 17 +-- src/njs_value.h | 39 +++-- src/njs_vm.c | 56 +++---- src/njs_vmcode.c | 14 +- src/test/lvlhsh_unit_test.c | 6 +- src/test/njs_externals_test.c | 8 +- 23 files changed, 646 insertions(+), 579 deletions(-) diff --git a/src/njs_array.c b/src/njs_array.c index e6f8ed83..3f424bc4 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -702,8 +702,10 @@ njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, uint32_t unused, } } - prop->type = NJS_PROPERTY; - njs_set_number(njs_prop_value(prop), length); + ret = njs_array_length_redefine(vm, value, length, 1); + if (ret != NJS_OK) { + return ret; + } njs_value_assign(retval, setval); diff --git a/src/njs_atom.c b/src/njs_atom.c index 24e6dc17..dc66f886 100644 --- a/src/njs_atom.c +++ b/src/njs_atom.c @@ -82,7 +82,7 @@ njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, size_t length, uint32_t hash) { njs_int_t ret; - njs_value_t *entry; + njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; lhq.key.start = key; @@ -92,33 +92,65 @@ njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, size_t length, ret = njs_lvlhsh_find(vm->atom_hash_current, &lhq); if (ret == NJS_OK) { - return lhq.value; + return njs_prop_value(lhq.value); } ret = njs_lvlhsh_find(&vm->atom_hash_shared, &lhq); if (ret == NJS_OK) { - return lhq.value; + return njs_prop_value(lhq.value); } - entry = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t)); - if (njs_slow_path(entry == NULL)) { + lhq.pool = vm->mem_pool; + + ret = njs_lvlhsh_insert(vm->atom_hash_current, &lhq); + if (njs_slow_path(ret != NJS_OK)) { return NULL; } - ret = njs_string_create(vm, entry, key, size); + prop = lhq.value; + + ret = njs_string_create(vm, &prop->u.value, key, size); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - entry->string.atom_id = vm->atom_id_generator++; - if (njs_atom_is_number(entry->string.atom_id)) { + prop->u.value.string.atom_id = vm->atom_id_generator++; + if (njs_atom_is_number(prop->u.value.string.atom_id)) { njs_internal_error(vm, "too many atoms"); return NULL; } - entry->string.token_type = NJS_KEYWORD_TYPE_UNDEF; + prop->u.value.string.token_type = NJS_KEYWORD_TYPE_UNDEF; + + return &prop->u.value; +} + + +static njs_value_t * +njs_atom_find_or_add_string(njs_vm_t *vm, njs_value_t *value, + uint32_t hash) +{ + njs_int_t ret; + njs_object_prop_t *prop; + njs_lvlhsh_query_t lhq; + + njs_assert(njs_is_string(value)); + + lhq.key.start = value->string.data->start; + lhq.key.length = value->string.data->size; + lhq.key_hash = hash; + lhq.proto = &njs_lexer_hash_proto; + + ret = njs_lvlhsh_find(vm->atom_hash_current, &lhq); + if (ret == NJS_OK) { + return njs_prop_value(lhq.value); + } + + ret = njs_lvlhsh_find(&vm->atom_hash_shared, &lhq); + if (ret == NJS_OK) { + return njs_prop_value(lhq.value); + } - lhq.value = entry; lhq.pool = vm->mem_pool; ret = njs_lvlhsh_insert(vm->atom_hash_current, &lhq); @@ -126,7 +158,19 @@ njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, size_t length, return NULL; } - return entry; + prop = lhq.value; + + prop->u.value = *value; + + prop->u.value.string.atom_id = vm->atom_id_generator++; + if (njs_atom_is_number(prop->u.value.string.atom_id)) { + njs_internal_error(vm, "too many atoms"); + return NULL; + } + + prop->u.value.string.token_type = NJS_KEYWORD_TYPE_UNDEF; + + return &prop->u.value; } @@ -190,7 +234,6 @@ njs_atom_hash_init(njs_vm_t *vm) if (value->type == NJS_SYMBOL) { lhq.key_hash = value->string.atom_id; - lhq.value = (void *) value; ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq); if (njs_slow_path(ret != NJS_OK)) { @@ -206,7 +249,6 @@ njs_atom_hash_init(njs_vm_t *vm) lhq.key_hash = njs_djb_hash(start, len); lhq.key.length = len; lhq.key.start = start; - lhq.value = (void *) value; ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq); if (njs_slow_path(ret != NJS_OK)) { @@ -214,6 +256,8 @@ njs_atom_hash_init(njs_vm_t *vm) return 0xffffffff; } } + + *njs_prop_value(lhq.value) = *value; } vm->atom_hash_current = &vm->atom_hash_shared; @@ -247,10 +291,7 @@ njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value) hash_id = njs_djb_hash(value->string.data->start, value->string.data->size); - entry = njs_atom_find_or_add(vm, value->string.data->start, - value->string.data->size, - value->string.data->length, - hash_id); + entry = njs_atom_find_or_add_string(vm, value, hash_id); if (njs_slow_path(entry == NULL)) { return NJS_ERROR; } @@ -320,13 +361,14 @@ njs_atom_symbol_add(njs_vm_t *vm, njs_value_t *value) if (value->type == NJS_SYMBOL) { lhq.key_hash = value->atom_id; - lhq.value = (void *) value; ret = njs_flathsh_insert(vm->atom_hash_current, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } + + *njs_prop_value(lhq.value) = *value; } return NJS_OK; diff --git a/src/njs_buffer.c b/src/njs_buffer.c index 3f0469e7..dbe9447a 100644 --- a/src/njs_buffer.c +++ b/src/njs_buffer.c @@ -2732,8 +2732,8 @@ static njs_int_t njs_buffer(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { - return njs_object_prop_init(vm, &njs_buffer_constructor_init, prop, atom_id, - value, retval); + return njs_object_props_init(vm, &njs_buffer_constructor_init, prop, + atom_id, value, retval); } @@ -2741,8 +2741,8 @@ static njs_int_t njs_buffer_constants(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { - return njs_object_prop_init(vm, &njs_buffer_constants_init, prop, atom_id, - value, retval); + return njs_object_props_init(vm, &njs_buffer_constants_init, prop, atom_id, + value, retval); } diff --git a/src/njs_builtin.c b/src/njs_builtin.c index c960fe1f..5ce2ec7e 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -433,17 +433,11 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) /* NJS_BUILTIN_TRAVERSE_KEYS. */ - prop = njs_object_prop_alloc(vm, &njs_value_null, 0); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - ret = njs_atom_string_create(vm, &prop_name, buf, p - buf); if (njs_slow_path(ret != NJS_OK)) { return ret; } - lhq.value = prop; lhq.key_hash = prop_name.atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -455,6 +449,14 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 0; + prop->writable = 0; + prop->u.value = njs_value_null; + return NJS_OK; } @@ -477,6 +479,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, njs_uint_t i, n; njs_value_t value, tag; njs_object_t object; + njs_object_prop_t *prop; njs_lvlhsh_each_t lhe; njs_exotic_slots_t *slots; njs_function_name_t *fn; @@ -538,12 +541,13 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, njs_lvlhsh_each_init(&lhe, &njs_modules_hash_proto); for ( ;; ) { - module = njs_lvlhsh_each(&vm->modules_hash, &lhe); - - if (module == NULL) { + prop = (njs_object_prop_t *) njs_flathsh_each(&vm->modules_hash, &lhe); + if (prop == NULL) { break; } + module = prop->u.mod; + if (njs_is_object(&module->value) && !njs_object(&module->value)->shared) { @@ -815,15 +819,6 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_value_assign(retval, setval); } - prop = njs_object_prop_alloc(vm, retval, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - njs_value_assign(njs_prop_value(prop), retval); - prop->enumerable = self->enumerable; - - lhq.value = prop; lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -835,6 +830,14 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = self->enumerable; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *retval; + return NJS_OK; } @@ -866,15 +869,6 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT); } - prop = njs_object_prop_alloc(vm, retval, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - njs_value_assign(njs_prop_value(prop), retval); - prop->enumerable = self->enumerable; - - lhq.value = prop; lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -886,6 +880,14 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = self->enumerable; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *retval; + return NJS_OK; } @@ -915,15 +917,6 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, return NJS_OK; } - prop = njs_object_prop_alloc(vm, retval, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - njs_value_assign(njs_prop_value(prop), retval); - prop->enumerable = 0; - - lhq.value = prop; lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -935,6 +928,14 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *retval; + return NJS_OK; } @@ -1205,28 +1206,29 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, } } - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - njs_set_array(njs_prop_value(prop), argv); - - lhq.value = prop; lhq.key_hash = NJS_ATOM_STRING_argv; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq); - if (njs_fast_path(ret == NJS_OK)) { - njs_value_assign(retval, njs_prop_value(prop)); - return NJS_OK; + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NJS_ERROR; } - njs_internal_error(vm, "lvlhsh insert failed"); + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + + njs_set_array(njs_prop_value(prop), argv); + + njs_value_assign(retval, njs_prop_value(prop)); + return NJS_OK; - return NJS_ERROR; } @@ -1251,10 +1253,6 @@ njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) ep = environment; while (*ep != NULL) { - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } entry = (u_char *) *ep++; @@ -1283,17 +1281,11 @@ njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) val++; - ret = njs_string_create(vm, njs_prop_value(prop), val, njs_strlen(val)); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - ret = njs_atom_atomize_key(vm, &prop_name); if (ret != NJS_OK) { return ret; } - lhq.value = prop; lhq.key_hash = prop_name.atom_id; ret = njs_flathsh_unique_insert(hash, &lhq); @@ -1309,6 +1301,19 @@ njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) * Always using the first element among the duplicates * and ignoring the rest. */ + continue; + } + + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + + ret = njs_string_create(vm, njs_prop_value(prop), val, njs_strlen(val)); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; } } @@ -1332,28 +1337,29 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, env->shared_hash = vm->shared->env_hash; - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - njs_set_object(njs_prop_value(prop), env); - lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - lhq.value = prop; lhq.key_hash = NJS_ATOM_STRING_env; ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq); - if (njs_fast_path(ret == NJS_OK)) { - njs_value_assign(retval, njs_prop_value(prop)); - return NJS_OK; + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NJS_ERROR; } - njs_internal_error(vm, "lvlhsh insert failed"); + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; - return NJS_ERROR; + njs_set_object(njs_prop_value(prop), env); + + njs_value_assign(retval, njs_prop_value(prop)); + + return NJS_OK; } diff --git a/src/njs_error.c b/src/njs_error.c index 6e12aa61..d19e0e22 100644 --- a/src/njs_error.c +++ b/src/njs_error.c @@ -212,12 +212,6 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, lhq.proto = &njs_object_hash_proto; if (name != NULL) { - prop = njs_object_prop_alloc(vm, name, 1); - if (njs_slow_path(prop == NULL)) { - goto memory_error; - } - - lhq.value = prop; lhq.key_hash = NJS_ATOM_STRING_name; ret = njs_flathsh_unique_insert(&error->hash, &lhq); @@ -225,17 +219,18 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, njs_internal_error(vm, "lvlhsh insert failed"); return NULL; } - } - if (message!= NULL) { - prop = njs_object_prop_alloc(vm, message, 1); - if (njs_slow_path(prop == NULL)) { - goto memory_error; - } + prop = lhq.value; - prop->enumerable = 0; + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + + prop->u.value = *name; + } - lhq.value = prop; + if (message!= NULL) { lhq.key_hash = NJS_ATOM_STRING_message; ret = njs_flathsh_unique_insert(&error->hash, &lhq); @@ -243,17 +238,18 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, njs_internal_error(vm, "lvlhsh insert failed"); return NULL; } - } - if (errors != NULL) { - prop = njs_object_prop_alloc(vm, errors, 1); - if (njs_slow_path(prop == NULL)) { - goto memory_error; - } + prop = lhq.value; + prop->type = NJS_PROPERTY; prop->enumerable = 0; + prop->configurable = 1; + prop->writable = 1; - lhq.value = prop; + prop->u.value = *message; + } + + if (errors != NULL) { lhq.key_hash = NJS_ATOM_STRING_errors; ret = njs_flathsh_unique_insert(&error->hash, &lhq); @@ -261,6 +257,15 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, njs_internal_error(vm, "lvlhsh insert failed"); return NULL; } + + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 1; + prop->writable = 1; + + prop->u.value = *errors; } return error; diff --git a/src/njs_extern.c b/src/njs_extern.c index 077d2a5f..adc8cd67 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -58,15 +58,6 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, continue; } - prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1); - if (njs_slow_path(prop == NULL)) { - goto memory_error; - } - - prop->writable = external->writable; - prop->configurable = external->configurable; - prop->enumerable = external->enumerable; - if (external->flags & NJS_EXTERN_SYMBOL) { lhq.key_hash = external->name.symbol; @@ -81,7 +72,20 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, lhq.key_hash = prop_name.atom_id; } - lhq.value = prop; + ret = njs_flathsh_unique_insert(hash, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NJS_ERROR; + } + + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = external->enumerable; + prop->configurable = external->configurable; + prop->writable = external->writable; + prop->u.value = njs_value_invalid; + switch (external->flags & NJS_EXTERN_TYPE_MASK) { case NJS_EXTERN_METHOD: @@ -167,12 +171,6 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, break; } - ret = njs_flathsh_unique_insert(hash, &lhq); - if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NJS_ERROR; - } - external++; } @@ -224,16 +222,6 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, njs_set_object_value(retval, ov); } - prop = njs_object_prop_alloc(vm, retval, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - prop->writable = self->writable; - prop->configurable = self->configurable; - prop->enumerable = self->enumerable; - - lhq.value = prop; lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -245,6 +233,15 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = self->enumerable; + prop->configurable = self->configurable; + prop->writable = self->writable; + + prop->u.value = *retval; + return NJS_OK; } diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c index 5a4efaa5..7e374c62 100644 --- a/src/njs_flathsh.c +++ b/src/njs_flathsh.c @@ -210,13 +210,14 @@ njs_flathsh_add_elt(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) elts = njs_hash_elts(h); elt = &elts[h->elts_count++]; - elt->value = fhq->value; elt->key_hash = fhq->key_hash; cell_num = fhq->key_hash & h->hash_mask; elt->next_elt = njs_hash_cells_end(h)[-cell_num - 1]; njs_hash_cells_end(h)[-cell_num - 1] = h->elts_count; + elt->type = NJS_PROPERTY; + return elt; } @@ -269,7 +270,7 @@ njs_expand_elts(njs_flathsh_query_t *fhq, njs_flathsh_descr_t *h) njs_memzero(chunk, sizeof(uint32_t) * new_hash_size); for (i = 0, elt = njs_hash_elts(h); i < h->elts_count; i++, elt++) { - if (elt->value != NULL) { + if (elt->type != NJS_FREE_FLATHSH_ELEMENT) { cell_num = elt->key_hash & new_hash_mask; elt->next_elt = njs_hash_cells_end(h)[-cell_num - 1]; njs_hash_cells_end(h)[-cell_num - 1] = i + 1; @@ -331,7 +332,7 @@ njs_flathsh_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq) if (e->key_hash == fhq->key_hash && fhq->proto->test(fhq, e->value) == NJS_OK) { - fhq->value = e->value; + fhq->value = e; return NJS_OK; } @@ -362,7 +363,7 @@ njs_flathsh_unique_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq) e = &elts[elt_num - 1]; if (e->key_hash == fhq->key_hash) { - fhq->value = e->value; + fhq->value = e; return NJS_OK; } @@ -402,8 +403,7 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) fhq->proto->test(fhq, elt->value) == NJS_OK) { if (fhq->replace) { - elt->value = fhq->value; - + fhq->value = elt; return NJS_OK; } else { @@ -419,7 +419,7 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) return NJS_ERROR; } - elt->value = fhq->value; + fhq->value = elt; return NJS_OK; } @@ -428,7 +428,6 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) njs_int_t njs_flathsh_unique_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) { - void *tmp; njs_int_t cell_num, elt_num; njs_flathsh_elt_t *elt, *elts; njs_flathsh_descr_t *h; @@ -453,15 +452,10 @@ njs_flathsh_unique_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) if (elt->key_hash == fhq->key_hash) { if (fhq->replace) { - tmp = fhq->value; - fhq->value = elt->value; - elt->value = tmp; - + fhq->value = elt; return NJS_OK; } else { - fhq->value = elt->value; - return NJS_DECLINED; } } @@ -474,7 +468,7 @@ njs_flathsh_unique_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) return NJS_ERROR; } - elt->value = fhq->value; + fhq->value = elt; return NJS_OK; } @@ -516,8 +510,8 @@ njs_shrink_elts(njs_flathsh_query_t *fhq, njs_flathsh_descr_t *h) elt_src = njs_hash_elts(h_src); for (i = 0, j = 0, elt = njs_hash_elts(h); i < h->elts_count; i++) { - if (elt_src->value != NULL) { - elt->value = elt_src->value; + if (elt_src->type != NJS_FREE_FLATHSH_ELEMENT) { + *elt = *elt_src; elt->key_hash = elt_src->key_hash; cell_num = elt_src->key_hash & new_hash_mask; @@ -567,7 +561,7 @@ njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) if (elt->key_hash == fhq->key_hash && fhq->proto->test(fhq, elt->value) == NJS_OK) { - fhq->value = elt->value; + fhq->value = elt; if (elt_prev != NULL) { elt_prev->next_elt = elt->next_elt; @@ -578,7 +572,7 @@ njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) h->elts_deleted_count++; - elt->value = NULL; + elt->type = NJS_FREE_FLATHSH_ELEMENT; /* Shrink elts if elts_deleted_count is eligible. */ @@ -632,7 +626,7 @@ njs_flathsh_unique_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) elt = &elts[elt_num - 1]; if (elt->key_hash == fhq->key_hash) { - fhq->value = elt->value; + fhq->value = elt; if (elt_prev != NULL) { elt_prev->next_elt = elt->next_elt; @@ -643,7 +637,7 @@ njs_flathsh_unique_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) h->elts_deleted_count++; - elt->value = NULL; + elt->type = NJS_FREE_FLATHSH_ELEMENT; /* Shrink elts if elts_deleted_count is eligible. */ @@ -690,7 +684,7 @@ njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe) while (fhe->cp < h->elts_count) { e = &elt[fhe->cp++]; - if (e->value != NULL) { + if (e->type != NJS_FREE_FLATHSH_ELEMENT) { return e; } } diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index 38a9c56e..06fd00c0 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -13,9 +13,18 @@ typedef struct { typedef struct { - uint32_t next_elt; + /* next_elt + property descriptor : 32 bits */ + + uint32_t next_elt:26; + + uint32_t type:3; + uint32_t writable:1; + uint32_t enumerable:1; + uint32_t configurable:1; + uint32_t key_hash; - void *value; + + void *value[16 / sizeof(void *)]; } njs_flathsh_elt_t; @@ -174,7 +183,7 @@ typedef struct njs_flathsh_proto_s njs_lvlhsh_proto_t; #define njs_lvlhsh_delete(lh, lhq) njs_flathsh_delete(lh, lhq) #define njs_lvlhsh_each_init(lhe, _proto) njs_flathsh_each_init(lhe, _proto) -njs_inline void * +njs_inline njs_flathsh_elt_t * njs_lvlhsh_each(const njs_flathsh_t *lh, njs_flathsh_each_t *lhe) { njs_flathsh_elt_t *e; @@ -184,7 +193,7 @@ njs_lvlhsh_each(const njs_flathsh_t *lh, njs_flathsh_each_t *lhe) return NULL; } - return e->value; + return e; } diff --git a/src/njs_function.c b/src/njs_function.c index 7db342f6..09bc2ebb 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -126,11 +126,25 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function, njs_object_prop_t *prop; njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, name, 0); - if (njs_slow_path(prop == NULL)) { + lhq.key_hash = NJS_ATOM_STRING_name; + lhq.replace = 0; + lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; + + ret = njs_flathsh_unique_insert(&function->object.hash, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 1; + prop->writable = 0; + prop->u.value = *name; + symbol = 0; if (njs_is_symbol(njs_prop_value(prop))) { @@ -172,20 +186,6 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function, } } - prop->configurable = 1; - - lhq.value = prop; - lhq.key_hash = NJS_ATOM_STRING_name; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; - - ret = njs_flathsh_unique_insert(&function->object.hash, &lhq); - if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NJS_ERROR; - } - return NJS_OK; } @@ -327,12 +327,12 @@ njs_function_prototype_thrower(njs_vm_t *vm, njs_value_t *args, const njs_object_prop_init_t njs_arguments_object_instance_properties[] = { { - .atom_id = NJS_ATOM_STRING_callee, .desc = { + .atom_id = NJS_ATOM_STRING_callee, .type = NJS_ACCESSOR, .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, njs_function_prototype_thrower, 0), - .writable = NJS_ATTRIBUTE_UNSET, + .writable = 0, }, }, }; @@ -894,14 +894,6 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_flathsh_t *hash, njs_object_prop_t *prop; njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, prototype, 0); - if (njs_slow_path(prop == NULL)) { - return NULL; - } - - prop->writable = 1; - - lhq.value = prop; lhq.key_hash = NJS_ATOM_STRING_prototype; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -909,13 +901,21 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_flathsh_t *hash, ret = njs_flathsh_unique_insert(hash, &lhq); - if (njs_fast_path(ret == NJS_OK)) { - return njs_prop_value(prop); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NULL; } - njs_internal_error(vm, "lvlhsh insert failed"); + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 0; + prop->writable = 1; + prop->u.value = *prototype; + + return njs_prop_value(prop); - return NULL; } @@ -1432,23 +1432,23 @@ static const njs_object_prop_init_t njs_function_prototype_properties[] = NJS_DECLARE_PROP_NATIVE(STRING_bind, njs_function_prototype_bind, 1, 0), { - .atom_id = NJS_ATOM_STRING_caller, .desc = { + .atom_id = NJS_ATOM_STRING_caller, .type = NJS_ACCESSOR, .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, njs_function_prototype_thrower, 0), - .writable = NJS_ATTRIBUTE_UNSET, + .writable = 0, .configurable = 1, }, }, { - .atom_id = NJS_ATOM_STRING_arguments, .desc = { + .atom_id = NJS_ATOM_STRING_arguments, .type = NJS_ACCESSOR, .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, njs_function_prototype_thrower, 0), - .writable = NJS_ATTRIBUTE_UNSET, + .writable = 0, .configurable = 1, }, }, diff --git a/src/njs_json.c b/src/njs_json.c index e79b1eb4..49c2b7e7 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -394,12 +394,6 @@ njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value, return NULL; } - prop = njs_object_prop_alloc(ctx->vm, &prop_value, 1); - if (njs_slow_path(prop == NULL)) { - goto memory_error; - } - - lhq.value = prop; lhq.key_hash = prop_name.atom_id; lhq.replace = 1; lhq.pool = ctx->pool; @@ -411,6 +405,14 @@ njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value, return NULL; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = prop_value; + p = njs_json_skip_space(p, ctx->end); if (njs_slow_path(p == ctx->end)) { goto error_end; @@ -1609,12 +1611,6 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, wrapper->type = NJS_OBJECT; wrapper->data.truth = 1; - prop = njs_object_prop_alloc(vm, value, 1); - if (njs_slow_path(prop == NULL)) { - return NULL; - } - - lhq.value = prop; lhq.key_hash = NJS_ATOM_STRING_empty; lhq.replace = 0; lhq.pool = vm->mem_pool; @@ -1625,6 +1621,14 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, return NULL; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *value; + return wrapper->data.u.object; } diff --git a/src/njs_module.c b/src/njs_module.c index 5af174f3..7d58972c 100644 --- a/src/njs_module.c +++ b/src/njs_module.c @@ -13,7 +13,7 @@ njs_module_hash_test(njs_lvlhsh_query_t *lhq, void *data) { njs_mod_t *module; - module = data; + module = *(njs_mod_t **) data; if (njs_strstr_eq(&lhq->key, &module->name)) { return NJS_OK; @@ -39,6 +39,7 @@ njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t shared) njs_int_t ret; njs_mod_t *shrd, *module; njs_object_t *object; + njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; lhq.key = *name; @@ -46,11 +47,11 @@ njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t shared) lhq.proto = &njs_modules_hash_proto; if (njs_lvlhsh_find(&vm->modules_hash, &lhq) == NJS_OK) { - return lhq.value; + return njs_prop_module(lhq.value); } if (njs_lvlhsh_find(&vm->shared->modules_hash, &lhq) == NJS_OK) { - shrd = lhq.value; + shrd = njs_prop_module(lhq.value); if (shared) { return shrd; @@ -70,13 +71,19 @@ njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t shared) } lhq.replace = 0; - lhq.value = module; lhq.pool = vm->mem_pool; ret = njs_lvlhsh_insert(&vm->modules_hash, &lhq); - if (njs_fast_path(ret == NJS_OK)) { - return module; + if (njs_slow_path(ret != NJS_OK)) { + return NULL; } + + prop = lhq.value; + + prop->u.mod = module; + + return module; + } return NULL; @@ -88,6 +95,7 @@ njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value) { njs_int_t ret; njs_mod_t *module; + njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; module = njs_mp_zalloc(vm->mem_pool, sizeof(njs_mod_t)); @@ -105,7 +113,6 @@ njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value) lhq.replace = 0; lhq.key = *name; lhq.key_hash = njs_djb_hash(name->start, name->length); - lhq.value = module; lhq.pool = vm->mem_pool; lhq.proto = &njs_modules_hash_proto; @@ -115,6 +122,10 @@ njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value) return NULL; } + prop = lhq.value; + + prop->u.mod = module; + if (value != NULL) { njs_value_assign(&module->value, value); module->function.native = 1; diff --git a/src/njs_object.c b/src/njs_object.c index b842b1ab..0c592176 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -157,6 +157,7 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, const njs_object_prop_init_t *prop, njs_uint_t n) { njs_int_t ret; + njs_object_prop_t *obj_prop; njs_flathsh_query_t lhq; lhq.replace = 0; @@ -164,7 +165,7 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, lhq.pool = vm->mem_pool; while (n != 0) { - lhq.key_hash = prop->atom_id; + lhq.key_hash = prop->desc.atom_id; lhq.value = (void *) prop; ret = njs_flathsh_unique_insert(hash, &lhq); @@ -173,6 +174,14 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, return NJS_ERROR; } + obj_prop = lhq.value; + + obj_prop->type = prop->desc.type; + obj_prop->enumerable = prop->desc.enumerable; + obj_prop->configurable = prop->desc.configurable; + obj_prop->writable = prop->desc.writable; + obj_prop->u.value = prop->desc.u.value; + prop++; n--; } @@ -939,7 +948,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, break; } - prop = elt->value; + prop = (njs_object_prop_t *) elt; ret = njs_atom_to_value(vm, &prop_name, elt->key_hash); if (ret != NJS_OK) { @@ -980,7 +989,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, } else { - if (!(((njs_object_prop_t *)(lhq.value))->enumerable + if (!(((njs_object_prop_t *) (lhq.value))->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY))) { continue; @@ -1012,7 +1021,7 @@ local_hash: break; } - prop = elt->value; + prop = (njs_object_prop_t *) elt; ret = njs_atom_to_value(vm, &prop_name, elt->key_hash); if (ret != NJS_OK) { @@ -1215,7 +1224,7 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object) njs_int_t ret; njs_value_t prop_name; njs_flathsh_t new_hash, *shared_hash; - njs_object_prop_t *prop; + njs_object_prop_t *prop, *obj_prop; njs_flathsh_elt_t *elt; njs_flathsh_each_t fhe; njs_flathsh_query_t fhq; @@ -1235,7 +1244,7 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object) break; } - prop = elt->value; + prop = (njs_object_prop_t *) elt; ret = njs_atom_to_value(vm, &prop_name, elt->key_hash); if (ret != NJS_OK) { @@ -1251,13 +1260,19 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object) fhq.key_hash = elt->key_hash; } - fhq.value = prop; - ret = njs_flathsh_unique_insert(&new_hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } + + obj_prop = fhq.value; + + obj_prop->type = prop->type; + obj_prop->enumerable = prop->enumerable; + obj_prop->configurable = prop->configurable; + obj_prop->writable = prop->writable; + obj_prop->u.value = prop->u.value; } object->shared_hash = new_hash; @@ -1274,7 +1289,7 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object) njs_object_t **start; njs_value_t value, *key; njs_traverse_t *s; - njs_object_prop_t *prop; + njs_object_prop_t *prop, *obj_prop; njs_property_query_t pq; njs_traverse_t state[NJS_TRAVERSE_MAX_DEPTH]; @@ -1353,6 +1368,14 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object) return NJS_ERROR; } + obj_prop = pq.lhq.value; + + obj_prop->type = prop->type; + obj_prop->enumerable = prop->enumerable; + obj_prop->configurable = prop->configurable; + obj_prop->writable = prop->writable; + obj_prop->u.value = prop->u.value; + njs_value_assign(&value, njs_prop_value(prop)); if (njs_is_object(&value) @@ -1652,7 +1675,7 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, njs_array_t *names; njs_value_t descriptor, *value, *key; njs_object_t *descriptors; - njs_object_prop_t *pr; + njs_object_prop_t *prop; njs_flathsh_query_t lhq; value = njs_arg(args, nargs, 1); @@ -1690,20 +1713,22 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, goto done; } - pr = njs_object_prop_alloc(vm, &descriptor, 1); - if (njs_slow_path(pr == NULL)) { - ret = NJS_ERROR; - goto done; - } - lhq.key_hash = key->atom_id; - lhq.value = pr; ret = njs_flathsh_unique_insert(&descriptors->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); goto done; } + + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + + prop->u.value = descriptor; } ret = NJS_OK; @@ -1882,7 +1907,7 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args, break; } - prop = elt->value; + prop = (njs_object_prop_t *) elt; if (level == NJS_OBJECT_INTEGRITY_FROZEN && !njs_is_accessor_descriptor(prop)) @@ -1942,7 +1967,7 @@ njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args, break; } - prop = elt->value; + prop = (njs_object_prop_t *) elt; if (prop->configurable) { goto done; @@ -2165,15 +2190,6 @@ njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash, njs_object_prop_t *prop; njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 0); - if (njs_slow_path(prop == NULL)) { - return NULL; - } - - lhq.value = prop; - - njs_set_type_object(njs_prop_value(prop), prototype, prototype->type); - lhq.key_hash = NJS_ATOM_STRING_prototype; lhq.replace = 1; @@ -2182,13 +2198,21 @@ njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash, ret = njs_flathsh_unique_insert(hash, &lhq); - if (njs_fast_path(ret == NJS_OK)) { - return njs_prop_value(prop); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NULL; } - njs_internal_error(vm, "lvlhsh insert failed"); + prop = lhq.value; - return NULL; + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 0; + prop->writable = 0; + + njs_set_type_object(njs_prop_value(prop), prototype, prototype->type); + + return njs_prop_value(prop); } @@ -2426,15 +2450,6 @@ njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash, njs_object_prop_t *prop; njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, constructor, 1); - if (njs_slow_path(prop == NULL)) { - return NULL; - } - - prop->enumerable = 0; - - lhq.value = prop; - lhq.key_hash = NJS_ATOM_STRING_constructor; lhq.replace = 1; @@ -2442,13 +2457,21 @@ njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash, lhq.proto = &njs_object_hash_proto; ret = njs_flathsh_unique_insert(hash, &lhq); - if (njs_fast_path(ret == NJS_OK)) { - return njs_prop_value(prop); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert/replace failed"); + return NULL; } - njs_internal_error(vm, "lvlhsh insert/replace failed"); + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 0; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *constructor; + + return njs_prop_value(prop); - return NULL; } diff --git a/src/njs_object.h b/src/njs_object.h index 85e914d4..fac49aa8 100644 --- a/src/njs_object.h +++ b/src/njs_object.h @@ -101,8 +101,8 @@ njs_int_t njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *dst); njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, njs_object_t *proto); -njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, - const njs_value_t *value, uint8_t attributes); +void njs_object_prop_init(njs_object_prop_t *prop, njs_object_prop_type_t type, + uint8_t attributes); njs_int_t njs_object_property(njs_vm_t *vm, njs_object_t *object, njs_flathsh_query_t *lhq, njs_value_t *retval); njs_object_prop_t *njs_object_property_add(njs_vm_t *vm, njs_value_t *object, @@ -114,7 +114,7 @@ njs_int_t njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_int_t njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); const char *njs_prop_type_string(njs_object_prop_type_t type); -njs_int_t njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, +njs_int_t njs_object_props_init(njs_vm_t *vm, const njs_object_init_t* init, njs_object_prop_t *base, uint32_t atom_id, njs_value_t *value, njs_value_t *retval); @@ -122,10 +122,10 @@ njs_int_t njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, njs_inline njs_bool_t njs_is_data_descriptor(njs_object_prop_t *prop) { - return prop->writable != NJS_ATTRIBUTE_UNSET - || (prop->type != NJS_ACCESSOR && njs_is_valid(njs_prop_value(prop))) + return (prop->type == NJS_PROPERTY && njs_is_valid(njs_prop_value(prop))) + || prop->type == NJS_PROPERTY_REF + || prop->type == NJS_PROPERTY_PLACE_REF || prop->type == NJS_PROPERTY_HANDLER; - } @@ -136,13 +136,6 @@ njs_is_accessor_descriptor(njs_object_prop_t *prop) } -njs_inline njs_bool_t -njs_is_generic_descriptor(njs_object_prop_t *prop) -{ - return !njs_is_data_descriptor(prop) && !njs_is_accessor_descriptor(prop); -} - - njs_inline njs_int_t njs_primitive_value_to_key(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src) diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index 275cd9ac..6b93960c 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -8,54 +8,18 @@ #include -static njs_object_prop_t *njs_object_prop_alloc2(njs_vm_t *vm, - njs_object_prop_type_t type, unsigned flags); static njs_object_prop_t *njs_descriptor_prop(njs_vm_t *vm, - const njs_value_t *desc); + const njs_value_t *desc, njs_object_prop_t *prop, + uint32_t *unset_enumerable, uint32_t *unset_configuarble, + uint32_t *enum_writable); -njs_object_prop_t * -njs_object_prop_alloc(njs_vm_t *vm, - const njs_value_t *value, uint8_t attributes) -{ - unsigned flags; - njs_object_prop_t *prop; - - switch (attributes) { - case NJS_ATTRIBUTE_FALSE: - case NJS_ATTRIBUTE_TRUE: - flags = attributes ? NJS_OBJECT_PROP_VALUE_ECW : 0; - break; - - case NJS_ATTRIBUTE_UNSET: - default: - flags = NJS_OBJECT_PROP_UNSET; - break; - } - - prop = njs_object_prop_alloc2(vm, NJS_PROPERTY, flags); - if (njs_slow_path(prop == NULL)) { - return NULL; - } - - njs_value_assign(njs_prop_value(prop), value); - - return prop; -} - - -static njs_object_prop_t * -njs_object_prop_alloc2(njs_vm_t *vm, - njs_object_prop_type_t type, unsigned flags) +void +njs_object_prop_init(njs_object_prop_t *prop, njs_object_prop_type_t type, + uint8_t flags) { - njs_object_prop_t *prop; - - prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), - sizeof(njs_object_prop_t)); - if (njs_slow_path(prop == NULL)) { - njs_memory_error(vm); - return NULL; - } + prop->next_elt = 0; + prop->atom_id = 0; prop->type = type; @@ -67,16 +31,14 @@ njs_object_prop_alloc2(njs_vm_t *vm, prop->writable = !!(flags & NJS_OBJECT_PROP_WRITABLE); } else { - prop->writable = NJS_ATTRIBUTE_UNSET; + prop->writable = 0; } } else { - prop->enumerable = NJS_ATTRIBUTE_UNSET; - prop->configurable = NJS_ATTRIBUTE_UNSET; - prop->writable = NJS_ATTRIBUTE_UNSET; + prop->enumerable = 0; + prop->configurable = 0; + prop->writable = 0; } - - return prop; } @@ -141,12 +103,6 @@ njs_object_property_add(njs_vm_t *vm, njs_value_t *object, unsigned atom_id, njs_object_prop_t *prop; njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1); - if (njs_slow_path(prop == NULL)) { - return NULL; - } - - lhq.value = prop; lhq.key_hash = atom_id; lhq.replace = replace; lhq.pool = vm->mem_pool; @@ -158,6 +114,14 @@ njs_object_property_add(njs_vm_t *vm, njs_value_t *object, unsigned atom_id, return NULL; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = njs_value_invalid; + return prop; } @@ -169,15 +133,21 @@ njs_int_t njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, unsigned atom_id, njs_value_t *value, unsigned flags) { - uint32_t length, index; + uint32_t length, index, set_enumerable, set_configurable, + set_writable; njs_int_t ret; njs_array_t *array; njs_value_t key, retval; - njs_object_prop_t *prop, *prev; + njs_object_prop_t _prop; + njs_object_prop_t *prop = &_prop, *prev, *obj_prop; njs_property_query_t pq; again: + set_enumerable = 1; + set_configurable = 1; + set_writable = 1; + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 1); ret = (flags & NJS_OBJECT_PROP_CREATE) @@ -190,7 +160,8 @@ again: switch (njs_prop_type(flags)) { case NJS_OBJECT_PROP_DESCRIPTOR: - prop = njs_descriptor_prop(vm, value); + prop = njs_descriptor_prop(vm, value, prop, &set_enumerable, + &set_configurable, &set_writable); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -211,12 +182,8 @@ again: } } - prop = njs_object_prop_alloc2(vm, NJS_PROPERTY, - flags & NJS_OBJECT_PROP_VALUE_ECW); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - + njs_object_prop_init(prop, NJS_PROPERTY, + flags & NJS_OBJECT_PROP_VALUE_ECW); njs_value_assign(njs_prop_value(prop), value); break; @@ -225,11 +192,9 @@ again: default: njs_assert(njs_is_function(value)); - prop = njs_object_prop_alloc2(vm, NJS_ACCESSOR, - NJS_OBJECT_PROP_VALUE_EC); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } + njs_object_prop_init(prop, NJS_ACCESSOR, NJS_OBJECT_PROP_VALUE_EC); + + set_writable = 0; if (njs_prop_type(flags) == NJS_OBJECT_PROP_GETTER) { njs_prop_getter(prop) = njs_function(value); @@ -282,7 +247,7 @@ set_prop: } } else { - if (prop->writable == NJS_ATTRIBUTE_UNSET) { + if (!set_writable) { prop->writable = 0; } @@ -291,11 +256,11 @@ set_prop: } } - if (prop->enumerable == NJS_ATTRIBUTE_UNSET) { + if (!set_enumerable) { prop->enumerable = 0; } - if (prop->configurable == NJS_ATTRIBUTE_UNSET) { + if (!set_configurable) { prop->configurable = 0; } @@ -304,6 +269,8 @@ set_prop: if (njs_slow_path(prev->type == NJS_WHITEOUT)) { /* Previously deleted property. */ + prop->atom_id = prev->atom_id; + prop->next_elt = prev->next_elt; *prev = *prop; } @@ -311,7 +278,6 @@ set_prop: pq.lhq.key_hash = atom_id; pq.lhq.proto = &njs_object_hash_proto; - pq.lhq.value = prop; pq.lhq.replace = 0; pq.lhq.pool = vm->mem_pool; @@ -320,6 +286,13 @@ set_prop: njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } + + obj_prop = pq.lhq.value; + obj_prop->enumerable = prop->enumerable; + obj_prop->configurable = prop->configurable; + obj_prop->writable = prop->writable; + obj_prop->type = prop->type; + obj_prop->u.value = prop->u.value; } return NJS_OK; @@ -339,9 +312,9 @@ set_prop: case NJS_PROPERTY_PLACE_REF: if (prev->type == NJS_PROPERTY_REF && !njs_is_accessor_descriptor(prop) - && prop->configurable != NJS_ATTRIBUTE_FALSE - && prop->enumerable != NJS_ATTRIBUTE_FALSE - && prop->writable != NJS_ATTRIBUTE_FALSE) + && (!set_configurable || prop->configurable) + && (!set_enumerable || prop->enumerable) + && (!set_writable || prop->writable)) { if (njs_is_valid(njs_prop_value(prop))) { njs_value_assign(njs_prop_ref(prev), njs_prop_value(prop)); @@ -372,9 +345,9 @@ set_prop: goto exception; } - if (prop->configurable == NJS_ATTRIBUTE_TRUE || - prop->enumerable == NJS_ATTRIBUTE_FALSE || - prop->writable == NJS_ATTRIBUTE_FALSE) + if ((set_configurable && prop->configurable) + || (set_enumerable && !prop->enumerable) + || (set_writable && !prop->writable)) { goto exception; } @@ -400,22 +373,24 @@ set_prop: if (!prev->configurable) { - if (prop->configurable == NJS_ATTRIBUTE_TRUE) { + if (prop->configurable) { goto exception; } - if (prop->enumerable != NJS_ATTRIBUTE_UNSET - && prev->enumerable != prop->enumerable) - { + if (set_enumerable && prev->enumerable != prop->enumerable) { goto exception; } } - if (njs_is_generic_descriptor(prop)) { + if (!(set_writable || njs_is_data_descriptor(prop)) + && !njs_is_accessor_descriptor(prop)) + { goto done; } - if (njs_is_data_descriptor(prev) != njs_is_data_descriptor(prop)) { + if (njs_is_data_descriptor(prev) + != (set_writable || njs_is_data_descriptor(prop))) + { if (!prev->configurable) { goto exception; } @@ -434,12 +409,12 @@ set_prop: } if (njs_is_data_descriptor(prev)) { - prev->writable = NJS_ATTRIBUTE_UNSET; + set_writable = 0; njs_prop_getter(prev) = NULL; njs_prop_setter(prev) = NULL; } else { - prev->writable = NJS_ATTRIBUTE_FALSE; + prev->writable = 0; njs_set_undefined(njs_prop_value(prev)); } @@ -447,10 +422,10 @@ set_prop: prev->type = prop->type; } else if (njs_is_data_descriptor(prev) - && njs_is_data_descriptor(prop)) + && (set_writable || njs_is_data_descriptor(prop))) { if (!prev->configurable && !prev->writable) { - if (prop->writable == NJS_ATTRIBUTE_TRUE) { + if (prop->writable) { goto exception; } @@ -483,7 +458,7 @@ done: if (njs_slow_path(njs_is_fast_array(object) && pq.lhq.key_hash == NJS_ATOM_STRING_length) - && prop->writable == NJS_ATTRIBUTE_FALSE) + && (set_writable && !prop->writable)) { array = njs_array(object); length = array->length; @@ -538,8 +513,8 @@ done: if (njs_slow_path(njs_is_array(object) && pq.lhq.key_hash == NJS_ATOM_STRING_length)) { - if (prev->configurable != NJS_ATTRIBUTE_TRUE - && prev->writable != NJS_ATTRIBUTE_TRUE + if (!prev->configurable + && !prev->writable && !njs_values_strict_equal(vm, njs_prop_value(prev), njs_prop_value(prop))) { @@ -547,7 +522,7 @@ done: return NJS_ERROR; } - if (prop->writable != NJS_ATTRIBUTE_UNSET) { + if (set_writable) { prev->writable = prop->writable; } @@ -564,15 +539,15 @@ done: * attribute of the property named P of object O to the value of the field. */ - if (prop->writable != NJS_ATTRIBUTE_UNSET) { + if (set_writable) { prev->writable = prop->writable; } - if (prop->enumerable != NJS_ATTRIBUTE_UNSET) { + if (set_enumerable) { prev->enumerable = prop->enumerable; } - if (prop->configurable != NJS_ATTRIBUTE_UNSET) { + if (set_configurable) { prev->configurable = prop->configurable; } @@ -597,18 +572,9 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, njs_function_t *function; njs_object_prop_t *prop, *shared; - prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), - sizeof(njs_object_prop_t)); - if (njs_slow_path(prop == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } - shared = pq->lhq.value; - *prop = *shared; pq->lhq.replace = 0; - pq->lhq.value = prop; pq->lhq.pool = vm->mem_pool; ret = njs_flathsh_unique_insert(&proto->hash, &pq->lhq); @@ -617,6 +583,13 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, return NJS_ERROR; } + prop = pq->lhq.value; + prop->enumerable = shared->enumerable; + prop->configurable = shared->configurable; + prop->writable = shared->writable; + prop->type = shared->type; + prop->u.value = shared->u.value; + if (njs_is_accessor_descriptor(prop)) { if (njs_prop_getter(prop) != NULL) { function = njs_function_copy(vm, njs_prop_getter(prop)); @@ -683,14 +656,15 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, static njs_object_prop_t * -njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc) +njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, + njs_object_prop_t *prop, uint32_t *set_enumerable, + uint32_t *set_configurable, uint32_t *set_writable) { njs_int_t ret; njs_bool_t data, accessor; njs_value_t value; njs_object_t *desc_object; njs_function_t *getter, *setter; - njs_object_prop_t *prop; njs_flathsh_query_t lhq; if (!njs_is_object(desc)) { @@ -698,11 +672,12 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc) return NULL; } - prop = njs_object_prop_alloc(vm, &njs_value_invalid, - NJS_ATTRIBUTE_UNSET); - if (njs_slow_path(prop == NULL)) { - return NULL; - } + njs_object_prop_init(prop, NJS_PROPERTY, NJS_OBJECT_PROP_UNSET); + *njs_prop_value(prop) = njs_value_invalid; + + *set_enumerable = 0; + *set_configurable = 0; + *set_writable = 0; data = 0; accessor = 0; @@ -767,6 +742,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc) if (ret == NJS_OK) { data = 1; prop->writable = njs_is_true(&value); + *set_writable = 1; } if (accessor && data) { @@ -784,6 +760,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc) if (ret == NJS_OK) { prop->enumerable = njs_is_true(&value); + *set_enumerable = 1; } lhq.key_hash = NJS_ATOM_STRING_configurable; @@ -795,6 +772,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc) if (ret == NJS_OK) { prop->configurable = njs_is_true(&value); + *set_configurable = 1; } if (accessor) { @@ -878,29 +856,23 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, if (njs_is_data_descriptor(prop)) { lhq.key_hash = NJS_ATOM_STRING_value; - pr = njs_object_prop_alloc(vm, njs_prop_value(prop), 1); - if (njs_slow_path(pr == NULL)) { - return NJS_ERROR; - } - - lhq.value = pr; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } - lhq.key_hash = NJS_ATOM_STRING_writable; + pr = lhq.value; - setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false; + pr->type = NJS_PROPERTY; + pr->enumerable = 1; + pr->configurable = 1; + pr->writable = 1; + pr->u.value = *(njs_prop_value(prop)); - pr = njs_object_prop_alloc(vm, setval, 1); - if (njs_slow_path(pr == NULL)) { - return NJS_ERROR; - } + lhq.key_hash = NJS_ATOM_STRING_writable; - lhq.value = pr; + setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false; ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { @@ -908,20 +880,37 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, return NJS_ERROR; } + pr = lhq.value; + + pr->type = NJS_PROPERTY; + pr->enumerable = 1; + pr->configurable = 1; + pr->writable = 1; + pr->u.value = *setval; + } else { lhq.key_hash = NJS_ATOM_STRING_get; - pr = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(pr == NULL)) { + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } + pr = lhq.value; + + pr->type = NJS_PROPERTY; + pr->enumerable = 1; + pr->configurable = 1; + pr->writable = 1; + pr->u.value = njs_value_undefined; + if (njs_prop_getter(prop) != NULL) { njs_set_function(njs_prop_value(pr), njs_prop_getter(prop)); } - lhq.value = pr; + lhq.key_hash = NJS_ATOM_STRING_set; ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { @@ -929,53 +918,40 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, return NJS_ERROR; } - lhq.key_hash = NJS_ATOM_STRING_set; + pr = lhq.value; - pr = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(pr == NULL)) { - return NJS_ERROR; - } + pr->type = NJS_PROPERTY; + pr->enumerable = 1; + pr->configurable = 1; + pr->writable = 1; + pr->u.value = njs_value_undefined; if (njs_prop_setter(prop) != NULL) { njs_set_function(njs_prop_value(pr), njs_prop_setter(prop)); } - - lhq.value = pr; - - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); - if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NJS_ERROR; - } } lhq.key_hash = NJS_ATOM_STRING_enumerable; setval = (prop->enumerable == 1) ? &njs_value_true : &njs_value_false; - pr = njs_object_prop_alloc(vm, setval, 1); - if (njs_slow_path(pr == NULL)) { - return NJS_ERROR; - } - - lhq.value = pr; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } - lhq.key_hash = NJS_ATOM_STRING_configurable; + pr = lhq.value; - setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false; + pr->type = NJS_PROPERTY; + pr->enumerable = 1; + pr->configurable = 1; + pr->writable = 1; + pr->u.value = *setval; - pr = njs_object_prop_alloc(vm, setval, 1); - if (njs_slow_path(pr == NULL)) { - return NJS_ERROR; - } + lhq.key_hash = NJS_ATOM_STRING_configurable; - lhq.value = pr; + setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false; ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { @@ -983,6 +959,14 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, return NJS_ERROR; } + pr = lhq.value; + + pr->type = NJS_PROPERTY; + pr->enumerable = 1; + pr->configurable = 1; + pr->writable = 1; + pr->u.value = *setval; + njs_set_object(dest, desc); return NJS_OK; @@ -1006,6 +990,9 @@ njs_prop_type_string(njs_object_prop_type_t type) case NJS_PROPERTY: return "property"; + case NJS_FREE_FLATHSH_ELEMENT: + return "free hash element"; + default: return "unknown"; } @@ -1013,7 +1000,7 @@ njs_prop_type_string(njs_object_prop_type_t type) njs_int_t -njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, +njs_object_props_init(njs_vm_t *vm, const njs_object_init_t* init, njs_object_prop_t *base, uint32_t atom_id, njs_value_t *value, njs_value_t *retval) { @@ -1033,31 +1020,26 @@ njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, return NJS_ERROR; } - prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), - sizeof(njs_object_prop_t)); - if (njs_slow_path(prop == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } - - *prop = *base; - - prop->type = NJS_PROPERTY; - njs_set_object(njs_prop_value(prop), object); - - lhq.value = prop; lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); - if (njs_fast_path(ret == NJS_OK)) { - njs_value_assign(retval, njs_prop_value(prop)); - return NJS_OK; + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NJS_ERROR; } - njs_internal_error(vm, "lvlhsh insert failed"); + prop = lhq.value; - return NJS_ERROR; + prop->enumerable = base->enumerable; + prop->configurable = base->configurable; + prop->writable = base->writable; + prop->type = NJS_PROPERTY; + njs_set_object(njs_prop_value(prop), object); + + njs_value_assign(retval, njs_prop_value(prop)); + + return NJS_OK; } diff --git a/src/njs_object_prop_declare.h b/src/njs_object_prop_declare.h index f2f7a5eb..3c991c50 100644 --- a/src/njs_object_prop_declare.h +++ b/src/njs_object_prop_declare.h @@ -9,8 +9,8 @@ #define NJS_DECLARE_PROP_VALUE(_name, _v, _fl) \ { \ - .atom_id = NJS_ATOM_ ## _name, \ .desc = { \ + .atom_id = NJS_ATOM_ ## _name, \ .type = NJS_PROPERTY, \ .u.value = _v, \ .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ @@ -28,8 +28,8 @@ #define NJS_DECLARE_PROP_HANDLER(_name, _native, _m16, _fl) \ { \ - .atom_id = NJS_ATOM_ ## _name, \ .desc = { \ + .atom_id = NJS_ATOM_ ## _name, \ .type = NJS_PROPERTY_HANDLER, \ .u.value = njs_prop_handler2(_native, _m16), \ .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ @@ -41,11 +41,11 @@ #define NJS_DECLARE_PROP_GETTER(_name, _native, _magic) \ { \ - .atom_id = NJS_ATOM_ ## _name, \ .desc = { \ + .atom_id = NJS_ATOM_ ## _name, \ .type = NJS_ACCESSOR, \ .u.accessor = njs_getter(_native, _magic), \ - .writable = NJS_ATTRIBUTE_UNSET, \ + .writable = 0, \ .configurable = 1, \ }, \ } diff --git a/src/njs_regexp.c b/src/njs_regexp.c index ed560b18..d958e2af 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -1038,25 +1038,9 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, } /* FIXME: implement fast CreateDataPropertyOrThrow(). */ - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - goto fail; - } - - c = njs_regex_capture(match_data, 0); - - if (utf8 == NJS_STRING_UTF8) { - index = njs_string_index(string, c); - - } else { - index = c; - } - - njs_set_number(&prop->u.value, index); lhq.key_hash = NJS_ATOM_STRING_index; lhq.replace = 0; - lhq.value = prop; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; @@ -1065,32 +1049,54 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, goto insert_fail; } - prop = njs_object_prop_alloc(vm, ®exp->string, 1); - if (njs_slow_path(prop == NULL)) { - goto fail; + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + + c = njs_regex_capture(match_data, 0); + + if (utf8 == NJS_STRING_UTF8) { + index = njs_string_index(string, c); + + } else { + index = c; } + njs_set_number(&prop->u.value, index); + lhq.key_hash = NJS_ATOM_STRING_input; - lhq.value = prop; ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - goto fail; - } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = regexp->string; lhq.key_hash = NJS_ATOM_STRING_groups; - lhq.value = prop; ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = njs_value_undefined; + if (pattern->ngroups != 0) { groups = njs_object_alloc(vm); if (njs_slow_path(groups == NULL)) { @@ -1110,19 +1116,21 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, goto fail; } - prop = njs_object_prop_alloc(vm, &array->start[group->capture], 1); - if (njs_slow_path(prop == NULL)) { - goto fail; - } - lhq.key_hash = name.atom_id; - lhq.value = prop; ret = njs_flathsh_unique_insert(&groups->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = array->start[group->capture]; + i++; } while (i < pattern->ngroups); @@ -1149,26 +1157,10 @@ static void njs_regexp_exec_result_free(njs_vm_t *vm, njs_array_t *result) { njs_flathsh_t *hash; - njs_object_prop_t *prop; - njs_flathsh_elt_t *elt; - njs_flathsh_each_t lhe; njs_flathsh_query_t lhq; - njs_flathsh_each_init(&lhe, &njs_object_hash_proto); - hash = &result->object.hash; - for ( ;; ) { - elt = njs_flathsh_each(hash, &lhe); - if (elt == NULL) { - break; - } - - prop = elt->value; - - njs_mp_free(vm->mem_pool, prop); - } - lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; diff --git a/src/njs_scope.c b/src/njs_scope.c index b95d3979..7959849a 100644 --- a/src/njs_scope.c +++ b/src/njs_scope.c @@ -108,7 +108,7 @@ njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data) njs_str_t string; njs_value_t *value; - value = data; + value = *(njs_value_t **) data; if (njs_is_string(value)) { /* parser strings are always initialized. */ @@ -156,6 +156,7 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, njs_value_t *value; njs_string_t *string; njs_lvlhsh_t *values_hash; + njs_object_prop_t *pr; njs_lvlhsh_query_t lhq; is_string = 0; @@ -181,12 +182,12 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, lhq.proto = &njs_values_hash_proto; if (njs_lvlhsh_find(&vm->shared->values_hash, &lhq) == NJS_OK) { - value = lhq.value; + value = ((njs_object_prop_t *) lhq.value)->u.val; *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t)); } else if (runtime && njs_lvlhsh_find(&vm->values_hash, &lhq) == NJS_OK) { - value = lhq.value; + value = ((njs_object_prop_t *) lhq.value)->u.val; *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t)); @@ -228,7 +229,6 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, **index = NJS_INDEX_ERROR; lhq.replace = 0; - lhq.value = value; lhq.pool = vm->mem_pool; values_hash = runtime ? &vm->values_hash : &vm->shared->values_hash; @@ -237,6 +237,9 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, if (njs_slow_path(ret != NJS_OK)) { return NULL; } + + pr = lhq.value; + pr->u.val = value; } if (start != (u_char *) src) { diff --git a/src/njs_value.c b/src/njs_value.c index 92c87e85..78f03821 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -960,6 +960,7 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, pq->lhq.value = prop; + prop->type = NJS_PROPERTY; prop->writable = slots->writable; prop->configurable = slots->configurable; prop->enumerable = slots->enumerable; @@ -1279,10 +1280,7 @@ slow_path: return NJS_ERROR; } - elt->value = (&pq.lhq)->value; - - prop = (njs_object_prop_t *) elt->value; - + prop = (njs_object_prop_t *) elt; prop->type = NJS_PROPERTY; prop->enumerable = 1; prop->configurable = 1; @@ -1318,13 +1316,8 @@ slow_path: goto fail; } - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } pq.lhq.replace = 0; - pq.lhq.value = prop; pq.lhq.key_hash = atom_id; pq.lhq.pool = vm->mem_pool; @@ -1334,6 +1327,12 @@ slow_path: return NJS_ERROR; } + prop = pq.lhq.value; + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + found: njs_value_assign(njs_prop_value(prop), setval); diff --git a/src/njs_value.h b/src/njs_value.h index da53f158..3fba344b 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -287,7 +287,8 @@ struct njs_object_type_init_s { typedef enum { - NJS_PROPERTY = 0, + NJS_FREE_FLATHSH_ELEMENT = 0, + NJS_PROPERTY, NJS_ACCESSOR, NJS_PROPERTY_HANDLER, @@ -305,22 +306,23 @@ typedef enum { } njs_prop_query_t; -/* - * Attributes are generally used as Boolean values. - * The UNSET value is can be seen: - * for newly created property descriptors in njs_define_property(), - * for writable attribute of accessor descriptors (desc->writable - * cannot be used as a boolean value). - */ -typedef enum { - NJS_ATTRIBUTE_FALSE = 0, - NJS_ATTRIBUTE_TRUE = 1, - NJS_ATTRIBUTE_UNSET, -} njs_object_attribute_t; - +/* njs_object_prop_s: same structure and length as njs_flathsh_elt_t. */ struct njs_object_prop_s { + /* next_elt + property descriptor : 32 bits */ + + uint32_t next_elt:26; + + uint32_t type:3; + uint32_t writable:1; + uint32_t enumerable:1; + uint32_t configurable:1; + + uint32_t atom_id; + union { + njs_value_t *val; + njs_mod_t *mod; njs_value_t value; struct { njs_function_t *getter; @@ -328,7 +330,8 @@ struct njs_object_prop_s { } accessor; } u; -#define njs_prop_value(_p) (&(_p)->u.value) +#define njs_prop_value(_p) (&((njs_object_prop_t *) (_p))->u.value) +#define njs_prop_module(_p) (((njs_object_prop_t *) (_p))->u.mod) #define njs_prop_handler(_p) (_p)->u.value.data.u.prop_handler #define njs_prop_ref(_p) (_p)->u.value.data.u.value #define njs_prop_typed_ref(_p) (_p)->u.value.data.u.typed_array @@ -338,17 +341,11 @@ struct njs_object_prop_s { #define njs_prop_getter(_p) (_p)->u.accessor.getter #define njs_prop_setter(_p) (_p)->u.accessor.setter - njs_object_prop_type_t type:8; /* 3 bits */ - - njs_object_attribute_t writable:8; /* 2 bits */ - njs_object_attribute_t enumerable:8; /* 2 bits */ - njs_object_attribute_t configurable:8; /* 2 bits */ }; struct njs_object_prop_init_s { struct njs_object_prop_s desc; - uint32_t atom_id; }; diff --git a/src/njs_vm.c b/src/njs_vm.c index 18a1c8e6..e6aac927 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -903,6 +903,7 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, njs_value_t prop_name; njs_object_t *global; njs_flathsh_t *hash; + njs_object_prop_t *obj_prop; njs_flathsh_query_t lhq; ret = njs_atom_string_create(vm, &prop_name, var_name->start, @@ -911,7 +912,6 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, return NJS_ERROR; } - lhq.value = prop; lhq.key_hash = prop_name.atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -926,6 +926,14 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, return ret; } + obj_prop = lhq.value; + + obj_prop->type = prop->type; + obj_prop->enumerable = prop->enumerable; + obj_prop->configurable = prop->configurable; + obj_prop->writable = prop->writable; + obj_prop->u.value = prop->u.value; + return NJS_OK; } @@ -934,14 +942,13 @@ njs_int_t njs_vm_bind(njs_vm_t *vm, const njs_str_t *var_name, const njs_value_t *value, njs_bool_t shared) { - njs_object_prop_t *prop; + njs_object_prop_t prop; - prop = njs_object_prop_alloc(vm, value, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } + njs_object_prop_init(&prop, NJS_PROPERTY, + NJS_OBJECT_PROP_VALUE_ECW); + *njs_prop_value(&prop) = *value; - return njs_vm_bind2(vm, var_name, prop, shared); + return njs_vm_bind2(vm, var_name, &prop, shared); } @@ -950,21 +957,18 @@ njs_vm_bind_handler(njs_vm_t *vm, const njs_str_t *var_name, njs_prop_handler_t handler, uint16_t magic16, uint32_t magic32, njs_bool_t shared) { - njs_object_prop_t *prop; + njs_object_prop_t prop; - prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } + njs_object_prop_init(&prop, NJS_PROPERTY_HANDLER, + NJS_OBJECT_PROP_VALUE_ECW); - prop->type = NJS_PROPERTY_HANDLER; - prop->u.value.type = NJS_INVALID; - prop->u.value.data.truth = 1; - njs_prop_magic16(prop) = magic16; - njs_prop_magic32(prop) = magic32; - njs_prop_handler(prop) = handler; + prop.u.value.type = NJS_INVALID; + prop.u.value.data.truth = 1; + njs_prop_magic16(&prop) = magic16; + njs_prop_magic32(&prop) = magic32; + njs_prop_handler(&prop) = handler; - return njs_vm_bind2(vm, var_name, prop, shared); + return njs_vm_bind2(vm, var_name, &prop, shared); } @@ -1242,11 +1246,6 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) goto done; } - prop = njs_object_prop_alloc(vm, value, 1); - if (njs_slow_path(prop == NULL)) { - goto done; - } - if (name->atom_id == NJS_ATOM_STRING_unknown) { ret = njs_atom_atomize_key(vm, name); if (ret != NJS_OK) { @@ -1254,7 +1253,6 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) } } - lhq.value = prop; lhq.key_hash = name->atom_id; lhq.replace = 0; lhq.pool = vm->mem_pool; @@ -1265,6 +1263,14 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) njs_internal_error(vm, NULL); goto done; } + + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *value; } ret = NJS_OK; diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index ba6df7d8..727dc6d0 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -2123,12 +2123,6 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, } } - prop = njs_object_prop_alloc(vm, init, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - - lhq.value = prop; lhq.key_hash = name.atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; @@ -2140,6 +2134,14 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, return NJS_ERROR; } + prop = lhq.value; + + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + prop->u.value = *init; + break; default: diff --git a/src/test/lvlhsh_unit_test.c b/src/test/lvlhsh_unit_test.c index 6172c1c7..0e334c5d 100644 --- a/src/test/lvlhsh_unit_test.c +++ b/src/test/lvlhsh_unit_test.c @@ -11,7 +11,7 @@ static njs_int_t lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) { - if (*(uintptr_t *) lhq->key.start == (uintptr_t) data) { + if (*(uintptr_t *) lhq->key.start == *(uintptr_t *) data) { return NJS_OK; } @@ -51,13 +51,13 @@ lvlhsh_unit_test_add(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto, lhq.replace = 0; lhq.key.length = sizeof(uintptr_t); lhq.key.start = (u_char *) &key; - lhq.value = (void *) key; lhq.proto = proto; lhq.pool = pool; switch (njs_lvlhsh_insert(lh, &lhq)) { case NJS_OK: + ((njs_flathsh_elt_t *) lhq.value)->value[0] = (void *) key; return NJS_OK; case NJS_DECLINED: @@ -84,7 +84,7 @@ lvlhsh_unit_test_get(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto, if (njs_lvlhsh_find(lh, &lhq) == NJS_OK) { - if (key == (uintptr_t) lhq.value) { + if (key == (uintptr_t) ((njs_flathsh_elt_t *) lhq.value)->value[0]) { return NJS_OK; } } diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c index 8d71aae7..d3d3f1c1 100644 --- a/src/test/njs_externals_test.c +++ b/src/test/njs_externals_test.c @@ -61,7 +61,7 @@ lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) njs_str_t name; njs_unit_test_prop_t *prop; - prop = data; + prop = *(njs_unit_test_prop_t **) data; name = prop->name; if (name.length != lhq->key.length) { @@ -129,13 +129,13 @@ lvlhsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r, lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); lhq.replace = 1; - lhq.value = (void *) prop; lhq.proto = &lvlhsh_proto; lhq.pool = pool; switch (njs_lvlhsh_insert(&r->hash, &lhq)) { case NJS_OK: + ((njs_flathsh_elt_t *) lhq.value)->value[0] = (void *) prop; return NJS_OK; case NJS_DECLINED: @@ -291,9 +291,9 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, ret = njs_lvlhsh_find(&r->hash, &lhq); - prop = lhq.value; - if (ret == NJS_OK) { + prop = ((njs_flathsh_elt_t *) lhq.value)->value[0]; + if (retval == NULL) { njs_value_invalid_set(njs_value_arg(&prop->value)); return NJS_OK; From noreply at nginx.com Thu Jul 10 15:01:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 10 Jul 2025 15:01:02 +0000 (UTC) Subject: [nginx] SSL: SSL_group_to_name() compatibility macro. Message-ID: <20250710150102.DEC1D4838D@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/a5d60c30d3d494291dd7e2ddde4536a439bab5bf branches: master commit: a5d60c30d3d494291dd7e2ddde4536a439bab5bf user: Sergey Kandaurov date: Tue, 8 Jul 2025 17:59:50 +0400 description: SSL: SSL_group_to_name() compatibility macro. No functional changes. --- src/event/ngx_event_openssl.c | 12 ------------ src/event/ngx_event_openssl.h | 5 +++++ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index a7b389444..fc7f26655 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -5055,11 +5055,7 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) return NGX_OK; } -#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL) name = SSL_group_to_name(c->ssl->connection, nid); -#else - name = NULL; -#endif s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1; s->data = ngx_pnalloc(pool, s->len); @@ -5113,11 +5109,7 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) nid = curves[i]; if (nid & TLSEXT_nid_unknown) { -#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL) name = SSL_group_to_name(c->ssl->connection, nid); -#else - name = NULL; -#endif len += name ? ngx_strlen(name) : sizeof("0x0000") - 1; @@ -5139,11 +5131,7 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) nid = curves[i]; if (nid & TLSEXT_nid_unknown) { -#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL) name = SSL_group_to_name(c->ssl->connection, nid); -#else - name = NULL; -#endif p = name ? ngx_cpymem(p, name, ngx_strlen(name)) : ngx_sprintf(p, "0x%04xd", nid & 0xffff); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 9e68deb44..61ce16dab 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -96,6 +96,11 @@ #endif +#if (OPENSSL_VERSION_NUMBER < 0x3000000fL) +#define SSL_group_to_name(s, nid) NULL +#endif + + typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t; From noreply at nginx.com Thu Jul 10 15:01:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 10 Jul 2025 15:01:02 +0000 (UTC) Subject: [nginx] SSL: fixed testing OPENSSL_VERSION_NUMBER for OpenSSL 3.0+. Message-ID: <20250710150102.E3DFD488BE@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/a5ca38f30392e93aadc32cf5955c29fddcaa3871 branches: master commit: a5ca38f30392e93aadc32cf5955c29fddcaa3871 user: Sergey Kandaurov date: Tue, 8 Jul 2025 18:07:04 +0400 description: SSL: fixed testing OPENSSL_VERSION_NUMBER for OpenSSL 3.0+. Prior to OpenSSL 3.0, OPENSSL_VERSION_NUMBER used the following format: MNNFFPPS: major minor fix patch status Where the status nibble (S) has 0+ for development and f for release. The format was changed in OpenSSL 3.0.0, where it is always zero: MNN00PP0: major minor patch --- src/event/ngx_event_openssl.c | 2 +- src/event/ngx_event_openssl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index fc7f26655..ff604c562 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1374,7 +1374,7 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed", file->data); -#if (OPENSSL_VERSION_NUMBER >= 0x3000001fL) +#if (OPENSSL_VERSION_NUMBER >= 0x30000010L) EVP_PKEY_free(dh); #endif BIO_free(bio); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 61ce16dab..0c9e9e840 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -96,7 +96,7 @@ #endif -#if (OPENSSL_VERSION_NUMBER < 0x3000000fL) +#if (OPENSSL_VERSION_NUMBER < 0x30000000L) #define SSL_group_to_name(s, nid) NULL #endif From noreply at nginx.com Thu Jul 10 18:15:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 10 Jul 2025 18:15:02 +0000 (UTC) Subject: [njs] Fixed property set for objects with a TypedArray in prototype. Message-ID: <20250710181502.D2139488BE@pubserv1.nginx> details: https://github.com/nginx/njs/commit/941c1f9c09487bdb8328624e06deeb9519083e62 branches: master commit: 941c1f9c09487bdb8328624e06deeb9519083e62 user: Dmitry Volyntsev date: Thu, 10 Jul 2025 10:40:05 -0700 description: Fixed property set for objects with a TypedArray in prototype. The issue was introduced in 2f288a9c. --- src/njs_object.h | 7 ++++--- src/test/njs_unit_test.c | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/njs_object.h b/src/njs_object.h index fac49aa8..dd5334d2 100644 --- a/src/njs_object.h +++ b/src/njs_object.h @@ -123,9 +123,10 @@ njs_inline njs_bool_t njs_is_data_descriptor(njs_object_prop_t *prop) { return (prop->type == NJS_PROPERTY && njs_is_valid(njs_prop_value(prop))) - || prop->type == NJS_PROPERTY_REF - || prop->type == NJS_PROPERTY_PLACE_REF - || prop->type == NJS_PROPERTY_HANDLER; + || prop->type == NJS_PROPERTY_HANDLER + || prop->type == NJS_PROPERTY_REF + || prop->type == NJS_PROPERTY_PLACE_REF + || prop->type == NJS_PROPERTY_TYPED_ARRAY_REF; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index fd98dbb5..78e12197 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -5908,6 +5908,12 @@ static njs_unit_test_t njs_test[] = " catch (e) { return e.message == 'Cannot redefine property: \"1\"'}})"), njs_str("true") }, + { njs_str(NJS_TYPED_ARRAY_LIST + ".every(v=>{Object.defineProperty(v.prototype, '0', {set(){ throw 'Oops' }});" + " var t = new v([0]); var r = Object.create(t);" + " r[0] = 1; return true})"), + njs_str("true") }, + { njs_str(NJS_TYPED_ARRAY_LIST ".every(v=>{try {var a = new v([1,1]); Object.defineProperty(a, '1', {get(){return 22}})} " " catch (e) { return e.message == 'Cannot redefine property: \"1\"'}})"), From noreply at nginx.com Thu Jul 10 18:15:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 10 Jul 2025 18:15:02 +0000 (UTC) Subject: [njs] Version 0.9.1. Message-ID: <20250710181502.D5C79489D3@pubserv1.nginx> details: https://github.com/nginx/njs/commit/4fd3ff98e413ede57c88456cf84b116a8382061a branches: master commit: 4fd3ff98e413ede57c88456cf84b116a8382061a user: Dmitry Volyntsev date: Wed, 9 Jul 2025 14:34:05 -0700 description: Version 0.9.1. --- CHANGES | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGES b/CHANGES index af7e4b61..719e25b4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,58 @@ +Changes with njs 0.9.1 10 Jul 2025 + + nginx modules: + + *) Feature: added Fetch API for QuickJS engine. + + *) Feature: added state file for a shared dictionary. + + *) Bugfix: fixed handling of Content-Length header when + a body is provided for Fetch API. + + *) Bugfix: fixed qjs engine after bellard/quickjs at 458c34d2. + + *) Bugfix: fixed NULL pointer dereference when processing + If-* headers. + + Core: + + *) Feature: added ECDH support for WebCrypto. + + *) Improvement: reduced memory consumption by the object hash. + The new hash uses 42% less memory per element. + + *) Improvement: reduced memory consumption for concatenation of + numbers and strings. + + *) Improvement: reduced memory consumption of + String.prototype.concat() with scalar values. + + *) Bugfix: fixed segfault in njs_property_query(). + The issue was introduced in b28e50b1 (0.9.0). + + *) Bugfix: fixed Function constructor template injection. + + *) Bugfix: fixed GCC compilation with O3 optimization level. + + *) Bugfix: fixed constant is too large for 'long' warning + on MIPS -mabi=n32. + + *) Bugfix: fixed compilation with GCC 4.1. + + *) Bugfix: fixed %TypedArray%.from() with the buffer is detached + by the mapper. + + *) Bugfix: fixed %TypedArray%.prototype.slice() with overlapping + buffers. + + *) Bugfix: fixed handling of detached buffers for typed arrays. + + *) Bugfix: fixed frame saving for async functions with + closures. + + *) Bugfix: fixed RegExp compilation of patterns with + escaped '[' characters. + Changes with njs 0.9.0 06 May 2025 Core: From noreply at nginx.com Thu Jul 10 18:17:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 10 Jul 2025 18:17:02 +0000 (UTC) Subject: [njs] Lightweight tag created: 0.9.1 Message-ID: <20250710181702.A2E39489D3@pubserv1.nginx> details: https://github.com/nginx/njs/releases/tag/0.9.1 branches: commit: 4fd3ff98e413ede57c88456cf84b116a8382061a user: Dmitry Volyntsev date: Wed Jul 9 14:34:05 2025 -0700 description: Version 0.9.1. From noreply at nginx.com Fri Jul 11 12:26:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Fri, 11 Jul 2025 12:26:02 +0000 (UTC) Subject: [nginx] Events: fixed -Wzero-as-null-pointer-constant warnings in kqueue. Message-ID: <20250711122602.9202C483A0@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/0daaba5c54aeeddffff400bfc77a08a1fd71b757 branches: master commit: 0daaba5c54aeeddffff400bfc77a08a1fd71b757 user: Sergey Kandaurov date: Tue, 8 Jul 2025 22:45:33 +0400 description: Events: fixed -Wzero-as-null-pointer-constant warnings in kqueue. The kevent udata field is special in that we maintain compatibility with NetBSD versions that predate using the "void *" type. The fix is to cast to intermediate uintptr_t that is casted back to "void *" where appropriate. --- src/event/modules/ngx_kqueue_module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index 9c7244c45..fb8a6527c 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -191,7 +191,7 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer) kev.flags = EV_ADD|EV_ENABLE; kev.fflags = 0; kev.data = timer; - kev.udata = 0; + kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0; ts.tv_sec = 0; ts.tv_nsec = 0; @@ -237,7 +237,7 @@ ngx_kqueue_notify_init(ngx_log_t *log) notify_kev.data = 0; notify_kev.flags = EV_ADD|EV_CLEAR; notify_kev.fflags = 0; - notify_kev.udata = 0; + notify_kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0; if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, From noreply at nginx.com Fri Jul 11 12:26:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Fri, 11 Jul 2025 12:26:02 +0000 (UTC) Subject: [nginx] Events: compatibility with NetBSD 10.0 in kqueue. Message-ID: <20250711122602.99EF2490BC@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/c52c5698cd7640621b8e4ba8a54ccfc38f5b95ff branches: master commit: c52c5698cd7640621b8e4ba8a54ccfc38f5b95ff user: Sergey Kandaurov date: Thu, 10 Jul 2025 16:59:05 +0400 description: Events: compatibility with NetBSD 10.0 in kqueue. The kevent udata field was changed from intptr_t to "void *", similar to other BSDs and Darwin. The NGX_KQUEUE_UDATA_T macro is adjusted to reflect that change, fixing -Werror=int-conversion errors. --- src/event/modules/ngx_kqueue_module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index 2ed862e9e..0c905eff3 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -10,9 +10,9 @@ #include -/* NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t" */ +/* NetBSD up to 10.0 incompatibly defines kevent.udata as "intptr_t" */ -#if (__NetBSD__) +#if (__NetBSD__ && __NetBSD_Version__ < 1000000000) #define NGX_KQUEUE_UDATA_T #else #define NGX_KQUEUE_UDATA_T (void *) From noreply at nginx.com Fri Jul 11 12:26:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Fri, 11 Jul 2025 12:26:02 +0000 (UTC) Subject: [nginx] Configure: set NGX_KQUEUE_UDATA_T at compile time. Message-ID: <20250711122602.95868490B9@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/3f5f8a7f51b16097ce6d5811ea3934efdfb27dd6 branches: master commit: 3f5f8a7f51b16097ce6d5811ea3934efdfb27dd6 user: Sergey Kandaurov date: Thu, 10 Jul 2025 16:30:35 +0400 description: Configure: set NGX_KQUEUE_UDATA_T at compile time. The NGX_KQUEUE_UDATA_T macro is used to compensate the incompatible kqueue() API in NetBSD, it doesn't really belong to feature tests. The change limits the macro visibility to the kqueue event module. Moving from autotests also simplifies testing a particular NetBSD version as seen in a subsequent change. --- auto/unix | 20 -------------------- src/event/modules/ngx_kqueue_module.c | 9 +++++++++ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/auto/unix b/auto/unix index 0dd66cfcd..6087e04fd 100644 --- a/auto/unix +++ b/auto/unix @@ -129,26 +129,6 @@ if test -z "$NGX_KQUEUE_CHECKED"; then fi -if [ "$NGX_SYSTEM" = "NetBSD" ]; then - - # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t" - - cat << END >> $NGX_AUTO_CONFIG_H - -#define NGX_KQUEUE_UDATA_T - -END - -else - cat << END >> $NGX_AUTO_CONFIG_H - -#define NGX_KQUEUE_UDATA_T (void *) - -END - -fi - - ngx_feature="crypt()" ngx_feature_name="NGX_HAVE_CRYPT" ngx_feature_run=no diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index fb8a6527c..2ed862e9e 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -10,6 +10,15 @@ #include +/* NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t" */ + +#if (__NetBSD__) +#define NGX_KQUEUE_UDATA_T +#else +#define NGX_KQUEUE_UDATA_T (void *) +#endif + + typedef struct { ngx_uint_t changes; ngx_uint_t events; From noreply at nginx.com Fri Jul 18 13:42:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Fri, 18 Jul 2025 13:42:02 +0000 (UTC) Subject: [njs] Version bump. Message-ID: <20250718134202.C8ADD490D6@pubserv1.nginx> details: https://github.com/nginx/njs/commit/b46cbce9c721ca288f2c403a1263e92cad687e10 branches: master commit: b46cbce9c721ca288f2c403a1263e92cad687e10 user: Dmitry Volyntsev date: Fri, 11 Jul 2025 18:26:19 -0700 description: Version bump. --- src/njs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/njs.h b/src/njs.h index 017f908a..702e74b5 100644 --- a/src/njs.h +++ b/src/njs.h @@ -11,8 +11,8 @@ #include -#define NJS_VERSION "0.9.1" -#define NJS_VERSION_NUMBER 0x000901 +#define NJS_VERSION "0.9.2" +#define NJS_VERSION_NUMBER 0x000902 #include From noreply at nginx.com Fri Jul 18 13:42:02 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Fri, 18 Jul 2025 13:42:02 +0000 (UTC) Subject: [njs] Removed remnants of level hash. Message-ID: <20250718134202.DDDD9490D7@pubserv1.nginx> details: https://github.com/nginx/njs/commit/b605a4d93f7e282835b6f8df58eb7f22456ddec5 branches: master commit: b605a4d93f7e282835b6f8df58eb7f22456ddec5 user: Vadim Zhestikov date: Fri, 11 Jul 2025 15:51:14 -0700 description: Removed remnants of level hash. Level hash has not been compiled since e64a376 (0.8.1) when flat hash was introduced. However, the compatibility layer remained to reduce the diff. --- auto/make | 4 +- auto/sources | 2 +- src/njs_array.c | 10 +- src/njs_array_buffer.c | 4 +- src/njs_atom.c | 128 ++++--- src/njs_buffer.c | 8 +- src/njs_builtin.c | 123 +++--- src/njs_date.c | 12 +- src/njs_error.c | 40 +- src/njs_extern.c | 38 +- src/njs_flathsh.c | 2 +- src/njs_flathsh.h | 34 -- src/njs_function.c | 36 +- src/njs_json.c | 46 +-- src/njs_lvlhsh.c | 854 ------------------------------------------ src/njs_lvlhsh.h | 178 --------- src/njs_module.c | 73 ++-- src/njs_module.h | 4 +- src/njs_number.c | 2 +- src/njs_object.c | 137 ++++--- src/njs_object.h | 2 +- src/njs_object_prop.c | 178 ++++----- src/njs_promise.c | 4 +- src/njs_regexp.c | 44 +-- src/njs_scope.c | 57 ++- src/njs_typed_array.c | 8 +- src/njs_value.c | 84 ++--- src/njs_value.h | 6 +- src/njs_vm.c | 42 +-- src/njs_vm.h | 18 +- src/njs_vmcode.c | 30 +- src/test/flathsh_unit_test.c | 205 ++++++++++ src/test/lvlhsh_unit_test.c | 206 ---------- src/test/njs_externals_test.c | 76 ++-- 34 files changed, 812 insertions(+), 1883 deletions(-) diff --git a/auto/make b/auto/make index cc3b022b..feffb69a 100644 --- a/auto/make +++ b/auto/make @@ -301,12 +301,12 @@ njs_fuzzer: $NJS_BUILD_DIR/njs_auto_config.h \\ lib_test: $NJS_BUILD_DIR/njs_auto_config.h \\ $NJS_BUILD_DIR/random_unit_test \\ $NJS_BUILD_DIR/rbtree_unit_test \\ - $NJS_BUILD_DIR/lvlhsh_unit_test \\ + $NJS_BUILD_DIR/flathsh_unit_test \\ $NJS_BUILD_DIR/unicode_unit_test $NJS_BUILD_DIR/random_unit_test $NJS_BUILD_DIR/rbtree_unit_test - $NJS_BUILD_DIR/lvlhsh_unit_test + $NJS_BUILD_DIR/flathsh_unit_test $NJS_BUILD_DIR/unicode_unit_test test262_njs: njs diff --git a/auto/sources b/auto/sources index 0e8db2cd..1a89edf5 100644 --- a/auto/sources +++ b/auto/sources @@ -57,7 +57,7 @@ QJS_LIB_SRCS=" \ " NJS_LIB_TEST_SRCS=" \ - src/test/lvlhsh_unit_test.c \ + src/test/flathsh_unit_test.c \ src/test/random_unit_test.c \ src/test/rbtree_unit_test.c \ src/test/unicode_unit_test.c \ diff --git a/src/njs_array.c b/src/njs_array.c index 3f424bc4..bcf428e9 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -81,7 +81,7 @@ njs_array_alloc(njs_vm_t *vm, njs_bool_t flat, uint64_t length, uint32_t spare) } array->start = array->data; - njs_lvlhsh_init(&array->object.hash); + njs_flathsh_init(&array->object.hash); array->object.shared_hash = vm->shared->array_instance_hash; array->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_ARRAY); array->object.slots = NULL; @@ -1615,13 +1615,13 @@ njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, { njs_int_t ret; njs_value_t value; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_is_object(njs_argument(args, 0))) { - lhq.proto = &njs_object_hash_proto; - lhq.key_hash = NJS_ATOM_STRING_join; + fhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_join; - ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &lhq, + ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { diff --git a/src/njs_array_buffer.c b/src/njs_array_buffer.c index c0e51c9f..9f1ee49a 100644 --- a/src/njs_array_buffer.c +++ b/src/njs_array_buffer.c @@ -35,8 +35,8 @@ njs_array_buffer_alloc(njs_vm_t *vm, uint64_t size, njs_bool_t zeroing) proto = njs_vm_proto(vm, NJS_OBJ_TYPE_ARRAY_BUFFER); - njs_lvlhsh_init(&array->object.hash); - njs_lvlhsh_init(&array->object.shared_hash); + njs_flathsh_init(&array->object.hash); + njs_flathsh_init(&array->object.shared_hash); array->object.__proto__ = proto; array->object.slots = NULL; array->object.type = NJS_ARRAY_BUFFER; diff --git a/src/njs_atom.c b/src/njs_atom.c index dc66f886..45733f45 100644 --- a/src/njs_atom.c +++ b/src/njs_atom.c @@ -8,8 +8,8 @@ #include -static njs_int_t njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data); -static njs_int_t njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data); +static njs_int_t njs_lexer_hash_test(njs_flathsh_query_t *fhq, void *data); +static njs_int_t njs_atom_hash_test(njs_flathsh_query_t *fhq, void *data); const njs_value_t njs_atom[] = { @@ -33,28 +33,26 @@ const njs_value_t njs_atom[] = { }; -const njs_lvlhsh_proto_t njs_lexer_hash_proto +const njs_flathsh_proto_t njs_lexer_hash_proto njs_aligned(64) = { - NJS_LVLHSH_DEFAULT, njs_lexer_hash_test, - njs_lvlhsh_alloc, - njs_lvlhsh_free, + njs_flathsh_proto_alloc, + njs_flathsh_proto_free, }; const njs_flathsh_proto_t njs_atom_hash_proto njs_aligned(64) = { - 0, njs_atom_hash_test, - njs_lvlhsh_alloc, - njs_lvlhsh_free, + njs_flathsh_proto_alloc, + njs_flathsh_proto_free, }; static njs_int_t -njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data) +njs_lexer_hash_test(njs_flathsh_query_t *fhq, void *data) { u_char *start; njs_value_t *name; @@ -63,13 +61,13 @@ njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data) njs_assert(name->type == NJS_STRING); - if (lhq->key.length != name->string.data->size) { + if (fhq->key.length != name->string.data->size) { return NJS_DECLINED; } start = name->string.data->start; - if (memcmp(start, lhq->key.start, lhq->key.length) == 0) { + if (memcmp(start, fhq->key.start, fhq->key.length) == 0) { return NJS_OK; } @@ -81,33 +79,33 @@ njs_value_t * njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, size_t length, uint32_t hash) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t fhq; - lhq.key.start = key; - lhq.key.length = size; - lhq.key_hash = hash; - lhq.proto = &njs_lexer_hash_proto; + fhq.key.start = key; + fhq.key.length = size; + fhq.key_hash = hash; + fhq.proto = &njs_lexer_hash_proto; - ret = njs_lvlhsh_find(vm->atom_hash_current, &lhq); + ret = njs_flathsh_find(vm->atom_hash_current, &fhq); if (ret == NJS_OK) { - return njs_prop_value(lhq.value); + return njs_prop_value(fhq.value); } - ret = njs_lvlhsh_find(&vm->atom_hash_shared, &lhq); + ret = njs_flathsh_find(&vm->atom_hash_shared, &fhq); if (ret == NJS_OK) { - return njs_prop_value(lhq.value); + return njs_prop_value(fhq.value); } - lhq.pool = vm->mem_pool; + fhq.pool = vm->mem_pool; - ret = njs_lvlhsh_insert(vm->atom_hash_current, &lhq); + ret = njs_flathsh_insert(vm->atom_hash_current, &fhq); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - prop = lhq.value; + prop = fhq.value; ret = njs_string_create(vm, &prop->u.value, key, size); if (njs_slow_path(ret != NJS_OK)) { @@ -130,35 +128,35 @@ static njs_value_t * njs_atom_find_or_add_string(njs_vm_t *vm, njs_value_t *value, uint32_t hash) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t fhq; njs_assert(njs_is_string(value)); - lhq.key.start = value->string.data->start; - lhq.key.length = value->string.data->size; - lhq.key_hash = hash; - lhq.proto = &njs_lexer_hash_proto; + fhq.key.start = value->string.data->start; + fhq.key.length = value->string.data->size; + fhq.key_hash = hash; + fhq.proto = &njs_lexer_hash_proto; - ret = njs_lvlhsh_find(vm->atom_hash_current, &lhq); + ret = njs_flathsh_find(vm->atom_hash_current, &fhq); if (ret == NJS_OK) { - return njs_prop_value(lhq.value); + return njs_prop_value(fhq.value); } - ret = njs_lvlhsh_find(&vm->atom_hash_shared, &lhq); + ret = njs_flathsh_find(&vm->atom_hash_shared, &fhq); if (ret == NJS_OK) { - return njs_prop_value(lhq.value); + return njs_prop_value(fhq.value);; } - lhq.pool = vm->mem_pool; + fhq.pool = vm->mem_pool; - ret = njs_lvlhsh_insert(vm->atom_hash_current, &lhq); + ret = njs_flathsh_insert(vm->atom_hash_current, &fhq); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - prop = lhq.value; + prop = fhq.value; prop->u.value = *value; @@ -175,7 +173,7 @@ njs_atom_find_or_add_string(njs_vm_t *vm, njs_value_t *value, static njs_int_t -njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data) +njs_atom_hash_test(njs_flathsh_query_t *fhq, void *data) { size_t size; u_char *start; @@ -184,25 +182,25 @@ njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data) name = data; if (name->type == NJS_STRING - && ((njs_value_t *) lhq->value)->type == NJS_STRING) + && ((njs_value_t *) fhq->value)->type == NJS_STRING) { size = name->string.data->length; - if (lhq->key.length != size) { + if (fhq->key.length != size) { return NJS_DECLINED; } start = (u_char *) name->string.data->start; - if (memcmp(start, lhq->key.start, lhq->key.length) == 0) { + if (memcmp(start, fhq->key.start, fhq->key.length) == 0) { return NJS_OK; } } if (name->type == NJS_SYMBOL - && ((njs_value_t *) lhq->value)->type == NJS_SYMBOL) + && ((njs_value_t *) fhq->value)->type == NJS_SYMBOL) { - if (lhq->key_hash == name->atom_id) { + if (fhq->key_hash == name->atom_id) { return NJS_OK; } } @@ -219,23 +217,23 @@ njs_atom_hash_init(njs_vm_t *vm) njs_int_t ret; njs_uint_t n; const njs_value_t *value, *values; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; values = &njs_atom[0]; - njs_lvlhsh_init(&vm->atom_hash_shared); + njs_flathsh_init(&vm->atom_hash_shared); - lhq.replace = 0; - lhq.proto = &njs_atom_hash_proto; - lhq.pool = vm->mem_pool; + fhq.replace = 0; + fhq.proto = &njs_atom_hash_proto; + fhq.pool = vm->mem_pool; for (n = 0; n < NJS_ATOM_SIZE; n++) { value = &values[n]; if (value->type == NJS_SYMBOL) { - lhq.key_hash = value->string.atom_id; + fhq.key_hash = value->string.atom_id; - ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq); + ret = njs_flathsh_insert(&vm->atom_hash_shared, &fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert/replace failed"); return 0xffffffff; @@ -246,18 +244,18 @@ njs_atom_hash_init(njs_vm_t *vm) start = value->string.data->start; len = value->string.data->length; - lhq.key_hash = njs_djb_hash(start, len); - lhq.key.length = len; - lhq.key.start = start; + fhq.key_hash = njs_djb_hash(start, len); + fhq.key.length = len; + fhq.key.start = start; - ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq); + ret = njs_flathsh_insert(&vm->atom_hash_shared, &fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert/replace failed"); return 0xffffffff; } } - *njs_prop_value(lhq.value) = *value; + *njs_prop_value(fhq.value) = *value; } vm->atom_hash_current = &vm->atom_hash_shared; @@ -349,26 +347,26 @@ njs_int_t njs_atom_symbol_add(njs_vm_t *vm, njs_value_t *value) { njs_int_t ret; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; njs_assert(value->atom_id == NJS_ATOM_STRING_unknown); - lhq.replace = 0; - lhq.proto = &njs_lexer_hash_proto; - lhq.pool = vm->mem_pool; + fhq.replace = 0; + fhq.proto = &njs_lexer_hash_proto; + fhq.pool = vm->mem_pool; value->atom_id = vm->atom_id_generator++; if (value->type == NJS_SYMBOL) { - lhq.key_hash = value->atom_id; + fhq.key_hash = value->atom_id; - ret = njs_flathsh_insert(vm->atom_hash_current, &lhq); + ret = njs_flathsh_insert(vm->atom_hash_current, &fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - *njs_prop_value(lhq.value) = *value; + *njs_prop_value(fhq.value) = *value; } return NJS_OK; diff --git a/src/njs_buffer.c b/src/njs_buffer.c index dbe9447a..93426e5c 100644 --- a/src/njs_buffer.c +++ b/src/njs_buffer.c @@ -156,8 +156,8 @@ njs_buffer_set(njs_vm_t *vm, njs_value_t *value, const u_char *start, proto = njs_vm_proto(vm, NJS_OBJ_TYPE_ARRAY_BUFFER); - njs_lvlhsh_init(&buffer->object.hash); - njs_lvlhsh_init(&buffer->object.shared_hash); + njs_flathsh_init(&buffer->object.hash); + njs_flathsh_init(&buffer->object.shared_hash); buffer->object.__proto__ = proto; buffer->object.slots = NULL; buffer->object.type = NJS_ARRAY_BUFFER; @@ -171,8 +171,8 @@ njs_buffer_set(njs_vm_t *vm, njs_value_t *value, const u_char *start, proto = njs_vm_proto(vm, NJS_OBJ_TYPE_BUFFER); array->type = NJS_OBJ_TYPE_UINT8_ARRAY; - njs_lvlhsh_init(&array->object.hash); - njs_lvlhsh_init(&array->object.shared_hash); + njs_flathsh_init(&array->object.hash); + njs_flathsh_init(&array->object.shared_hash); array->object.__proto__ = proto; array->object.slots = NULL; array->object.type = NJS_TYPED_ARRAY; diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 5ce2ec7e..1b486ba9 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -158,7 +158,7 @@ njs_builtin_objects_create(njs_vm_t *vm) vm->shared = shared; - njs_lvlhsh_init(&shared->values_hash); + njs_flathsh_init(&shared->values_hash); vm->atom_id_generator = njs_atom_hash_init(vm); if (njs_slow_path(vm->atom_id_generator == 0xffffffff)) { @@ -300,13 +300,13 @@ njs_builtin_objects_create(njs_vm_t *vm) vm->global_object.shared = 0; string_object = &shared->string_object; - njs_lvlhsh_init(&string_object->hash); + njs_flathsh_init(&string_object->hash); string_object->shared_hash = shared->string_instance_hash; string_object->type = NJS_OBJECT_VALUE; string_object->shared = 1; string_object->extensible = 0; - njs_lvlhsh_init(&shared->modules_hash); + njs_flathsh_init(&shared->modules_hash); return NJS_OK; } @@ -323,7 +323,7 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) njs_value_t key, *value, prop_name; njs_function_t *func, *target; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; njs_builtin_traverse_t *ctx; njs_traverse_t *path[NJS_TRAVERSE_MAX_DEPTH]; u_char buf[256]; @@ -438,18 +438,18 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) return ret; } - lhq.key_hash = prop_name.atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = prop_name.atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(&ctx->keys, &lhq); + ret = njs_flathsh_unique_insert(&ctx->keys, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -480,7 +480,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, njs_value_t value, tag; njs_object_t object; njs_object_prop_t *prop; - njs_lvlhsh_each_t lhe; + njs_flathsh_each_t lhe; njs_exotic_slots_t *slots; njs_function_name_t *fn; njs_function_native_t native; @@ -538,7 +538,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, /* Modules. */ - njs_lvlhsh_each_init(&lhe, &njs_modules_hash_proto); + njs_flathsh_each_init(&lhe, &njs_modules_hash_proto); for ( ;; ) { prop = (njs_object_prop_t *) njs_flathsh_each(&vm->modules_hash, &lhe); @@ -807,7 +807,7 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, { njs_int_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (retval == NULL) { return NJS_DECLINED; @@ -819,18 +819,18 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_value_assign(retval, setval); } - lhq.key_hash = atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(global), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = self->enumerable; @@ -849,7 +849,7 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_int_t ret; njs_object_t *object; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_slow_path(setval != NULL)) { njs_value_assign(retval, setval); @@ -869,18 +869,18 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT); } - lhq.key_hash = atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(global), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = self->enumerable; @@ -900,7 +900,7 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, njs_int_t ret; njs_function_t *ctor; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_slow_path(setval != NULL)) { njs_value_assign(retval, setval); @@ -917,18 +917,18 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, return NJS_OK; } - lhq.key_hash = atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(global), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -1189,7 +1189,7 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, njs_uint_t i; njs_array_t *argv; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; argv = njs_array_alloc(vm, 1, vm->options.argc, 0); if (njs_slow_path(argv == NULL)) { @@ -1206,18 +1206,18 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, } } - lhq.key_hash = NJS_ATOM_STRING_argv; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_argv; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(process), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1244,11 +1244,11 @@ njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) const u_char *val, *entry, *s, *end; njs_object_prop_t *prop; njs_string_prop_t string; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; ep = environment; @@ -1286,12 +1286,12 @@ njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) return ret; } - lhq.key_hash = prop_name.atom_id; + fhq.key_hash = prop_name.atom_id; - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_ERROR) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } @@ -1304,7 +1304,7 @@ njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) continue; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1328,7 +1328,7 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, njs_int_t ret; njs_object_t *env; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; env = njs_object_alloc(vm); if (njs_slow_path(env == NULL)) { @@ -1337,18 +1337,19 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, env->shared_hash = vm->shared->env_hash; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; - lhq.key_hash = NJS_ATOM_STRING_env; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_env; - ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(process), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); + return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; diff --git a/src/njs_date.c b/src/njs_date.c index 2832abbd..03e866a1 100644 --- a/src/njs_date.c +++ b/src/njs_date.c @@ -375,8 +375,8 @@ njs_date_alloc(njs_vm_t *vm, double time) return NULL; } - njs_lvlhsh_init(&date->object.hash); - njs_lvlhsh_init(&date->object.shared_hash); + njs_flathsh_init(&date->object.hash); + njs_flathsh_init(&date->object.shared_hash); date->object.type = NJS_DATE; date->object.shared = 0; date->object.extensible = 1; @@ -1443,13 +1443,13 @@ njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, { njs_int_t ret; njs_value_t value; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_is_object(njs_argument(args, 0))) { - lhq.proto = &njs_object_hash_proto; - lhq.key_hash = NJS_ATOM_STRING_toISOString; + fhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_toISOString; - ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &lhq, + ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { diff --git a/src/njs_error.c b/src/njs_error.c index d19e0e22..57ab477a 100644 --- a/src/njs_error.c +++ b/src/njs_error.c @@ -186,7 +186,7 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, njs_object_t *error; njs_object_prop_t *prop; njs_object_value_t *ov; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; ov = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_value_t)); if (njs_slow_path(ov == NULL)) { @@ -196,8 +196,8 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, njs_set_data(&ov->value, NULL, NJS_DATA_TAG_ANY); error = &ov->object; - njs_lvlhsh_init(&error->hash); - njs_lvlhsh_init(&error->shared_hash); + njs_flathsh_init(&error->hash); + njs_flathsh_init(&error->shared_hash); error->type = NJS_OBJECT_VALUE; error->shared = 0; error->extensible = 1; @@ -207,20 +207,20 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, error->__proto__ = proto; error->slots = NULL; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; if (name != NULL) { - lhq.key_hash = NJS_ATOM_STRING_name; + fhq.key_hash = NJS_ATOM_STRING_name; - ret = njs_flathsh_unique_insert(&error->hash, &lhq); + ret = njs_flathsh_unique_insert(&error->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -231,15 +231,15 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, } if (message!= NULL) { - lhq.key_hash = NJS_ATOM_STRING_message; + fhq.key_hash = NJS_ATOM_STRING_message; - ret = njs_flathsh_unique_insert(&error->hash, &lhq); + ret = njs_flathsh_unique_insert(&error->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -250,15 +250,15 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, } if (errors != NULL) { - lhq.key_hash = NJS_ATOM_STRING_errors; + fhq.key_hash = NJS_ATOM_STRING_errors; - ret = njs_flathsh_unique_insert(&error->hash, &lhq); + ret = njs_flathsh_unique_insert(&error->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -495,8 +495,8 @@ njs_memory_error_set(njs_vm_t *vm, njs_value_t *value) njs_set_data(&ov->value, NULL, NJS_DATA_TAG_ANY); object = &ov->object; - njs_lvlhsh_init(&object->hash); - njs_lvlhsh_init(&object->shared_hash); + njs_flathsh_init(&object->hash); + njs_flathsh_init(&object->shared_hash); object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_INTERNAL_ERROR); object->slots = NULL; object->type = NJS_OBJECT_VALUE; diff --git a/src/njs_extern.c b/src/njs_extern.c index adc8cd67..bbac8c73 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -25,22 +25,22 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, njs_function_t *function; njs_object_prop_t *prop; njs_exotic_slots_t *slot, *next; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; const njs_external_t *end; slot = njs_arr_add(protos); njs_memzero(slot, sizeof(njs_exotic_slots_t)); hash = &slot->external_shared_hash; - njs_lvlhsh_init(hash); + njs_flathsh_init(hash); if (n == 0) { return NJS_OK; } - lhq.replace = 0; - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; + fhq.replace = 0; + fhq.proto = &njs_object_hash_proto; + fhq.pool = vm->mem_pool; end = external + n; @@ -59,7 +59,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, } if (external->flags & NJS_EXTERN_SYMBOL) { - lhq.key_hash = external->name.symbol; + fhq.key_hash = external->name.symbol; } else { ret = njs_atom_string_create(vm, &prop_name, @@ -69,16 +69,16 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, return NJS_ERROR; } - lhq.key_hash = prop_name.atom_id; + fhq.key_hash = prop_name.atom_id; } - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = external->enumerable; @@ -142,7 +142,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, prop->u.value.type = NJS_INVALID; prop->u.value.data.truth = 1; njs_prop_magic16(prop) = next - slot; - njs_prop_magic32(prop) = lhq.key_hash; + njs_prop_magic32(prop) = fhq.key_hash; njs_prop_handler(prop) = njs_external_prop_handler; if (external->u.object.prop_handler) { @@ -194,7 +194,7 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, njs_external_ptr_t external; njs_object_value_t *ov; njs_exotic_slots_t *slots; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_slow_path(retval == NULL)) { return NJS_DECLINED; @@ -222,18 +222,18 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, njs_set_object_value(retval, ov); } - lhq.key_hash = atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = self->enumerable; diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c index 7e374c62..601018d1 100644 --- a/src/njs_flathsh.c +++ b/src/njs_flathsh.c @@ -143,7 +143,7 @@ njs_flathsh_descr_t * njs_flathsh_new(njs_flathsh_query_t *fhq) { return njs_flathsh_alloc(fhq, NJS_FLATHSH_HASH_INITIAL_SIZE, - NJS_FLATHSH_ELTS_INITIAL_SIZE); + NJS_FLATHSH_ELTS_INITIAL_SIZE); } diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index 06fd00c0..2d2f6ae1 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -46,7 +46,6 @@ typedef struct njs_flathsh_proto_s njs_flathsh_proto_t; struct njs_flathsh_proto_s { - uint32_t not_used; njs_flathsh_test_t test; njs_flathsh_alloc_t alloc; njs_flathsh_free_t free; @@ -164,37 +163,4 @@ NJS_EXPORT njs_flathsh_descr_t *njs_flathsh_new(njs_flathsh_query_t *fhq); NJS_EXPORT void njs_flathsh_destroy(njs_flathsh_t *fh, njs_flathsh_query_t *fhq); -/* Temporary backward compatibility .*/ - -typedef struct njs_flathsh_query_s njs_lvlhsh_query_t; - -#define NJS_LVLHSH_DEFAULT 0 -#define NJS_LVLHSH_LARGE_SLAB 0 - -typedef struct njs_flathsh_proto_s njs_lvlhsh_proto_t; - -#define njs_lvlhsh_is_empty njs_flathsh_is_empty -#define njs_lvlhsh_init njs_flathsh_init -#define njs_lvlhsh_eq njs_flathsh_eq -#define njs_lvlhsh_t njs_flathsh_t -#define njs_lvlhsh_each_t njs_flathsh_each_t -#define njs_lvlhsh_find(lh, lhq) njs_flathsh_find(lh, lhq) -#define njs_lvlhsh_insert(lh, lhq) njs_flathsh_insert(lh, lhq) -#define njs_lvlhsh_delete(lh, lhq) njs_flathsh_delete(lh, lhq) -#define njs_lvlhsh_each_init(lhe, _proto) njs_flathsh_each_init(lhe, _proto) - -njs_inline njs_flathsh_elt_t * -njs_lvlhsh_each(const njs_flathsh_t *lh, njs_flathsh_each_t *lhe) -{ - njs_flathsh_elt_t *e; - - e = njs_flathsh_each(lh, lhe); - if (e == NULL) { - return NULL; - } - - return e; -} - - #endif /* _NJS_FLATHSH_H_INCLUDED_ */ diff --git a/src/njs_function.c b/src/njs_function.c index 09bc2ebb..9ed4bb42 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -28,7 +28,7 @@ njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda, /* * njs_mp_zalloc() does also: - * njs_lvlhsh_init(&function->object.hash); + * njs_flathsh_init(&function->object.hash); * function->object.__proto__ = NULL; */ @@ -124,20 +124,20 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function, njs_value_t value; njs_string_prop_t string; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key_hash = NJS_ATOM_STRING_name; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_name; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(&function->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&function->object.hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -892,21 +892,21 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_flathsh_t *hash, { njs_int_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key_hash = NJS_ATOM_STRING_prototype; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_prototype; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -1353,7 +1353,7 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, function->native = 1; function->u.native = njs_function_bound_call; - njs_lvlhsh_init(&function->object.hash); + njs_flathsh_init(&function->object.hash); /* Bound functions have no "prototype" property. */ function->object.shared_hash = vm->shared->arrow_instance_hash; diff --git a/src/njs_json.c b/src/njs_json.c index 49c2b7e7..d77befdd 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -339,7 +339,7 @@ njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value, njs_object_t *object; njs_value_t prop_name, prop_value; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_slow_path(--ctx->depth == 0)) { njs_json_parse_exception(ctx, "Nested too deep", p); @@ -394,18 +394,18 @@ njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value, return NULL; } - lhq.key_hash = prop_name.atom_id; - lhq.replace = 1; - lhq.pool = ctx->pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = prop_name.atom_id; + fhq.replace = 1; + fhq.pool = ctx->pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(&object->hash, &lhq); + ret = njs_flathsh_unique_insert(&object->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(ctx->vm, "lvlhsh insert/replace failed"); + njs_internal_error(ctx->vm, "flathsh insert/replace failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1235,13 +1235,13 @@ njs_object_to_json_function(njs_vm_t *vm, njs_value_t *value) { njs_int_t ret; njs_value_t retval; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (njs_is_object(value)) { - lhq.proto = &njs_object_hash_proto; - lhq.key_hash = NJS_ATOM_STRING_toJSON; + fhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_toJSON; - ret = njs_object_property(vm, njs_object(value), &lhq, &retval); + ret = njs_object_property(vm, njs_object(value), &fhq, &retval); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; @@ -1601,7 +1601,7 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, { njs_int_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; wrapper->data.u.object = njs_object_alloc(vm); if (njs_slow_path(njs_object(wrapper) == NULL)) { @@ -1611,17 +1611,17 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, wrapper->type = NJS_OBJECT; wrapper->data.truth = 1; - lhq.key_hash = NJS_ATOM_STRING_empty; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_empty; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(wrapper), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(wrapper), &fhq); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -2051,7 +2051,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, goto exception; } - prop = pq.lhq.value; + prop = pq.fhq.value; if (prop->type == NJS_WHITEOUT || !prop->enumerable) { if (!state->array) { @@ -2069,8 +2069,8 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, njs_dump_empty(stringify, state, &chain, 1); if (!state->array || isnan(njs_key_to_index(key))) { - njs_atom_string_get(vm, key->atom_id, &pq.lhq.key); - njs_chb_append(&chain, pq.lhq.key.start, pq.lhq.key.length); + njs_atom_string_get(vm, key->atom_id, &pq.fhq.key); + njs_chb_append(&chain, pq.fhq.key.start, pq.fhq.key.length); njs_chb_append_literal(&chain, ":"); if (stringify->space.length != 0) { njs_chb_append_literal(&chain, " "); @@ -2082,7 +2082,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, if (prop->type == NJS_PROPERTY_HANDLER) { pq.scratch = *prop; prop = &pq.scratch; - ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash, + ret = njs_prop_handler(prop)(vm, prop, pq.fhq.key_hash, &state->value, NULL, njs_prop_value(prop)); diff --git a/src/njs_lvlhsh.c b/src/njs_lvlhsh.c deleted file mode 100644 index 8443a08c..00000000 --- a/src/njs_lvlhsh.c +++ /dev/null @@ -1,854 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - - -#include - - -/* - * The level hash consists of hierarchical levels of arrays of pointers. - * The pointers may point to another level, a bucket, or NULL. - * The levels and buckets must be allocated in manner alike posix_memalign() - * to bookkeep additional information in pointer low bits. - * - * A level is an array of pointers. Its size is a power of 2. Levels - * may be different sizes, but on the same level the sizes are the same. - * Level sizes are specified by number of bits per level in lvlhsh->shift - * array. A hash may have up to 7 levels. There are two predefined - * shift arrays given by the first two shift array values: - * - * 1) [0, 0]: [4, 4, 4, 4, 4, 4, 4] on a 64-bit platform or - * [5, 5, 5, 5, 5, 5, 0] on a 32-bit platform, - * so default size of levels is 128 bytes. - * - * 2) [0, 10]: [10, 4, 4, 4, 4, 4, 0] on a 64-bit platform or - * [10, 5, 5, 5, 5, 0, 0] on a 32-bit platform, - * so default size of levels is 128 bytes on all levels except - * the first level. The first level is 8K or 4K on 64-bit or 32-bit - * platforms respectively. - * - * All buckets in a hash are the same size which is a power of 2. - * A bucket contains several entries stored and tested sequentially. - * The bucket size should be one or two CPU cache line size, a minimum - * allowed size is 32 bytes. A default 128-byte bucket contains 10 64-bit - * entries or 15 32-bit entries. Each entry consists of pointer to value - * data and 32-bit key. If an entry value pointer is NULL, the entry is free. - * On a 64-bit platform entry value pointers are no aligned, therefore they - * are accessed as two 32-bit integers. The rest trailing space in a bucket - * is used as pointer to next bucket and this pointer is always aligned. - * Although the level hash allows to store a lot of values in a bucket chain, - * this is non optimal way. The large data set should be stored using - * several levels. - */ - -#define njs_lvlhsh_is_bucket(p) \ - ((uintptr_t) (p) & 1) - - -#define njs_lvlhsh_count_inc(n) \ - n = (void *) ((uintptr_t) (n) + 2) - - -#define njs_lvlhsh_count_dec(n) \ - n = (void *) ((uintptr_t) (n) - 2) - - -#define njs_lvlhsh_level_size(proto, nlvl) \ - ((uintptr_t) 1 << proto->shift[nlvl]) - - -#define njs_lvlhsh_level(lvl, mask) \ - (void **) ((uintptr_t) lvl & (~mask << 2)) - - -#define njs_lvlhsh_level_entries(lvl, mask) \ - ((uintptr_t) lvl & (mask << 1)) - - -#define njs_lvlhsh_store_bucket(slot, bkt) \ - slot = (void **) ((uintptr_t) bkt | 2 | 1) - - -#define njs_lvlhsh_bucket_size(proto) \ - proto->bucket_size - - -#define njs_lvlhsh_bucket(proto, bkt) \ - (uint32_t *) ((uintptr_t) bkt & ~(uintptr_t) proto->bucket_mask) - - -#define njs_lvlhsh_bucket_entries(proto, bkt) \ - (((uintptr_t) bkt & (uintptr_t) proto->bucket_mask) >> 1) - - -#define njs_lvlhsh_bucket_end(proto, bkt) \ - &bkt[proto->bucket_end] - - -#define njs_lvlhsh_free_entry(e) \ - (!(njs_lvlhsh_valid_entry(e))) - - -#define njs_lvlhsh_next_bucket(proto, bkt) \ - ((void **) &bkt[proto->bucket_end]) - -#if (NJS_64BIT) - -#define njs_lvlhsh_valid_entry(e) \ - (((e)[0] | (e)[1]) != 0) - - -#define njs_lvlhsh_entry_value(e) \ - (void *) (((uintptr_t) (e)[1] << 32) + (e)[0]) - - -#define njs_lvlhsh_set_entry_value(e, n) \ - (e)[0] = (uint32_t) (uintptr_t) n; \ - (e)[1] = (uint32_t) ((uintptr_t) n >> 32) - - -#define njs_lvlhsh_entry_key(e) \ - (e)[2] - - -#define njs_lvlhsh_set_entry_key(e, n) \ - (e)[2] = n - -#else - -#define njs_lvlhsh_valid_entry(e) \ - ((e)[0] != 0) - - -#define njs_lvlhsh_entry_value(e) \ - (void *) (e)[0] - - -#define njs_lvlhsh_set_entry_value(e, n) \ - (e)[0] = (uint32_t) n - - -#define njs_lvlhsh_entry_key(e) \ - (e)[1] - - -#define njs_lvlhsh_set_entry_key(e, n) \ - (e)[1] = n - -#endif - - -#define NJS_LVLHSH_BUCKET_DONE ((void *) -1) - - -static njs_int_t njs_lvlhsh_level_find(njs_lvlhsh_query_t *lhq, void **lvl, - uint32_t key, njs_uint_t nlvl); -static njs_int_t njs_lvlhsh_bucket_find(njs_lvlhsh_query_t *lhq, void **bkt); -static njs_int_t njs_lvlhsh_new_bucket(njs_lvlhsh_query_t *lhq, void **slot); -static njs_int_t njs_lvlhsh_level_insert(njs_lvlhsh_query_t *lhq, - void **slot, uint32_t key, njs_uint_t nlvl); -static njs_int_t njs_lvlhsh_bucket_insert(njs_lvlhsh_query_t *lhq, - void **slot, uint32_t key, njs_int_t nlvl); -static njs_int_t njs_lvlhsh_convert_bucket_to_level(njs_lvlhsh_query_t *lhq, - void **slot, njs_uint_t nlvl, uint32_t *bucket); -static njs_int_t njs_lvlhsh_level_convertion_insert(njs_lvlhsh_query_t *lhq, - void **parent, uint32_t key, njs_uint_t nlvl); -static njs_int_t njs_lvlhsh_bucket_convertion_insert(njs_lvlhsh_query_t *lhq, - void **slot, uint32_t key, njs_int_t nlvl); -static njs_int_t njs_lvlhsh_free_level(njs_lvlhsh_query_t *lhq, void **level, - njs_uint_t size); -static njs_int_t njs_lvlhsh_level_delete(njs_lvlhsh_query_t *lhq, void **slot, - uint32_t key, njs_uint_t nlvl); -static njs_int_t njs_lvlhsh_bucket_delete(njs_lvlhsh_query_t *lhq, void **bkt); -static void *njs_lvlhsh_level_each(njs_lvlhsh_each_t *lhe, void **level, - njs_uint_t nlvl, njs_uint_t shift); -static void *njs_lvlhsh_bucket_each(njs_lvlhsh_each_t *lhe); - - -njs_int_t -njs_lvlhsh_find(const njs_lvlhsh_t *lh, njs_lvlhsh_query_t *lhq) -{ - void *slot; - - slot = lh->slot; - - if (njs_fast_path(slot != NULL)) { - - if (njs_lvlhsh_is_bucket(slot)) { - return njs_lvlhsh_bucket_find(lhq, slot); - } - - return njs_lvlhsh_level_find(lhq, slot, lhq->key_hash, 0); - } - - return NJS_DECLINED; -} - - -static njs_int_t -njs_lvlhsh_level_find(njs_lvlhsh_query_t *lhq, void **lvl, uint32_t key, - njs_uint_t nlvl) -{ - void **slot; - uintptr_t mask; - njs_uint_t shift; - - shift = lhq->proto->shift[nlvl]; - mask = ((uintptr_t) 1 << shift) - 1; - - lvl = njs_lvlhsh_level(lvl, mask); - slot = lvl[key & mask]; - - if (slot != NULL) { - - if (njs_lvlhsh_is_bucket(slot)) { - return njs_lvlhsh_bucket_find(lhq, slot); - } - - return njs_lvlhsh_level_find(lhq, slot, key >> shift, nlvl + 1); - } - - return NJS_DECLINED; -} - - -static njs_int_t -njs_lvlhsh_bucket_find(njs_lvlhsh_query_t *lhq, void **bkt) -{ - void *value; - uint32_t *bucket, *e; - njs_uint_t n; - - do { - bucket = njs_lvlhsh_bucket(lhq->proto, bkt); - n = njs_lvlhsh_bucket_entries(lhq->proto, bkt); - e = bucket; - - do { - if (njs_lvlhsh_valid_entry(e)) { - n--; - - if (njs_lvlhsh_entry_key(e) == lhq->key_hash) { - - value = njs_lvlhsh_entry_value(e); - - if (lhq->proto->test(lhq, value) == NJS_OK) { - lhq->value = value; - - return NJS_OK; - } - } - } - - e += NJS_LVLHSH_ENTRY_SIZE; - - } while (n != 0); - - bkt = *njs_lvlhsh_next_bucket(lhq->proto, bucket); - - } while (bkt != NULL); - - return NJS_DECLINED; -} - - -njs_int_t -njs_lvlhsh_insert(njs_lvlhsh_t *lh, njs_lvlhsh_query_t *lhq) -{ - uint32_t key; - - if (njs_fast_path(lh->slot != NULL)) { - - key = lhq->key_hash; - - if (njs_lvlhsh_is_bucket(lh->slot)) { - return njs_lvlhsh_bucket_insert(lhq, &lh->slot, key, -1); - } - - return njs_lvlhsh_level_insert(lhq, &lh->slot, key, 0); - } - - return njs_lvlhsh_new_bucket(lhq, &lh->slot); -} - - -static njs_int_t -njs_lvlhsh_new_bucket(njs_lvlhsh_query_t *lhq, void **slot) -{ - uint32_t *bucket; - - bucket = lhq->proto->alloc(lhq->pool, njs_lvlhsh_bucket_size(lhq->proto)); - - if (njs_fast_path(bucket != NULL)) { - - njs_lvlhsh_set_entry_value(bucket, lhq->value); - njs_lvlhsh_set_entry_key(bucket, lhq->key_hash); - - *njs_lvlhsh_next_bucket(lhq->proto, bucket) = NULL; - - njs_lvlhsh_store_bucket(*slot, bucket); - - return NJS_OK; - } - - return NJS_ERROR; -} - - -static njs_int_t -njs_lvlhsh_level_insert(njs_lvlhsh_query_t *lhq, void **parent, uint32_t key, - njs_uint_t nlvl) -{ - void **slot, **lvl; - njs_int_t ret; - uintptr_t mask; - njs_uint_t shift; - - shift = lhq->proto->shift[nlvl]; - mask = ((uintptr_t) 1 << shift) - 1; - - lvl = njs_lvlhsh_level(*parent, mask); - slot = &lvl[key & mask]; - - if (*slot != NULL) { - key >>= shift; - - if (njs_lvlhsh_is_bucket(*slot)) { - return njs_lvlhsh_bucket_insert(lhq, slot, key, nlvl); - } - - return njs_lvlhsh_level_insert(lhq, slot, key, nlvl + 1); - } - - ret = njs_lvlhsh_new_bucket(lhq, slot); - - if (njs_fast_path(ret == NJS_OK)) { - njs_lvlhsh_count_inc(*parent); - } - - return ret; -} - - -static njs_int_t -njs_lvlhsh_bucket_insert(njs_lvlhsh_query_t *lhq, void **slot, uint32_t key, - njs_int_t nlvl) -{ - void **bkt, **vacant_bucket, *value; - uint32_t *bucket, *e, *vacant_entry; - njs_int_t ret; - uintptr_t n; - const void *new_value; - const njs_lvlhsh_proto_t *proto; - - bkt = slot; - vacant_entry = NULL; - vacant_bucket = NULL; - proto = lhq->proto; - - /* Search for duplicate entry in bucket chain. */ - - do { - bucket = njs_lvlhsh_bucket(proto, *bkt); - n = njs_lvlhsh_bucket_entries(proto, *bkt); - e = bucket; - - do { - if (njs_lvlhsh_valid_entry(e)) { - - if (njs_lvlhsh_entry_key(e) == lhq->key_hash) { - - value = njs_lvlhsh_entry_value(e); - - if (proto->test(lhq, value) == NJS_OK) { - - new_value = lhq->value; - lhq->value = value; - - if (lhq->replace) { - njs_lvlhsh_set_entry_value(e, new_value); - - return NJS_OK; - } - - return NJS_DECLINED; - } - } - - n--; - - } else { - /* - * Save a hole vacant position in bucket - * and continue to search for duplicate entry. - */ - if (vacant_entry == NULL) { - vacant_entry = e; - vacant_bucket = bkt; - } - } - - e += NJS_LVLHSH_ENTRY_SIZE; - - } while (n != 0); - - if (e < njs_lvlhsh_bucket_end(proto, bucket)) { - /* - * Save a vacant position on incomplete bucket's end - * and continue to search for duplicate entry. - */ - if (vacant_entry == NULL) { - vacant_entry = e; - vacant_bucket = bkt; - } - } - - bkt = njs_lvlhsh_next_bucket(proto, bucket); - - } while (*bkt != NULL); - - if (vacant_entry != NULL) { - njs_lvlhsh_set_entry_value(vacant_entry, lhq->value); - njs_lvlhsh_set_entry_key(vacant_entry, lhq->key_hash); - njs_lvlhsh_count_inc(*vacant_bucket); - - return NJS_OK; - } - - /* All buckets are full. */ - - nlvl++; - - if (njs_fast_path(proto->shift[nlvl] != 0)) { - - ret = njs_lvlhsh_convert_bucket_to_level(lhq, slot, nlvl, bucket); - - if (njs_fast_path(ret == NJS_OK)) { - return njs_lvlhsh_level_insert(lhq, slot, key, nlvl); - } - - return ret; - } - - /* The last allowed level, only buckets may be allocated here. */ - - return njs_lvlhsh_new_bucket(lhq, bkt); -} - - -static njs_int_t -njs_lvlhsh_convert_bucket_to_level(njs_lvlhsh_query_t *lhq, void **slot, - njs_uint_t nlvl, uint32_t *bucket) -{ - void *lvl, **level; - uint32_t *e, *end, key; - njs_int_t ret; - njs_uint_t i, shift, size; - njs_lvlhsh_query_t q; - const njs_lvlhsh_proto_t *proto; - - proto = lhq->proto; - size = njs_lvlhsh_level_size(proto, nlvl); - - lvl = proto->alloc(lhq->pool, size * (sizeof(void *))); - - if (njs_slow_path(lvl == NULL)) { - return NJS_ERROR; - } - - njs_memzero(lvl, size * (sizeof(void *))); - - level = lvl; - shift = 0; - - for (i = 0; i < nlvl; i++) { - /* - * Using SIMD operations in this trivial loop with maximum - * 8 iterations may increase code size by 170 bytes. - */ - njs_pragma_loop_disable_vectorization; - - shift += proto->shift[i]; - } - - end = njs_lvlhsh_bucket_end(proto, bucket); - - for (e = bucket; e < end; e += NJS_LVLHSH_ENTRY_SIZE) { - - q.proto = proto; - q.pool = lhq->pool; - q.value = njs_lvlhsh_entry_value(e); - key = njs_lvlhsh_entry_key(e); - q.key_hash = key; - - ret = njs_lvlhsh_level_convertion_insert(&q, &lvl, key >> shift, nlvl); - - if (njs_slow_path(ret != NJS_OK)) { - return njs_lvlhsh_free_level(lhq, level, size); - } - } - - *slot = lvl; - - proto->free(lhq->pool, bucket, njs_lvlhsh_bucket_size(proto)); - - return NJS_OK; -} - - -static njs_int_t -njs_lvlhsh_level_convertion_insert(njs_lvlhsh_query_t *lhq, void **parent, - uint32_t key, njs_uint_t nlvl) -{ - void **slot, **lvl; - njs_int_t ret; - uintptr_t mask; - njs_uint_t shift; - - shift = lhq->proto->shift[nlvl]; - mask = ((uintptr_t) 1 << shift) - 1; - - lvl = njs_lvlhsh_level(*parent, mask); - slot = &lvl[key & mask]; - - if (*slot == NULL) { - ret = njs_lvlhsh_new_bucket(lhq, slot); - - if (njs_fast_path(ret == NJS_OK)) { - njs_lvlhsh_count_inc(*parent); - } - - return ret; - } - - /* Only backets can be here. */ - - return njs_lvlhsh_bucket_convertion_insert(lhq, slot, key >> shift, nlvl); -} - - -/* - * The special bucket insertion procedure is required because during - * convertion lhq->key contains garbage values and the test function - * cannot be called. Besides, the procedure can be simpler because - * a new entry is inserted just after occupied entries. - */ - -static njs_int_t -njs_lvlhsh_bucket_convertion_insert(njs_lvlhsh_query_t *lhq, void **slot, - uint32_t key, njs_int_t nlvl) -{ - void **bkt; - uint32_t *bucket, *e; - njs_int_t ret; - uintptr_t n; - const njs_lvlhsh_proto_t *proto; - - bkt = slot; - proto = lhq->proto; - - do { - bucket = njs_lvlhsh_bucket(proto, *bkt); - n = njs_lvlhsh_bucket_entries(proto, *bkt); - e = bucket + n * NJS_LVLHSH_ENTRY_SIZE; - - if (njs_fast_path(e < njs_lvlhsh_bucket_end(proto, bucket))) { - - njs_lvlhsh_set_entry_value(e, lhq->value); - njs_lvlhsh_set_entry_key(e, lhq->key_hash); - njs_lvlhsh_count_inc(*bkt); - - return NJS_OK; - } - - bkt = njs_lvlhsh_next_bucket(proto, bucket); - - } while (*bkt != NULL); - - /* All buckets are full. */ - - nlvl++; - - if (njs_fast_path(proto->shift[nlvl] != 0)) { - - ret = njs_lvlhsh_convert_bucket_to_level(lhq, slot, nlvl, bucket); - - if (njs_fast_path(ret == NJS_OK)) { - return njs_lvlhsh_level_insert(lhq, slot, key, nlvl); - } - - return ret; - } - - /* The last allowed level, only buckets may be allocated here. */ - - return njs_lvlhsh_new_bucket(lhq, bkt); -} - - -static njs_int_t -njs_lvlhsh_free_level(njs_lvlhsh_query_t *lhq, void **level, njs_uint_t size) -{ - size_t bsize; - njs_uint_t i; - const njs_lvlhsh_proto_t *proto; - - proto = lhq->proto; - bsize = njs_lvlhsh_bucket_size(proto); - - for (i = 0; i < size; i++) { - - if (level[i] != NULL) { - /* - * Chained buckets are not possible here, since even - * in the worst case one bucket cannot be converted - * in two chained buckets but remains the same bucket. - */ - proto->free(lhq->pool, njs_lvlhsh_bucket(proto, level[i]), bsize); - } - } - - proto->free(lhq->pool, level, size * (sizeof(void *))); - - return NJS_ERROR; -} - - -njs_int_t -njs_lvlhsh_delete(njs_lvlhsh_t *lh, njs_lvlhsh_query_t *lhq) -{ - if (njs_fast_path(lh->slot != NULL)) { - - if (njs_lvlhsh_is_bucket(lh->slot)) { - return njs_lvlhsh_bucket_delete(lhq, &lh->slot); - } - - return njs_lvlhsh_level_delete(lhq, &lh->slot, lhq->key_hash, 0); - } - - return NJS_DECLINED; -} - - -static njs_int_t -njs_lvlhsh_level_delete(njs_lvlhsh_query_t *lhq, void **parent, uint32_t key, - njs_uint_t nlvl) -{ - size_t size; - void **slot, **lvl; - uintptr_t mask; - njs_int_t ret; - njs_uint_t shift; - - shift = lhq->proto->shift[nlvl]; - mask = ((uintptr_t) 1 << shift) - 1; - - lvl = njs_lvlhsh_level(*parent, mask); - slot = &lvl[key & mask]; - - if (*slot != NULL) { - - if (njs_lvlhsh_is_bucket(*slot)) { - ret = njs_lvlhsh_bucket_delete(lhq, slot); - - } else { - key >>= shift; - ret = njs_lvlhsh_level_delete(lhq, slot, key, nlvl + 1); - } - - if (*slot == NULL) { - njs_lvlhsh_count_dec(*parent); - - if (njs_lvlhsh_level_entries(*parent, mask) == 0) { - *parent = NULL; - size = njs_lvlhsh_level_size(lhq->proto, nlvl); - lhq->proto->free(lhq->pool, lvl, size * sizeof(void *)); - } - } - - return ret; - } - - return NJS_DECLINED; -} - - -static njs_int_t -njs_lvlhsh_bucket_delete(njs_lvlhsh_query_t *lhq, void **bkt) -{ - void *value; - size_t size; - uint32_t *bucket, *e; - uintptr_t n; - const njs_lvlhsh_proto_t *proto; - - proto = lhq->proto; - - do { - bucket = njs_lvlhsh_bucket(proto, *bkt); - n = njs_lvlhsh_bucket_entries(proto, *bkt); - e = bucket; - - do { - if (njs_lvlhsh_valid_entry(e)) { - - if (njs_lvlhsh_entry_key(e) == lhq->key_hash) { - - value = njs_lvlhsh_entry_value(e); - - if (proto->test(lhq, value) == NJS_OK) { - - if (njs_lvlhsh_bucket_entries(proto, *bkt) == 1) { - *bkt = *njs_lvlhsh_next_bucket(proto, bucket); - size = njs_lvlhsh_bucket_size(proto); - proto->free(lhq->pool, bucket, size); - - } else { - njs_lvlhsh_count_dec(*bkt); - njs_lvlhsh_set_entry_value(e, NULL); - } - - lhq->value = value; - - return NJS_OK; - } - } - - n--; - } - - e += NJS_LVLHSH_ENTRY_SIZE; - - } while (n != 0); - - bkt = njs_lvlhsh_next_bucket(proto, bucket); - - } while (*bkt != NULL); - - return NJS_DECLINED; -} - - -void * -njs_lvlhsh_each(const njs_lvlhsh_t *lh, njs_lvlhsh_each_t *lhe) -{ - void **slot; - - if (lhe->bucket == NJS_LVLHSH_BUCKET_DONE) { - slot = lh->slot; - - if (njs_lvlhsh_is_bucket(slot)) { - return NULL; - } - - } else { - if (njs_slow_path(lhe->bucket == NULL)) { - - /* The first iteration only. */ - - slot = lh->slot; - - if (slot == NULL) { - return NULL; - } - - if (!njs_lvlhsh_is_bucket(slot)) { - goto level; - } - - lhe->bucket = njs_lvlhsh_bucket(lhe->proto, slot); - lhe->entries = njs_lvlhsh_bucket_entries(lhe->proto, slot); - } - - return njs_lvlhsh_bucket_each(lhe); - } - -level: - - return njs_lvlhsh_level_each(lhe, slot, 0, 0); -} - - -static void * -njs_lvlhsh_level_each(njs_lvlhsh_each_t *lhe, void **level, njs_uint_t nlvl, - njs_uint_t shift) -{ - void **slot, *value; - uintptr_t mask; - njs_uint_t n, level_shift; - - level_shift = lhe->proto->shift[nlvl]; - mask = ((uintptr_t) 1 << level_shift) - 1; - - level = njs_lvlhsh_level(level, mask); - - do { - n = (lhe->current >> shift) & mask; - slot = level[n]; - - if (slot != NULL) { - if (njs_lvlhsh_is_bucket(slot)) { - - if (lhe->bucket != NJS_LVLHSH_BUCKET_DONE) { - - lhe->bucket = njs_lvlhsh_bucket(lhe->proto, slot); - lhe->entries = njs_lvlhsh_bucket_entries(lhe->proto, slot); - lhe->entry = 0; - - return njs_lvlhsh_bucket_each(lhe); - } - - lhe->bucket = NULL; - - } else { - value = njs_lvlhsh_level_each(lhe, slot, nlvl + 1, - shift + level_shift); - if (value != NULL) { - return value; - } - } - } - - lhe->current &= ~(mask << shift); - n = ((n + 1) & mask) << shift; - lhe->current |= n; - - } while (n != 0); - - return NULL; -} - - -static void * -njs_lvlhsh_bucket_each(njs_lvlhsh_each_t *lhe) -{ - void *value, **next; - uint32_t *bucket; - - /* At least one valid entry must present here. */ - do { - bucket = &lhe->bucket[lhe->entry]; - lhe->entry += NJS_LVLHSH_ENTRY_SIZE; - - } while (njs_lvlhsh_free_entry(bucket)); - - value = njs_lvlhsh_entry_value(bucket); - lhe->key_hash = njs_lvlhsh_entry_key(bucket); - - lhe->entries--; - - if (lhe->entries == 0) { - next = *njs_lvlhsh_next_bucket(lhe->proto, lhe->bucket); - - lhe->bucket = (next == NULL) ? NJS_LVLHSH_BUCKET_DONE - : njs_lvlhsh_bucket(lhe->proto, next); - - lhe->entries = njs_lvlhsh_bucket_entries(lhe->proto, next); - lhe->entry = 0; - } - - return value; -} diff --git a/src/njs_lvlhsh.h b/src/njs_lvlhsh.h deleted file mode 100644 index ab58de2d..00000000 --- a/src/njs_lvlhsh.h +++ /dev/null @@ -1,178 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#ifndef _NJS_LVLHSH_H_INCLUDED_ -#define _NJS_LVLHSH_H_INCLUDED_ - - -typedef struct njs_lvlhsh_query_s njs_lvlhsh_query_t; - -typedef njs_int_t (*njs_lvlhsh_test_t)(njs_lvlhsh_query_t *lhq, void *data); -typedef void *(*njs_lvlhsh_alloc_t)(void *ctx, size_t size); -typedef void (*njs_lvlhsh_free_t)(void *ctx, void *p, size_t size); - - -#if (NJS_64BIT) - -#define NJS_LVLHSH_DEFAULT_BUCKET_SIZE 128 -#define NJS_LVLHSH_ENTRY_SIZE 3 - -/* 3 is shift of 64-bit pointer. */ -#define NJS_LVLHSH_MEMALIGN_SHIFT (NJS_MAX_MEMALIGN_SHIFT - 3) - -#else - -#define NJS_LVLHSH_DEFAULT_BUCKET_SIZE 64 -#define NJS_LVLHSH_ENTRY_SIZE 2 - -/* 2 is shift of 32-bit pointer. */ -#define NJS_LVLHSH_MEMALIGN_SHIFT (NJS_MAX_MEMALIGN_SHIFT - 2) - -#endif - - -#if (NJS_LVLHSH_MEMALIGN_SHIFT < 10) -#define NJS_LVLHSH_MAX_MEMALIGN_SHIFT NJS_LVLHSH_MEMALIGN_SHIFT -#else -#define NJS_LVLHSH_MAX_MEMALIGN_SHIFT 10 -#endif - - -#define NJS_LVLHSH_BUCKET_END(bucket_size) \ - (((bucket_size) - sizeof(void *)) \ - / (NJS_LVLHSH_ENTRY_SIZE * sizeof(uint32_t)) \ - * NJS_LVLHSH_ENTRY_SIZE) - - -#define NJS_LVLHSH_BUCKET_SIZE(bucket_size) \ - NJS_LVLHSH_BUCKET_END(bucket_size), bucket_size, (bucket_size - 1) - - -#define NJS_LVLHSH_DEFAULT \ - NJS_LVLHSH_BUCKET_SIZE(NJS_LVLHSH_DEFAULT_BUCKET_SIZE), \ - { 4, 4, 4, 4, 4, 4, 4, 0 } - - -#define NJS_LVLHSH_LARGE_SLAB \ - NJS_LVLHSH_BUCKET_SIZE(NJS_LVLHSH_DEFAULT_BUCKET_SIZE), \ - { 10, 4, 4, 4, 4, 4, 4, 0 } - - -#define NJS_LVLHSH_LARGE_MEMALIGN \ - NJS_LVLHSH_BUCKET_SIZE(NJS_LVLHSH_DEFAULT_BUCKET_SIZE), \ - { NJS_LVLHSH_MAX_MEMALIGN_SHIFT, 4, 4, 4, 4, 0, 0, 0 } - - -typedef struct { - uint32_t bucket_end; - uint32_t bucket_size; - uint32_t bucket_mask; - uint8_t shift[8]; - - njs_lvlhsh_test_t test; - njs_lvlhsh_alloc_t alloc; - njs_lvlhsh_free_t free; -} njs_lvlhsh_proto_t; - - -typedef struct { - void *slot; -} njs_lvlhsh_t; - - -struct njs_lvlhsh_query_s { - uint32_t key_hash; - njs_str_t key; - - uint8_t replace; /* 1 bit */ - void *value; - - const njs_lvlhsh_proto_t *proto; - void *pool; - - /* Opaque data passed for the test function. */ - void *data; -}; - - -#define njs_lvlhsh_is_empty(lh) \ - ((lh)->slot == NULL) - - -#define njs_lvlhsh_init(lh) \ - (lh)->slot = NULL - - -#define njs_lvlhsh_eq(lhl, lhr) \ - ((lhl)->slot == (lhr)->slot) - -/* - * njs_lvlhsh_find() finds a hash element. If the element has been - * found then it is stored in the lhq->value and njs_lvlhsh_find() - * returns NJS_OK. Otherwise NJS_DECLINED is returned. - * - * The required njs_lvlhsh_query_t fields: key_hash, key, proto. - */ -NJS_EXPORT njs_int_t njs_lvlhsh_find(const njs_lvlhsh_t *lh, - njs_lvlhsh_query_t *lhq); - -/* - * njs_lvlhsh_insert() adds a hash element. If the element already - * presents in lvlhsh and the lhq->replace flag is zero, then lhq->value - * is updated with the old element and NJS_DECLINED is returned. - * If the element already presents in lvlhsh and the lhq->replace flag - * is non-zero, then the old element is replaced with the new element. - * lhq->value is updated with the old element, and NJS_OK is returned. - * If the element is not present in lvlhsh, then it is inserted and - * NJS_OK is returned. The lhq->value is not changed. - * On memory allocation failure NJS_ERROR is returned. - * - * The required njs_lvlhsh_query_t fields: key_hash, key, proto, replace, value. - * The optional njs_lvlhsh_query_t fields: pool. - */ -NJS_EXPORT njs_int_t njs_lvlhsh_insert(njs_lvlhsh_t *lh, - njs_lvlhsh_query_t *lhq); - -/* - * njs_lvlhsh_delete() deletes a hash element. If the element has been - * found then it is removed from lvlhsh and is stored in the lhq->value, - * and NJS_OK is returned. Otherwise NJS_DECLINED is returned. - * - * The required njs_lvlhsh_query_t fields: key_hash, key, proto. - * The optional njs_lvlhsh_query_t fields: pool. - */ -NJS_EXPORT njs_int_t njs_lvlhsh_delete(njs_lvlhsh_t *lh, - njs_lvlhsh_query_t *lhq); - - -typedef struct { - const njs_lvlhsh_proto_t *proto; - - /* - * Fields to store current bucket entry position. They cannot be - * combined in a single bucket pointer with number of entries in low - * bits, because entry positions are not aligned. A current level is - * stored as key bit path from the root. - */ - uint32_t *bucket; - uint32_t current; - uint32_t entry; - uint32_t entries; - uint32_t key_hash; -} njs_lvlhsh_each_t; - - -#define njs_lvlhsh_each_init(lhe, _proto) \ - do { \ - njs_memzero(lhe, sizeof(njs_lvlhsh_each_t)); \ - (lhe)->proto = _proto; \ - } while (0) - -NJS_EXPORT void *njs_lvlhsh_each(const njs_lvlhsh_t *lh, - njs_lvlhsh_each_t *lhe); - - -#endif /* _NJS_LVLHSH_H_INCLUDED_ */ diff --git a/src/njs_module.c b/src/njs_module.c index 7d58972c..b971035a 100644 --- a/src/njs_module.c +++ b/src/njs_module.c @@ -9,13 +9,13 @@ static njs_int_t -njs_module_hash_test(njs_lvlhsh_query_t *lhq, void *data) +njs_module_hash_test(njs_flathsh_query_t *fhq, void *data) { njs_mod_t *module; module = *(njs_mod_t **) data; - if (njs_strstr_eq(&lhq->key, &module->name)) { + if (njs_strstr_eq(&fhq->key, &module->name)) { return NJS_OK; } @@ -23,35 +23,36 @@ njs_module_hash_test(njs_lvlhsh_query_t *lhq, void *data) } -const njs_lvlhsh_proto_t njs_modules_hash_proto +const njs_flathsh_proto_t njs_modules_hash_proto njs_aligned(64) = { - NJS_LVLHSH_DEFAULT, njs_module_hash_test, - njs_lvlhsh_alloc, - njs_lvlhsh_free, + njs_flathsh_proto_alloc, + njs_flathsh_proto_free, }; njs_mod_t * njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t shared) { - njs_int_t ret; - njs_mod_t *shrd, *module; - njs_object_t *object; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - lhq.key = *name; - lhq.key_hash = njs_djb_hash(name->start, name->length); - lhq.proto = &njs_modules_hash_proto; - - if (njs_lvlhsh_find(&vm->modules_hash, &lhq) == NJS_OK) { - return njs_prop_module(lhq.value); + njs_int_t ret; + njs_mod_t *shrd, *module; + njs_object_t *object; + njs_object_prop_t *prop; + njs_flathsh_query_t fhq; + + fhq.key = *name; + fhq.key_hash = njs_djb_hash(name->start, name->length); + fhq.proto = &njs_modules_hash_proto; + + ret = njs_flathsh_find(&vm->modules_hash, &fhq); + if (ret == NJS_OK) { + return njs_prop_module(fhq.value); } - if (njs_lvlhsh_find(&vm->shared->modules_hash, &lhq) == NJS_OK) { - shrd = njs_prop_module(lhq.value); + ret = njs_flathsh_find(&vm->shared->modules_hash, &fhq); + if (ret == NJS_OK) { + shrd = ((njs_object_prop_t *)fhq.value)->u.mod; if (shared) { return shrd; @@ -70,15 +71,15 @@ njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t shared) return NULL; } - lhq.replace = 0; - lhq.pool = vm->mem_pool; + fhq.replace = 0; + fhq.pool = vm->mem_pool; - ret = njs_lvlhsh_insert(&vm->modules_hash, &lhq); + ret = njs_flathsh_insert(&vm->modules_hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - prop = lhq.value; + prop = fhq.value; prop->u.mod = module; @@ -93,10 +94,10 @@ njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t shared) njs_mod_t * njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value) { - njs_int_t ret; - njs_mod_t *module; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_mod_t *module; + njs_object_prop_t *prop; + njs_flathsh_query_t fhq; module = njs_mp_zalloc(vm->mem_pool, sizeof(njs_mod_t)); if (njs_slow_path(module == NULL)) { @@ -110,19 +111,19 @@ njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value) return NULL; } - lhq.replace = 0; - lhq.key = *name; - lhq.key_hash = njs_djb_hash(name->start, name->length); - lhq.pool = vm->mem_pool; - lhq.proto = &njs_modules_hash_proto; + fhq.replace = 0; + fhq.key = *name; + fhq.key_hash = njs_djb_hash(name->start, name->length); + fhq.pool = vm->mem_pool; + fhq.proto = &njs_modules_hash_proto; - ret = njs_lvlhsh_insert(&vm->shared->modules_hash, &lhq); + ret = njs_flathsh_insert(&vm->shared->modules_hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->u.mod = module; diff --git a/src/njs_module.h b/src/njs_module.h index 23853ad0..4510a9b0 100644 --- a/src/njs_module.h +++ b/src/njs_module.h @@ -23,8 +23,8 @@ njs_int_t njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); -extern njs_module_t *njs_modules[]; -extern const njs_lvlhsh_proto_t njs_modules_hash_proto; +extern njs_module_t *njs_modules[]; +extern const njs_flathsh_proto_t njs_modules_hash_proto; #endif /* _NJS_MODULE_H_INCLUDED_ */ diff --git a/src/njs_number.c b/src/njs_number.c index 29df50a5..15f08651 100644 --- a/src/njs_number.c +++ b/src/njs_number.c @@ -35,7 +35,7 @@ njs_key_to_index(const njs_value_t *value) array = njs_array(value); - if (njs_lvlhsh_is_empty(&array->object.hash)) { + if (njs_flathsh_is_empty(&array->object.hash)) { if (array->length == 0) { /* An empty array value is zero. */ diff --git a/src/njs_object.c b/src/njs_object.c index 0c592176..7f0b1822 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -15,7 +15,7 @@ typedef enum { static njs_object_prop_t *njs_object_exist_in_proto(const njs_object_t *begin, - const njs_object_t *end, njs_flathsh_query_t *lhq); + const njs_object_t *end, njs_flathsh_query_t *fhq); static njs_int_t njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array, njs_array_t *items, uint32_t flags); static njs_int_t njs_object_enumerate_typed_array(njs_vm_t *vm, @@ -41,8 +41,8 @@ njs_object_alloc(njs_vm_t *vm) object = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_t)); if (njs_fast_path(object != NULL)) { - njs_lvlhsh_init(&object->hash); - njs_lvlhsh_init(&object->shared_hash); + njs_flathsh_init(&object->hash); + njs_flathsh_init(&object->shared_hash); object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT); object->slots = NULL; object->type = NJS_OBJECT; @@ -126,13 +126,13 @@ njs_object_value_alloc(njs_vm_t *vm, njs_uint_t prototype_index, size_t extra, return NULL; } - njs_lvlhsh_init(&ov->object.hash); + njs_flathsh_init(&ov->object.hash); if (prototype_index == NJS_OBJ_TYPE_STRING) { ov->object.shared_hash = vm->shared->string_instance_hash; } else { - njs_lvlhsh_init(&ov->object.shared_hash); + njs_flathsh_init(&ov->object.shared_hash); } ov->object.type = NJS_OBJECT_VALUE; @@ -158,23 +158,23 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, { njs_int_t ret; njs_object_prop_t *obj_prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.replace = 0; - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; + fhq.replace = 0; + fhq.proto = &njs_object_hash_proto; + fhq.pool = vm->mem_pool; while (n != 0) { - lhq.key_hash = prop->desc.atom_id; - lhq.value = (void *) prop; + fhq.key_hash = prop->desc.atom_id; + fhq.value = (void *) prop; - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - obj_prop = lhq.value; + obj_prop = fhq.value; obj_prop->type = prop->desc.type; obj_prop->enumerable = prop->desc.enumerable; @@ -193,10 +193,9 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, const njs_flathsh_proto_t njs_object_hash_proto njs_aligned(64) = { - 0, NULL, - njs_lvlhsh_alloc, - njs_lvlhsh_free, + njs_flathsh_proto_alloc, + njs_flathsh_proto_free, }; @@ -380,28 +379,28 @@ njs_object_entries(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_object_prop_t * njs_object_exist_in_proto(const njs_object_t *object, const njs_object_t *end, - njs_flathsh_query_t *lhq) + njs_flathsh_query_t *fhq) { njs_int_t ret; njs_object_prop_t *prop; while (object != end) { - ret = njs_flathsh_unique_find(&object->hash, lhq); + ret = njs_flathsh_unique_find(&object->hash, fhq); if (njs_fast_path(ret == NJS_OK)) { - prop = lhq->value; + prop = fhq->value; if (prop->type == NJS_WHITEOUT) { goto next; } - return lhq->value; + return fhq->value; } - ret = njs_flathsh_unique_find(&object->shared_hash, lhq); + ret = njs_flathsh_unique_find(&object->shared_hash, fhq); if (njs_fast_path(ret == NJS_OK)) { - return lhq->value; + return fhq->value; } next: @@ -919,7 +918,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, njs_flathsh_elt_t *elt; njs_flathsh_each_t lhe; const njs_flathsh_t *hash; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; items_length = items->length; @@ -933,7 +932,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, return NJS_ERROR; } - lhq.proto = &njs_object_hash_proto; + fhq.proto = &njs_object_hash_proto; njs_flathsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->shared_hash; @@ -959,14 +958,14 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, continue; } - lhq.key_hash = elt->key_hash; + fhq.key_hash = elt->key_hash; - ext_prop = njs_object_exist_in_proto(parent, object, &lhq); + ext_prop = njs_object_exist_in_proto(parent, object, &fhq); if (ext_prop != NULL) { continue; } - ret = njs_flathsh_unique_find(&object->hash, &lhq); + ret = njs_flathsh_unique_find(&object->hash, &fhq); if (ret != NJS_OK) { if (!(prop->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY))) { @@ -989,7 +988,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, } else { - if (!(((njs_object_prop_t *) (lhq.value))->enumerable + if (!(((njs_object_prop_t *) (fhq.value))->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY))) { continue; @@ -1000,7 +999,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, num = njs_string_to_index(&prop_name); if (!njs_number_is_integer_index(num)) { - njs_object_prop_t *hash_prop = lhq.value; + njs_object_prop_t *hash_prop = fhq.value; if (hash_prop->type != NJS_WHITEOUT) { njs_process_prop(vm, &prop_name, flags, items_string, @@ -1035,9 +1034,9 @@ local_hash: continue; } - lhq.key_hash = elt->key_hash; + fhq.key_hash = elt->key_hash; - ext_prop = njs_object_exist_in_proto(parent, object, &lhq); + ext_prop = njs_object_exist_in_proto(parent, object, &fhq); if (ext_prop != NULL) { continue; } @@ -1052,7 +1051,7 @@ local_hash: } else { - ret = njs_flathsh_unique_find(&object->shared_hash, &lhq); + ret = njs_flathsh_unique_find(&object->shared_hash, &fhq); if (ret != NJS_OK) { /* prop is: in_hash && !in_shared_hash */ @@ -1326,8 +1325,8 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object) (void) njs_traverse_visit(&visited, &s->value); - pq.lhq.replace = 0; - pq.lhq.pool = vm->mem_pool; + pq.fhq.replace = 0; + pq.fhq.pool = vm->mem_pool; for ( ;; ) { @@ -1359,16 +1358,16 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object) } - prop = pq.lhq.value; + prop = pq.fhq.value; ret = njs_flathsh_unique_insert(&njs_object(&s->value)->shared_hash, - &pq.lhq); + &pq.fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - obj_prop = pq.lhq.value; + obj_prop = pq.fhq.value; obj_prop->type = prop->type; obj_prop->enumerable = prop->enumerable; @@ -1481,9 +1480,9 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx, return NJS_ERROR; } - prop = pq.lhq.value; + prop = pq.fhq.value; s->prop = prop; - s->atom_id = pq.lhq.key_hash; + s->atom_id = pq.fhq.key_hash; ret = cb(vm, s, ctx); if (njs_slow_path(ret != NJS_OK)) { @@ -1497,7 +1496,7 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx, njs_value_assign(&value, njs_prop_value(prop)); if (prop->type == NJS_PROPERTY_HANDLER) { - ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash, &s->value, + ret = njs_prop_handler(prop)(vm, prop, pq.fhq.key_hash, &s->value, NULL, &value); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -1617,7 +1616,7 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, goto done; } - prop = pq.lhq.value; + prop = pq.fhq.value; if (ret == NJS_DECLINED || !prop->enumerable) { continue; @@ -1676,7 +1675,7 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, njs_value_t descriptor, *value, *key; njs_object_t *descriptors; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; value = njs_arg(args, nargs, 1); @@ -1701,9 +1700,9 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, goto done; } - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; for (i = 0; i < length; i++) { key = &names->start[i]; @@ -1713,15 +1712,15 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, goto done; } - lhq.key_hash = key->atom_id; + fhq.key_hash = key->atom_id; - ret = njs_flathsh_unique_insert(&descriptors->hash, &lhq); + ret = njs_flathsh_unique_insert(&descriptors->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); goto done; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -2069,7 +2068,7 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, goto exception; } - prop = pq.lhq.value; + prop = pq.fhq.value; if (!prop->enumerable) { continue; } @@ -2188,22 +2187,22 @@ njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash, { njs_int_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key_hash = NJS_ATOM_STRING_prototype; + fhq.key_hash = NJS_ATOM_STRING_prototype; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -2448,21 +2447,21 @@ njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash, { njs_int_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key_hash = NJS_ATOM_STRING_constructor; + fhq.key_hash = NJS_ATOM_STRING_constructor; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 0; @@ -2530,7 +2529,7 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval) name = NJS_ATOM_STRING__object_Array_; } else if (njs_is_object(this) - && njs_lvlhsh_eq(&njs_object(this)->shared_hash, + && njs_flathsh_eq(&njs_object(this)->shared_hash, &vm->shared->arguments_object_instance_hash)) { name = NJS_ATOM_STRING__object_Arguments_; @@ -2671,7 +2670,7 @@ njs_object_prototype_prop_is_enumerable(njs_vm_t *vm, njs_value_t *args, switch (ret) { case NJS_OK: - prop = pq.lhq.value; + prop = pq.fhq.value; njs_set_boolean(retval, prop->enumerable); break; diff --git a/src/njs_object.h b/src/njs_object.h index dd5334d2..d2b49180 100644 --- a/src/njs_object.h +++ b/src/njs_object.h @@ -104,7 +104,7 @@ njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, void njs_object_prop_init(njs_object_prop_t *prop, njs_object_prop_type_t type, uint8_t attributes); njs_int_t njs_object_property(njs_vm_t *vm, njs_object_t *object, - njs_flathsh_query_t *lhq, njs_value_t *retval); + njs_flathsh_query_t *fhq, njs_value_t *retval); njs_object_prop_t *njs_object_property_add(njs_vm_t *vm, njs_value_t *object, uint32_t atom_id, njs_bool_t replace); njs_int_t njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index 6b93960c..aeaeb71b 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -44,24 +44,24 @@ njs_object_prop_init(njs_object_prop_t *prop, njs_object_prop_type_t type, njs_int_t njs_object_property(njs_vm_t *vm, njs_object_t *object, - njs_flathsh_query_t *lhq, njs_value_t *retval) + njs_flathsh_query_t *fhq, njs_value_t *retval) { njs_int_t ret; njs_value_t value; njs_object_prop_t *prop; do { - ret = njs_flathsh_unique_find(&object->hash, lhq); + ret = njs_flathsh_unique_find(&object->hash, fhq); if (njs_fast_path(ret == NJS_OK)) { - prop = lhq->value; + prop = fhq->value; if (prop->type != NJS_WHITEOUT) { goto found; } } - ret = njs_flathsh_unique_find(&object->shared_hash, lhq); + ret = njs_flathsh_unique_find(&object->shared_hash, fhq); if (njs_fast_path(ret == NJS_OK)) { goto found; @@ -77,7 +77,7 @@ njs_object_property(njs_vm_t *vm, njs_object_t *object, found: - prop = lhq->value; + prop = fhq->value; if (njs_is_data_descriptor(prop)) { njs_value_assign(retval, njs_prop_value(prop)); @@ -101,20 +101,20 @@ njs_object_property_add(njs_vm_t *vm, njs_value_t *object, unsigned atom_id, { njs_int_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key_hash = atom_id; - lhq.replace = replace; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = atom_id; + fhq.replace = replace; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(object), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(object), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NULL; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -213,9 +213,9 @@ again: set_prop: if (!njs_object(object)->extensible) { - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot add property \"%V\", " - "object is not extensible", &pq.lhq.key); + "object is not extensible", &pq.fhq.key); return NJS_ERROR; } @@ -264,8 +264,8 @@ set_prop: prop->configurable = 0; } - if (njs_slow_path(pq.lhq.value != NULL)) { - prev = pq.lhq.value; + if (njs_slow_path(pq.fhq.value != NULL)) { + prev = pq.fhq.value; if (njs_slow_path(prev->type == NJS_WHITEOUT)) { /* Previously deleted property. */ @@ -276,18 +276,18 @@ set_prop: } else { - pq.lhq.key_hash = atom_id; - pq.lhq.proto = &njs_object_hash_proto; - pq.lhq.replace = 0; - pq.lhq.pool = vm->mem_pool; + pq.fhq.key_hash = atom_id; + pq.fhq.proto = &njs_object_hash_proto; + pq.fhq.replace = 0; + pq.fhq.pool = vm->mem_pool; - ret = njs_flathsh_unique_insert(njs_object_hash(object), &pq.lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(object), &pq.fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - obj_prop = pq.lhq.value; + obj_prop = pq.fhq.value; obj_prop->enumerable = prop->enumerable; obj_prop->configurable = prop->configurable; obj_prop->writable = prop->writable; @@ -300,7 +300,7 @@ set_prop: /* Updating existing prop. */ - prev = pq.lhq.value; + prev = pq.fhq.value; switch (prev->type) { case NJS_PROPERTY: @@ -402,7 +402,7 @@ set_prop: */ if (pq.temp) { - pq.lhq.value = NULL; + pq.fhq.value = NULL; prop->configurable = prev->configurable; prop->enumerable = prev->enumerable; goto set_prop; @@ -457,7 +457,7 @@ set_prop: done: if (njs_slow_path(njs_is_fast_array(object) - && pq.lhq.key_hash == NJS_ATOM_STRING_length) + && pq.fhq.key_hash == NJS_ATOM_STRING_length) && (set_writable && !prop->writable)) { array = njs_array(object); @@ -498,7 +498,7 @@ done: } if (ret == NJS_DECLINED) { - pq.lhq.value = NULL; + pq.fhq.value = NULL; goto set_prop; } @@ -511,7 +511,7 @@ done: } else { if (njs_slow_path(njs_is_array(object) - && pq.lhq.key_hash == NJS_ATOM_STRING_length)) + && pq.fhq.key_hash == NJS_ATOM_STRING_length)) { if (!prev->configurable && !prev->writable @@ -555,8 +555,8 @@ done: exception: - njs_atom_string_get(vm, atom_id, &pq.lhq.key); - njs_type_error(vm, "Cannot redefine property: \"%V\"", &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); + njs_type_error(vm, "Cannot redefine property: \"%V\"", &pq.fhq.key); return NJS_ERROR; } @@ -572,18 +572,18 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, njs_function_t *function; njs_object_prop_t *prop, *shared; - shared = pq->lhq.value; + shared = pq->fhq.value; - pq->lhq.replace = 0; - pq->lhq.pool = vm->mem_pool; + pq->fhq.replace = 0; + pq->fhq.pool = vm->mem_pool; - ret = njs_flathsh_unique_insert(&proto->hash, &pq->lhq); + ret = njs_flathsh_unique_insert(&proto->hash, &pq->fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - prop = pq->lhq.value; + prop = pq->fhq.value; prop->enumerable = shared->enumerable; prop->configurable = shared->configurable; prop->writable = shared->writable; @@ -640,7 +640,7 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, return NJS_ERROR; } - ret = njs_atom_to_value(vm, &prop_name, pq->lhq.key_hash); + ret = njs_atom_to_value(vm, &prop_name, pq->fhq.key_hash); if (ret != NJS_OK) { return NJS_ERROR; } @@ -665,7 +665,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, njs_value_t value; njs_object_t *desc_object; njs_function_t *getter, *setter; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; if (!njs_is_object(desc)) { njs_type_error(vm, "property descriptor must be an object"); @@ -685,10 +685,10 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, setter = NJS_PROP_PTR_UNSET; desc_object = njs_object(desc); - lhq.proto = &njs_object_hash_proto; - lhq.key_hash = NJS_ATOM_STRING_get; + fhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_get; - ret = njs_object_property(vm, desc_object, &lhq, &value); + ret = njs_object_property(vm, desc_object, &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; } @@ -703,9 +703,9 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, getter = njs_is_function(&value) ? njs_function(&value) : NULL; } - lhq.key_hash = NJS_ATOM_STRING_set; + fhq.key_hash = NJS_ATOM_STRING_set; - ret = njs_object_property(vm, desc_object, &lhq, &value); + ret = njs_object_property(vm, desc_object, &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; } @@ -720,9 +720,9 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, setter = njs_is_function(&value) ? njs_function(&value) : NULL; } - lhq.key_hash = NJS_ATOM_STRING_value; + fhq.key_hash = NJS_ATOM_STRING_value; - ret = njs_object_property(vm, desc_object, &lhq, &value); + ret = njs_object_property(vm, desc_object, &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; } @@ -732,9 +732,9 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, njs_value_assign(njs_prop_value(prop), &value); } - lhq.key_hash = NJS_ATOM_STRING_writable; + fhq.key_hash = NJS_ATOM_STRING_writable; - ret = njs_object_property(vm, desc_object, &lhq, &value); + ret = njs_object_property(vm, desc_object, &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; } @@ -751,9 +751,9 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, return NULL; } - lhq.key_hash = NJS_ATOM_STRING_enumerable; + fhq.key_hash = NJS_ATOM_STRING_enumerable; - ret = njs_object_property(vm, desc_object, &lhq, &value); + ret = njs_object_property(vm, desc_object, &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; } @@ -763,9 +763,9 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc, *set_enumerable = 1; } - lhq.key_hash = NJS_ATOM_STRING_configurable; + fhq.key_hash = NJS_ATOM_STRING_configurable; - ret = njs_object_property(vm, desc_object, &lhq, &value); + ret = njs_object_property(vm, desc_object, &fhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; } @@ -793,7 +793,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_object_t *desc; njs_object_prop_t *pr, *prop; const njs_value_t *setval; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; njs_property_query_t pq; njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1); @@ -809,7 +809,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, switch (ret) { case NJS_OK: - prop = pq.lhq.value; + prop = pq.fhq.value; switch (prop->type) { case NJS_PROPERTY: @@ -849,20 +849,20 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, return NJS_ERROR; } - lhq.proto = &njs_object_hash_proto; - lhq.replace = 0; - lhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; + fhq.replace = 0; + fhq.pool = vm->mem_pool; if (njs_is_data_descriptor(prop)) { - lhq.key_hash = NJS_ATOM_STRING_value; + fhq.key_hash = NJS_ATOM_STRING_value; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - pr = lhq.value; + pr = fhq.value; pr->type = NJS_PROPERTY; pr->enumerable = 1; @@ -870,17 +870,17 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, pr->writable = 1; pr->u.value = *(njs_prop_value(prop)); - lhq.key_hash = NJS_ATOM_STRING_writable; + fhq.key_hash = NJS_ATOM_STRING_writable; setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - pr = lhq.value; + pr = fhq.value; pr->type = NJS_PROPERTY; pr->enumerable = 1; @@ -890,15 +890,15 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, } else { - lhq.key_hash = NJS_ATOM_STRING_get; + fhq.key_hash = NJS_ATOM_STRING_get; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - pr = lhq.value; + pr = fhq.value; pr->type = NJS_PROPERTY; pr->enumerable = 1; @@ -910,15 +910,15 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_set_function(njs_prop_value(pr), njs_prop_getter(prop)); } - lhq.key_hash = NJS_ATOM_STRING_set; + fhq.key_hash = NJS_ATOM_STRING_set; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - pr = lhq.value; + pr = fhq.value; pr->type = NJS_PROPERTY; pr->enumerable = 1; @@ -931,17 +931,17 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, } } - lhq.key_hash = NJS_ATOM_STRING_enumerable; + fhq.key_hash = NJS_ATOM_STRING_enumerable; setval = (prop->enumerable == 1) ? &njs_value_true : &njs_value_false; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - pr = lhq.value; + pr = fhq.value; pr->type = NJS_PROPERTY; pr->enumerable = 1; @@ -949,17 +949,17 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, pr->writable = 1; pr->u.value = *setval; - lhq.key_hash = NJS_ATOM_STRING_configurable; + fhq.key_hash = NJS_ATOM_STRING_configurable; setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false; - ret = njs_flathsh_unique_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - pr = lhq.value; + pr = fhq.value; pr->type = NJS_PROPERTY; pr->enumerable = 1; @@ -1007,7 +1007,7 @@ njs_object_props_init(njs_vm_t *vm, const njs_object_init_t* init, njs_int_t ret; njs_object_t *object; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; object = njs_object_alloc(vm); if (object == NULL) { @@ -1020,18 +1020,18 @@ njs_object_props_init(njs_vm_t *vm, const njs_object_init_t* init, return NJS_ERROR; } - lhq.key_hash = atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->enumerable = base->enumerable; prop->configurable = base->configurable; diff --git a/src/njs_promise.c b/src/njs_promise.c index 78043af4..a0ca8516 100644 --- a/src/njs_promise.c +++ b/src/njs_promise.c @@ -117,8 +117,8 @@ njs_promise_alloc(njs_vm_t *vm) goto memory_error; } - njs_lvlhsh_init(&promise->object.hash); - njs_lvlhsh_init(&promise->object.shared_hash); + njs_flathsh_init(&promise->object.hash); + njs_flathsh_init(&promise->object.shared_hash); promise->object.type = NJS_PROMISE; promise->object.shared = 0; promise->object.extensible = 1; diff --git a/src/njs_regexp.c b/src/njs_regexp.c index d958e2af..7d09d5c8 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -501,7 +501,7 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern) regexp = njs_mp_alloc(vm->mem_pool, sizeof(njs_regexp_t)); if (njs_fast_path(regexp != NULL)) { - njs_lvlhsh_init(®exp->object.hash); + njs_flathsh_init(®exp->object.hash); regexp->object.shared_hash = vm->shared->regexp_instance_hash; regexp->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_REGEXP); regexp->object.slots = NULL; @@ -1007,7 +1007,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, njs_regexp_t *regexp; njs_object_prop_t *prop; njs_regexp_group_t *group; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; njs_regexp_pattern_t *pattern; regexp = njs_regexp(r); @@ -1039,17 +1039,17 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, /* FIXME: implement fast CreateDataPropertyOrThrow(). */ - lhq.key_hash = NJS_ATOM_STRING_index; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = NJS_ATOM_STRING_index; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&array->object.hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1067,14 +1067,14 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, njs_set_number(&prop->u.value, index); - lhq.key_hash = NJS_ATOM_STRING_input; + fhq.key_hash = NJS_ATOM_STRING_input; - ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&array->object.hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1082,14 +1082,14 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, prop->writable = 1; prop->u.value = regexp->string; - lhq.key_hash = NJS_ATOM_STRING_groups; + fhq.key_hash = NJS_ATOM_STRING_groups; - ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&array->object.hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1116,14 +1116,14 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, goto fail; } - lhq.key_hash = name.atom_id; + fhq.key_hash = name.atom_id; - ret = njs_flathsh_unique_insert(&groups->hash, &lhq); + ret = njs_flathsh_unique_insert(&groups->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1141,7 +1141,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, insert_fail: - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); fail: @@ -1157,14 +1157,14 @@ static void njs_regexp_exec_result_free(njs_vm_t *vm, njs_array_t *result) { njs_flathsh_t *hash; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; hash = &result->object.hash; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - njs_flathsh_destroy(hash, &lhq); + njs_flathsh_destroy(hash, &fhq); njs_array_destroy(vm, result); } diff --git a/src/njs_scope.c b/src/njs_scope.c index 7959849a..cd1176a2 100644 --- a/src/njs_scope.c +++ b/src/njs_scope.c @@ -103,7 +103,7 @@ njs_scope_value_get(njs_vm_t *vm, njs_index_t index) static njs_int_t -njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data) +njs_scope_values_hash_test(njs_flathsh_query_t *fhq, void *data) { njs_str_t string; njs_value_t *value; @@ -119,8 +119,8 @@ njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data) string.length = sizeof(njs_value_t); } - if (lhq->key.length == string.length - && memcmp(lhq->key.start, string.start, string.length) == 0) + if (fhq->key.length == string.length + && memcmp(fhq->key.start, string.start, string.length) == 0) { return NJS_OK; } @@ -129,13 +129,12 @@ njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data) } -static const njs_lvlhsh_proto_t njs_values_hash_proto +static const njs_flathsh_proto_t njs_values_hash_proto njs_aligned(64) = { - NJS_LVLHSH_DEFAULT, njs_scope_values_hash_test, - njs_lvlhsh_alloc, - njs_lvlhsh_free, + njs_flathsh_proto_alloc, + njs_flathsh_proto_free, }; @@ -148,16 +147,16 @@ static njs_value_t * njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, njs_index_t **index) { - u_char *start; - uint32_t value_size, size, length; - njs_int_t ret; - njs_str_t str; - njs_bool_t is_string; - njs_value_t *value; - njs_string_t *string; - njs_lvlhsh_t *values_hash; - njs_object_prop_t *pr; - njs_lvlhsh_query_t lhq; + u_char *start; + uint32_t value_size, size, length; + njs_int_t ret; + njs_str_t str; + njs_bool_t is_string; + njs_value_t *value; + njs_string_t *string; + njs_flathsh_t *values_hash; + njs_object_prop_t *pr; + njs_flathsh_query_t fhq; is_string = 0; value_size = sizeof(njs_value_t); @@ -176,18 +175,18 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, start = (u_char *) src; } - lhq.key_hash = njs_djb_hash(start, size); - lhq.key.length = size; - lhq.key.start = start; - lhq.proto = &njs_values_hash_proto; + fhq.key_hash = njs_djb_hash(start, size); + fhq.key.length = size; + fhq.key.start = start; + fhq.proto = &njs_values_hash_proto; - if (njs_lvlhsh_find(&vm->shared->values_hash, &lhq) == NJS_OK) { - value = ((njs_object_prop_t *) lhq.value)->u.val; + if (njs_flathsh_find(&vm->shared->values_hash, &fhq) == NJS_OK) { + value = ((njs_object_prop_t *) fhq.value)->u.val; *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t)); - } else if (runtime && njs_lvlhsh_find(&vm->values_hash, &lhq) == NJS_OK) { - value = ((njs_object_prop_t *) lhq.value)->u.val; + } else if (runtime && njs_flathsh_find(&vm->values_hash, &fhq) == NJS_OK) { + value = ((njs_object_prop_t *) fhq.value)->u.val; *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t)); @@ -228,17 +227,17 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t)); **index = NJS_INDEX_ERROR; - lhq.replace = 0; - lhq.pool = vm->mem_pool; + fhq.replace = 0; + fhq.pool = vm->mem_pool; values_hash = runtime ? &vm->values_hash : &vm->shared->values_hash; - ret = njs_lvlhsh_insert(values_hash, &lhq); + ret = njs_flathsh_insert(values_hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - pr = lhq.value; + pr = fhq.value; pr->u.val = value; } diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c index d7ca2e83..39440172 100644 --- a/src/njs_typed_array.c +++ b/src/njs_typed_array.c @@ -178,8 +178,8 @@ njs_typed_array_alloc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - njs_lvlhsh_init(&array->object.hash); - njs_lvlhsh_init(&array->object.shared_hash); + njs_flathsh_init(&array->object.hash); + njs_flathsh_init(&array->object.shared_hash); array->object.__proto__ = njs_vm_proto(vm, type); array->object.type = NJS_TYPED_ARRAY; array->object.extensible = 1; @@ -2400,8 +2400,8 @@ njs_data_view_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, view->byte_length = size; view->type = NJS_OBJ_TYPE_DATA_VIEW; - njs_lvlhsh_init(&view->object.hash); - njs_lvlhsh_init(&view->object.shared_hash); + njs_flathsh_init(&view->object.hash); + njs_flathsh_init(&view->object.shared_hash); view->object.__proto__ = njs_vm_proto(vm, view->type); view->object.type = NJS_DATA_VIEW; view->object.extensible = 1; diff --git a/src/njs_value.c b/src/njs_value.c index 78f03821..7959c4ed 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -43,7 +43,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, njs_int_t ret; njs_uint_t tries; njs_value_t method, retval; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; static const uint32_t atoms[] = { NJS_ATOM_STRING_valueOf, @@ -56,7 +56,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, } tries = 0; - lhq.proto = &njs_object_hash_proto; + fhq.proto = &njs_object_hash_proto; for ( ;; ) { ret = NJS_ERROR; @@ -64,9 +64,9 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, if (njs_is_object(value) && tries < 2) { hint ^= tries++; - lhq.key_hash = atoms[hint]; + fhq.key_hash = atoms[hint]; - ret = njs_object_property(vm, njs_object(value), &lhq, &method); + ret = njs_object_property(vm, njs_object(value), &fhq, &method); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -542,7 +542,7 @@ njs_value_is_data_view(const njs_value_t *value) * ES5.1, 8.12.1: [[GetOwnProperty]], [[GetProperty]]. * The njs_property_query() returns values * NJS_OK property has been found in object, - * retval of type njs_object_prop_t * is in pq->lhq.value. + * retval of type njs_object_prop_t * is in pq->fhq.value. * in NJS_PROPERTY_QUERY_GET * prop->type is NJS_PROPERTY or NJS_PROPERTY_HANDLER. * in NJS_PROPERTY_QUERY_SET, NJS_PROPERTY_QUERY_DELETE @@ -550,7 +550,7 @@ njs_value_is_data_view(const njs_value_t *value) * NJS_PROPERTY_TYPED_ARRAY_REF or * NJS_PROPERTY_HANDLER. * NJS_DECLINED property was not found in object, - * if pq->lhq.value != NULL it contains retval of type + * if pq->fhq.value != NULL it contains retval of type * njs_object_prop_t * where prop->type is NJS_WHITEOUT * NJS_ERROR exception has been thrown. */ @@ -598,8 +598,8 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, case NJS_UNDEFINED: case NJS_NULL: default: - njs_atom_string_get(vm, atom_id, &pq->lhq.key); - njs_type_error(vm, "cannot get property \"%V\" of %s", &pq->lhq.key, + njs_atom_string_get(vm, atom_id, &pq->fhq.key); + njs_type_error(vm, "cannot get property \"%V\" of %s", &pq->fhq.key, njs_type_string(value->type)); return NJS_ERROR; } @@ -628,7 +628,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_typed_array_t *tarray; njs_object_value_t *ov; - pq->lhq.proto = &njs_object_hash_proto; + pq->fhq.proto = &njs_object_hash_proto; own = pq->own; pq->own = 1; @@ -705,12 +705,12 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, break; } - pq->lhq.key_hash = atom_id; + pq->fhq.key_hash = atom_id; - ret = njs_flathsh_unique_find(&proto->hash, &pq->lhq); + ret = njs_flathsh_unique_find(&proto->hash, &pq->fhq); if (ret == NJS_OK) { - prop = pq->lhq.value; + prop = pq->fhq.value; if (prop->type != NJS_WHITEOUT) { return ret; @@ -721,7 +721,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, } } else { - ret = njs_flathsh_unique_find(&proto->shared_hash, &pq->lhq); + ret = njs_flathsh_unique_find(&proto->shared_hash, &pq->fhq); if (ret == NJS_OK) { return njs_prop_private_copy(vm, pq, proto); } @@ -803,11 +803,11 @@ njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, } } - pq->lhq.key_hash = atom_id; + pq->fhq.key_hash = atom_id; - ret = njs_flathsh_unique_find(&array->object.hash, &pq->lhq); + ret = njs_flathsh_unique_find(&array->object.hash, &pq->fhq); if (ret == NJS_OK) { - prop = pq->lhq.value; + prop = pq->fhq.value; if (prop->type != NJS_WHITEOUT) { return NJS_OK; @@ -852,7 +852,7 @@ prop: prop->enumerable = 1; prop->configurable = 1; - pq->lhq.value = prop; + pq->fhq.value = prop; return NJS_OK; } @@ -890,7 +890,7 @@ njs_typed_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, prop->enumerable = 1; prop->configurable = 0; - pq->lhq.value = prop; + pq->fhq.value = prop; return NJS_OK; } @@ -922,7 +922,7 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq, prop->enumerable = 1; prop->configurable = 0; - pq->lhq.value = prop; + pq->fhq.value = prop; return NJS_OK; } @@ -958,7 +958,7 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_prop_magic32(prop) = slots->magic32; - pq->lhq.value = prop; + pq->fhq.value = prop; prop->type = NJS_PROPERTY; prop->writable = slots->writable; @@ -968,7 +968,7 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, switch (pq->query) { case NJS_PROPERTY_QUERY_GET: - return slots->prop_handler(vm, prop, pq->lhq.key_hash, value, NULL, + return slots->prop_handler(vm, prop, pq->fhq.key_hash, value, NULL, njs_prop_value(prop)); case NJS_PROPERTY_QUERY_SET: @@ -1053,7 +1053,7 @@ slow_path: switch (ret) { case NJS_OK: - prop = pq.lhq.value; + prop = pq.fhq.value; switch (prop->type) { case NJS_PROPERTY: @@ -1176,14 +1176,14 @@ slow_path: switch (ret) { case NJS_OK: - prop = pq.lhq.value; + prop = pq.fhq.value; if (njs_is_data_descriptor(prop)) { if (!prop->writable) { - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot assign to read-only property \"%V\" of %s", - &pq.lhq.key, njs_type_string(value->type)); + &pq.fhq.key, njs_type_string(value->type)); return NJS_ERROR; } @@ -1193,10 +1193,10 @@ slow_path: value, setval, 1, &retval); } - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot set property \"%V\" of %s which has only a getter", - &pq.lhq.key, njs_type_string(value->type)); + &pq.fhq.key, njs_type_string(value->type)); return NJS_ERROR; } @@ -1257,9 +1257,9 @@ slow_path: goto fail; } - pq.lhq.pool = vm->mem_pool; + pq.fhq.pool = vm->mem_pool; - int rc = njs_flathsh_unique_delete(pq.own_whiteout, &pq.lhq); + int rc = njs_flathsh_unique_delete(pq.own_whiteout, &pq.fhq); if (rc != NJS_OK) { return NJS_ERROR; } @@ -1267,7 +1267,7 @@ slow_path: h = pq.own_whiteout->slot; if (h == NULL) { - h = njs_flathsh_new(&pq.lhq); + h = njs_flathsh_new(&pq.fhq); if (njs_slow_path(h == NULL)) { return NJS_ERROR; } @@ -1275,7 +1275,7 @@ slow_path: pq.own_whiteout->slot = h; } - elt = njs_flathsh_add_elt(pq.own_whiteout, &pq.lhq); + elt = njs_flathsh_add_elt(pq.own_whiteout, &pq.fhq); if (njs_slow_path(elt == NULL)) { return NJS_ERROR; } @@ -1317,17 +1317,17 @@ slow_path: } - pq.lhq.replace = 0; - pq.lhq.key_hash = atom_id; - pq.lhq.pool = vm->mem_pool; + pq.fhq.replace = 0; + pq.fhq.key_hash = atom_id; + pq.fhq.pool = vm->mem_pool; - ret = njs_flathsh_unique_insert(njs_object_hash(value), &pq.lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &pq.fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } - prop = pq.lhq.value; + prop = pq.fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; prop->configurable = 1; @@ -1341,9 +1341,9 @@ found: fail: - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot add property \"%V\", object is not extensible", - &pq.lhq.key); + &pq.fhq.key); return NJS_ERROR; } @@ -1386,13 +1386,13 @@ slow_path: return ret; } - prop = pq.lhq.value; + prop = pq.fhq.value; if (njs_slow_path(!prop->configurable)) { if (thrw) { - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot delete property \"%V\" of %s", - &pq.lhq.key, njs_type_string(value->type)); + &pq.fhq.key, njs_type_string(value->type)); return NJS_ERROR; } diff --git a/src/njs_value.h b/src/njs_value.h index 3fba344b..2ffa04e7 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -350,14 +350,14 @@ struct njs_object_prop_init_s { typedef struct { - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; uint8_t query; /* scratch is used to get the value of an NJS_PROPERTY_HANDLER property. */ njs_object_prop_t scratch; - njs_flathsh_t *own_whiteout; + njs_flathsh_t *own_whiteout; uint8_t temp; uint8_t own; @@ -987,7 +987,7 @@ njs_property_query_init(njs_property_query_t *pq, njs_prop_query_t query, pq->own = own; if (query == NJS_PROPERTY_QUERY_SET) { - pq->lhq.value = NULL; + pq->fhq.value = NULL; pq->own_whiteout = NULL; pq->temp = 0; } diff --git a/src/njs_vm.c b/src/njs_vm.c index e6aac927..19c50e48 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -54,7 +54,7 @@ njs_vm_create(njs_vm_opt_t *options) return NULL; } - njs_lvlhsh_init(&vm->values_hash); + njs_flathsh_init(&vm->values_hash); vm->options = *options; @@ -414,7 +414,7 @@ njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external) nvm->shared_atom_count = vm->atom_id_generator; - njs_lvlhsh_init(&nvm->atom_hash); + njs_flathsh_init(&nvm->atom_hash); nvm->atom_hash_current = &nvm->atom_hash; ret = njs_vm_runtime_init(nvm); @@ -492,9 +492,9 @@ njs_vm_runtime_init(njs_vm_t *vm) return NJS_ERROR; } - njs_lvlhsh_init(&vm->values_hash); + njs_flathsh_init(&vm->values_hash); - njs_lvlhsh_init(&vm->modules_hash); + njs_flathsh_init(&vm->modules_hash); njs_rbtree_init(&vm->global_symbols, njs_symbol_rbtree_cmp); @@ -904,7 +904,7 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, njs_object_t *global; njs_flathsh_t *hash; njs_object_prop_t *obj_prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; ret = njs_atom_string_create(vm, &prop_name, var_name->start, var_name->length); @@ -912,21 +912,21 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, return NJS_ERROR; } - lhq.key_hash = prop_name.atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = prop_name.atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; global = &vm->global_object; hash = shared ? &global->shared_hash : &global->hash; - ret = njs_flathsh_unique_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return ret; } - obj_prop = lhq.value; + obj_prop = fhq.value; obj_prop->type = prop->type; obj_prop->enumerable = prop->enumerable; @@ -1218,7 +1218,7 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) njs_value_t *name, *value; njs_object_t *object; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; object = njs_object_alloc(vm); if (njs_slow_path(object == NULL)) { @@ -1253,18 +1253,18 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) } } - lhq.key_hash = name->atom_id; - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = name->atom_id; + fhq.replace = 0; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(&object->hash, &lhq); + ret = njs_flathsh_unique_insert(&object->hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, NULL); goto done; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -1637,14 +1637,14 @@ njs_vm_string_compare(njs_vm_t *vm, const njs_value_t *v1, void * -njs_lvlhsh_alloc(void *data, size_t size) +njs_flathsh_proto_alloc(void *data, size_t size) { return njs_mp_align(data, NJS_MAX_ALIGNMENT, size); } void -njs_lvlhsh_free(void *data, void *p, size_t size) +njs_flathsh_proto_free(void *data, void *p, size_t size) { njs_mp_free(data, p); } diff --git a/src/njs_vm.h b/src/njs_vm.h index 3e21fdf2..3351dee4 100644 --- a/src/njs_vm.h +++ b/src/njs_vm.h @@ -128,16 +128,16 @@ struct njs_vm_s { njs_native_frame_t *top_frame; njs_frame_t *active_frame; - njs_lvlhsh_t atom_hash_shared; - njs_lvlhsh_t atom_hash; - njs_lvlhsh_t *atom_hash_current; + njs_flathsh_t atom_hash_shared; + njs_flathsh_t atom_hash; + njs_flathsh_t *atom_hash_current; uint32_t shared_atom_count; uint32_t atom_id_generator; - njs_lvlhsh_t values_hash; + njs_flathsh_t values_hash; njs_arr_t *modules; - njs_lvlhsh_t modules_hash; + njs_flathsh_t modules_hash; uint32_t event_id; njs_queue_t jobs; @@ -207,7 +207,7 @@ typedef struct { struct njs_vm_shared_s { - njs_lvlhsh_t values_hash; + njs_flathsh_t values_hash; njs_flathsh_t array_instance_hash; njs_flathsh_t string_instance_hash; @@ -218,7 +218,7 @@ struct njs_vm_shared_s { njs_flathsh_t regexp_instance_hash; size_t module_items; - njs_lvlhsh_t modules_hash; + njs_flathsh_t modules_hash; njs_flathsh_t env_hash; @@ -253,8 +253,8 @@ njs_int_t njs_builtin_match_native_function(njs_vm_t *vm, void njs_disassemble(u_char *start, u_char *end, njs_int_t count, njs_arr_t *lines); -void *njs_lvlhsh_alloc(void *data, size_t size); -void njs_lvlhsh_free(void *data, void *p, size_t size); +void *njs_flathsh_proto_alloc(void *data, size_t size); +void njs_flathsh_proto_free(void *data, void *p, size_t size); extern const njs_str_t njs_entry_empty; diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 727dc6d0..70da4630 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -2064,7 +2064,7 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, njs_array_t *array; njs_value_t *val, name; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; switch (value->type) { case NJS_ARRAY: @@ -2123,18 +2123,18 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, } } - lhq.key_hash = name.atom_id; - lhq.replace = 1; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; + fhq.key_hash = name.atom_id; + fhq.replace = 1; + fhq.pool = vm->mem_pool; + fhq.proto = &njs_object_hash_proto; - ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); + njs_internal_error(vm, "flathsh insert/replace failed"); return NJS_ERROR; } - prop = lhq.value; + prop = fhq.value; prop->type = NJS_PROPERTY; prop->enumerable = 1; @@ -2164,26 +2164,26 @@ njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused, njs_value_t retval; njs_jump_off_t ret; njs_object_prop_t *prop; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key_hash = NJS_ATOM_STRING___proto__; - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; + fhq.key_hash = NJS_ATOM_STRING___proto__; + fhq.proto = &njs_object_hash_proto; + fhq.pool = vm->mem_pool; obj = njs_object(value); - ret = njs_flathsh_unique_find(&obj->__proto__->shared_hash, &lhq); + ret = njs_flathsh_unique_find(&obj->__proto__->shared_hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { goto fail; } - prop = lhq.value; + prop = fhq.value; if (prop->type != NJS_PROPERTY_HANDLER) { goto fail; } - ret = njs_prop_handler(prop)(vm, prop, lhq.key_hash, value, init, &retval); + ret = njs_prop_handler(prop)(vm, prop, fhq.key_hash, value, init, &retval); if (njs_slow_path(ret != NJS_OK)) { goto fail; } diff --git a/src/test/flathsh_unit_test.c b/src/test/flathsh_unit_test.c new file mode 100644 index 00000000..b2a76f30 --- /dev/null +++ b/src/test/flathsh_unit_test.c @@ -0,0 +1,205 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + + +#include + + +static njs_int_t +flathsh_unit_test_key_test(njs_flathsh_query_t *fhq, void *data) +{ + if (*(uintptr_t *) fhq->key.start == *(uintptr_t *) data) { + return NJS_OK; + } + + return NJS_DECLINED; +} + + +static void * +flathsh_unit_test_pool_alloc(void *pool, size_t size) +{ + return njs_mp_align(pool, NJS_MAX_ALIGNMENT, size); +} + + +static void +flathsh_unit_test_pool_free(void *pool, void *p, size_t size) +{ + njs_mp_free(pool, p); +} + + +static const njs_flathsh_proto_t flathsh_proto njs_aligned(64) = { + flathsh_unit_test_key_test, + flathsh_unit_test_pool_alloc, + flathsh_unit_test_pool_free, +}; + + +static njs_int_t +flathsh_unit_test_add(njs_flathsh_t *lh, const njs_flathsh_proto_t *proto, + void *pool, uintptr_t key) +{ + njs_flathsh_query_t fhq; + + fhq.key_hash = key; + fhq.replace = 0; + fhq.key.length = sizeof(uintptr_t); + fhq.key.start = (u_char *) &key; + fhq.proto = proto; + fhq.pool = pool; + + switch (njs_flathsh_insert(lh, &fhq)) { + + case NJS_OK: + ((njs_flathsh_elt_t *) fhq.value)->value[0] = (void *) key; + return NJS_OK; + + case NJS_DECLINED: + njs_printf("flathsh unit test failed: key %08Xl is already in hash\n", + (long) key); + /* Fall through. */ + + default: + return NJS_ERROR; + } +} + + +static njs_int_t +flathsh_unit_test_get(njs_flathsh_t *lh, const njs_flathsh_proto_t *proto, + uintptr_t key) +{ + njs_flathsh_query_t fhq; + + fhq.key_hash = key; + fhq.key.length = sizeof(uintptr_t); + fhq.key.start = (u_char *) &key; + fhq.proto = proto; + + if (njs_flathsh_find(lh, &fhq) == NJS_OK) { + + if (key == (uintptr_t) ((njs_flathsh_elt_t *) fhq.value)->value[0]) { + return NJS_OK; + } + } + + njs_printf("flathsh unit test failed: key %08Xl not found in hash\n", + (long) key); + + return NJS_ERROR; +} + + +static njs_int_t +flathsh_unit_test_delete(njs_flathsh_t *lh, const njs_flathsh_proto_t *proto, + void *pool, uintptr_t key) +{ + njs_int_t ret; + njs_flathsh_query_t fhq; + + fhq.key_hash = key; + fhq.key.length = sizeof(uintptr_t); + fhq.key.start = (u_char *) &key; + fhq.proto = proto; + fhq.pool = pool; + + ret = njs_flathsh_delete(lh, &fhq); + + if (ret != NJS_OK) { + njs_printf("flathsh unit test failed: key %08lX not found in hash\n", + (long) key); + } + + return ret; +} + + +static njs_int_t +flathsh_unit_test(njs_uint_t n) +{ + njs_mp_t *pool; + uint32_t key; + njs_uint_t i; + njs_flathsh_t lh; + njs_flathsh_each_t lhe; + + const size_t min_chunk_size = 32; + const size_t page_size = 1024; + const size_t page_alignment = 128; + const size_t cluster_size = 4096; + + pool = njs_mp_create(cluster_size, page_alignment, page_size, + min_chunk_size); + if (pool == NULL) { + return NJS_ERROR; + } + + njs_printf("flathsh unit test started: %l items\n", (long) n); + + njs_memzero(&lh, sizeof(njs_flathsh_t)); + + key = 0; + for (i = 0; i < n; i++) { + key = njs_murmur_hash2(&key, sizeof(uint32_t)); + + if (flathsh_unit_test_add(&lh, &flathsh_proto, pool, key) != NJS_OK) { + njs_printf("flathsh add unit test failed at %l\n", (long) i); + return NJS_ERROR; + } + } + + key = 0; + for (i = 0; i < n; i++) { + key = njs_murmur_hash2(&key, sizeof(uint32_t)); + + if (flathsh_unit_test_get(&lh, &flathsh_proto, key) != NJS_OK) { + return NJS_ERROR; + } + } + + njs_flathsh_each_init(&lhe, &flathsh_proto); + + for (i = 0; i < n + 1; i++) { + if (njs_flathsh_each(&lh, &lhe) == NULL) { + break; + } + } + + if (i != n) { + njs_printf("flathsh each unit test failed at %l of %l\n", + (long) i, (long) n); + return NJS_ERROR; + } + + key = 0; + for (i = 0; i < n; i++) { + key = njs_murmur_hash2(&key, sizeof(uint32_t)); + + if (flathsh_unit_test_delete(&lh, &flathsh_proto, pool, key) != NJS_OK) { + return NJS_ERROR; + } + } + + if (!njs_mp_is_empty(pool)) { + njs_printf("mem cache pool is not empty\n"); + return NJS_ERROR; + } + + njs_mp_destroy(pool); + + njs_printf("flathsh unit test passed\n"); + + return NJS_OK; +} + + +int +main(void) +{ + return flathsh_unit_test(1000 * 1000); +} diff --git a/src/test/lvlhsh_unit_test.c b/src/test/lvlhsh_unit_test.c deleted file mode 100644 index 0e334c5d..00000000 --- a/src/test/lvlhsh_unit_test.c +++ /dev/null @@ -1,206 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - - -#include - - -static njs_int_t -lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) -{ - if (*(uintptr_t *) lhq->key.start == *(uintptr_t *) data) { - return NJS_OK; - } - - return NJS_DECLINED; -} - - -static void * -lvlhsh_unit_test_pool_alloc(void *pool, size_t size) -{ - return njs_mp_align(pool, NJS_MAX_ALIGNMENT, size); -} - - -static void -lvlhsh_unit_test_pool_free(void *pool, void *p, size_t size) -{ - njs_mp_free(pool, p); -} - - -static const njs_lvlhsh_proto_t lvlhsh_proto njs_aligned(64) = { - NJS_LVLHSH_LARGE_SLAB, - lvlhsh_unit_test_key_test, - lvlhsh_unit_test_pool_alloc, - lvlhsh_unit_test_pool_free, -}; - - -static njs_int_t -lvlhsh_unit_test_add(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto, - void *pool, uintptr_t key) -{ - njs_lvlhsh_query_t lhq; - - lhq.key_hash = key; - lhq.replace = 0; - lhq.key.length = sizeof(uintptr_t); - lhq.key.start = (u_char *) &key; - lhq.proto = proto; - lhq.pool = pool; - - switch (njs_lvlhsh_insert(lh, &lhq)) { - - case NJS_OK: - ((njs_flathsh_elt_t *) lhq.value)->value[0] = (void *) key; - return NJS_OK; - - case NJS_DECLINED: - njs_printf("lvlhsh unit test failed: key %08Xl is already in hash\n", - (long) key); - /* Fall through. */ - - default: - return NJS_ERROR; - } -} - - -static njs_int_t -lvlhsh_unit_test_get(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto, - uintptr_t key) -{ - njs_lvlhsh_query_t lhq; - - lhq.key_hash = key; - lhq.key.length = sizeof(uintptr_t); - lhq.key.start = (u_char *) &key; - lhq.proto = proto; - - if (njs_lvlhsh_find(lh, &lhq) == NJS_OK) { - - if (key == (uintptr_t) ((njs_flathsh_elt_t *) lhq.value)->value[0]) { - return NJS_OK; - } - } - - njs_printf("lvlhsh unit test failed: key %08Xl not found in hash\n", - (long) key); - - return NJS_ERROR; -} - - -static njs_int_t -lvlhsh_unit_test_delete(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto, - void *pool, uintptr_t key) -{ - njs_int_t ret; - njs_lvlhsh_query_t lhq; - - lhq.key_hash = key; - lhq.key.length = sizeof(uintptr_t); - lhq.key.start = (u_char *) &key; - lhq.proto = proto; - lhq.pool = pool; - - ret = njs_lvlhsh_delete(lh, &lhq); - - if (ret != NJS_OK) { - njs_printf("lvlhsh unit test failed: key %08lX not found in hash\n", - (long) key); - } - - return ret; -} - - -static njs_int_t -lvlhsh_unit_test(njs_uint_t n) -{ - njs_mp_t *pool; - uint32_t key; - njs_uint_t i; - njs_lvlhsh_t lh; - njs_lvlhsh_each_t lhe; - - const size_t min_chunk_size = 32; - const size_t page_size = 1024; - const size_t page_alignment = 128; - const size_t cluster_size = 4096; - - pool = njs_mp_create(cluster_size, page_alignment, page_size, - min_chunk_size); - if (pool == NULL) { - return NJS_ERROR; - } - - njs_printf("lvlhsh unit test started: %l items\n", (long) n); - - njs_memzero(&lh, sizeof(njs_lvlhsh_t)); - - key = 0; - for (i = 0; i < n; i++) { - key = njs_murmur_hash2(&key, sizeof(uint32_t)); - - if (lvlhsh_unit_test_add(&lh, &lvlhsh_proto, pool, key) != NJS_OK) { - njs_printf("lvlhsh add unit test failed at %l\n", (long) i); - return NJS_ERROR; - } - } - - key = 0; - for (i = 0; i < n; i++) { - key = njs_murmur_hash2(&key, sizeof(uint32_t)); - - if (lvlhsh_unit_test_get(&lh, &lvlhsh_proto, key) != NJS_OK) { - return NJS_ERROR; - } - } - - njs_lvlhsh_each_init(&lhe, &lvlhsh_proto); - - for (i = 0; i < n + 1; i++) { - if (njs_lvlhsh_each(&lh, &lhe) == NULL) { - break; - } - } - - if (i != n) { - njs_printf("lvlhsh each unit test failed at %l of %l\n", - (long) i, (long) n); - return NJS_ERROR; - } - - key = 0; - for (i = 0; i < n; i++) { - key = njs_murmur_hash2(&key, sizeof(uint32_t)); - - if (lvlhsh_unit_test_delete(&lh, &lvlhsh_proto, pool, key) != NJS_OK) { - return NJS_ERROR; - } - } - - if (!njs_mp_is_empty(pool)) { - njs_printf("mem cache pool is not empty\n"); - return NJS_ERROR; - } - - njs_mp_destroy(pool); - - njs_printf("lvlhsh unit test passed\n"); - - return NJS_OK; -} - - -int -main(void) -{ - return lvlhsh_unit_test(1000 * 1000); -} diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c index d3d3f1c1..d34ec1f2 100644 --- a/src/test/njs_externals_test.c +++ b/src/test/njs_externals_test.c @@ -13,7 +13,7 @@ typedef struct { - njs_lvlhsh_t hash; + njs_flathsh_t hash; uint32_t a; uint32_t d; @@ -56,7 +56,7 @@ njs_module_t njs_unit_test_external_module = { static njs_int_t -lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) +flathsh_unit_test_key_test(njs_flathsh_query_t *fhq, void *data) { njs_str_t name; njs_unit_test_prop_t *prop; @@ -64,11 +64,11 @@ lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) prop = *(njs_unit_test_prop_t **) data; name = prop->name; - if (name.length != lhq->key.length) { + if (name.length != fhq->key.length) { return NJS_DECLINED; } - if (memcmp(name.start, lhq->key.start, lhq->key.length) == 0) { + if (memcmp(name.start, fhq->key.start, fhq->key.length) == 0) { return NJS_OK; } @@ -77,29 +77,28 @@ lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) static void * -lvlhsh_unit_test_pool_alloc(void *pool, size_t size) +flathsh_unit_test_pool_alloc(void *pool, size_t size) { return njs_mp_align(pool, NJS_MAX_ALIGNMENT, size); } static void -lvlhsh_unit_test_pool_free(void *pool, void *p, size_t size) +flathsh_unit_test_pool_free(void *pool, void *p, size_t size) { njs_mp_free(pool, p); } -static const njs_lvlhsh_proto_t lvlhsh_proto njs_aligned(64) = { - NJS_LVLHSH_LARGE_SLAB, - lvlhsh_unit_test_key_test, - lvlhsh_unit_test_pool_alloc, - lvlhsh_unit_test_pool_free, +static const njs_flathsh_proto_t flathsh_proto njs_aligned(64) = { + flathsh_unit_test_key_test, + flathsh_unit_test_pool_alloc, + flathsh_unit_test_pool_free, }; static njs_unit_test_prop_t * -lvlhsh_unit_test_alloc(njs_mp_t *pool, const njs_str_t *name, +flathsh_unit_test_alloc(njs_mp_t *pool, const njs_str_t *name, const njs_value_t *value) { njs_unit_test_prop_t *prop; @@ -120,22 +119,21 @@ lvlhsh_unit_test_alloc(njs_mp_t *pool, const njs_str_t *name, static njs_int_t -lvlhsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r, +flathsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r, njs_unit_test_prop_t *prop) { - njs_lvlhsh_query_t lhq; + njs_flathsh_query_t fhq; - lhq.key = prop->name; - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); + fhq.key = prop->name; + fhq.key_hash = njs_djb_hash(fhq.key.start, fhq.key.length); - lhq.replace = 1; - lhq.proto = &lvlhsh_proto; - lhq.pool = pool; - - switch (njs_lvlhsh_insert(&r->hash, &lhq)) { + fhq.replace = 1; + fhq.proto = &flathsh_proto; + fhq.pool = pool; + switch (njs_flathsh_insert(&r->hash, &fhq)) { case NJS_OK: - ((njs_flathsh_elt_t *) lhq.value)->value[0] = (void *) prop; + ((njs_flathsh_elt_t *) fhq.value)->value[0] = (void *) prop; return NJS_OK; case NJS_DECLINED: @@ -237,7 +235,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_int_t ret; - njs_lvlhsh_query_t lhq; + njs_flathsh_query_t fhq; njs_unit_test_req_t *r; njs_unit_test_prop_t *prop; @@ -247,7 +245,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, return NJS_DECLINED; } - ret = njs_vm_prop_name(vm, atom_id, &lhq.key); + ret = njs_vm_prop_name(vm, atom_id, &fhq.key); if (ret != NJS_OK) { if (setval == NULL && retval != NULL) { /* Get. */ @@ -260,7 +258,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, if (setval != NULL || retval == NULL) { /* Set or Delete. */ - if (lhq.key.length == 5 && memcmp(lhq.key.start, "error", 5) == 0) { + if (fhq.key.length == 5 && memcmp(fhq.key.start, "error", 5) == 0) { njs_vm_error(vm, "cannot %s \"error\" prop", retval != NULL ? "set" : "delete"); return NJS_ERROR; @@ -269,15 +267,15 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, if (setval != NULL) { /* Set. */ - prop = lvlhsh_unit_test_alloc(njs_vm_memory_pool(vm), &lhq.key, setval); + prop = flathsh_unit_test_alloc(njs_vm_memory_pool(vm), &fhq.key, setval); if (prop == NULL) { njs_vm_memory_error(vm); return NJS_ERROR; } - ret = lvlhsh_unit_test_add(njs_vm_memory_pool(vm), r, prop); + ret = flathsh_unit_test_add(njs_vm_memory_pool(vm), r, prop); if (ret != NJS_OK) { - njs_vm_error(vm, "lvlhsh_unit_test_add() failed"); + njs_vm_error(vm, "flathsh_unit_test_add() failed"); return NJS_ERROR; } @@ -286,13 +284,13 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, /* Get or Delete. */ - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); - lhq.proto = &lvlhsh_proto; + fhq.key_hash = njs_djb_hash(fhq.key.start, fhq.key.length); + fhq.proto = &flathsh_proto; - ret = njs_lvlhsh_find(&r->hash, &lhq); + ret = njs_flathsh_find(&r->hash, &fhq); if (ret == NJS_OK) { - prop = ((njs_flathsh_elt_t *) lhq.value)->value[0]; + prop = ((njs_flathsh_elt_t *) fhq.value)->value[0]; if (retval == NULL) { njs_value_invalid_set(njs_value_arg(&prop->value)); @@ -1130,19 +1128,19 @@ njs_externals_init_internal(njs_vm_t *vm, njs_unit_test_req_init_t *init, return NJS_ERROR; } - prop = lvlhsh_unit_test_alloc(njs_vm_memory_pool(vm), - &init[i].props[j].name, - njs_value_arg(&value)); + prop = flathsh_unit_test_alloc(njs_vm_memory_pool(vm), + &init[i].props[j].name, + njs_value_arg(&value)); if (njs_slow_path(prop == NULL)) { - njs_printf("lvlhsh_unit_test_alloc() failed\n"); + njs_printf("flathsh_unit_test_alloc() failed\n"); return NJS_ERROR; } - ret = lvlhsh_unit_test_add(njs_vm_memory_pool(vm), &requests[i], - prop); + ret = flathsh_unit_test_add(njs_vm_memory_pool(vm), &requests[i], + prop); if (njs_slow_path(ret != NJS_OK)) { - njs_printf("lvlhsh_unit_test_add() failed\n"); + njs_printf("flathsh_unit_test_add() failed\n"); return NJS_ERROR; } } From noreply at nginx.com Thu Jul 24 17:28:51 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 24 Jul 2025 17:28:51 +0000 (UTC) Subject: [nginx] HTTP/3: fixed potential type overflow in string literal parser. Message-ID: <20250724172851.7794C3F633@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/3739fe94d1c3c844708b219776f1921bff16b56f branches: master commit: 3739fe94d1c3c844708b219776f1921bff16b56f user: Sergey Kandaurov date: Thu, 5 Sep 2024 19:35:43 +0400 description: HTTP/3: fixed potential type overflow in string literal parser. This might happen for Huffman encoded string literals as the result of length expansion. Notably, the maximum length of string literals is already limited with the "large_client_header_buffers" directive, so this was only possible with nonsensically large configured limits. --- src/http/v3/ngx_http_v3_parse.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c index 436765c8a..bcbf0dbe1 100644 --- a/src/http/v3/ngx_http_v3_parse.c +++ b/src/http/v3/ngx_http_v3_parse.c @@ -623,6 +623,12 @@ ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st, } if (st->huffman) { + if (n > NGX_MAX_INT_T_VALUE / 8) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent too large field line"); + return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD; + } + n = n * 8 / 5; st->huffstate = 0; } From noreply at nginx.com Thu Jul 24 17:28:52 2025 From: noreply at nginx.com (noreply at nginx.com) Date: Thu, 24 Jul 2025 17:28:52 +0000 (UTC) Subject: [nginx] HTTP/3: fixed handling of :authority and Host with port. Message-ID: <20250724172852.5064D3F633@pubserv1.nginx> details: https://github.com/nginx/nginx/commit/4da771108282cd233ddc37f83ba8bd01981beeb7 branches: master commit: 4da771108282cd233ddc37f83ba8bd01981beeb7 user: Roman Arutyunyan date: Thu, 26 Jun 2025 20:19:59 +0400 description: HTTP/3: fixed handling of :authority and Host with port. RFC 9114, Section 4.3.1. specifies a restriction for :authority and Host coexistence in an HTTP/3 request: : If both fields are present, they MUST contain the same value. Previously, this restriction was correctly enforced only for portless values. When Host contained a port, the request failed as if :authority and Host were different, regardless of :authority presence. This happens because the value of r->headers_in.server used for :authority has port stripped. The fix is to use r->host_start / r->host_end instead. --- src/http/v3/ngx_http_v3_request.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c index e41ad50a8..32b11b598 100644 --- a/src/http/v3/ngx_http_v3_request.c +++ b/src/http/v3/ngx_http_v3_request.c @@ -1003,6 +1003,7 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r) { ssize_t n; ngx_buf_t *b; + ngx_str_t host; ngx_connection_t *c; ngx_http_v3_session_t *h3c; ngx_http_v3_srv_conf_t *h3scf; @@ -1034,11 +1035,13 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r) goto failed; } - if (r->headers_in.host) { - if (r->headers_in.host->value.len != r->headers_in.server.len - || ngx_memcmp(r->headers_in.host->value.data, - r->headers_in.server.data, - r->headers_in.server.len) + if (r->headers_in.host && r->host_end) { + + host.len = r->host_end - r->host_start; + host.data = r->host_start; + + if (r->headers_in.host->value.len != host.len + || ngx_memcmp(r->headers_in.host->value.data, host.data, host.len) != 0) { ngx_log_error(NGX_LOG_INFO, c->log, 0,