From michael.wuertinger at egym.com Mon Jul 1 09:24:28 2019 From: michael.wuertinger at egym.com (=?UTF-8?Q?Michael_W=C3=BCrtinger?=) Date: Mon, 1 Jul 2019 11:24:28 +0200 Subject: HTTP/2: allow unlimited number of requests in connection In-Reply-To: <20190629100516.GY1877@mdounin.ru> References: <20190629100516.GY1877@mdounin.ru> Message-ID: Hi Maxim, thanks a lot for your reply. Could you please elaborate a little bit which memory resources need to be freed periodically? How much memory can be held by a connection? What's the worst case scenario? We are currently running it in production with http2_max_requests set to a value so high that the connection practically lives forever and so far we cannot spot any problems but maybe we're missing something? Regards, Michael On Sat, Jun 29, 2019 at 12:05 PM Maxim Dounin wrote: > > Hello! > > On Wed, Jun 26, 2019 at 07:41:27PM +0200, Michael W?rtinger wrote: > > > Hello, > > > > we're running a gRPC service behind an NGINX load balancer and we > > often see that the connection gets shut down with a GOAWAY message. > > Since our request deadlines are quite small and it takes some time to > > re-establish a connection this often leads to many failed requests. > > > > After analyzing the situation we realized that it is caused by the > > "http2_max_requests" option which defaults to 1000. After setting this > > to a ridiculously high value our problems disappeared. > > > > While there probably are use cases where limiting the life time of a > > connection makes sense we were wondering why it is not possible to > > disable this functionality and let a connection just live as long as > > possible? > > > > The following patch allows to do just that by setting http2_max_requests to 0. > > No, thank you. Closing connections periodically is required to > free associated memory, and shouldn't be disabled. > > -- > Maxim Dounin > http://mdounin.ru/ > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- --- Michael W?rtinger Technology Fellow eGym GmbH T +49 (89) 9213105 - 11 | michael.wuertinger at egym.com egym.com/business | qualitrain.net Einsteinstra?e 172, 81677 M?nchen Gesch?ftsf?hrer: Martin Fichter, Patrick Meininger, Philipp Roesch-Schlanderer, Florian Sauter Gerichtsstand M?nchen | Amtsgericht M?nchen HRB 186394 | USt.-Id. DE275313632 -- From xeioex at nginx.com Mon Jul 1 16:25:34 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 01 Jul 2019 16:25:34 +0000 Subject: [njs] Fixed using of uninitialized value in String.prototype.padStart(). Message-ID: details: https://hg.nginx.org/njs/rev/e123c7406264 branches: changeset: 1021:e123c7406264 user: Dmitry Volyntsev date: Mon Jul 01 19:24:10 2019 +0300 description: Fixed using of uninitialized value in String.prototype.padStart(). diffstat: njs/njs_string.c | 49 +++++++++++++++++++++++++------------------------ 1 files changed, 25 insertions(+), 24 deletions(-) diffs (75 lines): diff -r 40f26bb516a6 -r e123c7406264 njs/njs_string.c --- a/njs/njs_string.c Thu Jun 27 18:55:34 2019 +0300 +++ b/njs/njs_string.c Mon Jul 01 19:24:10 2019 +0300 @@ -2463,8 +2463,11 @@ njs_string_prototype_pad(njs_vm_t *vm, n int32_t length, new_length; uint32_t n, pad_length; const u_char *end; + const njs_value_t *pad; njs_string_prop_t string, pad_string; + static const njs_value_t string_space = njs_string(" "); + length = njs_string_prop(&string, &args[0]); new_length = nargs > 1 ? args[1].data.u.number : 0; @@ -2484,26 +2487,27 @@ njs_string_prototype_pad(njs_vm_t *vm, n n = 0; trunc = 0; - if (nargs > 2) { - pad_length = njs_string_prop(&pad_string, &args[2]); - - if (pad_string.size == 0) { - vm->retval = args[0]; - return NJS_OK; - } - - if (pad_string.size > 1) { - n = padding / pad_length; - trunc = padding % pad_length; - - if (pad_string.size != (size_t) pad_length) { - /* UTF-8 string. */ - end = pad_string.start + pad_string.size; - end = njs_string_offset(pad_string.start, end, trunc); - - trunc = end - pad_string.start; - padding = pad_string.size * n + trunc; - } + pad = njs_arg(args, nargs, 2); + pad = njs_is_undefined(pad) ? &string_space : pad; + + pad_length = njs_string_prop(&pad_string, pad); + + if (pad_string.size == 0) { + vm->retval = args[0]; + return NJS_OK; + } + + if (pad_string.size > 1) { + n = padding / pad_length; + trunc = padding % pad_length; + + if (pad_string.size != (size_t) pad_length) { + /* UTF-8 string. */ + end = pad_string.start + pad_string.size; + end = njs_string_offset(pad_string.start, end, trunc); + + trunc = end - pad_string.start; + padding = pad_string.size * n + trunc; } } @@ -2525,10 +2529,7 @@ njs_string_prototype_pad(njs_vm_t *vm, n memcpy(start, string.start, string.size); - if (nargs == 2) { - nxt_memset(p, ' ', padding); - - } else if (pad_string.size == 1) { + if (pad_string.size == 1) { nxt_memset(p, pad_string.start[0], padding); } else { From alexander.borisov at nginx.com Mon Jul 1 18:28:13 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Mon, 01 Jul 2019 18:28:13 +0000 Subject: [njs] Added support for functions in regexp with global match. Message-ID: details: https://hg.nginx.org/njs/rev/f66b593ef3da branches: changeset: 1022:f66b593ef3da user: Alexander Borisov date: Mon Jul 01 19:57:34 2019 +0300 description: Added support for functions in regexp with global match. This closes #183 issue on GitHub. diffstat: njs/njs_string.c | 36 ++++++++++++++++++++++++++++-------- njs/test/njs_unit_test.c | 6 ++++++ 2 files changed, 34 insertions(+), 8 deletions(-) diffs (104 lines): diff -r e123c7406264 -r f66b593ef3da njs/njs_string.c --- a/njs/njs_string.c Mon Jul 01 19:24:10 2019 +0300 +++ b/njs/njs_string.c Mon Jul 01 19:57:34 2019 +0300 @@ -49,6 +49,8 @@ typedef struct { nxt_regex_match_data_t *match_data; + nxt_bool_t empty; + njs_utf8_t utf8:8; njs_regexp_utf8_t type:8; } njs_string_replace_t; @@ -3143,6 +3145,11 @@ njs_string_replace_regexp(njs_vm_t *vm, r->part[2].start = start + 1; } + if (r->function != NULL) { + return njs_string_replace_regexp_function(vm, args, r, + captures, ret); + } + r->part[0] = replace; } else { @@ -3194,11 +3201,12 @@ static njs_ret_t njs_string_replace_regexp_function(njs_vm_t *vm, njs_value_t *args, njs_string_replace_t *r, int *captures, nxt_uint_t n) { - u_char *start; - size_t size, length; - njs_ret_t ret; - nxt_uint_t i, k; - njs_value_t *arguments; + u_char *start; + size_t size, length; + njs_ret_t ret; + nxt_uint_t i, k; + njs_value_t *arguments; + njs_string_prop_t string; r->u.cont.function = njs_string_replace_regexp_continuation; njs_set_invalid(&r->retval); @@ -3225,14 +3233,18 @@ njs_string_replace_regexp_function(njs_v } } + r->empty = (captures[0] == captures[1]); + /* The offset of the matched substring. */ njs_value_number_set(&arguments[n + 1], captures[0]); /* The whole string being examined. */ length = njs_string_calc_length(r->utf8, r->part[0].start, r->part[0].size); - ret = njs_string_new(vm, &arguments[n + 2], r->part[0].start, - r->part[0].size, length); + (void) njs_string_prop(&string, &args[0]); + + ret = njs_string_new(vm, &arguments[n + 2], string.start, string.size, + length); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; @@ -3249,15 +3261,23 @@ static njs_ret_t njs_string_replace_regexp_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { + njs_string_prop_t string; njs_string_replace_t *r; r = njs_vm_continuation(vm); + (void) njs_string_prop(&string, &args[0]); + if (njs_is_string(&r->retval)) { - njs_string_replacement_copy(&r->part[1], &r->retval); + njs_string_replacement_copy(&r->part[r->empty ? 0 : 1], &r->retval); if (args[1].data.u.regexp->pattern->global) { r->part += 2; + + if (r->part[0].start > (string.start + string.size)) { + return njs_string_replace_regexp_join(vm, r); + } + return njs_string_replace_regexp(vm, args, r); } diff -r e123c7406264 -r f66b593ef3da njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Jul 01 19:24:10 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon Jul 01 19:57:34 2019 +0300 @@ -5560,6 +5560,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("'12345'.replace(3, () => ({toString: () => 'aaaa'}))"), nxt_string("12aaaa45") }, + { nxt_string("'abc'.replace(/(z*)/g, function v0() {return '124'})"), + nxt_string("124a124b124c124") }, + + { nxt_string("'abc'.replace(/(a*)/g, function v0() {return '124'})"), + nxt_string("124124b124c124") }, + { nxt_string("/]/"), nxt_string("/\\]/") }, From eran.kornblau at kaltura.com Mon Jul 1 19:23:11 2019 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Mon, 1 Jul 2019 19:23:11 +0000 Subject: Question about ngx_handle_write_event Message-ID: Hi all, Something is unclear to me regarding the use of this function, the development guide says - "the functions ngx_handle_read_event(rev, flags) and ngx_handle_write_event(wev, lowat) must be called after handling an I/O socket notification or calling any I/O functions on that socket" If my module finished sending all the data it had, and is now waiting for more data to arrive (on some other socket) does it still have to call ngx_handle_write_event? I'm currently calling this function unconditionally at the end of the write handler, and I'm seeing the handler being called even when it has nothing to do, so thought maybe I'm doing something wrong... Thank you, Eran -------------- next part -------------- An HTML attachment was scrubbed... URL: From careygister at outlook.com Mon Jul 1 22:07:41 2019 From: careygister at outlook.com (Carey Gister) Date: Mon, 1 Jul 2019 22:07:41 +0000 Subject: Bug in ngx_http_slice_filter_module ngx_http_slice_parse_content_range function In-Reply-To: <20190629103251.GZ1877@mdounin.ru> References: , <20190629103251.GZ1877@mdounin.ru> Message-ID: Hi Maxim, Thank you for your reply. My use case is as follows: After the slice header filter calls ngx_http_next_header_filter the contents of the request headers_out fields will be modified if an If-Range header is valid. The production version of the slice header filter already relies on the modified headers_out fields set by the range filter. My extension needs to know the bounds of the new range IF the If-Range header is valid. So I parse the new content_range value using the ngx_http_slice_parse_content_range function to return the stored values. If this is incorrect, then please tell me how I can know if the If-Range header is valid, preferably without duplicating the code in the range filter, and if it is valid, what the correct range values will be. Parenthetically, the behavior I observe is that the computer headers_out.content_range value IS null terminated EXCEPT when the request is read from a disk cache. In this case, the string IS NOT null terminated and instead, has an 'L' (ASCII decimal value 77) after the length of bytes indicated in the ngx_str_t. The existing ngx_http_slice_parse_content_range function fails with an NGX_ERROR return when the string IS NOT null terminated. Carey Gister ________________________________ From: nginx-devel on behalf of Maxim Dounin Sent: Saturday, June 29, 2019 03:32 To: nginx-devel at nginx.org Subject: Re: Bug in ngx_http_slice_filter_module ngx_http_slice_parse_content_range function Hello! On Thu, Jun 27, 2019 at 02:01:27AM +0000, Carey Gister wrote: > The ngx_http_slice_parse_content_range function assumes that the > parsed buffer is null terminated. Since the buffer is an > ngx_str_t, that assumption is false. If, by chance, the buffer > is null terminated it is simply a matter of luck, and not > design. In many cases ngx_str_t is used for null-terminated strings. Most simple example is directive arguments during configuration parsing - while arguments are using ngx_str_t type, they are guaranteed to be null-terminated. Other examples are input headers, and upstream input headers. The latter implies that response Content-Range header will be null-terminated as seen by the slice module - unless you are producing it with some custom module. > In particular, if the headers_out.content_range ngx_str_t was > allocated in the ngx_http_range_filter_module then the buffer > was allocated as a non-zero terminated buffer by ngx_pnalloc. The range filter works after the slice module, hence whatever is set in the headers_out.content_range field by the range filter cannot affect slice module. Further, if slice module ever uses Content-Range header set by the range filter, this would indicate a severe bug, as it is expected to use Content-Range header from a backend response, not Content-Range header from the resulting response to the client. -- Maxim Dounin http://mdounin.ru/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From xeioex at nginx.com Tue Jul 2 12:29:38 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 02 Jul 2019 12:29:38 +0000 Subject: [njs] Crypto: zeroing the context after usage. Message-ID: details: https://hg.nginx.org/njs/rev/7a8584306099 branches: changeset: 1023:7a8584306099 user: David Carlier date: Tue Jun 18 15:02:57 2019 +0000 description: Crypto: zeroing the context after usage. Regardless of the compiler optimisation. This closes #181 pull request. diffstat: nxt/nxt_md5.c | 2 +- nxt/nxt_sha1.c | 2 +- nxt/nxt_sha2.c | 2 +- nxt/nxt_string.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diffs (48 lines): diff -r f66b593ef3da -r 7a8584306099 nxt/nxt_md5.c --- a/nxt/nxt_md5.c Mon Jul 01 19:57:34 2019 +0300 +++ b/nxt/nxt_md5.c Tue Jun 18 15:02:57 2019 +0000 @@ -110,7 +110,7 @@ nxt_md5_final(u_char result[16], nxt_md5 result[14] = (u_char) (ctx->d >> 16); result[15] = (u_char) (ctx->d >> 24); - nxt_memzero(ctx, sizeof(*ctx)); + nxt_explicit_memzero(ctx, sizeof(*ctx)); } diff -r f66b593ef3da -r 7a8584306099 nxt/nxt_sha1.c --- a/nxt/nxt_sha1.c Mon Jul 01 19:57:34 2019 +0300 +++ b/nxt/nxt_sha1.c Tue Jun 18 15:02:57 2019 +0000 @@ -116,7 +116,7 @@ nxt_sha1_final(u_char result[20], nxt_sh result[18] = (u_char) (ctx->e >> 8); result[19] = (u_char) ctx->e; - nxt_memzero(ctx, sizeof(*ctx)); + nxt_explicit_memzero(ctx, sizeof(*ctx)); } diff -r f66b593ef3da -r 7a8584306099 nxt/nxt_sha2.c --- a/nxt/nxt_sha2.c Mon Jul 01 19:57:34 2019 +0300 +++ b/nxt/nxt_sha2.c Tue Jun 18 15:02:57 2019 +0000 @@ -131,7 +131,7 @@ nxt_sha2_final(u_char result[32], nxt_sh result[30] = (u_char) (ctx->h >> 8); result[31] = (u_char) ctx->h; - nxt_memzero(ctx, sizeof(*ctx)); + nxt_explicit_memzero(ctx, sizeof(*ctx)); } diff -r f66b593ef3da -r 7a8584306099 nxt/nxt_string.h --- a/nxt/nxt_string.h Mon Jul 01 19:57:34 2019 +0300 +++ b/nxt/nxt_string.h Tue Jun 18 15:02:57 2019 +0000 @@ -97,7 +97,7 @@ nxt_explicit_memzero(buf, length) (void) explicit_memset(buf, 0, length) #else nxt_inline void -nxt_explicit_memzero(u_char *buf, size_t length) +nxt_explicit_memzero(void *buf, size_t length) { volatile u_char *p = (volatile u_char *) buf; From vbart at nginx.com Tue Jul 2 12:59:50 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 02 Jul 2019 12:59:50 +0000 Subject: [njs] Reduced nesting level of branches in njs_string_replace_regexp(). Message-ID: details: https://hg.nginx.org/njs/rev/4a0f6ff54f88 branches: changeset: 1024:4a0f6ff54f88 user: Valentin Bartenev date: Mon Jul 01 22:44:14 2019 +0300 description: Reduced nesting level of branches in njs_string_replace_regexp(). No functional changes. diffstat: njs/njs_string.c | 163 +++++++++++++++++++++++++++--------------------------- 1 files changed, 82 insertions(+), 81 deletions(-) diffs (181 lines): diff -r 7a8584306099 -r 4a0f6ff54f88 njs/njs_string.c --- a/njs/njs_string.c Tue Jun 18 15:02:57 2019 +0000 +++ b/njs/njs_string.c Mon Jul 01 22:44:14 2019 +0300 @@ -3092,95 +3092,96 @@ njs_string_replace_regexp(njs_vm_t *vm, r->part[0].start, r->part[0].size, r->match_data); - if (ret >= 0) { - captures = nxt_regex_captures(r->match_data); - - if (r->substitutions != NULL) { - ret = njs_string_replace_substitute(vm, r, captures); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - if (!pattern->global) { - return njs_string_replace_regexp_join(vm, r); - } + if (ret < 0) { + if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) { + return NXT_ERROR; + } + + break; + } + + captures = nxt_regex_captures(r->match_data); + + if (r->substitutions != NULL) { + ret = njs_string_replace_substitute(vm, r, captures); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + if (!pattern->global) { + return njs_string_replace_regexp_join(vm, r); + } + + continue; + } + + if (r->part != r->parts.start) { + r->part = nxt_array_add(&r->parts, &njs_array_mem_proto, + vm->mem_pool); + if (nxt_slow_path(r->part == NULL)) { + return NXT_ERROR; + } + + r->part = nxt_array_add(&r->parts, &njs_array_mem_proto, + vm->mem_pool); + if (nxt_slow_path(r->part == NULL)) { + return NXT_ERROR; + } + + r->part -= 2; + } + + if (captures[1] == 0) { + + /* Empty match. */ + + start = r->part[0].start; + + if (start < end) { + p = (u_char *) nxt_utf8_next(start, end); + + r->part[1].start = start; + r->part[1].size = p - start; + + r->part[2].start = p; + r->part[2].size = end - p; } else { - if (r->part != r->parts.start) { - r->part = nxt_array_add(&r->parts, &njs_array_mem_proto, - vm->mem_pool); - if (nxt_slow_path(r->part == NULL)) { - return NXT_ERROR; - } - - r->part = nxt_array_add(&r->parts, &njs_array_mem_proto, - vm->mem_pool); - if (nxt_slow_path(r->part == NULL)) { - return NXT_ERROR; - } - - r->part -= 2; - } - - if (captures[1] == 0) { - - /* Empty match. */ - - start = r->part[0].start; - - if (start < end) { - p = (u_char *) nxt_utf8_next(start, end); - - r->part[1].start = start; - r->part[1].size = p - start; - - r->part[2].start = p; - r->part[2].size = end - p; - - } else { - r->part[1].size = 0; - r->part[2].size = 0; - - /* To exit the loop. */ - r->part[2].start = start + 1; - } - - if (r->function != NULL) { - return njs_string_replace_regexp_function(vm, args, r, - captures, ret); - } - - r->part[0] = replace; - - } else { - r->part[2].start = r->part[0].start + captures[1]; - r->part[2].size = r->part[0].size - captures[1]; - njs_set_invalid(&r->part[2].value); - - if (r->function != NULL) { - return njs_string_replace_regexp_function(vm, args, r, - captures, ret); - } - - r->part[0].size = captures[0]; - - r->part[1] = replace; - } - - if (!pattern->global) { - return njs_string_replace_regexp_join(vm, r); - } - - r->part += 2; + r->part[1].size = 0; + r->part[2].size = 0; + + /* To exit the loop. */ + r->part[2].start = start + 1; } - } else if (ret == NXT_REGEX_NOMATCH) { - break; + if (r->function != NULL) { + return njs_string_replace_regexp_function(vm, args, r, + captures, ret); + } + + r->part[0] = replace; } else { - return NXT_ERROR; + r->part[2].start = r->part[0].start + captures[1]; + r->part[2].size = r->part[0].size - captures[1]; + njs_set_invalid(&r->part[2].value); + + if (r->function != NULL) { + return njs_string_replace_regexp_function(vm, args, r, + captures, ret); + } + + r->part[0].size = captures[0]; + + r->part[1] = replace; } + if (!pattern->global) { + return njs_string_replace_regexp_join(vm, r); + } + + r->part += 2; + } while (r->part[0].start <= end); if (r->part != r->parts.start) { From alexander.borisov at nginx.com Tue Jul 2 15:15:04 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Tue, 02 Jul 2019 15:15:04 +0000 Subject: [njs] Fixed String.prototype.replace() for '$0' replacement string. Message-ID: details: https://hg.nginx.org/njs/rev/0f2d18a5eed3 branches: changeset: 1025:0f2d18a5eed3 user: Alexander Borisov date: Tue Jul 02 18:14:47 2019 +0300 description: Fixed String.prototype.replace() for '$0' replacement string. For example: '0'.replace(/^/g, "$0") diffstat: njs/njs_string.c | 2 +- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 4a0f6ff54f88 -r 0f2d18a5eed3 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 01 22:44:14 2019 +0300 +++ b/njs/njs_string.c Tue Jul 02 18:14:47 2019 +0300 @@ -3470,7 +3470,7 @@ skip: size = 2; - if (c >= '0' && c <= '9') { + if (c >= '1' && c <= '9') { type = c - '0'; if (p < end) { diff -r 4a0f6ff54f88 -r 0f2d18a5eed3 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Jul 01 22:44:14 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue Jul 02 18:14:47 2019 +0300 @@ -5566,6 +5566,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc'.replace(/(a*)/g, function v0() {return '124'})"), nxt_string("124124b124c124") }, + { nxt_string("typeof '0'.replace(/^/g, '$0')"), + nxt_string("string") }, + { nxt_string("/]/"), nxt_string("/\\]/") }, From iii at linux.ibm.com Tue Jul 2 17:00:37 2019 From: iii at linux.ibm.com (Ilya Leoshkevich) Date: Tue, 2 Jul 2019 19:00:37 +0200 Subject: [PATCH] Gzip: use zlib to write header and trailer Message-ID: <20190702170037.47522-1-iii@linux.ibm.com> When nginx is used with zlib patched with [1], which provides integration with the future IBM Z hardware deflate acceleration, it ends up computing CRC32 twice: one time in hardware, which always does this, and one time in software by explicitly calling crc32(). crc32() calls were added in commits 14827c7c6f83 ("nginx-0.0.1- 2003-09-24-23:51:12 import") and 02f0132392913bd6 ("nginx-0.0.1- 2003-09-26-09:45:21 import") as part of gzip wrapping feature - back then zlib did not support it. However, since then gzip wrapping was implemented in zlib v1.2.0.4, and it's already being used by nginx for log compression. This patch replaces hand-written gzip wrapping with the one provided by zlib. It simplifies the code, and makes it avoid computing CRC32 twice when using hardware acceleration. [1] https://github.com/madler/zlib/pull/410 --- .../modules/ngx_http_gzip_filter_module.c | 118 +----------------- 1 file changed, 4 insertions(+), 114 deletions(-) diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index e4c343c9..0a66df00 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -55,44 +55,23 @@ typedef struct { unsigned redo:1; unsigned done:1; unsigned nomem:1; - unsigned gzheader:1; unsigned buffering:1; unsigned intel:1; size_t zin; size_t zout; - uint32_t crc32; z_stream zstream; ngx_http_request_t *request; } ngx_http_gzip_ctx_t; -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) - -struct gztrailer { - uint32_t crc32; - uint32_t zlen; -}; - -#else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */ - -struct gztrailer { - u_char crc32[4]; - u_char zlen[4]; -}; - -#endif - - static void ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_buffer(ngx_http_gzip_ctx_t *ctx, ngx_chain_t *in); static ngx_int_t ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); -static ngx_int_t ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, - ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, @@ -446,12 +425,6 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return ctx->busy ? NGX_AGAIN : NGX_OK; } - if (!ctx->gzheader) { - if (ngx_http_gzip_filter_gzheader(r, ctx) != NGX_OK) { - goto failed; - } - } - rc = ngx_http_next_body_filter(r, ctx->out); if (rc == NGX_ERROR) { @@ -643,7 +616,7 @@ ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r, ctx->zstream.opaque = ctx; rc = deflateInit2(&ctx->zstream, (int) conf->level, Z_DEFLATED, - - ctx->wbits, ctx->memlevel, Z_DEFAULT_STRATEGY); + ctx->wbits + 16, ctx->memlevel, Z_DEFAULT_STRATEGY); if (rc != Z_OK) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, @@ -652,45 +625,12 @@ ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r, } ctx->last_out = &ctx->out; - ctx->crc32 = crc32(0L, Z_NULL, 0); ctx->flush = Z_NO_FLUSH; return NGX_OK; } -static ngx_int_t -ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) -{ - ngx_buf_t *b; - ngx_chain_t *cl; - static u_char gzheader[10] = - { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; - - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - b->memory = 1; - b->pos = gzheader; - b->last = b->pos + 10; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - cl->next = ctx->out; - ctx->out = cl; - - ctx->gzheader = 1; - - return NGX_OK; -} - - static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { @@ -745,12 +685,7 @@ ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) ctx->flush = Z_SYNC_FLUSH; } - if (ctx->zstream.avail_in) { - - ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in, - ctx->zstream.avail_in); - - } else if (ctx->flush == Z_NO_FLUSH) { + if (!ctx->zstream.avail_in && ctx->flush == Z_NO_FLUSH) { return NGX_AGAIN; } @@ -933,12 +868,10 @@ ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { int rc; - ngx_buf_t *b; ngx_chain_t *cl; - struct gztrailer *trailer; ctx->zin = ctx->zstream.total_in; - ctx->zout = 10 + ctx->zstream.total_out + 8; + ctx->zout = ctx->zstream.total_out; rc = deflateEnd(&ctx->zstream); @@ -960,50 +893,7 @@ ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r, *ctx->last_out = cl; ctx->last_out = &cl->next; - if (ctx->zstream.avail_out >= 8) { - trailer = (struct gztrailer *) ctx->out_buf->last; - ctx->out_buf->last += 8; - ctx->out_buf->last_buf = 1; - - } else { - b = ngx_create_temp_buf(r->pool, 8); - if (b == NULL) { - return NGX_ERROR; - } - - b->last_buf = 1; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - cl->next = NULL; - *ctx->last_out = cl; - ctx->last_out = &cl->next; - trailer = (struct gztrailer *) b->pos; - b->last += 8; - } - -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) - - trailer->crc32 = ctx->crc32; - trailer->zlen = ctx->zin; - -#else - - trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff); - trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff); - trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff); - trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff); - - trailer->zlen[0] = (u_char) (ctx->zin & 0xff); - trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff); - trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff); - trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff); - -#endif + ctx->out_buf->last_buf = 1; ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; -- 2.21.0 From xeioex at nginx.com Tue Jul 2 18:49:17 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 02 Jul 2019 18:49:17 +0000 Subject: [njs] Refactored functions inlining. Message-ID: details: https://hg.nginx.org/njs/rev/775430ca2cab branches: changeset: 1026:775430ca2cab user: Dmitry Volyntsev date: Tue Jul 02 21:37:10 2019 +0300 description: Refactored functions inlining. Allowing compiler to decide whether inline a function or not by removing most of nxt_noinline prefixes. Inlining simple functions. Splitting public function getters from njs internal value getters. diffstat: njs/njs.c | 164 +++++++++++++++++++++++++++- njs/njs_array.c | 151 +++++++++++-------------- njs/njs_builtin.c | 14 +- njs/njs_crypto.c | 4 +- njs/njs_date.c | 101 ++++++++--------- njs/njs_error.c | 2 +- njs/njs_error.h | 4 +- njs/njs_event.c | 2 +- njs/njs_extern.c | 2 +- njs/njs_fs.c | 20 +- njs/njs_function.c | 14 +- njs/njs_generator.c | 50 ++++---- njs/njs_json.c | 44 +++---- njs/njs_math.c | 70 ++++++------ njs/njs_module.c | 12 +- njs/njs_number.c | 121 +-------------------- njs/njs_number.h | 124 +++++++++++++++++++- njs/njs_object.c | 50 ++------ njs/njs_object_property.c | 12 +- njs/njs_regexp.c | 14 +- njs/njs_string.c | 66 +++++------ njs/njs_string.h | 8 +- njs/njs_vm.c | 264 ++++++++------------------------------------- njs/njs_vm.h | 90 +++++++++++++++ nxt/nxt_lvlhsh.c | 2 +- 25 files changed, 701 insertions(+), 704 deletions(-) diffs (truncated from 3690 to 1000 lines): diff -r 0f2d18a5eed3 -r 775430ca2cab njs/njs.c --- a/njs/njs.c Tue Jul 02 18:14:47 2019 +0300 +++ b/njs/njs.c Tue Jul 02 21:37:10 2019 +0300 @@ -663,20 +663,174 @@ njs_vm_add_path(njs_vm_t *vm, const nxt_ } -nxt_noinline njs_value_t * +njs_value_t * njs_vm_retval(njs_vm_t *vm) { return &vm->retval; } -nxt_noinline void +void njs_vm_retval_set(njs_vm_t *vm, const njs_value_t *value) { vm->retval = *value; } +void +njs_value_undefined_set(njs_value_t *value) +{ + njs_set_undefined(value); +} + + +void +njs_value_boolean_set(njs_value_t *value, int yn) +{ + njs_set_boolean(value, yn); +} + + +void +njs_value_number_set(njs_value_t *value, double num) +{ + njs_set_number(value, num); +} + + +void +njs_value_data_set(njs_value_t *value, void *data) +{ + njs_set_data(value, data); +} + + +njs_ret_t +njs_vm_value_string_set(njs_vm_t *vm, njs_value_t *value, const u_char *start, + uint32_t size) +{ + return njs_string_set(vm, value, start, size); +} + + +u_char * +njs_vm_value_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size) +{ + return njs_string_alloc(vm, value, size, 0); +} + + +nxt_noinline void +njs_vm_value_error_set(njs_vm_t *vm, njs_value_t *value, const char *fmt, ...) +{ + va_list args; + u_char buf[NXT_MAX_ERROR_STR], *p; + + p = buf; + + if (fmt != NULL) { + va_start(args, fmt); + p = nxt_vsprintf(buf, buf + sizeof(buf), fmt, args); + va_end(args); + } + + njs_error_new(vm, value, NJS_OBJECT_ERROR, buf, p - buf); +} + + +uint8_t +njs_value_bool(const njs_value_t *value) +{ + return njs_bool(value); +} + + +double +njs_value_number(const njs_value_t *value) +{ + return njs_number(value); +} + + +void * +njs_value_data(const njs_value_t *value) +{ + return njs_data(value); +} + + +njs_function_t * +njs_value_function(const njs_value_t *value) +{ + return njs_function(value); +} + + +nxt_int_t +njs_value_is_null(const njs_value_t *value) +{ + return njs_is_null(value); +} + + +nxt_int_t +njs_value_is_undefined(const njs_value_t *value) +{ + return njs_is_undefined(value); +} + + +nxt_int_t +njs_value_is_null_or_undefined(const njs_value_t *value) +{ + return njs_is_null_or_undefined(value); +} + + +nxt_int_t +njs_value_is_boolean(const njs_value_t *value) +{ + return njs_is_boolean(value); +} + + +nxt_int_t +njs_value_is_number(const njs_value_t *value) +{ + return njs_is_number(value); +} + + +nxt_int_t +njs_value_is_valid_number(const njs_value_t *value) +{ + return njs_is_number(value) + && !isnan(value->data.u.number) + && !isinf(value->data.u.number); +} + + +nxt_int_t +njs_value_is_string(const njs_value_t *value) +{ + return njs_is_string(value); +} + + +nxt_int_t +njs_value_is_object(const njs_value_t *value) +{ + return njs_is_object(value); +} + + +nxt_int_t +njs_value_is_function(const njs_value_t *value) +{ + return njs_is_function(value); +} + + nxt_noinline void njs_vm_memory_error(njs_vm_t *vm) { @@ -770,9 +924,7 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_va rc = NJS_OK; - retval->data.u.object = object; - retval->type = NJS_OBJECT; - retval->data.truth = 1; + njs_set_object(retval, object); done: @@ -797,7 +949,7 @@ njs_vm_object_prop(njs_vm_t *vm, const n lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); lhq.proto = &njs_object_hash_proto; - ret = nxt_lvlhsh_find(&value->data.u.object->hash, &lhq); + ret = nxt_lvlhsh_find(njs_object_hash(value), &lhq); if (nxt_slow_path(ret != NXT_OK)) { return NULL; } diff -r 0f2d18a5eed3 -r 775430ca2cab njs/njs_array.c --- a/njs/njs_array.c Tue Jul 02 18:14:47 2019 +0300 +++ b/njs/njs_array.c Tue Jul 02 21:37:10 2019 +0300 @@ -118,15 +118,15 @@ static njs_ret_t njs_array_prototype_fin njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static njs_ret_t njs_array_prototype_map_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static nxt_noinline uint32_t njs_array_prototype_map_index(njs_array_t *array, +static uint32_t njs_array_prototype_map_index(njs_array_t *array, njs_array_map_t *map); -static nxt_noinline njs_ret_t njs_array_iterator_args(njs_vm_t *vm, +static njs_ret_t njs_array_iterator_args(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs); -static nxt_noinline uint32_t njs_array_iterator_index(njs_array_t *array, +static uint32_t njs_array_iterator_index(njs_array_t *array, njs_array_iter_t *iter); -static nxt_noinline njs_ret_t njs_array_iterator_apply(njs_vm_t *vm, +static njs_ret_t njs_array_iterator_apply(njs_vm_t *vm, njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs); -static nxt_noinline njs_ret_t njs_array_prototype_find_apply(njs_vm_t *vm, +static njs_ret_t njs_array_prototype_find_apply(njs_vm_t *vm, njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs); static njs_ret_t njs_array_prototype_reduce_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); @@ -138,7 +138,7 @@ static njs_ret_t njs_array_prototype_sor njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -nxt_noinline njs_array_t * +njs_array_t * njs_array_alloc(njs_vm_t *vm, uint64_t length, uint32_t spare) { uint64_t size; @@ -308,7 +308,6 @@ njs_array_constructor(njs_vm_t *vm, njs_ if (nxt_fast_path(array != NULL)) { - vm->retval.data.u.array = array; value = array->start; if (args == NULL) { @@ -326,8 +325,8 @@ njs_array_constructor(njs_vm_t *vm, njs_ } } - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + + njs_set_array(&vm->retval, array); return NXT_OK; } @@ -369,9 +368,7 @@ njs_array_of(njs_vm_t *vm, njs_value_t * return NXT_ERROR; } - vm->retval.data.u.array = array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, array); for (i = 0; i < length; i++) { array->start[i] = args[i + 1]; @@ -464,7 +461,7 @@ njs_array_length(njs_vm_t *vm, njs_value array = (njs_array_t *) proto; - njs_value_number_set(retval, array->length); + njs_set_number(retval, array->length); return NJS_OK; } @@ -506,7 +503,7 @@ njs_array_length(njs_vm_t *vm, njs_value array->length = length; - njs_value_number_set(retval, length); + njs_set_number(retval, length); return NJS_OK; } @@ -619,15 +616,13 @@ njs_array_prototype_slice_copy(njs_vm_t return NXT_ERROR; } - vm->retval.data.u.array = array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, array); if (length != 0) { n = 0; if (nxt_fast_path(njs_is_array(this))) { - value = this->data.u.array->start; + value = njs_array_start(this); do { /* GC: retain long string and object in values[start]. */ @@ -704,7 +699,7 @@ njs_array_prototype_push(njs_vm_t *vm, n njs_array_t *array; if (njs_is_array(&args[0])) { - array = args[0].data.u.array; + array = njs_array(&args[0]); if (nargs != 0) { ret = njs_array_expand(vm, array, 0, nargs); @@ -718,7 +713,7 @@ njs_array_prototype_push(njs_vm_t *vm, n } } - njs_value_number_set(&vm->retval, array->length); + njs_set_number(&vm->retval, array->length); } return NXT_OK; @@ -735,7 +730,7 @@ njs_array_prototype_pop(njs_vm_t *vm, nj retval = &njs_value_undefined; if (njs_is_array(&args[0])) { - array = args[0].data.u.array; + array = njs_array(&args[0]); if (array->length != 0) { array->length--; @@ -762,7 +757,7 @@ njs_array_prototype_unshift(njs_vm_t *vm njs_array_t *array; if (njs_is_array(&args[0])) { - array = args[0].data.u.array; + array = njs_array(&args[0]); n = nargs - 1; if (n != 0) { @@ -782,7 +777,7 @@ njs_array_prototype_unshift(njs_vm_t *vm } while (n > 1); } - njs_value_number_set(&vm->retval, array->length); + njs_set_number(&vm->retval, array->length); } return NXT_OK; @@ -799,7 +794,7 @@ njs_array_prototype_shift(njs_vm_t *vm, retval = &njs_value_undefined; if (njs_is_array(&args[0])) { - array = args[0].data.u.array; + array = njs_array(&args[0]); if (array->length != 0) { array->length--; @@ -833,7 +828,7 @@ njs_array_prototype_splice(njs_vm_t *vm, delete = 0; if (njs_is_array(&args[0])) { - array = args[0].data.u.array; + array = njs_array(&args[0]); length = array->length; if (nargs > 1) { @@ -913,9 +908,7 @@ njs_array_prototype_splice(njs_vm_t *vm, } } - vm->retval.data.u.array = deleted; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, deleted); return NXT_OK; } @@ -930,7 +923,7 @@ njs_array_prototype_reverse(njs_vm_t *vm njs_array_t *array; if (njs_is_array(&args[0])) { - array = args[0].data.u.array; + array = njs_array(&args[0]); length = array->length; if (length > 1) { @@ -941,9 +934,7 @@ njs_array_prototype_reverse(njs_vm_t *vm } } - vm->retval.data.u.array = array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, array); } else { /* STUB */ @@ -991,7 +982,7 @@ njs_array_prototype_join(njs_vm_t *vm, n goto empty; } - array = args[0].data.u.array; + array = njs_array(&args[0]); if (array->length == 0) { goto empty; @@ -1076,7 +1067,7 @@ njs_array_prototype_join_continuation(nj n = 0; mask = -1; - array = args[0].data.u.array; + array = njs_array(&args[0]); for (i = 0; i < array->length; i++) { value = &array->start[i]; @@ -1168,7 +1159,7 @@ njs_array_prototype_concat(njs_vm_t *vm, for (i = 0; i < nargs; i++) { if (njs_is_array(&args[i])) { - length += args[i].data.u.array->length; + length += njs_array_len(&args[i]); } else { length++; @@ -1180,9 +1171,7 @@ njs_array_prototype_concat(njs_vm_t *vm, return NXT_ERROR; } - vm->retval.data.u.array = array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, array); value = array->start; @@ -1202,8 +1191,8 @@ njs_array_copy(njs_value_t *dst, njs_val n = 1; if (njs_is_array(src)) { - n = src->data.u.array->length; - src = src->data.u.array->start; + n = njs_array_len(src); + src = njs_array_start(src); } while (n != 0) { @@ -1230,7 +1219,7 @@ njs_array_prototype_index_of(njs_vm_t *v goto done; } - array = args[0].data.u.array; + array = njs_array(&args[0]); length = array->length; if (length == 0) { @@ -1270,7 +1259,7 @@ njs_array_prototype_index_of(njs_vm_t *v done: - njs_value_number_set(&vm->retval, index); + njs_set_number(&vm->retval, index); return NXT_OK; } @@ -1290,7 +1279,7 @@ njs_array_prototype_last_index_of(njs_vm goto done; } - array = args[0].data.u.array; + array = njs_array(&args[0]); length = array->length; if (length == 0) { @@ -1329,7 +1318,7 @@ njs_array_prototype_last_index_of(njs_vm done: - njs_value_number_set(&vm->retval, index); + njs_set_number(&vm->retval, index); return NXT_OK; } @@ -1350,7 +1339,7 @@ njs_array_prototype_includes(njs_vm_t *v goto done; } - array = args[0].data.u.array; + array = njs_array(&args[0]); length = array->length; if (length == 0) { @@ -1480,7 +1469,7 @@ njs_array_prototype_fill_continuation(nj fill = njs_vm_continuation(vm); if (njs_is_array(this)) { - array = this->data.u.array; + array = njs_array(this); length = array->length; } else { @@ -1584,7 +1573,7 @@ njs_array_prototype_for_each_continuatio iter = njs_vm_continuation(vm); - index = njs_array_iterator_index(args[0].data.u.array, iter); + index = njs_array_iterator_index(njs_array(&args[0]), iter); if (index == NJS_ARRAY_INVALID_INDEX) { vm->retval = njs_value_undefined; @@ -1628,7 +1617,7 @@ njs_array_prototype_some_continuation(nj retval = &njs_value_true; } else { - index = njs_array_iterator_index(args[0].data.u.array, iter); + index = njs_array_iterator_index(njs_array(&args[0]), iter); if (index == NJS_ARRAY_INVALID_INDEX) { retval = &njs_value_false; @@ -1678,7 +1667,7 @@ njs_array_prototype_every_continuation(n retval = &njs_value_false; } else { - index = njs_array_iterator_index(args[0].data.u.array, iter); + index = njs_array_iterator_index(njs_array(&args[0]), iter); if (index == NJS_ARRAY_INVALID_INDEX) { retval = &njs_value_true; @@ -1736,13 +1725,11 @@ njs_array_prototype_filter_continuation( } } - array = args[0].data.u.array; + array = njs_array(&args[0]); index = njs_array_iterator_index(array, &filter->iter); if (index == NJS_ARRAY_INVALID_INDEX) { - vm->retval.data.u.array = filter->array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, filter->array); return NXT_OK; } @@ -1788,7 +1775,7 @@ njs_array_prototype_find_continuation(nj iter = &find->iter; if (!njs_is_true(&iter->retval)) { - array = args[0].data.u.array; + array = njs_array(&args[0]); iter->index++; if (iter->index < iter->length && iter->index < array->length) { @@ -1843,7 +1830,7 @@ njs_array_prototype_find_index_continuat iter->index++; if (iter->index < iter->length - && iter->index < args[0].data.u.array->length) + && iter->index < njs_array_len(&args[0])) { return njs_array_prototype_find_apply(vm, iter, args, nargs); } @@ -1851,13 +1838,13 @@ njs_array_prototype_find_index_continuat index = -1; } - njs_value_number_set(&vm->retval, index); + njs_set_number(&vm->retval, index); return NXT_OK; } -static nxt_noinline njs_ret_t +static njs_ret_t njs_array_prototype_find_apply(njs_vm_t *vm, njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs) { @@ -1871,7 +1858,7 @@ njs_array_prototype_find_apply(njs_vm_t arguments[0] = *value; n = iter->index; - value = &args[0].data.u.array->start[n]; + value = &njs_array_start(&args[0])[n]; if (!njs_is_valid(value)) { value = &njs_value_undefined; @@ -1879,7 +1866,7 @@ njs_array_prototype_find_apply(njs_vm_t arguments[1] = *value; - njs_value_number_set(&arguments[2], n); + njs_set_number(&arguments[2], n); arguments[3] = args[0]; @@ -1904,7 +1891,7 @@ njs_array_prototype_map(njs_vm_t *vm, nj map->iter.u.cont.function = njs_array_prototype_map_continuation; njs_set_invalid(&map->iter.retval); - map->array = njs_array_alloc(vm, args[0].data.u.array->length, 0); + map->array = njs_array_alloc(vm, njs_array_len(&args[0]), 0); if (nxt_slow_path(map->array == NULL)) { return NXT_ERROR; } @@ -1913,7 +1900,7 @@ njs_array_prototype_map(njs_vm_t *vm, nj } -static nxt_noinline njs_ret_t +static njs_ret_t njs_array_prototype_map_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -1926,12 +1913,10 @@ njs_array_prototype_map_continuation(njs map->array->start[map->iter.index] = map->iter.retval; } - index = njs_array_prototype_map_index(args[0].data.u.array, map); + index = njs_array_prototype_map_index(njs_array(&args[0]), map); if (index == NJS_ARRAY_INVALID_INDEX) { - vm->retval.data.u.array = map->array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; + njs_set_array(&vm->retval, map->array); return NXT_OK; } @@ -1987,7 +1972,7 @@ njs_array_prototype_reduce(njs_vm_t *vm, iter->retval = args[2]; } else { - array = args[0].data.u.array; + array = njs_array(&args[0]); n = njs_array_iterator_index(array, iter); if (n == NJS_ARRAY_INVALID_INDEX) { @@ -2012,7 +1997,7 @@ njs_array_prototype_reduce_continuation( njs_array_iter_t *iter; iter = njs_vm_continuation(vm); - array = args[0].data.u.array; + array = njs_array(&args[0]); n = njs_array_iterator_index(array, iter); @@ -2028,7 +2013,7 @@ njs_array_prototype_reduce_continuation( arguments[2] = array->start[n]; - njs_value_number_set(&arguments[3], n); + njs_set_number(&arguments[3], n); arguments[4] = args[0]; @@ -2037,7 +2022,7 @@ njs_array_prototype_reduce_continuation( } -static nxt_noinline njs_ret_t +static njs_ret_t njs_array_iterator_args(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs) { njs_array_iter_t *iter; @@ -2045,7 +2030,7 @@ njs_array_iterator_args(njs_vm_t *vm, nj if (nargs > 1 && njs_is_array(&args[0]) && njs_is_function(&args[1])) { iter = njs_vm_continuation(vm); - iter->length = args[0].data.u.array->length; + iter->length = njs_array_len(&args[0]); iter->retval.data.truth = 0; iter->index = NJS_ARRAY_INVALID_INDEX; @@ -2058,7 +2043,7 @@ njs_array_iterator_args(njs_vm_t *vm, nj } -static nxt_noinline uint32_t +static uint32_t njs_array_iterator_index(njs_array_t *array, njs_array_iter_t *iter) { uint32_t i, length; @@ -2076,7 +2061,7 @@ njs_array_iterator_index(njs_array_t *ar } -static nxt_noinline njs_ret_t +static njs_ret_t njs_array_iterator_apply(njs_vm_t *vm, njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs) { @@ -2090,9 +2075,9 @@ njs_array_iterator_apply(njs_vm_t *vm, n arguments[0] = *value; n = iter->index; - arguments[1] = args[0].data.u.array->start[n]; - - njs_value_number_set(&arguments[2], n); + arguments[1] = njs_array_start(&args[0])[n]; + + njs_set_number(&arguments[2], n); arguments[3] = args[0]; @@ -2122,7 +2107,7 @@ njs_array_prototype_reduce_right(njs_vm_ iter->retval = args[2]; } else { - array = args[0].data.u.array; + array = njs_array(&args[0]); n = njs_array_reduce_right_index(array, iter); if (n == NJS_ARRAY_INVALID_INDEX) { @@ -2139,7 +2124,7 @@ njs_array_prototype_reduce_right(njs_vm_ } -static nxt_noinline njs_ret_t +static njs_ret_t njs_array_prototype_reduce_right_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -2149,7 +2134,7 @@ njs_array_prototype_reduce_right_continu njs_array_iter_t *iter; iter = njs_vm_continuation(vm); - array = args[0].data.u.array; + array = njs_array(&args[0]); n = njs_array_reduce_right_index(array, iter); @@ -2165,7 +2150,7 @@ njs_array_prototype_reduce_right_continu arguments[2] = array->start[n]; - njs_value_number_set(&arguments[3], n); + njs_set_number(&arguments[3], n); arguments[4] = args[0]; @@ -2174,7 +2159,7 @@ njs_array_prototype_reduce_right_continu } -static nxt_noinline uint32_t +static uint32_t njs_array_reduce_right_index(njs_array_t *array, njs_array_iter_t *iter) { uint32_t n; @@ -2212,7 +2197,7 @@ njs_array_string_sort(njs_vm_t *vm, njs_ ret = njs_string_cmp(&args[1], &args[2]); - njs_value_number_set(&vm->retval, ret); + njs_set_number(&vm->retval, ret); return NXT_OK; } @@ -2234,7 +2219,7 @@ njs_array_prototype_sort(njs_vm_t *vm, n { njs_array_sort_t *sort; - if (njs_is_array(&args[0]) && args[0].data.u.array->length > 1) { + if (njs_is_array(&args[0]) && njs_array_len(&args[0]) > 1) { sort = njs_vm_continuation(vm); sort->u.cont.function = njs_array_prototype_sort_continuation; @@ -2266,7 +2251,7 @@ njs_array_prototype_sort_continuation(nj njs_value_t value, *start, arguments[3]; njs_array_sort_t *sort; - array = args[0].data.u.array; + array = njs_array(&args[0]); start = array->start; sort = njs_vm_continuation(vm); diff -r 0f2d18a5eed3 -r 775430ca2cab njs/njs_builtin.c --- a/njs/njs_builtin.c Tue Jul 02 18:14:47 2019 +0300 +++ b/njs/njs_builtin.c Tue Jul 02 21:37:10 2019 +0300 @@ -840,7 +840,7 @@ njs_vm_expression_completions(njs_vm_t * lhq.key.length = p - lhq.key.start; lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); - ret = nxt_lvlhsh_find(&value->data.u.object->hash, &lhq); + ret = nxt_lvlhsh_find(njs_object_hash(value), &lhq); if (nxt_slow_path(ret != NXT_OK)) { return NULL; } @@ -1178,9 +1178,7 @@ njs_process_object_argv(njs_vm_t *vm, nj return NJS_ERROR; } - prop->value.data.u.array = argv; - prop->value.type = NJS_ARRAY; - prop->value.data.truth = 1; + njs_set_array(&prop->value, argv); lhq.value = prop; lhq.key_hash = NJS_ARGV_HASH; @@ -1189,7 +1187,7 @@ njs_process_object_argv(njs_vm_t *vm, nj lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = nxt_lvlhsh_insert(&process->data.u.object->hash, &lhq); + ret = nxt_lvlhsh_insert(njs_object_hash(process), &lhq); if (nxt_fast_path(ret == NXT_OK)) { *retval = prop->value; @@ -1281,9 +1279,7 @@ njs_process_object_env(njs_vm_t *vm, njs return NXT_ERROR; } - prop->value.data.u.object = env; - prop->value.type = NJS_OBJECT; - prop->value.data.truth = 1; + njs_set_object(&prop->value, env); lhq.replace = 0; lhq.pool = vm->mem_pool; @@ -1292,7 +1288,7 @@ njs_process_object_env(njs_vm_t *vm, njs lhq.key = nxt_string_value("env"); lhq.key_hash = NJS_ENV_HASH; - ret = nxt_lvlhsh_insert(&process->data.u.object->hash, &lhq); + ret = nxt_lvlhsh_insert(njs_object_hash(process), &lhq); if (nxt_fast_path(ret == NXT_OK)) { *retval = prop->value; diff -r 0f2d18a5eed3 -r 775430ca2cab njs/njs_crypto.c --- a/njs/njs_crypto.c Tue Jul 02 18:14:47 2019 +0300 +++ b/njs/njs_crypto.c Tue Jul 02 21:37:10 2019 +0300 @@ -186,7 +186,7 @@ njs_crypto_create_hash(njs_vm_t *vm, njs alg->init(&dgst->u); - njs_value_data_set(&hash->value, dgst); + njs_set_data(&hash->value, dgst); vm->retval.data.u.object_value = hash; vm->retval.type = NJS_OBJECT_VALUE; @@ -452,7 +452,7 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs return NJS_ERROR; } - njs_value_data_set(&hmac->value, ctx); + njs_set_data(&hmac->value, ctx); vm->retval.data.u.object_value = hmac; vm->retval.type = NJS_OBJECT_VALUE; diff -r 0f2d18a5eed3 -r 775430ca2cab njs/njs_date.c --- a/njs/njs_date.c Tue Jul 02 18:14:47 2019 +0300 +++ b/njs/njs_date.c Tue Jul 02 21:37:10 2019 +0300 @@ -23,32 +23,29 @@ sizeof("Mon Sep 28 1970 12:00:00 GMT+0600 (XXXXX)") -static nxt_noinline double njs_date_string_parse(njs_value_t *date); +static double njs_date_string_parse(njs_value_t *date); static double njs_date_rfc2822_string_parse(struct tm *tm, const u_char *p, const u_char *end); static double njs_date_js_string_parse(struct tm *tm, const u_char *p, const u_char *end); static const u_char *njs_date_skip_week_day(const u_char *p, const u_char *end); static const u_char *njs_date_skip_spaces(const u_char *p, const u_char *end); -static nxt_noinline nxt_int_t njs_date_month_parse(const u_char *p, - const u_char *end); -static nxt_noinline const u_char *njs_date_time_parse(struct tm *tm, - const u_char *p, const u_char *end); -static nxt_noinline nxt_int_t njs_date_gmtoff_parse(const u_char *start, +static nxt_int_t njs_date_month_parse(const u_char *p, const u_char *end); +static const u_char *njs_date_time_parse(struct tm *tm, const u_char *p, const u_char *end); -static nxt_noinline const u_char *njs_date_number_parse(int *value, - const u_char *p, const u_char *end, size_t size); +static nxt_int_t njs_date_gmtoff_parse(const u_char *start, const u_char *end); +static const u_char *njs_date_number_parse(int *value, const u_char *p, + const u_char *end, size_t size); static int64_t njs_timegm(struct tm *tm); -static nxt_noinline njs_ret_t njs_date_string(njs_vm_t *vm, const char *fmt, - double time); -static nxt_noinline double njs_date_time(struct tm *tm, int64_t ms); +static njs_ret_t njs_date_string(njs_vm_t *vm, const char *fmt, double time); +static double njs_date_time(struct tm *tm, int64_t ms); static double njs_date_utc_time(struct tm *tm, double time); static const njs_value_t njs_string_invalid_date = njs_string("Invalid Date"); -static nxt_noinline uint64_t +static uint64_t njs_gettime(void) { struct timeval tv; @@ -59,7 +56,7 @@ njs_gettime(void) } -static nxt_noinline double +static double njs_timeclip(double time) { if (isinf(time) || isnan(time) || fabs(time) > 8.64e15) { @@ -219,7 +216,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * done: - njs_value_number_set(&vm->retval, time); + njs_set_number(&vm->retval, time); return NXT_OK; } @@ -278,7 +275,7 @@ static njs_ret_t njs_date_now(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - njs_value_number_set(&vm->retval, njs_gettime()); + njs_set_number(&vm->retval, njs_gettime()); return NXT_OK; } @@ -297,13 +294,13 @@ njs_date_parse(njs_vm_t *vm, njs_value_t time = NAN; } - njs_value_number_set(&vm->retval, time); + njs_set_number(&vm->retval, time); return NXT_OK; } -static nxt_noinline double +static double njs_date_string_parse(njs_value_t *date) { int ext, ms, ms_length, skipped; @@ -704,7 +701,7 @@ njs_date_skip_spaces(const u_char *p, co } -static nxt_noinline nxt_int_t +static nxt_int_t njs_date_month_parse(const u_char *p, const u_char *end) { if (p + 2 < end) { @@ -792,7 +789,7 @@ njs_date_month_parse(const u_char *p, co } -static nxt_noinline const u_char * +static const u_char * njs_date_time_parse(struct tm *tm, const u_char *p, const u_char *end) { p = njs_date_number_parse(&tm->tm_hour, p, end, 2); @@ -821,7 +818,7 @@ njs_date_time_parse(struct tm *tm, const } -static nxt_noinline nxt_int_t +static nxt_int_t njs_date_gmtoff_parse(const u_char *start, const u_char *end) { int gmtoff, hour, min; @@ -852,7 +849,7 @@ njs_date_gmtoff_parse(const u_char *star } -static nxt_noinline const u_char * +static const u_char * njs_date_number_parse(int *value, const u_char *p, const u_char *end, size_t size) { @@ -950,7 +947,7 @@ static njs_ret_t njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - njs_value_number_set(&vm->retval, args[0].data.u.date->time); + njs_set_number(&vm->retval, args[0].data.u.date->time); return NXT_OK; } @@ -981,7 +978,7 @@ njs_date_prototype_to_time_string(njs_vm } -static nxt_noinline njs_ret_t +static njs_ret_t njs_date_string(njs_vm_t *vm, const char *fmt, double time) { size_t size; @@ -1097,7 +1094,7 @@ njs_date_prototype_get_full_year(njs_vm_ value = tm.tm_year + 1900; } - njs_value_number_set(&vm->retval, value); + njs_set_number(&vm->retval, value); return NXT_OK; } @@ -1120,7 +1117,7 @@ njs_date_prototype_get_utc_full_year(njs value = tm.tm_year + 1900; } From mdounin at mdounin.ru Tue Jul 2 22:52:00 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 3 Jul 2019 01:52:00 +0300 Subject: Bug in ngx_http_slice_filter_module ngx_http_slice_parse_content_range function In-Reply-To: References: <20190629103251.GZ1877@mdounin.ru> Message-ID: <20190702225200.GG1877@mdounin.ru> Hello! On Mon, Jul 01, 2019 at 10:07:41PM +0000, Carey Gister wrote: > Thank you for your reply. My use case is as follows: > > After the slice header filter calls ngx_http_next_header_filter > the contents of the request headers_out fields will be modified > if an If-Range header is valid. The production version of the > slice header filter already relies on the modified headers_out > fields set by the range filter. It is not clear what do you mean by "the production version", but the slice header filter as available in nginx calls next filter only after parsing r->header_out.content_range header. That is, it uses Content-Range header from a backend response, not the one set by the range header filter. > My extension needs to know the bounds of the new range IF the > If-Range header is valid. So I parse the new content_range value > using the ngx_http_slice_parse_content_range function to return > the stored values. So, you are misusing the ngx_http_slice_parse_content_range() function for something it's not intended for. > If this is incorrect, then please tell me how I can know if the > If-Range header is valid, preferably without duplicating the > code in the range filter, and if it is valid, what the correct > range values will be. I don't think there is a good way. -- Maxim Dounin http://mdounin.ru/ From careygister at outlook.com Tue Jul 2 23:39:16 2019 From: careygister at outlook.com (Carey Gister) Date: Tue, 2 Jul 2019 23:39:16 +0000 Subject: Bug in ngx_http_slice_filter_module ngx_http_slice_parse_content_range function In-Reply-To: <20190702225200.GG1877@mdounin.ru> References: <20190629103251.GZ1877@mdounin.ru> , <20190702225200.GG1877@mdounin.ru> Message-ID: Hi Maxim, Thank you. By "production version" I meant the current release version, which if I recall correctly, is 1.17.1. Ok. So then you recommend I copy the code that processes the If-Range header to determine if the If-Range is valid? I can then use those functions to determine the extent of the range, which is what I need to know. Carey Gister 415-310-5304 ________________________________ From: nginx-devel on behalf of Maxim Dounin Sent: Tuesday, July 2, 2019 15:52 To: nginx-devel at nginx.org Subject: Re: Bug in ngx_http_slice_filter_module ngx_http_slice_parse_content_range function Hello! On Mon, Jul 01, 2019 at 10:07:41PM +0000, Carey Gister wrote: > Thank you for your reply. My use case is as follows: > > After the slice header filter calls ngx_http_next_header_filter > the contents of the request headers_out fields will be modified > if an If-Range header is valid. The production version of the > slice header filter already relies on the modified headers_out > fields set by the range filter. It is not clear what do you mean by "the production version", but the slice header filter as available in nginx calls next filter only after parsing r->header_out.content_range header. That is, it uses Content-Range header from a backend response, not the one set by the range header filter. > My extension needs to know the bounds of the new range IF the > If-Range header is valid. So I parse the new content_range value > using the ngx_http_slice_parse_content_range function to return > the stored values. So, you are misusing the ngx_http_slice_parse_content_range() function for something it's not intended for. > If this is incorrect, then please tell me how I can know if the > If-Range header is valid, preferably without duplicating the > code in the range filter, and if it is valid, what the correct > range values will be. I don't think there is a good way. -- Maxim Dounin http://mdounin.ru/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Jul 3 00:23:25 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 3 Jul 2019 03:23:25 +0300 Subject: effect of bcrypt hash $cost on HTTP Basic authentication's login performance? In-Reply-To: References: Message-ID: <20190703002325.GI1877@mdounin.ru> Hello! On Sat, Jun 29, 2019 at 09:48:01AM -0700, PGNet Dev wrote: > When generating hashed data for "HTTP Basic" login auth > protection, using bcrypt as the hash algorithm, one can vary the > resultant hash strength by varying specify bcrypt's $cost, e.g. [...] > For site login usage, does *client* login time vary at all with > the hash $cost? > > Other than the initial, one-time hash generation, is there any > login-performance reason NOT to use the highest hash $cost? With Basic HTTP authentication, hashing happens on every user request. That is, with high costs you are likely make your site completely unusable. (And no, it does not look like an appropriate question for the nginx-devel@ list. Consider using nginx@ instead.) -- Maxim Dounin http://mdounin.ru/ From mdounin at mdounin.ru Wed Jul 3 01:04:25 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 3 Jul 2019 04:04:25 +0300 Subject: Question about ngx_handle_write_event In-Reply-To: References: Message-ID: <20190703010425.GL1877@mdounin.ru> Hello! On Mon, Jul 01, 2019 at 07:23:11PM +0000, Eran Kornblau wrote: > Something is unclear to me regarding the use of this function, the development guide says - > "the functions ngx_handle_read_event(rev, flags) and ngx_handle_write_event(wev, lowat) > must be called after handling an I/O socket notification or calling any I/O functions on that socket" > > If my module finished sending all the data it had, and is now waiting for more data to arrive > (on some other socket) does it still have to call ngx_handle_write_event? Yes. In particular, this is required with level-tiggered event methods, such as select and poll, to remove the socket from the event list if it was previously added there. -- Maxim Dounin http://mdounin.ru/ From xeioex at nginx.com Wed Jul 3 14:21:45 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 03 Jul 2019 14:21:45 +0000 Subject: [njs] Fixed Array.prototype.slice() for primitive types. Message-ID: details: https://hg.nginx.org/njs/rev/bf593c4b1c7f branches: changeset: 1027:bf593c4b1c7f user: Dmitry Volyntsev date: Wed Jul 03 17:16:40 2019 +0300 description: Fixed Array.prototype.slice() for primitive types. This closes #188 issue on Github. diffstat: njs/njs_array.c | 11 +++++++++++ njs/test/njs_unit_test.c | 4 ++++ 2 files changed, 15 insertions(+), 0 deletions(-) diffs (35 lines): diff -r 775430ca2cab -r bf593c4b1c7f njs/njs_array.c --- a/njs/njs_array.c Tue Jul 02 21:37:10 2019 +0300 +++ b/njs/njs_array.c Wed Jul 03 17:16:40 2019 +0300 @@ -683,6 +683,17 @@ njs_array_prototype_slice_copy(njs_vm_t length--; } while (length != 0); + + } else { + + /* Primitive types. */ + + value = array->start; + + do { + *value++ = njs_value_invalid; + length--; + } while (length != 0); } } diff -r 775430ca2cab -r bf593c4b1c7f njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 02 21:37:10 2019 +0300 +++ b/njs/test/njs_unit_test.c Wed Jul 03 17:16:40 2019 +0300 @@ -3687,6 +3687,10 @@ static njs_unit_test_t njs_test[] = { nxt_string("Array.prototype.slice.call(new String('??Z?'))"), nxt_string("?,?,Z,?") }, + { nxt_string("1..__proto__.length = '2';" + "Array.prototype.slice.call(1, 0, 2)"), + nxt_string(",") }, + { nxt_string("Array.prototype.pop()"), nxt_string("undefined") }, From xeioex at nginx.com Wed Jul 3 15:33:22 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 03 Jul 2019 15:33:22 +0000 Subject: [njs] Fixed heap-buffer-overflow while importing module. Message-ID: details: https://hg.nginx.org/njs/rev/5c57b9efd77e branches: changeset: 1028:5c57b9efd77e user: Dmitry Volyntsev date: Wed Jul 03 18:30:59 2019 +0300 description: Fixed heap-buffer-overflow while importing module. This closes #187 issue on Github. diffstat: njs/njs_module.c | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) diffs (21 lines): diff -r bf593c4b1c7f -r 5c57b9efd77e njs/njs_module.c --- a/njs/njs_module.c Wed Jul 03 17:16:40 2019 +0300 +++ b/njs/njs_module.c Wed Jul 03 18:30:59 2019 +0300 @@ -341,13 +341,12 @@ njs_module_read(njs_vm_t *vm, int fd, nx goto fail; } - text->length = nxt_length(NJS_MODULE_START); - - if (S_ISREG(sb.st_mode) && sb.st_size) { - text->length += sb.st_size; + if (!S_ISREG(sb.st_mode)) { + goto fail; } - text->length += nxt_length(NJS_MODULE_END); + text->length = nxt_length(NJS_MODULE_START) + sb.st_size + + nxt_length(NJS_MODULE_END); text->start = nxt_mp_alloc(vm->mem_pool, text->length); if (text->start == NULL) { From xeioex at nginx.com Wed Jul 3 17:39:38 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 03 Jul 2019 17:39:38 +0000 Subject: [njs] Introduced njs_function_lambda_alloc(). Message-ID: details: https://hg.nginx.org/njs/rev/5a7de2ee74ba branches: changeset: 1029:5a7de2ee74ba user: hongzhidao date: Tue Jul 02 22:10:19 2019 -0400 description: Introduced njs_function_lambda_alloc(). diffstat: njs/njs_function.c | 2 +- njs/njs_function.h | 17 ++++++++++++++++- njs/njs_parser.c | 14 +++++--------- 3 files changed, 22 insertions(+), 11 deletions(-) diffs (102 lines): diff -r 5c57b9efd77e -r 5a7de2ee74ba njs/njs_function.c --- a/njs/njs_function.c Wed Jul 03 18:30:59 2019 +0300 +++ b/njs/njs_function.c Tue Jul 02 22:10:19 2019 -0400 @@ -37,7 +37,7 @@ njs_function_alloc(njs_vm_t *vm, njs_fun * function->object.__proto__ = NULL; */ - function->ctor = !lambda->arrow; + function->ctor = lambda->ctor; function->args_offset = 1; function->u.lambda = lambda; diff -r 5c57b9efd77e -r 5a7de2ee74ba njs/njs_function.h --- a/njs/njs_function.h Wed Jul 03 18:30:59 2019 +0300 +++ b/njs/njs_function.h Tue Jul 02 22:10:19 2019 -0400 @@ -30,7 +30,7 @@ struct njs_function_lambda_s { /* Function internal block closures levels. */ uint8_t block_closures; /* 4 bits */ - uint8_t arrow; /* 1 bit */ + uint8_t ctor; /* 1 bit */ uint8_t rest_parameters; /* 1 bit */ /* Initial values of local scope. */ @@ -176,6 +176,21 @@ njs_ret_t njs_function_native_call(njs_v void njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame); +nxt_inline njs_function_lambda_t * +njs_function_lambda_alloc(njs_vm_t *vm, uint8_t ctor) +{ + njs_function_lambda_t *lambda; + + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t)); + + if (nxt_fast_path(lambda != NULL)) { + lambda->ctor = ctor; + } + + return lambda; +} + + nxt_inline njs_ret_t njs_function_frame(njs_vm_t *vm, njs_function_t *function, const njs_value_t *this, const njs_value_t *args, nxt_uint_t nargs, diff -r 5c57b9efd77e -r 5a7de2ee74ba njs/njs_parser.c --- a/njs/njs_parser.c Wed Jul 03 18:30:59 2019 +0300 +++ b/njs/njs_parser.c Tue Jul 02 22:10:19 2019 -0400 @@ -602,7 +602,7 @@ njs_parser_function_alloc(njs_vm_t *vm, njs_function_t *function; njs_function_lambda_t *lambda; - lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t)); + lambda = njs_function_lambda_alloc(vm, 1); if (nxt_slow_path(lambda == NULL)) { njs_memory_error(vm); return NULL; @@ -687,9 +687,7 @@ njs_parser_function_declaration(njs_vm_t return NJS_TOKEN_ERROR; } - token = njs_parser_function_lambda(vm, parser, function->u.lambda, token); - - return token; + return njs_parser_function_lambda(vm, parser, function->u.lambda, token); } @@ -745,7 +743,7 @@ njs_parser_function_expression(njs_vm_t } else { /* Anonymous function. */ - lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t)); + lambda = njs_function_lambda_alloc(vm, 1); if (nxt_slow_path(lambda == NULL)) { return NJS_TOKEN_ERROR; } @@ -1896,7 +1894,7 @@ njs_parser_module_lambda(njs_vm_t *vm, n return token; } - lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t)); + lambda = njs_function_lambda_alloc(vm, 1); if (nxt_slow_path(lambda == NULL)) { return NJS_TOKEN_ERROR; } @@ -2156,13 +2154,11 @@ njs_parser_arrow_expression(njs_vm_t *vm node->token_line = njs_parser_token_line(parser); parser->node = node; - lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t)); + lambda = njs_function_lambda_alloc(vm, 0); if (nxt_slow_path(lambda == NULL)) { return NJS_TOKEN_ERROR; } - lambda->arrow = 1; - node->u.value.data.u.lambda = lambda; ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION); From xeioex at nginx.com Wed Jul 3 17:39:39 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 03 Jul 2019 17:39:39 +0000 Subject: [njs] Splitting njs_vm_value_to_ext_string(). Message-ID: details: https://hg.nginx.org/njs/rev/e03f3e12589e branches: changeset: 1030:e03f3e12589e user: hongzhidao date: Tue Jul 02 22:18:56 2019 -0400 description: Splitting njs_vm_value_to_ext_string(). Into njs_vm_value_to_string() and njs_vm_backtrace_dump(). diffstat: nginx/ngx_http_js_module.c | 18 +- nginx/ngx_stream_js_module.c | 22 +- njs/njs.c | 163 +++++++++++++++++++++++++++- njs/njs.h | 16 ++- njs/njs_json.c | 2 +- njs/njs_object_property.c | 2 +- njs/njs_vm.c | 231 ++++++++------------------------------- njs/test/njs_benchmark.c | 4 +- njs/test/njs_interactive_test.c | 6 +- njs/test/njs_unit_test.c | 22 +-- 10 files changed, 258 insertions(+), 228 deletions(-) diffs (787 lines): diff -r 5a7de2ee74ba -r e03f3e12589e nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Tue Jul 02 22:10:19 2019 -0400 +++ b/nginx/ngx_http_js_module.c Tue Jul 02 22:18:56 2019 -0400 @@ -561,7 +561,7 @@ ngx_http_js_content_event_handler(ngx_ht ctx->status = NGX_HTTP_INTERNAL_SERVER_ERROR; if (njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->request), 1) != NJS_OK) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -693,7 +693,7 @@ ngx_http_js_variable(ngx_http_request_t pending = njs_vm_pending(ctx->vm); if (njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->request), 1) != NJS_OK) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -702,7 +702,7 @@ ngx_http_js_variable(ngx_http_request_t return NGX_OK; } - if (njs_vm_retval_to_ext_string(ctx->vm, &value) != NJS_OK) { + if (njs_vm_retval_string(ctx->vm, &value) != NJS_OK) { return NGX_ERROR; } @@ -767,7 +767,7 @@ ngx_http_js_init_vm(ngx_http_request_t * cln->data = ctx; if (njs_vm_start(ctx->vm) == NJS_ERROR) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -1371,7 +1371,7 @@ ngx_http_js_ext_log_core(njs_vm_t *vm, n c = r->connection; - if (njs_vm_value_to_ext_string(vm, &msg, njs_arg(args, nargs, 1), 0) + if (njs_vm_value_to_string(vm, &msg, njs_arg(args, nargs, 1)) == NJS_ERROR) { return NJS_ERROR; @@ -1797,7 +1797,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, arg = njs_arg(args, nargs, 2); if (njs_value_is_string(arg)) { - if (njs_vm_value_to_ext_string(vm, &args_arg, arg, 0) != NJS_OK) { + if (njs_vm_value_to_string(vm, &args_arg, arg) != NJS_OK) { njs_vm_error(vm, "failed to convert args"); return NJS_ERROR; } @@ -2172,7 +2172,7 @@ ngx_http_js_handle_event(ngx_http_reques rc = njs_vm_run(ctx->vm); if (rc == NJS_ERROR) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -2190,7 +2190,7 @@ static njs_ret_t ngx_http_js_string(njs_vm_t *vm, const njs_value_t *value, nxt_str_t *str) { if (!njs_value_is_null_or_undefined(value)) { - if (njs_vm_value_to_ext_string(vm, str, value, 0) == NJS_ERROR) { + if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) { return NJS_ERROR; } @@ -2342,7 +2342,7 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_ rc = njs_vm_compile(jmcf->vm, &start, end); if (rc != NJS_OK) { - njs_vm_retval_to_ext_string(jmcf->vm, &text); + njs_vm_retval_string(jmcf->vm, &text); ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%*s, included", diff -r 5a7de2ee74ba -r e03f3e12589e nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Tue Jul 02 22:10:19 2019 -0400 +++ b/nginx/ngx_stream_js_module.c Tue Jul 02 22:18:56 2019 -0400 @@ -489,7 +489,7 @@ ngx_stream_js_phase_handler(ngx_stream_s exception: - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, c->log, 0, "js exception: %*s", exception.length, exception.start); @@ -615,7 +615,7 @@ ngx_stream_js_body_filter(ngx_stream_ses exception: - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, c->log, 0, "js exception: %*s", exception.length, exception.start); @@ -666,7 +666,7 @@ ngx_stream_js_variable(ngx_stream_sessio pending = njs_vm_pending(ctx->vm); if (njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->args), 1) != NJS_OK) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -675,7 +675,7 @@ ngx_stream_js_variable(ngx_stream_sessio return NGX_OK; } - if (njs_vm_retval_to_ext_string(ctx->vm, &value) != NJS_OK) { + if (njs_vm_retval_string(ctx->vm, &value) != NJS_OK) { return NGX_ERROR; } @@ -740,7 +740,7 @@ ngx_stream_js_init_vm(ngx_stream_session cln->data = ctx; if (njs_vm_start(ctx->vm) == NJS_ERROR) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -1016,7 +1016,7 @@ ngx_stream_js_ext_log_core(njs_vm_t *vm, c = s->connection; - if (njs_vm_value_to_ext_string(vm, &msg, njs_arg(args, nargs, 1), 0) + if (njs_vm_value_to_string(vm, &msg, njs_arg(args, nargs, 1)) == NJS_ERROR) { return NJS_ERROR; @@ -1047,7 +1047,7 @@ ngx_stream_js_ext_on(njs_vm_t *vm, njs_v return NJS_ERROR; } - if (njs_vm_value_to_ext_string(vm, &name, njs_arg(args, nargs, 1), 0) + if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1)) == NJS_ERROR) { njs_vm_error(vm, "failed to convert event arg"); @@ -1093,7 +1093,7 @@ ngx_stream_js_ext_off(njs_vm_t *vm, njs_ return NJS_ERROR; } - if (njs_vm_value_to_ext_string(vm, &name, njs_arg(args, nargs, 1), 0) + if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1)) == NJS_ERROR) { njs_vm_error(vm, "failed to convert event arg"); @@ -1362,7 +1362,7 @@ ngx_stream_js_handle_event(ngx_stream_se rc = njs_vm_run(ctx->vm); if (rc == NJS_ERROR) { - njs_vm_retval_to_ext_string(ctx->vm, &exception); + njs_vm_retval_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "js exception: %*s", exception.length, exception.start); @@ -1380,7 +1380,7 @@ static njs_ret_t ngx_stream_js_string(njs_vm_t *vm, const njs_value_t *value, nxt_str_t *str) { if (!njs_value_is_null_or_undefined(value)) { - if (njs_vm_value_to_ext_string(vm, str, value, 0) == NJS_ERROR) { + if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) { return NJS_ERROR; } @@ -1533,7 +1533,7 @@ ngx_stream_js_include(ngx_conf_t *cf, ng rc = njs_vm_compile(jmcf->vm, &start, end); if (rc != NJS_OK) { - njs_vm_retval_to_ext_string(jmcf->vm, &text); + njs_vm_retval_string(jmcf->vm, &text); ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%*s, included", diff -r 5a7de2ee74ba -r e03f3e12589e njs/njs.c --- a/njs/njs.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/njs.c Tue Jul 02 22:18:56 2019 -0400 @@ -838,8 +838,167 @@ njs_vm_memory_error(njs_vm_t *vm) } +nxt_array_t * +njs_vm_backtrace(njs_vm_t *vm) +{ + if (vm->backtrace != NULL && !nxt_array_is_empty(vm->backtrace)) { + return vm->backtrace; + } + + return NULL; +} + + +static njs_ret_t +njs_vm_backtrace_dump(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src) +{ + u_char *p, *start, *end; + size_t len, count; + nxt_uint_t i; + nxt_array_t *backtrace; + njs_backtrace_entry_t *be, *prev; + + backtrace = njs_vm_backtrace(vm); + + len = dst->length + 1; + + count = 0; + prev = NULL; + + be = backtrace->start; + + for (i = 0; i < backtrace->items; i++) { + if (i != 0 && prev->name.start == be->name.start + && prev->line == be->line) + { + count++; + + } else { + + if (count != 0) { + len += nxt_length(" repeats times\n") + + NXT_INT_T_LEN; + count = 0; + } + + len += be->name.length + nxt_length(" at ()\n"); + + if (be->line != 0) { + len += be->file.length + NXT_INT_T_LEN + 1; + + } else { + len += nxt_length("native"); + } + } + + prev = be; + be++; + } + + p = nxt_mp_alloc(vm->mem_pool, len); + if (p == NULL) { + njs_memory_error(vm); + return NXT_ERROR; + } + + start = p; + end = start + len; + + p = nxt_cpymem(p, dst->start, dst->length); + *p++ = '\n'; + + count = 0; + prev = NULL; + + be = backtrace->start; + + for (i = 0; i < backtrace->items; i++) { + if (i != 0 && prev->name.start == be->name.start + && prev->line == be->line) + { + count++; + + } else { + if (count != 0) { + p = nxt_sprintf(p, end, " repeats %uz times\n", + count); + count = 0; + } + + p = nxt_sprintf(p, end, " at %V ", &be->name); + + if (be->line != 0) { + p = nxt_sprintf(p, end, "(%V:%uD)\n", &be->file, + be->line); + + } else { + p = nxt_sprintf(p, end, "(native)\n"); + } + } + + prev = be; + be++; + } + + dst->start = start; + dst->length = p - dst->start; + + return NXT_OK; +} + + njs_ret_t -njs_vm_retval_to_ext_string(njs_vm_t *vm, nxt_str_t *dst) +njs_vm_value_string(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src) +{ + njs_ret_t ret; + nxt_uint_t exception; + + if (nxt_slow_path(src->type == NJS_NUMBER + && njs_number(src) == 0 + && signbit(njs_number(src)))) + { + njs_string_get(&njs_string_minus_zero, dst); + return NXT_OK; + } + + exception = 1; + +again: + + ret = njs_vm_value_to_string(vm, dst, src); + + if (nxt_fast_path(ret == NXT_OK)) { + + if (njs_vm_backtrace(vm) != NULL) { + ret = njs_vm_backtrace_dump(vm, dst, src); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + } + + return NXT_OK; + } + + if (exception) { + exception = 0; + + /* value evaluation threw an exception. */ + + vm->top_frame->trap_tries = 0; + + src = &vm->retval; + goto again; + } + + dst->length = 0; + dst->start = NULL; + + return NXT_ERROR; +} + + +njs_ret_t +njs_vm_retval_string(njs_vm_t *vm, nxt_str_t *dst) { if (vm->top_frame == NULL) { /* An exception was thrown during compilation. */ @@ -847,7 +1006,7 @@ njs_vm_retval_to_ext_string(njs_vm_t *vm njs_vm_init(vm); } - return njs_vm_value_to_ext_string(vm, dst, &vm->retval, 1); + return njs_vm_value_string(vm, dst, &vm->retval); } diff -r 5a7de2ee74ba -r e03f3e12589e njs/njs.h --- a/njs/njs.h Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/njs.h Tue Jul 02 22:18:56 2019 -0400 @@ -249,9 +249,19 @@ NXT_EXPORT u_char *njs_vm_value_string_a uint32_t size); NXT_EXPORT nxt_int_t njs_vm_value_string_copy(njs_vm_t *vm, nxt_str_t *retval, const njs_value_t *value, uintptr_t *next); -NXT_EXPORT njs_ret_t njs_vm_value_to_ext_string(njs_vm_t *vm, nxt_str_t *dst, - const njs_value_t *src, nxt_uint_t handle_exception); -NXT_EXPORT njs_ret_t njs_vm_retval_to_ext_string(njs_vm_t *vm, nxt_str_t *dst); + +/* + * Converts a value to string. + */ +NXT_EXPORT njs_ret_t njs_vm_value_to_string(njs_vm_t *vm, nxt_str_t *dst, + const njs_value_t *src); + +/* + * Calls njs_vm_value_to_string(), if exception was thrown adds backtrace. + */ +NXT_EXPORT njs_ret_t njs_vm_value_string(njs_vm_t *vm, nxt_str_t *dst, + const njs_value_t *src); +NXT_EXPORT njs_ret_t njs_vm_retval_string(njs_vm_t *vm, nxt_str_t *dst); NXT_EXPORT njs_ret_t njs_vm_value_dump(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *value, nxt_uint_t console, nxt_uint_t indent); diff -r 5a7de2ee74ba -r e03f3e12589e njs/njs_json.c --- a/njs/njs_json.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/njs_json.c Tue Jul 02 22:18:56 2019 -0400 @@ -2566,7 +2566,7 @@ memory_error: exception: - njs_vm_value_to_ext_string(vm, retval, &vm->retval, 1); + njs_vm_value_string(vm, retval, &vm->retval); return NXT_OK; } diff -r 5a7de2ee74ba -r e03f3e12589e njs/njs_object_property.c --- a/njs/njs_object_property.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/njs_object_property.c Tue Jul 02 22:18:56 2019 -0400 @@ -437,7 +437,7 @@ njs_external_property_set(njs_vm_t *vm, pq = (njs_property_query_t *) vm->stash; if (!njs_is_null_or_undefined(setval)) { - ret = njs_vm_value_to_ext_string(vm, &s, setval, 0); + ret = njs_vm_value_to_string(vm, &s, setval); if (nxt_slow_path(ret != NXT_OK)) { return ret; } diff -r 5a7de2ee74ba -r e03f3e12589e njs/njs_vm.c --- a/njs/njs_vm.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/njs_vm.c Tue Jul 02 22:18:56 2019 -0400 @@ -3086,184 +3086,58 @@ njs_value_own_enumerate(njs_vm_t *vm, co njs_ret_t -njs_vm_value_to_ext_string(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src, - nxt_uint_t handle_exception) +njs_vm_value_to_string(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src) { - u_char *p, *start, *end; - size_t len, size, count; - njs_ret_t ret; - nxt_uint_t i, exception; - nxt_array_t *backtrace; - njs_value_t value; - njs_backtrace_entry_t *be, *prev; - - exception = handle_exception; - -again: - - if (nxt_fast_path(src != NULL)) { - - if (nxt_slow_path(src->type == NJS_OBJECT_INTERNAL_ERROR)) { - - /* MemoryError is a nonextensible internal error. */ - - if (!src->data.u.object->extensible) { - njs_string_get(&njs_string_memory_error, dst); - return NXT_OK; - } - } - - value = *src; - - if (nxt_slow_path(!njs_is_primitive(&value))) { - - ret = njs_object_value_to_string(vm, &value); - - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } - } - - if (nxt_slow_path((value.type == NJS_NUMBER - && value.data.u.number == 0 - && signbit(value.data.u.number)))) - { - value = njs_string_minus_zero; - ret = NXT_OK; - - } else { - ret = njs_primitive_value_to_string(vm, &value, &value); - } - - if (nxt_fast_path(ret == NXT_OK)) { - size = value.short_string.size; - - if (size != NJS_STRING_LONG) { - start = nxt_mp_alloc(vm->mem_pool, size); - if (nxt_slow_path(start == NULL)) { - njs_memory_error(vm); - return NXT_ERROR; - } - - memcpy(start, value.short_string.start, size); - - } else { - size = value.long_string.size; - start = value.long_string.data->start; - } - - dst->length = size; - dst->start = start; - - if (exception && njs_vm_backtrace(vm) != NULL) { - - backtrace = njs_vm_backtrace(vm); - - len = dst->length + 1; - - count = 0; - prev = NULL; - - be = backtrace->start; - - for (i = 0; i < backtrace->items; i++) { - if (i != 0 && prev->name.start == be->name.start - && prev->line == be->line) - { - count++; - - } else { - - if (count != 0) { - len += nxt_length(" repeats times\n") - + NXT_INT_T_LEN; - count = 0; - } - - len += be->name.length + nxt_length(" at ()\n"); - - if (be->line != 0) { - len += be->file.length + NXT_INT_T_LEN + 1; - - } else { - len += nxt_length("native"); - } - } - - prev = be; - be++; - } - - p = nxt_mp_alloc(vm->mem_pool, len); - if (p == NULL) { - njs_memory_error(vm); - return NXT_ERROR; - } - - start = p; - end = start + len; - - p = nxt_cpymem(p, dst->start, dst->length); - *p++ = '\n'; - - count = 0; - prev = NULL; - - be = backtrace->start; - - for (i = 0; i < backtrace->items; i++) { - if (i != 0 && prev->name.start == be->name.start - && prev->line == be->line) - { - count++; - - } else { - if (count != 0) { - p = nxt_sprintf(p, end, " repeats %uz times\n", - count); - count = 0; - } - - p = nxt_sprintf(p, end, " at %V ", &be->name); - - if (be->line != 0) { - p = nxt_sprintf(p, end, "(%V:%uD)\n", &be->file, - be->line); - - } else { - p = nxt_sprintf(p, end, "(native)\n"); - } - } - - prev = be; - be++; - } - - dst->start = start; - dst->length = p - dst->start; - } - + u_char *start; + size_t size; + njs_ret_t ret; + njs_value_t value; + + if (nxt_slow_path(src == NULL)) { + return NXT_ERROR; + } + + if (nxt_slow_path(src->type == NJS_OBJECT_INTERNAL_ERROR)) { + /* MemoryError is a nonextensible internal error. */ + if (!src->data.u.object->extensible) { + njs_string_get(&njs_string_memory_error, dst); return NXT_OK; } } -fail: - - if (handle_exception) { - handle_exception = 0; - - /* value evaluation threw an exception. */ - - vm->top_frame->trap_tries = 0; - - src = &vm->retval; - goto again; + value = *src; + + if (nxt_slow_path(!njs_is_primitive(&value))) { + ret = njs_object_value_to_string(vm, &value); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } } - dst->length = 0; - dst->start = NULL; - - return NXT_ERROR; + ret = njs_primitive_value_to_string(vm, &value, &value); + + if (nxt_fast_path(ret == NXT_OK)) { + size = value.short_string.size; + + if (size != NJS_STRING_LONG) { + start = nxt_mp_alloc(vm->mem_pool, size); + if (nxt_slow_path(start == NULL)) { + njs_memory_error(vm); + return NXT_ERROR; + } + + memcpy(start, value.short_string.start, size); + + } else { + size = value.long_string.size; + start = value.long_string.data->start; + } + + dst->length = size; + dst->start = start; + } + + return ret; } @@ -3299,7 +3173,7 @@ njs_object_value_to_string(njs_vm_t *vm, /* * Prevent njs_vmcode_interpreter() to unwind the current frame if * an exception happens. It preserves the current frame state if - * njs_vm_value_to_ext_string() is called from within njs_vm_run(). + * njs_vm_value_string() is called from within njs_vm_run(). */ previous = vm->top_frame->previous; vm->top_frame->previous = NULL; @@ -3371,7 +3245,7 @@ njs_vm_value_string_copy(njs_vm_t *vm, n return NXT_ERROR; } - return njs_vm_value_to_ext_string(vm, retval, value, 0); + return njs_vm_value_to_string(vm, retval, value); } @@ -3443,17 +3317,6 @@ njs_vm_add_backtrace_entry(njs_vm_t *vm, } -nxt_array_t * -njs_vm_backtrace(njs_vm_t *vm) -{ - if (vm->backtrace != NULL && !nxt_array_is_empty(vm->backtrace)) { - return vm->backtrace; - } - - return NULL; -} - - void njs_debug(njs_index_t index, njs_value_t *value) { diff -r 5a7de2ee74ba -r e03f3e12589e njs/test/njs_benchmark.c --- a/njs/test/njs_benchmark.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/test/njs_benchmark.c Tue Jul 02 22:18:56 2019 -0400 @@ -56,8 +56,8 @@ njs_unit_test_benchmark(nxt_str_t *scrip (void) njs_vm_start(nvm); - if (njs_vm_retval_to_ext_string(nvm, &s) != NXT_OK) { - nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + if (njs_vm_retval_string(nvm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_string() failed\n"); goto done; } diff -r 5a7de2ee74ba -r e03f3e12589e njs/test/njs_interactive_test.c --- a/njs/test/njs_interactive_test.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/test/njs_interactive_test.c Tue Jul 02 22:18:56 2019 -0400 @@ -226,7 +226,7 @@ static njs_interactive_test_t njs_test[ " repeats 2 times\n" " at main (native)\n") }, - /* Exception in njs_vm_retval_to_ext_string() */ + /* Exception in njs_vm_retval_string() */ { nxt_string("var o = { toString: function() { return [1] } }" ENTER "o" ENTER), @@ -305,8 +305,8 @@ njs_interactive_test(nxt_bool_t verbose) } } - if (njs_vm_retval_to_ext_string(vm, &s) != NXT_OK) { - nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + if (njs_vm_retval_string(vm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_string() failed\n"); goto done; } diff -r 5a7de2ee74ba -r e03f3e12589e njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 02 22:10:19 2019 -0400 +++ b/njs/test/njs_unit_test.c Tue Jul 02 22:18:56 2019 -0400 @@ -13427,7 +13427,7 @@ njs_unit_test_method_external(njs_vm_t * return NJS_ERROR; } - ret = njs_vm_value_to_ext_string(vm, &s, njs_arg(args, nargs, 1), 0); + ret = njs_vm_value_to_string(vm, &s, njs_arg(args, nargs, 1)); if (ret == NXT_OK && s.length == 3 && memcmp(s.start, "YES", 3) == 0) { return njs_vm_value_string_set(vm, njs_vm_retval(vm), r->uri.start, r->uri.length); @@ -13453,9 +13453,7 @@ njs_unit_test_create_external(njs_vm_t * return NJS_ERROR; } - if (njs_vm_value_to_ext_string(vm, &uri, njs_arg(args, nargs, 1), 0) - != NJS_OK) - { + if (njs_vm_value_to_string(vm, &uri, njs_arg(args, nargs, 1)) != NJS_OK) { return NJS_ERROR; } @@ -13799,14 +13797,14 @@ njs_unit_test(njs_unit_test_t tests[], s ret = njs_vm_start(nvm); - if (njs_vm_retval_to_ext_string(nvm, &s) != NXT_OK) { - nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + if (njs_vm_retval_string(nvm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_string() failed\n"); goto done; } } else { - if (njs_vm_retval_to_ext_string(vm, &s) != NXT_OK) { - nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + if (njs_vm_retval_string(vm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_string() failed\n"); goto done; } } @@ -14015,8 +14013,8 @@ njs_vm_json_test(nxt_bool_t disassemble, goto done; } - if (njs_vm_retval_to_ext_string(vm, &s) != NXT_OK) { - nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + if (njs_vm_retval_string(vm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_string() failed\n"); goto done; } @@ -14042,8 +14040,8 @@ done: nxt_printf("njs_vm_json_test passed\n"); } else { - if (njs_vm_retval_to_ext_string(vm, &s) != NXT_OK) { - nxt_printf("njs_vm_retval_to_ext_string() failed\n"); + if (njs_vm_retval_string(vm, &s) != NXT_OK) { + nxt_printf("njs_vm_retval_string() failed\n"); } else { nxt_printf("%V\n", &s); From xeioex at nginx.com Mon Jul 8 12:46:40 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 08 Jul 2019 12:46:40 +0000 Subject: [njs] Added njs_date() and njs_set_date() macros. Message-ID: details: https://hg.nginx.org/njs/rev/aa688dbdc7de branches: changeset: 1032:aa688dbdc7de user: Dmitry Volyntsev date: Mon Jul 08 15:31:39 2019 +0300 description: Added njs_date() and njs_set_date() macros. diffstat: njs/njs_date.c | 170 +++++++++++++++++++++++++++---------------------------- njs/njs_value.h | 13 ++++ 2 files changed, 97 insertions(+), 86 deletions(-) diffs (683 lines): diff -r 5c774a8c8332 -r aa688dbdc7de njs/njs_date.c --- a/njs/njs_date.c Sat Jul 06 10:27:14 2019 -0400 +++ b/njs/njs_date.c Mon Jul 08 15:31:39 2019 +0300 @@ -90,13 +90,13 @@ njs_date_constructor(njs_vm_t *vm, njs_v return njs_trap(vm, NJS_TRAP_PRIMITIVE_ARG); } - time = args[1].data.u.date->time; + time = njs_date(&args[1])->time; } else if (njs_is_string(&args[1])) { time = njs_date_string_parse(&args[1]); } else { - time = args[1].data.u.number; + time = njs_number(&args[1]); } } else { @@ -113,7 +113,7 @@ njs_date_constructor(njs_vm_t *vm, njs_v return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } - num = args[i].data.u.number; + num = njs_number(&args[i]); if (isnan(num)) { time = num; @@ -156,9 +156,7 @@ njs_date_constructor(njs_vm_t *vm, njs_v date->time = njs_timeclip(time); - vm->retval.data.u.date = date; - vm->retval.type = NJS_DATE; - vm->retval.data.truth = 1; + njs_set_date(&vm->retval, date); return NXT_OK; } @@ -190,7 +188,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } - num = args[i].data.u.number; + num = njs_number(&args[i]); if (isnan(num)) { goto done; @@ -947,7 +945,7 @@ static njs_ret_t njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - njs_set_number(&vm->retval, args[0].data.u.date->time); + njs_set_number(&vm->retval, njs_date(&args[0])->time); return NXT_OK; } @@ -958,7 +956,7 @@ njs_date_prototype_to_string(njs_vm_t *v njs_index_t unused) { return njs_date_string(vm, "%a %b %d %Y %T GMT%z (%Z)", - args[0].data.u.date->time); + njs_date(&args[0])->time); } @@ -966,7 +964,7 @@ static njs_ret_t njs_date_prototype_to_date_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - return njs_date_string(vm, "%a %b %d %Y", args[0].data.u.date->time); + return njs_date_string(vm, "%a %b %d %Y", njs_date(&args[0])->time); } @@ -974,7 +972,7 @@ static njs_ret_t njs_date_prototype_to_time_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - return njs_date_string(vm, "%T GMT%z (%Z)", args[0].data.u.date->time); + return njs_date_string(vm, "%T GMT%z (%Z)", njs_date(&args[0])->time); } @@ -1016,7 +1014,7 @@ njs_date_prototype_to_utc_string(njs_vm_ static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (!isnan(time)) { clock = time / 1000; @@ -1053,7 +1051,7 @@ njs_date_to_string(njs_vm_t *vm, njs_val u_char buf[NJS_ISO_DATE_TIME_LEN], *p; struct tm tm; - time = date->data.u.date->time; + time = njs_date(date)->time; if (!isnan(time)) { clock = time / 1000; @@ -1085,7 +1083,7 @@ njs_date_prototype_get_full_year(njs_vm_ time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1108,7 +1106,7 @@ njs_date_prototype_get_utc_full_year(njs time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1131,7 +1129,7 @@ njs_date_prototype_get_month(njs_vm_t *v time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1154,7 +1152,7 @@ njs_date_prototype_get_utc_month(njs_vm_ time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1178,7 +1176,7 @@ njs_date_prototype_get_date(njs_vm_t *vm time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1201,7 +1199,7 @@ njs_date_prototype_get_utc_date(njs_vm_t time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1224,7 +1222,7 @@ njs_date_prototype_get_day(njs_vm_t *vm, time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1247,7 +1245,7 @@ njs_date_prototype_get_utc_day(njs_vm_t time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1270,7 +1268,7 @@ njs_date_prototype_get_hours(njs_vm_t *v time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1294,7 +1292,7 @@ njs_date_prototype_get_utc_hours(njs_vm_ time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1317,7 +1315,7 @@ njs_date_prototype_get_minutes(njs_vm_t time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1341,7 +1339,7 @@ njs_date_prototype_get_utc_minutes(njs_v time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1362,7 +1360,7 @@ njs_date_prototype_get_seconds(njs_vm_t { double value; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { value = (int64_t) (value / 1000) % 60; @@ -1380,7 +1378,7 @@ njs_date_prototype_get_milliseconds(njs_ { double value; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { value = (int64_t) value % 1000; @@ -1400,7 +1398,7 @@ njs_date_prototype_get_timezone_offset(n time_t clock; struct tm tm; - value = args[0].data.u.date->time; + value = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(value))) { clock = value / 1000; @@ -1421,19 +1419,19 @@ njs_date_prototype_set_time(njs_vm_t *vm { double time; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { - time = args[1].data.u.number; + time = njs_number(&args[1]); } else { time = NAN; } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1446,19 +1444,19 @@ njs_date_prototype_set_milliseconds(njs_ { double time; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { - time = (int64_t) (time / 1000) * 1000 + args[1].data.u.number; + time = (int64_t) (time / 1000) * 1000 + njs_number(&args[1]); } else { time = NAN; } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1472,13 +1470,13 @@ njs_date_prototype_set_seconds(njs_vm_t double time; int64_t sec, ms; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { - sec = args[1].data.u.number; - ms = (nargs > 2) ? args[2].data.u.number : (int64_t) time % 1000; + sec = njs_number(&args[1]); + ms = (nargs > 2) ? njs_number(&args[2]) : (int64_t) time % 1000; time = (int64_t) (time / 60000) * 60000 + sec * 1000 + ms; @@ -1487,7 +1485,7 @@ njs_date_prototype_set_seconds(njs_vm_t } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1503,7 +1501,7 @@ njs_date_prototype_set_minutes(njs_vm_t int64_t ms; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1511,13 +1509,13 @@ njs_date_prototype_set_minutes(njs_vm_t clock = time / 1000; localtime_r(&clock, &tm); - tm.tm_min = args[1].data.u.number; + tm.tm_min = njs_number(&args[1]); if (nargs > 2) { - tm.tm_sec = args[2].data.u.number; + tm.tm_sec = njs_number(&args[2]); } - ms = (nargs > 3) ? args[3].data.u.number : (int64_t) time % 1000; + ms = (nargs > 3) ? njs_number(&args[3]) : (int64_t) time % 1000; time = njs_date_time(&tm, ms); @@ -1526,7 +1524,7 @@ njs_date_prototype_set_minutes(njs_vm_t } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1540,19 +1538,19 @@ njs_date_prototype_set_utc_minutes(njs_v double time; int64_t clock, min, sec, ms; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; - sec = (nargs > 2) ? args[2].data.u.number : clock % 60; - min = args[1].data.u.number; + sec = (nargs > 2) ? njs_number(&args[2]) : clock % 60; + min = njs_number(&args[1]); clock = clock / 3600 * 3600 + min * 60 + sec; - ms = (nargs > 3) ? args[3].data.u.number : (int64_t) time % 1000; + ms = (nargs > 3) ? njs_number(&args[3]) : (int64_t) time % 1000; time = clock * 1000 + ms; @@ -1561,7 +1559,7 @@ njs_date_prototype_set_utc_minutes(njs_v } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1577,7 +1575,7 @@ njs_date_prototype_set_hours(njs_vm_t *v int64_t ms; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1585,17 +1583,17 @@ njs_date_prototype_set_hours(njs_vm_t *v clock = time / 1000; localtime_r(&clock, &tm); - tm.tm_hour = args[1].data.u.number; + tm.tm_hour = njs_number(&args[1]); if (nargs > 2) { - tm.tm_min = args[2].data.u.number; + tm.tm_min = njs_number(&args[2]); } if (nargs > 3) { - tm.tm_sec = args[3].data.u.number; + tm.tm_sec = njs_number(&args[3]); } - ms = (nargs > 4) ? args[4].data.u.number : (int64_t) time % 1000; + ms = (nargs > 4) ? njs_number(&args[4]) : (int64_t) time % 1000; time = njs_date_time(&tm, ms); @@ -1604,7 +1602,7 @@ njs_date_prototype_set_hours(njs_vm_t *v } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1618,20 +1616,20 @@ njs_date_prototype_set_utc_hours(njs_vm_ double time; int64_t clock, hour, min, sec, ms; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { if (nargs > 1) { clock = time / 1000; - sec = (nargs > 3) ? args[3].data.u.number : clock % 60; - min = (nargs > 2) ? args[2].data.u.number : clock / 60 % 60; - hour = args[1].data.u.number; + sec = (nargs > 3) ? njs_number(&args[3]) : clock % 60; + min = (nargs > 2) ? njs_number(&args[2]) : clock / 60 % 60; + hour = njs_number(&args[1]); clock = clock / 86400 * 86400 + hour * 3600 + min * 60 + sec; - ms = (nargs > 4) ? args[4].data.u.number : (int64_t) time % 1000; + ms = (nargs > 4) ? njs_number(&args[4]) : (int64_t) time % 1000; time = clock * 1000 + ms; @@ -1640,7 +1638,7 @@ njs_date_prototype_set_utc_hours(njs_vm_ } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1655,7 +1653,7 @@ njs_date_prototype_set_date(njs_vm_t *vm time_t clock; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1663,7 +1661,7 @@ njs_date_prototype_set_date(njs_vm_t *vm clock = time / 1000; localtime_r(&clock, &tm); - tm.tm_mday = args[1].data.u.number; + tm.tm_mday = njs_number(&args[1]); time = njs_date_time(&tm, (int64_t) time % 1000); @@ -1672,7 +1670,7 @@ njs_date_prototype_set_date(njs_vm_t *vm } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1687,7 +1685,7 @@ njs_date_prototype_set_utc_date(njs_vm_t time_t clock; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1695,7 +1693,7 @@ njs_date_prototype_set_utc_date(njs_vm_t clock = time / 1000; gmtime_r(&clock, &tm); - tm.tm_mday = args[1].data.u.number; + tm.tm_mday = njs_number(&args[1]); time = njs_date_utc_time(&tm, time); @@ -1704,7 +1702,7 @@ njs_date_prototype_set_utc_date(njs_vm_t } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1719,7 +1717,7 @@ njs_date_prototype_set_month(njs_vm_t *v time_t clock; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1727,10 +1725,10 @@ njs_date_prototype_set_month(njs_vm_t *v clock = time / 1000; localtime_r(&clock, &tm); - tm.tm_mon = args[1].data.u.number; + tm.tm_mon = njs_number(&args[1]); if (nargs > 2) { - tm.tm_mday = args[2].data.u.number; + tm.tm_mday = njs_number(&args[2]); } time = njs_date_time(&tm, (int64_t) time % 1000); @@ -1740,7 +1738,7 @@ njs_date_prototype_set_month(njs_vm_t *v } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1755,7 +1753,7 @@ njs_date_prototype_set_utc_month(njs_vm_ time_t clock; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1763,10 +1761,10 @@ njs_date_prototype_set_utc_month(njs_vm_ clock = time / 1000; gmtime_r(&clock, &tm); - tm.tm_mon = args[1].data.u.number; + tm.tm_mon = njs_number(&args[1]); if (nargs > 2) { - tm.tm_mday = args[2].data.u.number; + tm.tm_mday = njs_number(&args[2]); } time = njs_date_utc_time(&tm, time); @@ -1776,7 +1774,7 @@ njs_date_prototype_set_utc_month(njs_vm_ } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1791,7 +1789,7 @@ njs_date_prototype_set_full_year(njs_vm_ time_t clock; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1799,14 +1797,14 @@ njs_date_prototype_set_full_year(njs_vm_ clock = time / 1000; localtime_r(&clock, &tm); - tm.tm_year = args[1].data.u.number - 1900; + tm.tm_year = njs_number(&args[1]) - 1900; if (nargs > 2) { - tm.tm_mon = args[2].data.u.number; + tm.tm_mon = njs_number(&args[2]); } if (nargs > 3) { - tm.tm_mday = args[3].data.u.number; + tm.tm_mday = njs_number(&args[3]); } time = njs_date_time(&tm, (int64_t) time % 1000); @@ -1816,7 +1814,7 @@ njs_date_prototype_set_full_year(njs_vm_ } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1831,7 +1829,7 @@ njs_date_prototype_set_utc_full_year(njs time_t clock; struct tm tm; - time = args[0].data.u.date->time; + time = njs_date(&args[0])->time; if (nxt_fast_path(!isnan(time))) { @@ -1839,14 +1837,14 @@ njs_date_prototype_set_utc_full_year(njs clock = time / 1000; gmtime_r(&clock, &tm); - tm.tm_year = args[1].data.u.number - 1900; + tm.tm_year = njs_number(&args[1]) - 1900; if (nargs > 2) { - tm.tm_mon = args[2].data.u.number; + tm.tm_mon = njs_number(&args[2]); } if (nargs > 3) { - tm.tm_mday = args[3].data.u.number; + tm.tm_mday = njs_number(&args[3]); } time = njs_date_utc_time(&tm, time); @@ -1856,7 +1854,7 @@ njs_date_prototype_set_utc_full_year(njs } } - args[0].data.u.date->time = time; + njs_date(&args[0])->time = time; njs_set_number(&vm->retval, time); return NXT_OK; @@ -1901,10 +1899,10 @@ njs_date_prototype_to_json(njs_vm_t *vm, lhq.key_hash = NJS_TO_ISO_STRING_HASH; lhq.key = nxt_string_value("toISOString"); - prop = njs_object_property(vm, args[0].data.u.object, &lhq); + prop = njs_object_property(vm, njs_object(&args[0]), &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { - return njs_function_replace(vm, prop->value.data.u.function, + return njs_function_replace(vm, njs_function(&prop->value), args, nargs, retval); } } diff -r 5c774a8c8332 -r aa688dbdc7de njs/njs_value.h --- a/njs/njs_value.h Sat Jul 06 10:27:14 2019 -0400 +++ b/njs/njs_value.h Mon Jul 08 15:31:39 2019 +0300 @@ -536,6 +536,10 @@ typedef enum { ((value)->data.u.array->start) +#define njs_date(value) \ + ((value)->data.u.date) + + #define njs_set_undefined(value) \ *(value) = njs_value_undefined @@ -588,6 +592,15 @@ njs_set_array(njs_value_t *value, njs_ar } +nxt_inline void +njs_set_date(njs_value_t *value, njs_date_t *date) +{ + value->data.u.date = date; + value->type = NJS_DATE; + value->data.truth = 1; +} + + #define njs_set_invalid(value) \ (value)->type = NJS_INVALID From xeioex at nginx.com Mon Jul 8 12:46:39 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 08 Jul 2019 12:46:39 +0000 Subject: [njs] Moving value methods to njs_value.c. Message-ID: details: https://hg.nginx.org/njs/rev/5c774a8c8332 branches: changeset: 1031:5c774a8c8332 user: hongzhidao date: Sat Jul 06 10:27:14 2019 -0400 description: Moving value methods to njs_value.c. diffstat: auto/sources | 1 + njs/njs_core.h | 1 + njs/njs_value.c | 418 +++++++++++++++++++++++++++++++++++ njs/njs_value.h | 660 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ njs/njs_vm.c | 431 +----------------------------------- njs/njs_vm.h | 652 +------------------------------------------------------- 6 files changed, 1091 insertions(+), 1072 deletions(-) diffs (truncated from 2351 to 1000 lines): diff -r e03f3e12589e -r 5c774a8c8332 auto/sources --- a/auto/sources Tue Jul 02 22:18:56 2019 -0400 +++ b/auto/sources Sat Jul 06 10:27:14 2019 -0400 @@ -30,6 +30,7 @@ NXT_TEST_SRCS=" \ NJS_LIB_SRCS=" \ njs/njs.c \ + njs/njs_value.c \ njs/njs_vm.c \ njs/njs_boolean.c \ njs/njs_number.c \ diff -r e03f3e12589e -r 5c774a8c8332 njs/njs_core.h --- a/njs/njs_core.h Tue Jul 02 22:18:56 2019 -0400 +++ b/njs/njs_core.h Sat Jul 06 10:27:14 2019 -0400 @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff -r e03f3e12589e -r 5c774a8c8332 njs/njs_value.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/njs/njs_value.c Sat Jul 06 10:27:14 2019 -0400 @@ -0,0 +1,418 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include +#include + + +const njs_value_t njs_value_null = njs_value(NJS_NULL, 0, 0.0); +const njs_value_t njs_value_undefined = njs_value(NJS_UNDEFINED, 0, NAN); +const njs_value_t njs_value_false = njs_value(NJS_BOOLEAN, 0, 0.0); +const njs_value_t njs_value_true = njs_value(NJS_BOOLEAN, 1, 1.0); +const njs_value_t njs_value_zero = njs_value(NJS_NUMBER, 0, 0.0); +const njs_value_t njs_value_nan = njs_value(NJS_NUMBER, 0, NAN); +const njs_value_t njs_value_invalid = njs_value(NJS_INVALID, 0, 0.0); + +const njs_value_t njs_string_empty = njs_string(""); +const njs_value_t njs_string_comma = njs_string(","); +const njs_value_t njs_string_null = njs_string("null"); +const njs_value_t njs_string_undefined = njs_string("undefined"); +const njs_value_t njs_string_boolean = njs_string("boolean"); +const njs_value_t njs_string_false = njs_string("false"); +const njs_value_t njs_string_true = njs_string("true"); +const njs_value_t njs_string_number = njs_string("number"); +const njs_value_t njs_string_minus_zero = njs_string("-0"); +const njs_value_t njs_string_minus_infinity = + njs_string("-Infinity"); +const njs_value_t njs_string_plus_infinity = + njs_string("Infinity"); +const njs_value_t njs_string_nan = njs_string("NaN"); +const njs_value_t njs_string_string = njs_string("string"); +const njs_value_t njs_string_object = njs_string("object"); +const njs_value_t njs_string_function = njs_string("function"); +const njs_value_t njs_string_memory_error = njs_string("MemoryError"); + + +void +njs_value_retain(njs_value_t *value) +{ + njs_string_t *string; + + if (njs_is_string(value)) { + + if (value->long_string.external != 0xff) { + string = value->long_string.data; + + nxt_thread_log_debug("retain:%uxD \"%*s\"", string->retain, + value->long_string.size, string->start); + + if (string->retain != 0xffff) { + string->retain++; + } + } + } +} + + +void +njs_value_release(njs_vm_t *vm, njs_value_t *value) +{ + njs_string_t *string; + + if (njs_is_string(value)) { + + if (value->long_string.external != 0xff) { + string = value->long_string.data; + + nxt_thread_log_debug("release:%uxD \"%*s\"", string->retain, + value->long_string.size, string->start); + + if (string->retain != 0xffff) { + string->retain--; + +#if 0 + if (string->retain == 0) { + if ((u_char *) string + sizeof(njs_string_t) + != string->start) + { + nxt_memcache_pool_free(vm->mem_pool, + string->start); + } + + nxt_memcache_pool_free(vm->mem_pool, string); + } +#endif + } + } + } +} + + +nxt_bool_t +njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2) +{ + size_t size, length1, length2; + const u_char *start1, *start2; + + if (val1->type != val2->type) { + return 0; + } + + if (njs_is_numeric(val1)) { + + if (njs_is_undefined(val1)) { + return 1; + } + + /* Infinities are handled correctly by comparision. */ + return (val1->data.u.number == val2->data.u.number); + } + + if (njs_is_string(val1)) { + size = val1->short_string.size; + + if (size != val2->short_string.size) { + return 0; + } + + if (size != NJS_STRING_LONG) { + length1 = val1->short_string.length; + length2 = val2->short_string.length; + + /* + * Using full memcmp() comparison if at least one string + * is a Byte string. + */ + if (length1 != 0 && length2 != 0 && length1 != length2) { + return 0; + } + + start1 = val1->short_string.start; + start2 = val2->short_string.start; + + } else { + size = val1->long_string.size; + + if (size != val2->long_string.size) { + return 0; + } + + length1 = val1->long_string.data->length; + length2 = val2->long_string.data->length; + + /* + * Using full memcmp() comparison if at least one string + * is a Byte string. + */ + if (length1 != 0 && length2 != 0 && length1 != length2) { + return 0; + } + + start1 = val1->long_string.data->start; + start2 = val2->long_string.data->start; + } + + return (memcmp(start1, start2, size) == 0); + } + + return (val1->data.u.object == val2->data.u.object); +} + + +/* + * A hint value is 0 for numbers and 1 for strings. The value chooses + * method calls order specified by ECMAScript 5.1: "valueOf", "toString" + * for numbers and "toString", "valueOf" for strings. + */ + +njs_ret_t +njs_value_to_primitive(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) +{ + njs_ret_t ret; + njs_value_t *retval; + njs_function_t *function; + njs_object_prop_t *prop; + nxt_lvlhsh_query_t lhq; + + static const uint32_t hashes[] = { + NJS_VALUE_OF_HASH, + NJS_TO_STRING_HASH, + }; + + static const nxt_str_t names[] = { + nxt_string("valueOf"), + nxt_string("toString"), + }; + + if (!njs_is_primitive(value)) { + retval = &vm->top_frame->trap_scratch; + + if (!njs_is_primitive(retval)) { + + for ( ;; ) { + ret = NXT_ERROR; + + if (njs_is_object(value) && vm->top_frame->trap_tries < 2) { + hint ^= vm->top_frame->trap_tries++; + + lhq.key_hash = hashes[hint]; + lhq.key = names[hint]; + + prop = njs_object_property(vm, value->data.u.object, &lhq); + + if (nxt_fast_path(prop != NULL)) { + + if (!njs_is_function(&prop->value)) { + /* Try the second method. */ + continue; + } + + function = prop->value.data.u.function; + + ret = njs_function_apply(vm, function, value, 1, + (njs_index_t) retval); + /* + * njs_function_apply() can return + * NXT_OK, NJS_APPLIED, NXT_ERROR, NXT_AGAIN. + */ + if (nxt_fast_path(ret == NXT_OK)) { + + if (njs_is_primitive(&vm->retval)) { + retval = &vm->retval; + break; + } + + /* Try the second method. */ + continue; + } + + if (ret == NJS_APPLIED) { + /* + * A user-defined method or continuation have + * been prepared to run. The method will return + * to the current instruction and will restart it. + */ + ret = 0; + } + } + } + + if (ret == NXT_ERROR) { + njs_type_error(vm, + "Cannot convert object to primitive value"); + } + + return ret; + } + } + + *value = *retval; + + njs_set_invalid(retval); + } + + vm->top_frame->trap_tries = 0; + + return 1; +} + + +njs_array_t * +njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value, + njs_object_enum_t kind, nxt_bool_t all) +{ + njs_object_value_t obj_val; + + if (njs_is_object(value)) { + return njs_object_enumerate(vm, value->data.u.object, kind, all); + } + + if (value->type != NJS_STRING) { + return njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); + } + + obj_val.object = vm->string_object; + obj_val.value = *value; + + return njs_object_enumerate(vm, (njs_object_t *) &obj_val, kind, all); +} + + +njs_array_t * +njs_value_own_enumerate(njs_vm_t *vm, const njs_value_t *value, + njs_object_enum_t kind, nxt_bool_t all) +{ + njs_object_value_t obj_val; + + if (njs_is_object(value)) { + return njs_object_own_enumerate(vm, value->data.u.object, kind, all); + } + + if (value->type != NJS_STRING) { + return njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); + } + + obj_val.object = vm->string_object; + obj_val.value = *value; + + return njs_object_own_enumerate(vm, (njs_object_t *) &obj_val, kind, all); +} + + +const char * +njs_type_string(njs_value_type_t type) +{ + switch (type) { + case NJS_NULL: + return "null"; + + case NJS_UNDEFINED: + return "undefined"; + + case NJS_BOOLEAN: + return "boolean"; + + case NJS_NUMBER: + return "number"; + + case NJS_STRING: + return "string"; + + case NJS_EXTERNAL: + return "external"; + + case NJS_INVALID: + return "invalid"; + + case NJS_OBJECT: + return "object"; + + case NJS_ARRAY: + return "array"; + + case NJS_OBJECT_BOOLEAN: + return "object boolean"; + + case NJS_OBJECT_NUMBER: + return "object number"; + + case NJS_OBJECT_STRING: + return "object string"; + + case NJS_FUNCTION: + return "function"; + + case NJS_REGEXP: + return "regexp"; + + case NJS_DATE: + return "date"; + + case NJS_OBJECT_ERROR: + return "error"; + + case NJS_OBJECT_EVAL_ERROR: + return "eval error"; + + case NJS_OBJECT_INTERNAL_ERROR: + return "internal error"; + + case NJS_OBJECT_RANGE_ERROR: + return "range error"; + + case NJS_OBJECT_REF_ERROR: + return "reference error"; + + case NJS_OBJECT_SYNTAX_ERROR: + return "syntax error"; + + case NJS_OBJECT_TYPE_ERROR: + return "type error"; + + case NJS_OBJECT_URI_ERROR: + return "uri error"; + + default: + return NULL; + } +} + + +const char * +njs_arg_type_string(uint8_t arg) +{ + switch (arg) { + case NJS_SKIP_ARG: + return "skip"; + + case NJS_NUMBER_ARG: + return "number"; + + case NJS_INTEGER_ARG: + return "integer"; + + case NJS_STRING_ARG: + return "string"; + + case NJS_OBJECT_ARG: + return "object"; + + case NJS_STRING_OBJECT_ARG: + return "string object"; + + case NJS_FUNCTION_ARG: + return "function"; + + case NJS_REGEXP_ARG: + return "regexp"; + + case NJS_DATE_ARG: + return "date"; + + default: + return "unknown"; + } +} diff -r e03f3e12589e -r 5c774a8c8332 njs/njs_value.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/njs/njs_value.h Sat Jul 06 10:27:14 2019 -0400 @@ -0,0 +1,660 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NJS_VALUE_H_INCLUDED_ +#define _NJS_VALUE_H_INCLUDED_ + + +#include +#include +#include +#include +#include +#include + +#include + + +/* + * The order of the enum is used in njs_vmcode_typeof() + * and njs_object_prototype_to_string(). + */ + +typedef enum { + NJS_NULL = 0x00, + NJS_UNDEFINED = 0x01, + + /* The order of the above type is used in njs_is_null_or_undefined(). */ + + NJS_BOOLEAN = 0x02, + /* + * The order of the above type is used in + * njs_is_null_or_undefined_or_boolean(). + */ + NJS_NUMBER = 0x03, + /* + * The order of the above type is used in njs_is_numeric(). + * Booleans, null and void values can be used in mathematical operations: + * a numeric value of the true value is one, + * a numeric value of the null and false values is zero, + * a numeric value of the void value is NaN. + */ + NJS_STRING = 0x04, + + /* The order of the above type is used in njs_is_primitive(). */ + + NJS_DATA = 0x05, + + /* The type is external code. */ + NJS_EXTERNAL = 0x06, + + /* + * The invalid value type is used: + * for uninitialized array members, + * to detect non-declared explicitly or implicitly variables, + * for native property getters. + */ + NJS_INVALID = 0x07, + + /* + * The object types are >= NJS_OBJECT, this is used in njs_is_object(). + * NJS_OBJECT_BOOLEAN, NJS_OBJECT_NUMBER, and NJS_OBJECT_STRING must be + * in the same order as NJS_BOOLEAN, NJS_NUMBER, and NJS_STRING. It is + * used in njs_primitive_prototype_index(). The order of object types + * is used in vm->prototypes and vm->constructors arrays. + */ + NJS_OBJECT = 0x10, + NJS_ARRAY = 0x11, + NJS_OBJECT_BOOLEAN = 0x12, + NJS_OBJECT_NUMBER = 0x13, + NJS_OBJECT_STRING = 0x14, + NJS_FUNCTION = 0x15, + NJS_REGEXP = 0x16, + NJS_DATE = 0x17, + NJS_OBJECT_ERROR = 0x18, + NJS_OBJECT_EVAL_ERROR = 0x19, + NJS_OBJECT_INTERNAL_ERROR = 0x1a, + NJS_OBJECT_RANGE_ERROR = 0x1b, + NJS_OBJECT_REF_ERROR = 0x1c, + NJS_OBJECT_SYNTAX_ERROR = 0x1d, + NJS_OBJECT_TYPE_ERROR = 0x1e, + NJS_OBJECT_URI_ERROR = 0x1f, + NJS_OBJECT_VALUE = 0x20, +#define NJS_TYPE_MAX (NJS_OBJECT_VALUE + 1) +} njs_value_type_t; + + +/* + * njs_prop_handler_t operates as a property getter and/or setter. + * The handler receives NULL setval if it is invoked in GET context and + * non-null otherwise. + * + * njs_prop_handler_t is expected to return: + * NXT_OK - handler executed successfully; + * NXT_ERROR - some error, vm->retval contains appropriate exception; + * NXT_DECLINED - handler was applied to inappropriate object. + */ +typedef njs_ret_t (*njs_prop_handler_t) (njs_vm_t *vm, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); +typedef njs_ret_t (*njs_function_native_t) (njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t retval); + + +typedef struct njs_string_s njs_string_t; +typedef struct njs_object_s njs_object_t; +typedef struct njs_object_value_s njs_object_value_t; +typedef struct njs_function_lambda_s njs_function_lambda_t; +typedef struct njs_regexp_pattern_s njs_regexp_pattern_t; +typedef struct njs_array_s njs_array_t; +typedef struct njs_regexp_s njs_regexp_t; +typedef struct njs_date_s njs_date_t; +typedef struct njs_property_next_s njs_property_next_t; +typedef struct njs_object_init_s njs_object_init_t; + + +union njs_value_s { + /* + * The njs_value_t size is 16 bytes and must be aligned to 16 bytes + * to provide 4 bits to encode scope in njs_index_t. This space is + * used to store short strings. The maximum size of a short string + * is 14 (NJS_STRING_SHORT). If the short_string.size field is 15 + * (NJS_STRING_LONG) then the size is in the long_string.size field + * and the long_string.data field points to a long string. + * + * The number of the string types is limited to 2 types to minimize + * overhead of processing string fields. It is also possible to add + * strings with size from 14 to 254 which size and length are stored in + * the string_size and string_length byte wide fields. This will lessen + * the maximum size of short string to 13. + */ + struct { + njs_value_type_t type:8; /* 6 bits */ + /* + * The truth field is set during value assignment and then can be + * quickly tested by logical and conditional operations regardless + * of value type. The truth field coincides with short_string.size + * and short_string.length so when string size and length are zero + * the string's value is false. + */ + uint8_t truth; + + uint16_t _spare1; + uint32_t _spare2; + + union { + double number; + njs_object_t *object; + njs_array_t *array; + njs_object_value_t *object_value; + njs_function_t *function; + njs_function_lambda_t *lambda; + njs_regexp_t *regexp; + njs_date_t *date; + njs_prop_handler_t prop_handler; + njs_value_t *value; + njs_property_next_t *next; + void *data; + } u; + } data; + + struct { + njs_value_type_t type:8; /* 6 bits */ + +#define NJS_STRING_SHORT 14 +#define NJS_STRING_LONG 15 + + uint8_t size:4; + uint8_t length:4; + + u_char start[NJS_STRING_SHORT]; + } short_string; + + struct { + njs_value_type_t type:8; /* 6 bits */ + uint8_t truth; + + /* 0xff if data is external string. */ + uint8_t external; + uint8_t _spare; + + uint32_t size; + njs_string_t *data; + } long_string; + + struct { + njs_value_type_t type:8; /* 6 bits */ + uint8_t truth; + + uint16_t _spare; + + uint32_t index; + const njs_extern_t *proto; + } external; + + njs_value_type_t type:8; /* 6 bits */ +}; + + +struct njs_object_s { + /* A private hash of njs_object_prop_t. */ + nxt_lvlhsh_t hash; + + /* A shared hash of njs_object_prop_t. */ + nxt_lvlhsh_t shared_hash; + + /* An object __proto__. */ + njs_object_t *__proto__; + + /* The type is used in constructor prototypes. */ + njs_value_type_t type:8; + uint8_t shared; /* 1 bit */ + uint8_t extensible; /* 1 bit */ +}; + + +struct njs_object_value_s { + njs_object_t object; + /* The value can be unaligned since it never used in nJSVM operations. */ + njs_value_t value; +}; + + +struct njs_array_s { + njs_object_t object; + uint32_t size; + uint32_t length; + njs_value_t *start; + njs_value_t *data; +}; + + +typedef struct { + union { + uint32_t count; + njs_value_t values; + } u; + + njs_value_t values[1]; +} njs_closure_t; + + +#define NJS_ARGS_TYPES_MAX 5 + +struct njs_function_s { + njs_object_t object; + + uint8_t args_types[NJS_ARGS_TYPES_MAX]; + uint8_t args_offset; + uint8_t continuation_size; + + /* Function is a closure. */ + uint8_t closure:1; + + uint8_t native:1; + uint8_t ctor:1; + + union { + njs_function_lambda_t *lambda; + njs_function_native_t native; + } u; + + njs_value_t *bound; +#if (NXT_SUNC) + njs_closure_t *closures[1]; +#else + njs_closure_t *closures[]; +#endif +}; + + +struct njs_regexp_s { + njs_object_t object; + uint32_t last_index; + njs_regexp_pattern_t *pattern; + /* + * This string value can be unaligned since + * it never used in nJSVM operations. + */ + njs_value_t string; +}; + + +struct njs_date_s { + njs_object_t object; + double time; +}; + + +typedef union { + njs_object_t object; + njs_object_value_t object_value; + njs_array_t array; + njs_function_t function; + njs_regexp_t regexp; + njs_date_t date; +} njs_object_prototype_t; + + +typedef enum { + NJS_ENUM_KEYS, + NJS_ENUM_VALUES, + NJS_ENUM_BOTH, +} njs_object_enum_t; + + +#define njs_value(_type, _truth, _number) { \ + .data = { \ + .type = _type, \ + .truth = _truth, \ + .u.number = _number, \ + } \ +} + + +#define njs_string(s) { \ + .short_string = { \ + .type = NJS_STRING, \ + .size = nxt_length(s), \ + .length = nxt_length(s), \ + .start = s, \ + } \ +} + + +/* NJS_STRING_LONG is set for both big and little endian platforms. */ + +#define njs_long_string(s) { \ + .long_string = { \ + .type = NJS_STRING, \ + .truth = (NJS_STRING_LONG << 4) | NJS_STRING_LONG, \ + .size = nxt_length(s), \ + .data = & (njs_string_t) { \ + .start = (u_char *) s, \ + .length = nxt_length(s), \ + } \ + } \ +} + + +#define njs_native_function(_function, _size, ...) { \ + .data = { \ + .type = NJS_FUNCTION, \ + .truth = 1, \ + .u.function = & (njs_function_t) { \ + .native = 1, \ + .continuation_size = _size, \ + .args_types = { __VA_ARGS__ }, \ + .args_offset = 1, \ + .u.native = _function, \ + .object = { .type = NJS_FUNCTION, \ + .shared = 1, \ + .extensible = 1 }, \ + } \ + } \ +} + + +#define njs_prop_handler(_handler) { \ + .data = { \ + .type = NJS_INVALID, \ + .truth = 1, \ + .u = { .prop_handler = _handler } \ + } \ +} + + +#define njs_is_null(value) \ + ((value)->type == NJS_NULL) + + +#define njs_is_undefined(value) \ + ((value)->type == NJS_UNDEFINED) + + +#define njs_is_null_or_undefined(value) \ + ((value)->type <= NJS_UNDEFINED) + + +#define njs_is_boolean(value) \ + ((value)->type == NJS_BOOLEAN) + + +#define njs_is_null_or_undefined_or_boolean(value) \ + ((value)->type <= NJS_BOOLEAN) + + +#define njs_is_true(value) \ + ((value)->data.truth != 0) + + +#define njs_is_number(value) \ + ((value)->type == NJS_NUMBER) + + +/* Testing for NaN first generates a better code at least on i386/amd64. */ + +#define njs_is_number_true(num) \ + (!isnan(num) && num != 0) + + +#define njs_is_numeric(value) \ + ((value)->type <= NJS_NUMBER) + + +#define njs_is_string(value) \ + ((value)->type == NJS_STRING) + +#define njs_is_error(value) \ + ((value)->type >= NJS_OBJECT_ERROR \ + && (value)->type <= NJS_OBJECT_URI_ERROR) + + +/* + * The truth field coincides with short_string.size and short_string.length + * so when string size and length are zero the string's value is false and + * otherwise is true. + */ +#define njs_string_truth(value, size) + + +#define njs_string_get(value, str) \ + do { \ + if ((value)->short_string.size != NJS_STRING_LONG) { \ + (str)->length = (value)->short_string.size; \ + (str)->start = (u_char *) (value)->short_string.start; \ + \ + } else { \ + (str)->length = (value)->long_string.size; \ + (str)->start = (u_char *) (value)->long_string.data->start; \ + } \ + } while (0) + + +#define njs_string_short_start(value) \ + (value)->short_string.start + + +#define njs_string_short_set(value, _size, _length) \ + do { \ + (value)->type = NJS_STRING; \ + njs_string_truth(value, _size); \ + (value)->short_string.size = _size; \ + (value)->short_string.length = _length; \ + } while (0) + + +#define njs_string_length_set(value, _length) \ + do { \ + if ((value)->short_string.size != NJS_STRING_LONG) { \ + (value)->short_string.length = length; \ + \ + } else { \ + (value)->long_string.data->length = length; \ + } \ + } while (0) + +#define njs_is_primitive(value) \ + ((value)->type <= NJS_STRING) + + +#define njs_is_data(value) \ + ((value)->type == NJS_DATA) + + +#define njs_is_object(value) \ + ((value)->type >= NJS_OBJECT) + + +#define njs_is_object_value(value) \ + ((value)->type == NJS_OBJECT_VALUE) + + +#define njs_object_value_type(type) \ + (type + NJS_OBJECT) + + +#define njs_is_array(value) \ + ((value)->type == NJS_ARRAY) + + +#define njs_is_function(value) \ + ((value)->type == NJS_FUNCTION) + + +#define njs_is_regexp(value) \ + ((value)->type == NJS_REGEXP) + + +#define njs_is_date(value) \ + ((value)->type == NJS_DATE) + + +#define njs_is_external(value) \ + ((value)->type == NJS_EXTERNAL) + + +#define njs_is_valid(value) \ + ((value)->type != NJS_INVALID) + + +#define njs_bool(value) \ + ((value)->data.truth) + + +#define njs_number(value) \ + ((value)->data.u.number) + + +#define njs_data(value) \ + ((value)->data.u.data) + + +#define njs_function(value) \ + ((value)->data.u.function) + + +#define njs_object(value) \ + ((value)->data.u.object) + + +#define njs_object_hash(value) \ + (&(value)->data.u.object->hash) + + +#define njs_array(value) \ + ((value)->data.u.array) + + +#define njs_array_len(value) \ + ((value)->data.u.array->length) + + +#define njs_array_start(value) \ + ((value)->data.u.array->start) + + +#define njs_set_undefined(value) \ + *(value) = njs_value_undefined + + +#define njs_set_boolean(value, yn) \ + *(value) = yn ? njs_value_true : njs_value_false + + +#define njs_set_true(value) \ + *(value) = njs_value_true + + +#define njs_set_false(value) \ + *(value) = njs_value_false From xeioex at nginx.com Mon Jul 8 14:52:34 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 08 Jul 2019 14:52:34 +0000 Subject: [njs] Using njs_number() and njs_set_number() everywhere. Message-ID: details: https://hg.nginx.org/njs/rev/254c9b04b0d2 branches: changeset: 1033:254c9b04b0d2 user: Dmitry Volyntsev date: Mon Jul 08 17:49:14 2019 +0300 description: Using njs_number() and njs_set_number() everywhere. diffstat: njs/njs.c | 4 +- njs/njs_array.c | 20 +++++----- njs/njs_builtin.c | 8 +--- njs/njs_error.c | 1 - njs/njs_fs.c | 6 +-- njs/njs_function.c | 12 +++--- njs/njs_json.c | 17 +++----- njs/njs_math.c | 80 ++++++++++++++++++++++---------------------- njs/njs_number.c | 22 ++++++------ njs/njs_number.h | 2 +- njs/njs_parser_expression.c | 5 +- njs/njs_parser_terminal.c | 8 +--- njs/njs_string.c | 36 ++++++++++---------- njs/njs_time.c | 4 +- njs/njs_value.c | 2 +- njs/njs_vm.c | 76 +++++++++++++++++++++--------------------- 16 files changed, 144 insertions(+), 159 deletions(-) diffs (truncated from 1200 to 1000 lines): diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs.c --- a/njs/njs.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs.c Mon Jul 08 17:49:14 2019 +0300 @@ -805,8 +805,8 @@ nxt_int_t njs_value_is_valid_number(const njs_value_t *value) { return njs_is_number(value) - && !isnan(value->data.u.number) - && !isinf(value->data.u.number); + && !isnan(njs_number(value)) + && !isinf(njs_number(value)); } diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_array.c --- a/njs/njs_array.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_array.c Mon Jul 08 17:49:14 2019 +0300 @@ -293,7 +293,7 @@ njs_array_constructor(njs_vm_t *vm, njs_ size = nargs - 1; if (size == 1 && njs_is_number(&args[0])) { - num = args[0].data.u.number; + num = njs_number(&args[0]); size = (uint32_t) num; if ((double) size != num) { @@ -474,7 +474,7 @@ njs_array_length(njs_vm_t *vm, njs_value return NJS_ERROR; } - num = setval->data.u.number; + num = njs_number(setval); length = (uint32_t) num; if ((double) length != num) { @@ -843,7 +843,7 @@ njs_array_prototype_splice(njs_vm_t *vm, length = array->length; if (nargs > 1) { - start = args[1].data.u.number; + start = njs_number(&args[1]); if (start < 0) { start += length; @@ -859,7 +859,7 @@ njs_array_prototype_splice(njs_vm_t *vm, delete = length - start; if (nargs > 2) { - n = args[2].data.u.number; + n = njs_number(&args[2]); if (n < 0) { delete = 0; @@ -1240,7 +1240,7 @@ njs_array_prototype_index_of(njs_vm_t *v i = 0; if (nargs > 2) { - i = args[2].data.u.number; + i = njs_number(&args[2]); if (i >= length) { goto done; @@ -1300,7 +1300,7 @@ njs_array_prototype_last_index_of(njs_vm i = length - 1; if (nargs > 2) { - n = args[2].data.u.number; + n = njs_number(&args[2]); if (n < 0) { i = n + length; @@ -1360,7 +1360,7 @@ njs_array_prototype_includes(njs_vm_t *v i = 0; if (nargs > 2) { - i = args[2].data.u.number; + i = njs_number(&args[2]); if (i >= length) { goto done; @@ -1378,12 +1378,12 @@ njs_array_prototype_includes(njs_vm_t *v start = array->start; value = &args[1]; - if (njs_is_number(value) && isnan(value->data.u.number)) { + if (njs_is_number(value) && isnan(njs_number(value))) { do { value = &start[i]; - if (njs_is_number(value) && isnan(value->data.u.number)) { + if (njs_is_number(value) && isnan(njs_number(value))) { retval = &njs_value_true; break; } @@ -2276,7 +2276,7 @@ njs_array_prototype_sort_continuation(nj * "goto next" moves control to the appropriate step of the algorithm. * The first iteration also goes there because sort->retval is zero. */ - if (sort->retval.data.u.number <= 0) { + if (njs_number(&sort->retval) <= 0) { goto next; } diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_builtin.c --- a/njs/njs_builtin.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_builtin.c Mon Jul 08 17:49:14 2019 +0300 @@ -1305,9 +1305,7 @@ static njs_ret_t njs_process_object_pid(njs_vm_t *vm, njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval) { - retval->data.u.number = getpid(); - retval->type = NJS_NUMBER; - retval->data.truth = njs_is_number_true(retval->data.u.number); + njs_set_number(retval, getpid()); return NJS_OK; } @@ -1317,9 +1315,7 @@ static njs_ret_t njs_process_object_ppid(njs_vm_t *vm, njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval) { - retval->data.u.number = getppid(); - retval->type = NJS_NUMBER; - retval->data.truth = njs_is_number_true(retval->data.u.number); + njs_set_number(retval, getppid()); return NJS_OK; } diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_error.c --- a/njs/njs_error.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_error.c Mon Jul 08 17:49:14 2019 +0300 @@ -515,7 +515,6 @@ njs_memory_error_set(njs_vm_t *vm, njs_v value->data.type = NJS_OBJECT_INTERNAL_ERROR; value->data.truth = 1; - value->data.u.number = NAN; value->data.u.object = object; } diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_fs.c --- a/njs/njs_fs.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_fs.c Mon Jul 08 17:49:14 2019 +0300 @@ -919,9 +919,7 @@ static njs_ret_t njs_fs_error(njs_vm_t * lhq.key_hash = NJS_ERRNO_HASH; lhq.proto = &njs_object_hash_proto; - value.data.type = NJS_NUMBER; - value.data.truth = 1; - value.data.u.number = errn; + njs_set_number(&value, errn); prop = njs_object_prop_alloc(vm, &njs_fs_errno_string, &value, 1); if (nxt_slow_path(prop == NULL)) { @@ -1013,7 +1011,7 @@ njs_fs_mode(njs_value_t *value) /* Fall through. */ case NJS_NUMBER: - return (mode_t) value->data.u.number; + return (mode_t) njs_number(value); case NJS_OBJECT_STRING: value = &value->data.u.object_value->value; diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_function.c --- a/njs/njs_function.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_function.c Mon Jul 08 17:49:14 2019 +0300 @@ -677,14 +677,14 @@ njs_normalize_args(njs_vm_t *vm, njs_val /* Numbers are truncated to fit in 32-bit integers. */ - if (isnan(args->data.u.number)) { - args->data.u.number = 0; + if (isnan(njs_number(args))) { + njs_number(args) = 0; - } else if (args->data.u.number > 2147483647.0) { - args->data.u.number = 2147483647.0; + } else if (njs_number(args) > 2147483647.0) { + njs_number(args) = 2147483647.0; - } else if (args->data.u.number < -2147483648.0) { - args->data.u.number = -2147483648.0; + } else if (njs_number(args) < -2147483648.0) { + njs_number(args) = -2147483648.0; } break; diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_json.c --- a/njs/njs_json.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_json.c Mon Jul 08 17:49:14 2019 +0300 @@ -305,7 +305,7 @@ njs_json_stringify(njs_vm_t *vm, njs_val stringify->space.length = nxt_min(stringify->space.length, 10); } else { - num = space->data.u.number; + num = njs_number(space); if (!isnan(num) && !isinf(num) && num > 0) { num = nxt_min(num, 10); @@ -872,10 +872,7 @@ njs_json_parse_number(njs_json_parse_ctx start = p; num = njs_number_dec_parse(&p, ctx->end); if (p != start) { - value->data.u.number = sign * num; - value->type = NJS_NUMBER; - value->data.truth = njs_is_number_true(num); - + njs_set_number(value, sign * num); return p; } @@ -1890,7 +1887,7 @@ njs_json_append_number(njs_json_stringif size_t size; double num; - num = value->data.u.number; + num = njs_number(value); if (isnan(num) || isinf(num)) { return njs_json_buf_append(stringify, "null", 4); @@ -2160,8 +2157,8 @@ njs_dump_value(njs_json_stringify_t *str case NJS_OBJECT_NUMBER: value = &value->data.u.object_value->value; - if (nxt_slow_path(value->data.u.number == 0.0 - && signbit(value->data.u.number))) + if (nxt_slow_path(njs_number(value) == 0.0 + && signbit(njs_number(value)))) { njs_dump("[Number: -0]"); @@ -2275,8 +2272,8 @@ njs_dump_value(njs_json_stringify_t *str return njs_json_buf_append(stringify, "]}", 2); case NJS_NUMBER: - if (nxt_slow_path(value->data.u.number == 0.0 - && signbit(value->data.u.number))) + if (nxt_slow_path(njs_number(value) == 0.0 + && signbit(njs_number(value)))) { njs_dump("-0"); diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_math.c --- a/njs/njs_math.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_math.c Mon Jul 08 17:49:14 2019 +0300 @@ -15,7 +15,7 @@ njs_object_math_abs(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = fabs(args[1].data.u.number); + num = fabs(njs_number(&args[1])); } else { num = NAN; @@ -34,7 +34,7 @@ njs_object_math_acos(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = njs_number(&args[1]); #if (NXT_SOLARIS) /* On Solaris acos(x) returns 0 for x > 1. */ @@ -62,7 +62,7 @@ njs_object_math_acosh(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = acosh(args[1].data.u.number); + num = acosh(njs_number(&args[1])); } else { num = NAN; @@ -81,7 +81,7 @@ njs_object_math_asin(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = njs_number(&args[1]); #if (NXT_SOLARIS) /* On Solaris asin(x) returns 0 for x > 1. */ @@ -109,7 +109,7 @@ njs_object_math_asinh(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = asinh(args[1].data.u.number); + num = asinh(njs_number(&args[1])); } else { num = NAN; @@ -128,7 +128,7 @@ njs_object_math_atan(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = atan(args[1].data.u.number); + num = atan(njs_number(&args[1])); } else { num = NAN; @@ -147,8 +147,8 @@ njs_object_math_atan2(njs_vm_t *vm, njs_ double num, y, x; if (nargs > 2) { - y = args[1].data.u.number; - x = args[2].data.u.number; + y = njs_number(&args[1]); + x = njs_number(&args[2]); num = atan2(y, x); @@ -169,7 +169,7 @@ njs_object_math_atanh(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = atanh(args[1].data.u.number); + num = atanh(njs_number(&args[1])); } else { num = NAN; @@ -188,7 +188,7 @@ njs_object_math_cbrt(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = cbrt(args[1].data.u.number); + num = cbrt(njs_number(&args[1])); } else { num = NAN; @@ -207,7 +207,7 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = ceil(args[1].data.u.number); + num = ceil(njs_number(&args[1])); } else { num = NAN; @@ -227,7 +227,7 @@ njs_object_math_clz32(njs_vm_t *vm, njs_ uint32_t ui32; if (nargs > 1) { - ui32 = njs_number_to_uint32(args[1].data.u.number); + ui32 = njs_number_to_uint32(njs_number(&args[1])); num = nxt_leading_zeros(ui32); } else { @@ -247,7 +247,7 @@ njs_object_math_cos(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = cos(args[1].data.u.number); + num = cos(njs_number(&args[1])); } else { num = NAN; @@ -266,7 +266,7 @@ njs_object_math_cosh(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = cosh(args[1].data.u.number); + num = cosh(njs_number(&args[1])); } else { num = NAN; @@ -285,7 +285,7 @@ njs_object_math_exp(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = exp(args[1].data.u.number); + num = exp(njs_number(&args[1])); } else { num = NAN; @@ -304,7 +304,7 @@ njs_object_math_expm1(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = expm1(args[1].data.u.number); + num = expm1(njs_number(&args[1])); } else { num = NAN; @@ -323,7 +323,7 @@ njs_object_math_floor(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = floor(args[1].data.u.number); + num = floor(njs_number(&args[1])); } else { num = NAN; @@ -342,7 +342,7 @@ njs_object_math_fround(njs_vm_t *vm, njs double num; if (nargs > 1) { - num = (float) args[1].data.u.number; + num = (float) njs_number(&args[1]); } else { num = NAN; @@ -369,10 +369,10 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ } } - num = (nargs > 1) ? fabs(args[1].data.u.number) : 0; + num = (nargs > 1) ? fabs(njs_number(&args[1])) : 0; for (i = 2; i < nargs; i++) { - num = hypot(num, args[i].data.u.number); + num = hypot(num, njs_number(&args[i])); if (num == INFINITY) { break; @@ -393,8 +393,8 @@ njs_object_math_imul(njs_vm_t *vm, njs_v uint32_t a, b; if (nargs > 2) { - a = njs_number_to_uint32(args[1].data.u.number); - b = njs_number_to_uint32(args[2].data.u.number); + a = njs_number_to_uint32(njs_number(&args[1])); + b = njs_number_to_uint32(njs_number(&args[2])); num = (int32_t) (a * b); @@ -415,7 +415,7 @@ njs_object_math_log(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = log(args[1].data.u.number); + num = log(njs_number(&args[1])); } else { num = NAN; @@ -434,7 +434,7 @@ njs_object_math_log10(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = log10(args[1].data.u.number); + num = log10(njs_number(&args[1])); } else { num = NAN; @@ -453,7 +453,7 @@ njs_object_math_log1p(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = log1p(args[1].data.u.number); + num = log1p(njs_number(&args[1])); } else { num = NAN; @@ -472,7 +472,7 @@ njs_object_math_log2(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = njs_number(&args[1]); #if (NXT_SOLARIS) /* On Solaris 10 log(-1) returns -Infinity. */ @@ -513,10 +513,10 @@ njs_object_math_max(njs_vm_t *vm, njs_va } } - num = args[1].data.u.number; + num = njs_number(&args[1]); for (i = 2; i < nargs; i++) { - num = fmax(num, args[i].data.u.number); + num = fmax(num, njs_number(&args[i])); } } else { @@ -547,10 +547,10 @@ njs_object_math_min(njs_vm_t *vm, njs_va } } - num = args[1].data.u.number; + num = njs_number(&args[1]); for (i = 2; i < nargs; i++) { - num = fmin(num, args[i].data.u.number); + num = fmin(num, njs_number(&args[i])); } } else { @@ -570,8 +570,8 @@ njs_object_math_pow(njs_vm_t *vm, njs_va double num, base, exponent; if (nargs > 2) { - base = args[1].data.u.number; - exponent = args[2].data.u.number; + base = njs_number(&args[1]); + exponent = njs_number(&args[2]); /* * According to ECMA-262: @@ -617,7 +617,7 @@ njs_object_math_round(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = round(args[1].data.u.number); + num = round(njs_number(&args[1])); } else { num = NAN; @@ -636,7 +636,7 @@ njs_object_math_sign(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = args[1].data.u.number; + num = njs_number(&args[1]); if (!isnan(num) && num != 0) { num = signbit(num) ? -1 : 1; @@ -659,7 +659,7 @@ njs_object_math_sin(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = sin(args[1].data.u.number); + num = sin(njs_number(&args[1])); } else { num = NAN; @@ -678,7 +678,7 @@ njs_object_math_sinh(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = sinh(args[1].data.u.number); + num = sinh(njs_number(&args[1])); } else { num = NAN; @@ -697,7 +697,7 @@ njs_object_math_sqrt(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = sqrt(args[1].data.u.number); + num = sqrt(njs_number(&args[1])); } else { num = NAN; @@ -716,7 +716,7 @@ njs_object_math_tan(njs_vm_t *vm, njs_va double num; if (nargs > 1) { - num = tan(args[1].data.u.number); + num = tan(njs_number(&args[1])); } else { num = NAN; @@ -735,7 +735,7 @@ njs_object_math_tanh(njs_vm_t *vm, njs_v double num; if (nargs > 1) { - num = tanh(args[1].data.u.number); + num = tanh(njs_number(&args[1])); } else { num = NAN; @@ -754,7 +754,7 @@ njs_object_math_trunc(njs_vm_t *vm, njs_ double num; if (nargs > 1) { - num = trunc(args[1].data.u.number); + num = trunc(njs_number(&args[1])); } else { num = NAN; diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_number.c --- a/njs/njs_number.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_number.c Mon Jul 08 17:49:14 2019 +0300 @@ -31,7 +31,7 @@ njs_value_to_index(const njs_value_t *va num = NAN; if (nxt_fast_path(njs_is_numeric(value))) { - num = value->data.u.number; + num = njs_number(value); } else if (njs_is_string(value)) { num = njs_string_to_index(value); @@ -212,7 +212,7 @@ njs_number_to_string(njs_vm_t *vm, njs_v const njs_value_t *value; u_char buf[128]; - num = number->data.u.number; + num = njs_number(number); if (isnan(num)) { value = &njs_string_nan; @@ -263,7 +263,7 @@ njs_number_constructor(njs_vm_t *vm, njs vm->retval.data.truth = 1; } else { - njs_set_number(&vm->retval, value->data.u.number); + njs_set_number(&vm->retval, njs_number(value)); } return NXT_OK; @@ -280,7 +280,7 @@ njs_number_is_integer(njs_vm_t *vm, njs_ value = &njs_value_false; if (nargs > 1 && njs_is_number(&args[1])) { - num = args[1].data.u.number; + num = njs_number(&args[1]); if (num == trunc(num) && !isinf(num)) { value = &njs_value_true; @@ -304,7 +304,7 @@ njs_number_is_safe_integer(njs_vm_t *vm, value = &njs_value_false; if (nargs > 1 && njs_is_number(&args[1])) { - num = args[1].data.u.number; + num = njs_number(&args[1]); if (num == (int64_t) num && fabs(num) <= NJS_MAX_SAFE_INTEGER) { value = &njs_value_true; @@ -327,7 +327,7 @@ njs_number_is_nan(njs_vm_t *vm, njs_valu if (nargs > 1 && njs_is_number(&args[1]) - && isnan(args[1].data.u.number)) + && isnan(njs_number(&args[1]))) { value = &njs_value_true; } @@ -527,14 +527,14 @@ njs_number_prototype_to_string(njs_vm_t } if (nargs > 1) { - radix = args[1].data.u.number; + radix = njs_number(&args[1]); if (radix < 2 || radix > 36 || radix != (int) radix) { njs_range_error(vm, NULL); return NXT_ERROR; } - number = value->data.u.number; + number = njs_number(value); if (radix != 10 && !isnan(number) && !isinf(number)) { return njs_number_to_string_radix(vm, &vm->retval, number, radix); @@ -663,7 +663,7 @@ njs_number_global_is_nan(njs_vm_t *vm, n value = &njs_value_true; - if (nargs > 1 && !isnan(args[1].data.u.number)) { + if (nargs > 1 && !isnan(njs_number(&args[1]))) { value = &njs_value_false; } @@ -683,7 +683,7 @@ njs_number_is_finite(njs_vm_t *vm, njs_v value = &njs_value_false; if (nargs > 1 && njs_is_number(&args[1])) { - num = args[1].data.u.number; + num = njs_number(&args[1]); if (!isnan(num) && !isinf(num)) { value = &njs_value_true; @@ -738,7 +738,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_v radix = 0; if (nargs > 2) { - radix = args[2].data.u.number; + radix = njs_number(&args[2]); if (radix != 0) { if (radix < 2 || radix > 36) { diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_number.h --- a/njs/njs_number.h Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_number.h Mon Jul 08 17:49:14 2019 +0300 @@ -133,7 +133,7 @@ nxt_inline double njs_primitive_value_to_number(const njs_value_t *value) { if (nxt_fast_path(njs_is_numeric(value))) { - return value->data.u.number; + return njs_number(value); } return njs_string_to_number(value, 1); diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_parser_expression.c Mon Jul 08 17:49:14 2019 +0300 @@ -580,9 +580,8 @@ njs_parser_unary_expression(njs_vm_t *vm if (token == NJS_TOKEN_UNARY_NEGATION && node->token == NJS_TOKEN_NUMBER) { /* Optimization of common negative number. */ - num = -node->u.value.data.u.number; - node->u.value.data.u.number = num; - node->u.value.data.truth = njs_is_number_true(num); + num = -njs_number(&node->u.value); + njs_set_number(&node->u.value, num); return next; } diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_parser_terminal.c Mon Jul 08 17:49:14 2019 +0300 @@ -157,9 +157,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa return NJS_TOKEN_ERROR; } - node->u.value.data.u.number = num; - node->u.value.type = NJS_NUMBER; - node->u.value.data.truth = njs_is_number_true(num); + njs_set_number(&node->u.value, num); break; @@ -710,9 +708,7 @@ njs_parser_array_item(njs_vm_t *vm, njs_ return NXT_ERROR; } - number->u.value.data.u.number = array->u.length; - number->u.value.type = NJS_NUMBER; - number->u.value.data.truth = (array->u.length != 0); + njs_set_number(&number->u.value, array->u.length); ret = njs_parser_object_property(vm, parser, array, number, value); if (nxt_slow_path(ret != NXT_OK)) { diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_string.c Mon Jul 08 17:49:14 2019 +0300 @@ -1121,7 +1121,7 @@ njs_string_prototype_substring(njs_vm_t start = 0; if (nargs > 1) { - start = args[1].data.u.number; + start = njs_number(&args[1]); if (start < 0) { start = 0; @@ -1133,7 +1133,7 @@ njs_string_prototype_substring(njs_vm_t end = length; if (nargs > 2) { - end = args[2].data.u.number; + end = njs_number(&args[2]); if (end < 0) { end = 0; @@ -1177,7 +1177,7 @@ njs_string_prototype_substr(njs_vm_t *vm start = 0; if (nargs > 1) { - start = args[1].data.u.number; + start = njs_number(&args[1]); if (start < length) { if (start < 0) { @@ -1191,7 +1191,7 @@ njs_string_prototype_substr(njs_vm_t *vm length -= start; if (nargs > 2) { - n = args[2].data.u.number; + n = njs_number(&args[2]); if (n < 0) { length = 0; @@ -1228,7 +1228,7 @@ njs_string_prototype_char_at(njs_vm_t *v length = 1; if (nargs > 1) { - start = args[1].data.u.number; + start = njs_number(&args[1]); if (start < 0 || start >= (ssize_t) slice.string_length) { start = 0; @@ -1263,7 +1263,7 @@ njs_string_slice_args(njs_slice_prop_t * length = slice->string_length; value = njs_arg(args, nargs, 1); - start = value->data.u.number; + start = njs_number(value); if (start < 0) { start += length; @@ -1280,7 +1280,7 @@ njs_string_slice_args(njs_slice_prop_t * } else { if (!njs_is_undefined(njs_arg(args, nargs, 2))) { value = njs_arg(args, nargs, 2); - end = value->data.u.number; + end = njs_number(value); } else { end = length; @@ -1385,7 +1385,7 @@ njs_string_prototype_char_code_at(njs_vm index = 0; if (nargs > 1) { - index = args[1].data.u.number; + index = njs_number(&args[1]); if (nxt_slow_path(index < 0 || index >= length)) { num = NAN; @@ -1472,7 +1472,7 @@ njs_string_bytes_from_array(njs_vm_t *vm octet = array->start; while (length != 0) { - *p++ = (u_char) njs_number_to_uint32(octet->data.u.number); + *p++ = (u_char) njs_number_to_uint32(njs_number(octet)); octet++; length--; } @@ -1699,7 +1699,7 @@ njs_string_from_char_code(njs_vm_t *vm, size = 0; for (i = 1; i < nargs; i++) { - num = args[i].data.u.number; + num = njs_number(&args[i]); if (isnan(num)) { goto range_error; } @@ -1719,7 +1719,7 @@ njs_string_from_char_code(njs_vm_t *vm, } for (i = 1; i < nargs; i++) { - p = nxt_utf8_encode(p, args[i].data.u.number); + p = nxt_utf8_encode(p, njs_number(&args[i])); } return NXT_OK; @@ -1747,7 +1747,7 @@ njs_string_prototype_index_of(njs_vm_t * index = 0; if (nargs > 2) { - index = args[2].data.u.number; + index = njs_number(&args[2]); if (index < 0) { index = 0; @@ -1828,7 +1828,7 @@ njs_string_prototype_last_index_of(njs_v goto done; } - pos = njs_arg(args, nargs, 2)->data.u.number; + pos = njs_number(njs_arg(args, nargs, 2)); if (isnan(pos)) { index = NJS_STRING_MAX_LENGTH; @@ -1929,7 +1929,7 @@ njs_string_prototype_includes(njs_vm_t * index = 0; if (nargs > 2) { - index = args[2].data.u.number; + index = njs_number(&args[2]); if (index < 0) { index = 0; @@ -2006,7 +2006,7 @@ njs_string_starts_or_ends_with(njs_vm_t length = njs_string_prop(&string, &args[0]); - index = (nargs > 2) ? args[2].data.u.number : -1; + index = (nargs > 2) ? njs_number(&args[2]) : -1; if (starts) { if (index < 0) { @@ -2407,7 +2407,7 @@ njs_string_prototype_repeat(njs_vm_t *vm max = (string.size > 1) ? NJS_STRING_MAX_LENGTH / string.size : NJS_STRING_MAX_LENGTH; - n = args[1].data.u.number; + n = njs_number(&args[1]); if (nxt_slow_path(n < 0 || n >= max)) { njs_range_error(vm, NULL); @@ -2471,7 +2471,7 @@ njs_string_prototype_pad(njs_vm_t *vm, n static const njs_value_t string_space = njs_string(" "); length = njs_string_prop(&string, &args[0]); - new_length = nargs > 1 ? args[1].data.u.number : 0; + new_length = nargs > 1 ? njs_number(&args[1]) : 0; if (new_length <= length) { vm->retval = args[0]; @@ -2793,7 +2793,7 @@ njs_string_prototype_split(njs_vm_t *vm, if (nargs > 1) { if (nargs > 2) { - limit = args[2].data.u.number; + limit = njs_number(&args[2]); if (limit == 0) { goto done; diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_time.c --- a/njs/njs_time.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_time.c Mon Jul 08 17:49:14 2019 +0300 @@ -37,7 +37,7 @@ njs_set_timer(njs_vm_t *vm, njs_value_t delay = 0; if (!immediate && nargs >= 3 && njs_is_number(&args[2])) { - delay = args[2].data.u.number; + delay = njs_number(&args[2]); } event = nxt_mp_alloc(vm->mem_pool, sizeof(njs_event_t)); @@ -110,7 +110,7 @@ njs_clear_timeout(njs_vm_t *vm, njs_valu } p = nxt_sprintf(buf, buf + nxt_length(buf), "%uD", - (unsigned) args[1].data.u.number); + (unsigned) njs_number(&args[1])); lhq.key.start = buf; lhq.key.length = p - buf; diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_value.c --- a/njs/njs_value.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_value.c Mon Jul 08 17:49:14 2019 +0300 @@ -108,7 +108,7 @@ njs_values_strict_equal(const njs_value_ } /* Infinities are handled correctly by comparision. */ - return (val1->data.u.number == val2->data.u.number); + return (njs_number(val1) == njs_number(val2)); } if (njs_is_string(val1)) { diff -r aa688dbdc7de -r 254c9b04b0d2 njs/njs_vm.c --- a/njs/njs_vm.c Mon Jul 08 15:31:39 2019 +0300 +++ b/njs/njs_vm.c Mon Jul 08 17:49:14 2019 +0300 @@ -899,7 +899,7 @@ njs_vmcode_increment(njs_vm_t *vm, njs_v double num; if (nxt_fast_path(njs_is_numeric(value))) { - num = value->data.u.number + 1.0; + num = njs_number(value) + 1.0; njs_release(vm, reference); @@ -919,7 +919,7 @@ njs_vmcode_decrement(njs_vm_t *vm, njs_v double num; if (nxt_fast_path(njs_is_numeric(value))) { - num = value->data.u.number - 1.0; + num = njs_number(value) - 1.0; njs_release(vm, reference); @@ -940,7 +940,7 @@ njs_vmcode_post_increment(njs_vm_t *vm, double num; if (nxt_fast_path(njs_is_numeric(value))) { - num = value->data.u.number; + num = njs_number(value); njs_release(vm, reference); @@ -961,7 +961,7 @@ njs_vmcode_post_decrement(njs_vm_t *vm, double num; if (nxt_fast_path(njs_is_numeric(value))) { - num = value->data.u.number; + num = njs_number(value); njs_release(vm, reference); @@ -1047,7 +1047,7 @@ njs_ret_t njs_vmcode_unary_plus(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld) { if (nxt_fast_path(njs_is_numeric(value))) { - njs_set_number(&vm->retval, value->data.u.number); + njs_set_number(&vm->retval, njs_number(value)); return sizeof(njs_vmcode_2addr_t); } @@ -1059,7 +1059,7 @@ njs_ret_t njs_vmcode_unary_negation(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld) { if (nxt_fast_path(njs_is_numeric(value))) { - njs_set_number(&vm->retval, - value->data.u.number); + njs_set_number(&vm->retval, - njs_number(value)); return sizeof(njs_vmcode_2addr_t); } @@ -1076,7 +1076,7 @@ njs_vmcode_addition(njs_vm_t *vm, njs_va if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num = val1->data.u.number + val2->data.u.number; + num = njs_number(val1) + njs_number(val2); njs_set_number(&vm->retval, num); return sizeof(njs_vmcode_3addr_t); @@ -1157,7 +1157,7 @@ njs_vmcode_substraction(njs_vm_t *vm, nj if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num = val1->data.u.number - val2->data.u.number; + num = njs_number(val1) - njs_number(val2); njs_set_number(&vm->retval, num); return sizeof(njs_vmcode_3addr_t); @@ -1174,7 +1174,7 @@ njs_vmcode_multiplication(njs_vm_t *vm, if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num = val1->data.u.number * val2->data.u.number; From xeioex at nginx.com Mon Jul 8 14:52:34 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 08 Jul 2019 14:52:34 +0000 Subject: [njs] Using njs_object() macro where applicable. Message-ID: details: https://hg.nginx.org/njs/rev/5eee6645c7e2 branches: changeset: 1034:5eee6645c7e2 user: Dmitry Volyntsev date: Mon Jul 08 17:49:43 2019 +0300 description: Using njs_object() macro where applicable. diffstat: njs/njs_array.c | 10 ++---- njs/njs_boolean.c | 8 ++--- njs/njs_builtin.c | 2 +- njs/njs_crypto.c | 70 +++++++++++++++++----------------------------- njs/njs_error.c | 18 ++++-------- njs/njs_fs.c | 8 ++--- njs/njs_function.c | 2 +- njs/njs_json.c | 22 +++++++------- njs/njs_number.c | 8 ++--- njs/njs_object.c | 56 ++++++++++++++++--------------------- njs/njs_object_property.c | 6 ++-- njs/njs_parser_terminal.c | 2 +- njs/njs_string.c | 8 ++--- njs/njs_value.c | 8 ++-- njs/njs_value.h | 23 +++++++++++++++ njs/njs_vm.c | 12 ++++---- 16 files changed, 122 insertions(+), 141 deletions(-) diffs (914 lines): diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_array.c --- a/njs/njs_array.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_array.c Mon Jul 08 17:49:43 2019 +0300 @@ -443,7 +443,7 @@ njs_array_length(njs_vm_t *vm, njs_value njs_array_t *array; njs_object_t *proto; - proto = value->data.u.object; + proto = njs_object(value); if (setval == NULL) { do { @@ -633,7 +633,7 @@ njs_array_prototype_slice_copy(njs_vm_t } else if (njs_is_string(this) || this->type == NJS_OBJECT_STRING) { if (this->type == NJS_OBJECT_STRING) { - this = &this->data.u.object_value->value; + this = njs_object_value(this); } string_slice.start = start; @@ -967,7 +967,7 @@ njs_array_prototype_to_string(njs_vm_t * lhq.key_hash = NJS_JOIN_HASH; lhq.key = nxt_string_value("join"); - prop = njs_object_property(vm, args[0].data.u.object, &lhq); + prop = njs_object_property(vm, njs_object(&args[0]), &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { return njs_function_replace(vm, prop->value.data.u.function, @@ -1470,9 +1470,7 @@ njs_array_prototype_fill_continuation(nj return NXT_ERROR; } - vm->retval.data.u.object = object; - vm->retval.type = object->type; - vm->retval.data.truth = 1; + njs_set_type_object(&vm->retval, object, object->type); return NXT_OK; } diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_boolean.c --- a/njs/njs_boolean.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_boolean.c Mon Jul 08 17:49:43 2019 +0300 @@ -27,9 +27,7 @@ njs_boolean_constructor(njs_vm_t *vm, nj return NXT_ERROR; } - vm->retval.data.u.object = object; - vm->retval.type = NJS_OBJECT_BOOLEAN; - vm->retval.data.truth = 1; + njs_set_type_object(&vm->retval, object, NJS_OBJECT_BOOLEAN); } else { vm->retval = *value; @@ -84,7 +82,7 @@ njs_boolean_prototype_value_of(njs_vm_t if (value->type != NJS_BOOLEAN) { if (value->type == NJS_OBJECT_BOOLEAN) { - value = &value->data.u.object_value->value; + value = njs_object_value(value); } else { njs_type_error(vm, "unexpected value type:%s", @@ -110,7 +108,7 @@ njs_boolean_prototype_to_string(njs_vm_t if (value->type != NJS_BOOLEAN) { if (value->type == NJS_OBJECT_BOOLEAN) { - value = &value->data.u.object_value->value; + value = njs_object_value(value); } else { njs_type_error(vm, "unexpected value type:%s", diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_builtin.c --- a/njs/njs_builtin.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_builtin.c Mon Jul 08 17:49:43 2019 +0300 @@ -854,7 +854,7 @@ njs_vm_expression_completions(njs_vm_t * value = &prop->value; } - return njs_object_completions(vm, value->data.u.object); + return njs_object_completions(vm, njs_object(value)); } diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_crypto.c --- a/njs/njs_crypto.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_crypto.c Mon Jul 08 17:49:43 2019 +0300 @@ -187,10 +187,7 @@ njs_crypto_create_hash(njs_vm_t *vm, njs alg->init(&dgst->u); njs_set_data(&hash->value, dgst); - - vm->retval.data.u.object_value = hash; - vm->retval.type = NJS_OBJECT_VALUE; - vm->retval.data.truth = 1; + njs_set_object_value(&vm->retval, hash); return NJS_OK; } @@ -200,9 +197,8 @@ static njs_ret_t njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_str_t data; - njs_digest_t *dgst; - njs_object_value_t *hash; + nxt_str_t data; + njs_digest_t *dgst; if (nxt_slow_path(nargs < 2 || !njs_is_string(&args[1]))) { njs_type_error(vm, "data must be a string"); @@ -214,16 +210,14 @@ njs_hash_prototype_update(njs_vm_t *vm, return NJS_ERROR; } - if (nxt_slow_path(!njs_is_data(&args[0].data.u.object_value->value))) { + if (nxt_slow_path(!njs_is_data(njs_object_value(&args[0])))) { njs_type_error(vm, "value of \"this\" is not a data type"); return NJS_ERROR; } - hash = args[0].data.u.object_value; - njs_string_get(&args[1], &data); - dgst = njs_value_data(&hash->value); + dgst = njs_value_data(njs_object_value(&args[0])); if (nxt_slow_path(dgst->alg == NULL)) { njs_error(vm, "Digest already called"); @@ -242,13 +236,12 @@ static njs_ret_t njs_hash_prototype_digest(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - u_char digest[32], *p; - njs_ret_t ret; - nxt_str_t enc_name, str; - njs_digest_t *dgst; - njs_hash_alg_t *alg; - njs_crypto_enc_t *enc; - njs_object_value_t *hash; + u_char digest[32], *p; + njs_ret_t ret; + nxt_str_t enc_name, str; + njs_digest_t *dgst; + njs_hash_alg_t *alg; + njs_crypto_enc_t *enc; if (nxt_slow_path(nargs > 1 && !njs_is_string(&args[1]))) { njs_type_error(vm, "encoding must be a string"); @@ -260,7 +253,7 @@ njs_hash_prototype_digest(njs_vm_t *vm, return NJS_ERROR; } - if (nxt_slow_path(!njs_is_data(&args[0].data.u.object_value->value))) { + if (nxt_slow_path(!njs_is_data(njs_object_value(&args[0])))) { njs_type_error(vm, "value of \"this\" is not a data type"); return NJS_ERROR; } @@ -276,9 +269,7 @@ njs_hash_prototype_digest(njs_vm_t *vm, } } - hash = args[0].data.u.object_value; - - dgst = njs_value_data(&hash->value); + dgst = njs_value_data(njs_object_value(&args[0])); if (nxt_slow_path(dgst->alg == NULL)) { njs_error(vm, "Digest already called"); @@ -453,10 +444,7 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs } njs_set_data(&hmac->value, ctx); - - vm->retval.data.u.object_value = hmac; - vm->retval.type = NJS_OBJECT_VALUE; - vm->retval.data.truth = 1; + njs_set_object_value(&vm->retval, hmac); return NJS_OK; } @@ -466,9 +454,8 @@ static njs_ret_t njs_hmac_prototype_update(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_str_t data; - njs_hmac_t *ctx; - njs_object_value_t *hmac; + nxt_str_t data; + njs_hmac_t *ctx; if (nxt_slow_path(nargs < 2 || !njs_is_string(&args[1]))) { njs_type_error(vm, "data must be a string"); @@ -480,16 +467,14 @@ njs_hmac_prototype_update(njs_vm_t *vm, return NJS_ERROR; } - if (nxt_slow_path(!njs_is_data(&args[0].data.u.object_value->value))) { + if (nxt_slow_path(!njs_is_data(njs_object_value(&args[0])))) { njs_type_error(vm, "value of \"this\" is not a data type"); return NJS_ERROR; } - hmac = args[0].data.u.object_value; - njs_string_get(&args[1], &data); - ctx = njs_value_data(&hmac->value); + ctx = njs_value_data(njs_object_value(&args[0])); if (nxt_slow_path(ctx->alg == NULL)) { njs_error(vm, "Digest already called"); @@ -508,13 +493,12 @@ static njs_ret_t njs_hmac_prototype_digest(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - u_char hash1[32], digest[32], *p; - nxt_str_t enc_name, str; - njs_ret_t ret; - njs_hmac_t *ctx; - njs_hash_alg_t *alg; - njs_crypto_enc_t *enc; - njs_object_value_t *hmac; + u_char hash1[32], digest[32], *p; + nxt_str_t enc_name, str; + njs_ret_t ret; + njs_hmac_t *ctx; + njs_hash_alg_t *alg; + njs_crypto_enc_t *enc; if (nxt_slow_path(nargs > 1 && !njs_is_string(&args[1]))) { njs_type_error(vm, "encoding must be a string"); @@ -526,7 +510,7 @@ njs_hmac_prototype_digest(njs_vm_t *vm, return NJS_ERROR; } - if (nxt_slow_path(!njs_is_data(&args[0].data.u.object_value->value))) { + if (nxt_slow_path(!njs_is_data(njs_object_value(&args[0])))) { njs_type_error(vm, "value of \"this\" is not a data type"); return NJS_ERROR; } @@ -542,9 +526,7 @@ njs_hmac_prototype_digest(njs_vm_t *vm, } } - hmac = args[0].data.u.object_value; - - ctx = njs_value_data(&hmac->value); + ctx = njs_value_data(njs_object_value(&args[0])); if (nxt_slow_path(ctx->alg == NULL)) { njs_error(vm, "Digest already called"); diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_error.c --- a/njs/njs_error.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_error.c Mon Jul 08 17:49:43 2019 +0300 @@ -29,9 +29,7 @@ njs_error_new(njs_vm_t *vm, njs_value_t error = njs_error_alloc(vm, type, NULL, &string); if (nxt_fast_path(error != NULL)) { - dst->data.u.object = error; - dst->type = type; - dst->data.truth = 1; + njs_set_type_object(dst, error, type); } } @@ -148,9 +146,7 @@ njs_error_create(njs_vm_t *vm, njs_value return NXT_ERROR; } - vm->retval.data.u.object = error; - vm->retval.type = type; - vm->retval.data.truth = 1; + njs_set_type_object(&vm->retval, error, type); return NXT_OK; } @@ -513,9 +509,7 @@ njs_memory_error_set(njs_vm_t *vm, njs_v */ object->extensible = 0; - value->data.type = NJS_OBJECT_INTERNAL_ERROR; - value->data.truth = 1; - value->data.u.object = object; + njs_set_type_object(value, object, NJS_OBJECT_INTERNAL_ERROR); } @@ -634,7 +628,7 @@ njs_error_to_string(njs_vm_t *vm, njs_va lhq.key = nxt_string_value("name"); lhq.proto = &njs_object_hash_proto; - prop = njs_object_property(vm, error->data.u.object, &lhq); + prop = njs_object_property(vm, njs_object(error), &lhq); if (prop != NULL) { name_value = &prop->value; @@ -648,7 +642,7 @@ njs_error_to_string(njs_vm_t *vm, njs_va lhq.key_hash = NJS_MESSAGE_HASH; lhq.key = nxt_string_value("message"); - prop = njs_object_property(vm, error->data.u.object, &lhq); + prop = njs_object_property(vm, njs_object(error), &lhq); if (prop != NULL) { message_value = &prop->value; @@ -773,7 +767,7 @@ njs_internal_error_prototype_to_string(n if (nargs >= 1 && njs_is_object(&args[0])) { /* MemoryError is a nonextensible internal error. */ - if (!args[0].data.u.object->extensible) { + if (!njs_object(&args[0])->extensible) { static const njs_value_t name = njs_string("MemoryError"); vm->retval = name; diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_fs.c --- a/njs/njs_fs.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_fs.c Mon Jul 08 17:49:43 2019 +0300 @@ -979,9 +979,7 @@ static njs_ret_t njs_fs_error(njs_vm_t * } } - retval->data.u.object = error; - retval->type = NJS_OBJECT_ERROR; - retval->data.truth = 1; + njs_set_type_object(retval, error, NJS_OBJECT_ERROR); return NJS_OK; } @@ -1007,14 +1005,14 @@ njs_fs_mode(njs_value_t *value) { switch (value->type) { case NJS_OBJECT_NUMBER: - value = &value->data.u.object_value->value; + value = njs_object_value(value); /* Fall through. */ case NJS_NUMBER: return (mode_t) njs_number(value); case NJS_OBJECT_STRING: - value = &value->data.u.object_value->value; + value = njs_object_value(value); /* Fall through. */ case NJS_STRING: diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_function.c --- a/njs/njs_function.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_function.c Mon Jul 08 17:49:43 2019 +0300 @@ -910,7 +910,7 @@ njs_function_instance_length(njs_vm_t *v njs_function_t *function; njs_function_lambda_t *lambda; - proto = value->data.u.object; + proto = njs_object(value); do { if (nxt_fast_path(proto->type == NJS_FUNCTION)) { diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_json.c --- a/njs/njs_json.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_json.c Mon Jul 08 17:49:43 2019 +0300 @@ -1487,7 +1487,7 @@ njs_object_to_json_function(njs_vm_t *vm lhq.key_hash = NJS_TO_JSON_HASH; lhq.key = nxt_string_value("toJSON"); - prop = njs_object_property(vm, value->data.u.object, &lhq); + prop = njs_object_property(vm, njs_object(value), &lhq); if (prop != NULL && njs_is_function(&prop->value)) { return prop->value.data.u.function; @@ -1622,7 +1622,7 @@ njs_json_stringify_array(njs_vm_t *vm, n switch (value->type) { case NJS_OBJECT_NUMBER: - value = &value->data.u.object_value->value; + value = njs_object_value(value); /* Fall through. */ case NJS_NUMBER: @@ -1635,7 +1635,7 @@ njs_json_stringify_array(njs_vm_t *vm, n break; case NJS_OBJECT_STRING: - value = &value->data.u.object_value->value; + value = njs_object_value(value); break; case NJS_STRING: @@ -1736,21 +1736,21 @@ njs_json_append_value(njs_json_stringify { switch (value->type) { case NJS_OBJECT_STRING: - value = &value->data.u.object_value->value; + value = njs_object_value(value); /* Fall through. */ case NJS_STRING: return njs_json_append_string(stringify, value, '\"'); case NJS_OBJECT_NUMBER: - value = &value->data.u.object_value->value; + value = njs_object_value(value); /* Fall through. */ case NJS_NUMBER: return njs_json_append_number(stringify, value); case NJS_OBJECT_BOOLEAN: - value = &value->data.u.object_value->value; + value = njs_object_value(value); /* Fall through. */ case NJS_BOOLEAN: @@ -1924,7 +1924,7 @@ njs_json_wrap_value(njs_vm_t *vm, const } wrapper->data.u.object = njs_object_alloc(vm); - if (nxt_slow_path(wrapper->data.u.object == NULL)) { + if (nxt_slow_path(njs_object(wrapper) == NULL)) { return NULL; } @@ -2134,7 +2134,7 @@ njs_dump_value(njs_json_stringify_t *str switch (value->type) { case NJS_OBJECT_STRING: - value = &value->data.u.object_value->value; + value = njs_object_value(value); njs_string_get(value, &str); @@ -2155,7 +2155,7 @@ njs_dump_value(njs_json_stringify_t *str break; case NJS_OBJECT_NUMBER: - value = &value->data.u.object_value->value; + value = njs_object_value(value); if (nxt_slow_path(njs_number(value) == 0.0 && signbit(njs_number(value)))) @@ -2178,7 +2178,7 @@ njs_dump_value(njs_json_stringify_t *str break; case NJS_OBJECT_BOOLEAN: - value = &value->data.u.object_value->value; + value = njs_object_value(value); if (njs_is_true(value)) { njs_dump("[Boolean: true]"); @@ -2457,7 +2457,7 @@ njs_vm_value_dump(njs_vm_t *vm, nxt_str_ val = &ext_val; } else { - object = state->value.data.u.object; + object = njs_object(&state->value); lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_find(&object->hash, &lhq); diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_number.c --- a/njs/njs_number.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_number.c Mon Jul 08 17:49:43 2019 +0300 @@ -258,9 +258,7 @@ njs_number_constructor(njs_vm_t *vm, njs return NXT_ERROR; } - vm->retval.data.u.object = object; - vm->retval.type = NJS_OBJECT_NUMBER; - vm->retval.data.truth = 1; + njs_set_type_object(&vm->retval, object, NJS_OBJECT_NUMBER); } else { njs_set_number(&vm->retval, njs_number(value)); @@ -490,7 +488,7 @@ njs_number_prototype_value_of(njs_vm_t * if (value->type != NJS_NUMBER) { if (value->type == NJS_OBJECT_NUMBER) { - value = &value->data.u.object_value->value; + value = njs_object_value(value); } else { njs_type_error(vm, "unexpected value type:%s", @@ -517,7 +515,7 @@ njs_number_prototype_to_string(njs_vm_t if (value->type != NJS_NUMBER) { if (value->type == NJS_OBJECT_NUMBER) { - value = &value->data.u.object_value->value; + value = njs_object_value(value); } else { njs_type_error(vm, "unexpected value type:%s", diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_object.c --- a/njs/njs_object.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_object.c Mon Jul 08 17:49:43 2019 +0300 @@ -57,7 +57,7 @@ njs_object_value_copy(njs_vm_t *vm, njs_ { njs_object_t *object; - object = value->data.u.object; + object = njs_object(value); if (!object->shared) { return object; @@ -66,7 +66,7 @@ njs_object_value_copy(njs_vm_t *vm, njs_ object = nxt_mp_alloc(vm->mem_pool, sizeof(njs_object_t)); if (nxt_fast_path(object != NULL)) { - *object = *value->data.u.object; + *object = *njs_object(value); object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object; object->shared = 0; value->data.u.object = object; @@ -212,7 +212,7 @@ njs_object_constructor(njs_vm_t *vm, njs } else { if (njs_is_object(value)) { - object = value->data.u.object; + object = njs_object(value); } else if (njs_is_primitive(value)) { @@ -232,9 +232,7 @@ njs_object_constructor(njs_vm_t *vm, njs } } - vm->retval.data.u.object = object; - vm->retval.type = type; - vm->retval.data.truth = 1; + njs_set_type_object(&vm->retval, object, type); return NXT_OK; } @@ -260,7 +258,7 @@ njs_object_create(njs_vm_t *vm, njs_valu if (!njs_is_null(value)) { /* GC */ - object->__proto__ = value->data.u.object; + object->__proto__ = njs_object(value); } else { object->__proto__ = NULL; @@ -1105,7 +1103,7 @@ njs_object_define_property(njs_vm_t *vm, value = njs_argument(args, 1); - if (!value->data.u.object->extensible) { + if (!njs_object(value)->extensible) { njs_type_error(vm, "object is not extensible"); return NXT_ERROR; } @@ -1149,7 +1147,7 @@ njs_object_define_properties(njs_vm_t *v value = njs_argument(args, 1); - if (!value->data.u.object->extensible) { + if (!njs_object(value)->extensible) { njs_type_error(vm, "object is not extensible"); return NXT_ERROR; } @@ -1339,7 +1337,7 @@ njs_object_freeze(njs_vm_t *vm, njs_valu return NXT_OK; } - object = value->data.u.object; + object = njs_object(value); object->extensible = 0; nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); @@ -1382,7 +1380,7 @@ njs_object_is_frozen(njs_vm_t *vm, njs_v retval = &njs_value_false; - object = value->data.u.object; + object = njs_object(value); nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->hash; @@ -1434,7 +1432,7 @@ njs_object_seal(njs_vm_t *vm, njs_value_ return NXT_OK; } - object = value->data.u.object; + object = njs_object(value); object->extensible = 0; nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); @@ -1476,7 +1474,7 @@ njs_object_is_sealed(njs_vm_t *vm, njs_v retval = &njs_value_false; - object = value->data.u.object; + object = njs_object(value); nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->hash; @@ -1520,7 +1518,7 @@ njs_object_prevent_extensions(njs_vm_t * return NXT_OK; } - args[1].data.u.object->extensible = 0; + njs_object(&args[1])->extensible = 0; vm->retval = *value; @@ -1541,8 +1539,8 @@ njs_object_is_extensible(njs_vm_t *vm, n return NXT_OK; } - retval = value->data.u.object->extensible ? &njs_value_true - : &njs_value_false; + retval = njs_object(value)->extensible ? &njs_value_true + : &njs_value_false; vm->retval = *retval; @@ -1568,16 +1566,14 @@ njs_primitive_prototype_get_proto(njs_vm * and have to return different results for primitive type and for objects. */ if (njs_is_object(value)) { - proto = value->data.u.object->__proto__; + proto = njs_object(value)->__proto__; } else { index = njs_primitive_prototype_index(value->type); proto = &vm->prototypes[index].object; } - retval->data.u.object = proto; - retval->type = proto->type; - retval->data.truth = 1; + njs_set_type_object(retval, proto, proto->type); return NXT_OK; } @@ -1633,9 +1629,7 @@ njs_property_prototype_create(njs_vm_t * /* GC */ - prop->value.data.u.object = prototype; - prop->value.type = prototype->type; - prop->value.data.truth = 1; + njs_set_type_object(&prop->value, prototype, prototype->type); lhq.value = prop; lhq.key_hash = NJS_PROTOTYPE_HASH; @@ -1861,7 +1855,7 @@ njs_object_set_prototype_of(njs_vm_t *vm { const njs_object_t *proto; - proto = njs_is_object(value) ? value->data.u.object->__proto__ + proto = njs_is_object(value) ? njs_object(value)->__proto__ : NULL; if (nxt_slow_path(object->__proto__ == proto)) { @@ -1882,7 +1876,7 @@ njs_object_set_prototype_of(njs_vm_t *vm } while (proto != NULL); - object->__proto__ = value->data.u.object; + object->__proto__ = njs_object(value); return 1; } @@ -1900,7 +1894,7 @@ njs_object_prototype_proto(njs_vm_t *vm, return NJS_OK; } - object = value->data.u.object; + object = njs_object(value); if (setval != NULL) { if (njs_is_object(setval) || njs_is_null(setval)) { @@ -1919,9 +1913,7 @@ njs_object_prototype_proto(njs_vm_t *vm, proto = object->__proto__; if (nxt_fast_path(proto != NULL)) { - retval->data.u.object = proto; - retval->type = proto->type; - retval->data.truth = 1; + njs_set_type_object(retval, proto, proto->type); } else { *retval = njs_value_null; @@ -1947,7 +1939,7 @@ njs_object_prototype_create_constructor( njs_object_prototype_t *prototype; if (njs_is_object(value)) { - object = value->data.u.object; + object = njs_object(value); do { prototype = (njs_object_prototype_t *) object; @@ -2217,8 +2209,8 @@ njs_object_prototype_is_prototype_of(njs value = njs_arg(args, nargs, 1); if (njs_is_object(prototype) && njs_is_object(value)) { - proto = prototype->data.u.object; - object = value->data.u.object; + proto = njs_object(prototype); + object = njs_object(value); do { object = object->__proto__; diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_object_property.c --- a/njs/njs_object_property.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_object_property.c Mon Jul 08 17:49:43 2019 +0300 @@ -97,7 +97,7 @@ njs_property_query(njs_vm_t *vm, njs_pro case NJS_OBJECT_TYPE_ERROR: case NJS_OBJECT_URI_ERROR: case NJS_OBJECT_VALUE: - obj = object->data.u.object; + obj = njs_object(object); break; case NJS_FUNCTION: @@ -678,7 +678,7 @@ njs_value_property_set(njs_vm_t *vm, njs return ret; } - if (nxt_slow_path(!object->data.u.object->extensible)) { + if (nxt_slow_path(!njs_object(object)->extensible)) { njs_type_error(vm, "Cannot add property \"%V\", " "object is not extensible", &pq.lhq.key); return NXT_ERROR; @@ -799,7 +799,7 @@ njs_object_prop_define(njs_vm_t *vm, njs return ret; } - prop = njs_descriptor_prop(vm, name, value->data.u.object); + prop = njs_descriptor_prop(vm, name, njs_object(value)); if (nxt_slow_path(prop == NULL)) { return NXT_ERROR; } diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_parser_terminal.c Mon Jul 08 17:49:43 2019 +0300 @@ -447,7 +447,7 @@ njs_parser_builtin(njs_vm_t *vm, njs_par switch (type) { case NJS_OBJECT: index = node->token - NJS_TOKEN_FIRST_OBJECT; - var->value.data.u.object = &vm->shared->objects[index]; + njs_set_object(&var->value, &vm->shared->objects[index]); break; case NJS_FUNCTION: diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_string.c Mon Jul 08 17:49:43 2019 +0300 @@ -562,9 +562,7 @@ njs_string_constructor(njs_vm_t *vm, njs return NXT_ERROR; } - vm->retval.data.u.object = object; - vm->retval.type = NJS_OBJECT_STRING; - vm->retval.data.truth = 1; + njs_set_type_object(&vm->retval, object, NJS_OBJECT_STRING); } else { vm->retval = *value; @@ -652,7 +650,7 @@ njs_string_instance_length(njs_vm_t *vm, length = 0; if (nxt_slow_path(njs_is_object(value))) { - proto = value->data.u.object; + proto = njs_object(value); do { if (nxt_fast_path(proto->type == NJS_OBJECT_STRING)) { @@ -769,7 +767,7 @@ njs_string_prototype_value_of(njs_vm_t * if (value->type != NJS_STRING) { if (value->type == NJS_OBJECT_STRING) { - value = &value->data.u.object_value->value; + value = njs_object_value(value); } else { njs_type_error(vm, "unexpected value type:%s", diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_value.c --- a/njs/njs_value.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_value.c Mon Jul 08 17:49:43 2019 +0300 @@ -158,7 +158,7 @@ njs_values_strict_equal(const njs_value_ return (memcmp(start1, start2, size) == 0); } - return (val1->data.u.object == val2->data.u.object); + return (njs_object(val1) == njs_object(val2)); } @@ -201,7 +201,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs lhq.key_hash = hashes[hint]; lhq.key = names[hint]; - prop = njs_object_property(vm, value->data.u.object, &lhq); + prop = njs_object_property(vm, njs_object(value), &lhq); if (nxt_fast_path(prop != NULL)) { @@ -267,7 +267,7 @@ njs_value_enumerate(njs_vm_t *vm, const njs_object_value_t obj_val; if (njs_is_object(value)) { - return njs_object_enumerate(vm, value->data.u.object, kind, all); + return njs_object_enumerate(vm, njs_object(value), kind, all); } if (value->type != NJS_STRING) { @@ -288,7 +288,7 @@ njs_value_own_enumerate(njs_vm_t *vm, co njs_object_value_t obj_val; if (njs_is_object(value)) { - return njs_object_own_enumerate(vm, value->data.u.object, kind, all); + return njs_object_own_enumerate(vm, njs_object(value), kind, all); } if (value->type != NJS_STRING) { diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_value.h --- a/njs/njs_value.h Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_value.h Mon Jul 08 17:49:43 2019 +0300 @@ -540,6 +540,10 @@ typedef enum { ((value)->data.u.date) +#define njs_object_value(_value) \ + (&(_value)->data.u.object_value->value) + + #define njs_set_undefined(value) \ *(value) = njs_value_undefined @@ -584,6 +588,16 @@ njs_set_object(njs_value_t *value, njs_o nxt_inline void +njs_set_type_object(njs_value_t *value, njs_object_t *object, + nxt_uint_t type) +{ + value->data.u.object = object; + value->type = type; + value->data.truth = 1; +} + + +nxt_inline void njs_set_array(njs_value_t *value, njs_array_t *array) { value->data.u.array = array; @@ -601,6 +615,15 @@ njs_set_date(njs_value_t *value, njs_dat } +nxt_inline void +njs_set_object_value(njs_value_t *value, njs_object_value_t *object_value) +{ + value->data.u.object_value = object_value; + value->type = NJS_OBJECT_VALUE; + value->data.truth = 1; +} + + #define njs_set_invalid(value) \ (value)->type = NJS_INVALID diff -r 254c9b04b0d2 -r 5eee6645c7e2 njs/njs_vm.c --- a/njs/njs_vm.c Mon Jul 08 17:49:14 2019 +0300 +++ b/njs/njs_vm.c Mon Jul 08 17:49:43 2019 +0300 @@ -523,7 +523,7 @@ njs_vmcode_property_init(njs_vm_t *vm, n lhq.proto = &njs_object_hash_proto; lhq.pool = vm->mem_pool; - obj = object->data.u.object; + obj = njs_object(object); ret = nxt_lvlhsh_find(&obj->__proto__->shared_hash, &lhq); if (ret == NXT_OK) { @@ -865,8 +865,8 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs return NXT_ERROR; } - prototype = value.data.u.object; - proto = object->data.u.object; + prototype = njs_object(&value); + proto = njs_object(object); do { proto = proto->__proto__; @@ -1494,7 +1494,7 @@ njs_values_equal(njs_vm_t *vm, const njs return njs_string_eq(val1, val2); } - return (val1->data.u.object == val2->data.u.object); + return (njs_object(val1) == njs_object(val2)); } /* Sort values as: numeric < string < objects. */ @@ -1805,7 +1805,7 @@ njs_function_new_object(njs_vm_t *vm, nj } if (nxt_fast_path(proto != NULL)) { - object->__proto__ = proto->data.u.object; + object->__proto__ = njs_object(proto); return object; } } @@ -2685,7 +2685,7 @@ njs_vm_value_to_string(njs_vm_t *vm, nxt if (nxt_slow_path(src->type == NJS_OBJECT_INTERNAL_ERROR)) { /* MemoryError is a nonextensible internal error. */ - if (!src->data.u.object->extensible) { + if (!njs_object(src)->extensible) { njs_string_get(&njs_string_memory_error, dst); return NXT_OK; } From xeioex at nginx.com Mon Jul 8 14:52:35 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 08 Jul 2019 14:52:35 +0000 Subject: [njs] Using njs_function() and njs_set_function() where applicable. Message-ID: details: https://hg.nginx.org/njs/rev/4c9047471ed0 branches: changeset: 1035:4c9047471ed0 user: Dmitry Volyntsev date: Mon Jul 08 17:51:35 2019 +0300 description: Using njs_function() and njs_set_function() where applicable. diffstat: njs/njs_array.c | 12 ++++++------ njs/njs_builtin.c | 6 ++---- njs/njs_error.c | 2 +- njs/njs_fs.c | 4 ++-- njs/njs_function.c | 12 +++++------- njs/njs_generator.c | 2 +- njs/njs_json.c | 12 ++++++------ njs/njs_object.c | 2 +- njs/njs_object_property.c | 8 +++----- njs/njs_parser.c | 4 +--- njs/njs_parser_terminal.c | 5 +---- njs/njs_string.c | 2 +- njs/njs_time.c | 2 +- njs/njs_value.c | 2 +- njs/njs_value.h | 13 +++++++++++++ njs/njs_variable.c | 2 +- njs/njs_vm.c | 8 +++----- 17 files changed, 49 insertions(+), 49 deletions(-) diffs (421 lines): diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_array.c --- a/njs/njs_array.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_array.c Mon Jul 08 17:51:35 2019 +0300 @@ -970,7 +970,7 @@ njs_array_prototype_to_string(njs_vm_t * prop = njs_object_property(vm, njs_object(&args[0]), &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { - return njs_function_replace(vm, prop->value.data.u.function, + return njs_function_replace(vm, njs_function(&prop->value), args, nargs, retval); } } @@ -1879,7 +1879,7 @@ njs_array_prototype_find_apply(njs_vm_t arguments[3] = args[0]; - return njs_function_apply(vm, args[1].data.u.function, arguments, 4, + return njs_function_apply(vm, njs_function(&args[1]), arguments, 4, (njs_index_t) &iter->retval); } @@ -2026,7 +2026,7 @@ njs_array_prototype_reduce_continuation( arguments[4] = args[0]; - return njs_function_apply(vm, args[1].data.u.function, arguments, 5, + return njs_function_apply(vm, njs_function(&args[1]), arguments, 5, (njs_index_t) &iter->retval); } @@ -2090,7 +2090,7 @@ njs_array_iterator_apply(njs_vm_t *vm, n arguments[3] = args[0]; - return njs_function_apply(vm, args[1].data.u.function, arguments, 4, + return njs_function_apply(vm, njs_function(&args[1]), arguments, 4, (njs_index_t) &iter->retval); } @@ -2163,7 +2163,7 @@ njs_array_prototype_reduce_right_continu arguments[4] = args[0]; - return njs_function_apply(vm, args[1].data.u.function, arguments, 5, + return njs_function_apply(vm, njs_function(&args[1]), arguments, 5, (njs_index_t) &iter->retval); } @@ -2236,7 +2236,7 @@ njs_array_prototype_sort(njs_vm_t *vm, n sort->retval = njs_value_zero; if (nargs > 1 && njs_is_function(&args[1])) { - sort->function = args[1].data.u.function; + sort->function = njs_function(&args[1]); } else { sort->function = (njs_function_t *) &njs_array_string_sort_function; diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_builtin.c --- a/njs/njs_builtin.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_builtin.c Mon Jul 08 17:51:35 2019 +0300 @@ -536,9 +536,7 @@ njs_builtin_objects_clone(njs_vm_t *vm) values = vm->scopes[NJS_SCOPE_GLOBAL]; for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) { - values[i].type = NJS_FUNCTION; - values[i].data.truth = 1; - values[i].data.u.function = &vm->constructors[i]; + njs_set_function(&values[i], &vm->constructors[i]); vm->constructors[i].object.__proto__ = function_prototype; } @@ -981,7 +979,7 @@ njs_builtin_match(const njs_object_init_ continue; } - if (function != pr->value.data.u.function) { + if (function != njs_function(&pr->value)) { continue; } diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_error.c --- a/njs/njs_error.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_error.c Mon Jul 08 17:51:35 2019 +0300 @@ -542,7 +542,7 @@ njs_memory_error_prototype_create(njs_vm index = NJS_PROTOTYPE_INTERNAL_ERROR; - function = value->data.u.function; + function = njs_function(value); proto = njs_property_prototype_create(vm, &function->object.hash, &vm->prototypes[index].object); if (proto == NULL) { diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_fs.c --- a/njs/njs_fs.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_fs.c Mon Jul 08 17:51:35 2019 +0300 @@ -289,7 +289,7 @@ done: cont = njs_vm_continuation(vm); cont->u.cont.function = njs_fs_done; - return njs_function_apply(vm, callback->data.u.function, + return njs_function_apply(vm, njs_function(callback), arguments, 3, (njs_index_t) &vm->retval); fail: @@ -709,7 +709,7 @@ done: cont = njs_vm_continuation(vm); cont->u.cont.function = njs_fs_done; - return njs_function_apply(vm, callback->data.u.function, + return njs_function_apply(vm, njs_function(callback), arguments, 2, (njs_index_t) &vm->retval); } diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_function.c --- a/njs/njs_function.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_function.c Mon Jul 08 17:51:35 2019 +0300 @@ -80,7 +80,7 @@ njs_function_value_copy(njs_vm_t *vm, nj { njs_function_t *function, *copy; - function = value->data.u.function; + function = njs_function(value); if (!function->object.shared) { return function; @@ -974,7 +974,7 @@ njs_function_prototype_call(njs_vm_t *vm nargs = 0; } - function = args[0].data.u.function; + function = njs_function(&args[0]); ret = njs_function_activate(vm, function, this, &args[2], nargs, retval, sizeof(njs_vmcode_function_call_t)); @@ -1018,7 +1018,7 @@ njs_function_prototype_apply(njs_vm_t *v return NXT_ERROR; } - func = (njs_argument(args, 0))->data.u.function; + func = njs_function(njs_argument(args, 0)); this = njs_arg(args, nargs, 1); arr_like = njs_arg(args, nargs, 2); @@ -1133,7 +1133,7 @@ njs_function_prototype_bind(njs_vm_t *vm return NXT_ERROR; } - function = njs_function_copy(vm, args[0].data.u.function); + function = njs_function_copy(vm, njs_function(&args[0])); if (nxt_slow_path(function == NULL)) { njs_memory_error(vm); return NXT_ERROR; @@ -1163,9 +1163,7 @@ njs_function_prototype_bind(njs_vm_t *vm memcpy(values, args, size); - vm->retval.data.u.function = function; - vm->retval.type = NJS_FUNCTION; - vm->retval.data.truth = 1; + njs_set_function(&vm->retval, function); return NXT_OK; } diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_generator.c --- a/njs/njs_generator.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_generator.c Mon Jul 08 17:51:35 2019 +0300 @@ -2319,7 +2319,7 @@ njs_generate_function_declaration(njs_vm return NXT_OK; } - lambda = var->value.data.u.function->u.lambda; + lambda = njs_function_lambda(&var->value); ret = njs_generate_function_scope(vm, lambda, node, &node->u.reference.name); diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_json.c --- a/njs/njs_json.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_json.c Mon Jul 08 17:51:35 2019 +0300 @@ -223,7 +223,7 @@ njs_json_parse(njs_vm_t *vm, njs_value_t parse = njs_vm_continuation(vm); parse->u.cont.function = njs_json_parse_continuation; - parse->function = reviver->data.u.function; + parse->function = njs_function(reviver); if (nxt_array_init(&parse->stack, NULL, 4, sizeof(njs_json_state_t), &njs_array_mem_proto, vm->mem_pool) @@ -256,7 +256,7 @@ njs_vm_json_parse(njs_vm_t *vm, njs_valu { njs_function_t *parse; - parse = njs_json_object_properties[0].value.data.u.function; + parse = njs_function(&njs_json_object_properties[0].value); return njs_vm_call(vm, parse, args, nargs); } @@ -354,7 +354,7 @@ njs_vm_json_stringify(njs_vm_t *vm, njs_ { njs_function_t *stringify; - stringify = njs_json_object_properties[1].value.data.u.function; + stringify = njs_function(&njs_json_object_properties[1].value); return njs_vm_call(vm, stringify, args, nargs); } @@ -1490,7 +1490,7 @@ njs_object_to_json_function(njs_vm_t *vm prop = njs_object_property(vm, njs_object(value), &lhq); if (prop != NULL && njs_is_function(&prop->value)) { - return prop->value.data.u.function; + return njs_function(&prop->value); } return NULL; @@ -1582,7 +1582,7 @@ njs_json_stringify_replacer(njs_vm_t *vm njs_set_invalid(&stringify->retval); - return njs_function_apply(vm, stringify->replacer.data.u.function, + return njs_function_apply(vm, njs_function(&stringify->replacer), arguments, 3, (njs_index_t) &stringify->retval); } @@ -2212,7 +2212,7 @@ njs_dump_value(njs_json_stringify_t *str break; case NJS_FUNCTION: - if (value->data.u.function->native) { + if (njs_function(value)->native) { njs_dump("[Function: native]"); } else { diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_object.c --- a/njs/njs_object.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_object.c Mon Jul 08 17:51:35 2019 +0300 @@ -1594,7 +1594,7 @@ njs_object_prototype_create(njs_vm_t *vm const njs_value_t *proto; proto = NULL; - function = value->data.u.function; + function = njs_function(value); index = function - vm->constructors; if (index >= 0 && index < NJS_PROTOTYPE_MAX) { diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_object_property.c --- a/njs/njs_object_property.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_object_property.c Mon Jul 08 17:51:35 2019 +0300 @@ -414,9 +414,7 @@ njs_external_property_query(njs_vm_t *vm done: if (ext_proto->type == NJS_EXTERN_METHOD) { - prop->value.type = NJS_FUNCTION; - prop->value.data.u.function = ext_proto->function; - prop->value.data.truth = 1; + njs_set_function(&prop->value, ext_proto->function); } pq->lhq.value = prop; @@ -523,7 +521,7 @@ njs_value_property(njs_vm_t *vm, const n break; } - return njs_function_activate(vm, prop->getter.data.u.function, + return njs_function_activate(vm, njs_function(&prop->getter), value, NULL, 0, (njs_index_t) retval, advance); @@ -631,7 +629,7 @@ njs_value_property_set(njs_vm_t *vm, njs if (njs_is_function(&prop->setter)) { return njs_function_activate(vm, - prop->setter.data.u.function, + njs_function(&prop->setter), object, value, 1, (njs_index_t) &vm->retval, advance); diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_parser.c --- a/njs/njs_parser.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_parser.c Mon Jul 08 17:51:35 2019 +0300 @@ -619,9 +619,7 @@ njs_parser_function_alloc(njs_vm_t *vm, return NULL; } - var->value.data.u.function = function; - var->value.type = NJS_FUNCTION; - var->value.data.truth = 1; + njs_set_function(&var->value, function); if (var->index != NJS_INDEX_NONE && njs_scope_accumulative(vm, parser->scope)) diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_parser_terminal.c Mon Jul 08 17:51:35 2019 +0300 @@ -452,16 +452,13 @@ njs_parser_builtin(njs_vm_t *vm, njs_par case NJS_FUNCTION: index = node->token - NJS_TOKEN_FIRST_FUNCTION; - var->value.data.u.function = &vm->shared->functions[index]; + njs_set_function(&var->value, &vm->shared->functions[index]); break; default: return NXT_ERROR; } - var->value.type = type; - var->value.data.truth = 1; - ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_string.c Mon Jul 08 17:51:35 2019 +0300 @@ -3039,7 +3039,7 @@ njs_string_prototype_replace(njs_vm_t *v } } else { - r->function = args[2].data.u.function; + r->function = njs_function(&args[2]); } r->part[0].start = string.start; diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_time.c --- a/njs/njs_time.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_time.c Mon Jul 08 17:51:35 2019 +0300 @@ -48,7 +48,7 @@ njs_set_timer(njs_vm_t *vm, njs_value_t n = immediate ? 2 : 3; event->destructor = ops->clear_timer; - event->function = args[1].data.u.function; + event->function = njs_function(&args[1]); event->nargs = (nargs >= n) ? nargs - n : 0; event->once = 1; event->posted = 0; diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_value.c --- a/njs/njs_value.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_value.c Mon Jul 08 17:51:35 2019 +0300 @@ -210,7 +210,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs continue; } - function = prop->value.data.u.function; + function = njs_function(&prop->value); ret = njs_function_apply(vm, function, value, 1, (njs_index_t) retval); diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_value.h --- a/njs/njs_value.h Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_value.h Mon Jul 08 17:51:35 2019 +0300 @@ -516,6 +516,10 @@ typedef enum { ((value)->data.u.function) +#define njs_function_lambda(value) \ + ((value)->data.u.function->u.lambda) + + #define njs_object(value) \ ((value)->data.u.object) @@ -607,6 +611,15 @@ njs_set_array(njs_value_t *value, njs_ar nxt_inline void +njs_set_function(njs_value_t *value, njs_function_t *function) +{ + value->data.u.function = function; + value->type = NJS_FUNCTION; + value->data.truth = 1; +} + + +nxt_inline void njs_set_date(njs_value_t *value, njs_date_t *date) { value->data.u.date = date; diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_variable.c --- a/njs/njs_variable.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_variable.c Mon Jul 08 17:51:35 2019 +0300 @@ -666,7 +666,7 @@ njs_vm_function(njs_vm_t *vm, const nxt_ value = njs_vm_value(vm, name); if (njs_is_function(value)) { - return value->data.u.function; + return njs_function(value); } return NULL; diff -r 5eee6645c7e2 -r 4c9047471ed0 njs/njs_vm.c --- a/njs/njs_vm.c Mon Jul 08 17:49:43 2019 +0300 +++ b/njs/njs_vm.c Mon Jul 08 17:51:35 2019 +0300 @@ -294,9 +294,7 @@ njs_vmcode_function(njs_vm_t *vm, njs_va return NXT_ERROR; } - vm->retval.data.u.function = function; - vm->retval.type = NJS_FUNCTION; - vm->retval.data.truth = 1; + njs_set_function(&vm->retval, function); return sizeof(njs_vmcode_function_t); } @@ -1746,7 +1744,7 @@ njs_function_frame_create(njs_vm_t *vm, if (nxt_fast_path(njs_is_function(value))) { - function = value->data.u.function; + function = njs_function(value); if (ctor) { if (!function->ctor) { @@ -1792,7 +1790,7 @@ njs_function_new_object(njs_vm_t *vm, nj lhq.key_hash = NJS_PROTOTYPE_HASH; lhq.key = nxt_string_value("prototype"); lhq.proto = &njs_object_hash_proto; - function = value->data.u.function; + function = njs_function(value); ret = nxt_lvlhsh_find(&function->object.hash, &lhq); From xeioex at nginx.com Mon Jul 8 14:52:36 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 08 Jul 2019 14:52:36 +0000 Subject: [njs] Using njs_set_regexp() and njs_regexp() where approprite. Message-ID: details: https://hg.nginx.org/njs/rev/b946c1073968 branches: changeset: 1036:b946c1073968 user: Dmitry Volyntsev date: Mon Jul 08 17:51:58 2019 +0300 description: Using njs_set_regexp() and njs_regexp() where approprite. diffstat: njs/njs_regexp.c | 22 ++++++++++------------ njs/njs_string.c | 12 ++++++------ njs/njs_value.h | 17 +++++++++++++++++ njs/njs_vm.c | 4 +--- 4 files changed, 34 insertions(+), 21 deletions(-) diffs (200 lines): diff -r 4c9047471ed0 -r b946c1073968 njs/njs_regexp.c --- a/njs/njs_regexp.c Mon Jul 08 17:51:35 2019 +0300 +++ b/njs/njs_regexp.c Mon Jul 08 17:51:58 2019 +0300 @@ -80,7 +80,7 @@ njs_regexp_value_flags(njs_vm_t *vm, con flags = 0; - pattern = regexp->data.u.regexp->pattern; + pattern = njs_regexp_pattern(regexp); if (pattern->global) { flags |= NJS_REGEXP_GLOBAL; @@ -195,9 +195,7 @@ njs_regexp_create(njs_vm_t *vm, njs_valu regexp = njs_regexp_alloc(vm, pattern); if (nxt_fast_path(regexp != NULL)) { - value->data.u.regexp = regexp; - value->type = NJS_REGEXP; - value->data.truth = 1; + njs_set_regexp(value, regexp); return NXT_OK; } @@ -729,7 +727,7 @@ njs_regexp_prototype_last_index(njs_vm_t njs_release(vm, value); - regexp = value->data.u.regexp; + regexp = njs_regexp(value); (void) njs_string_prop(&string, ®exp->string); @@ -746,7 +744,7 @@ njs_regexp_prototype_global(njs_vm_t *vm { njs_regexp_pattern_t *pattern; - pattern = value->data.u.regexp->pattern; + pattern = njs_regexp_pattern(value); *retval = pattern->global ? njs_value_true : njs_value_false; njs_release(vm, value); @@ -760,7 +758,7 @@ njs_regexp_prototype_ignore_case(njs_vm_ { njs_regexp_pattern_t *pattern; - pattern = value->data.u.regexp->pattern; + pattern = njs_regexp_pattern(value); *retval = pattern->ignore_case ? njs_value_true : njs_value_false; njs_release(vm, value); @@ -774,7 +772,7 @@ njs_regexp_prototype_multiline(njs_vm_t { njs_regexp_pattern_t *pattern; - pattern = value->data.u.regexp->pattern; + pattern = njs_regexp_pattern(value); *retval = pattern->multiline ? njs_value_true : njs_value_false; njs_release(vm, value); @@ -791,7 +789,7 @@ njs_regexp_prototype_source(njs_vm_t *vm uint32_t size; njs_regexp_pattern_t *pattern; - pattern = value->data.u.regexp->pattern; + pattern = njs_regexp_pattern(value); /* Skip starting "/". */ source = pattern->source + 1; @@ -825,7 +823,7 @@ njs_regexp_to_string(njs_vm_t *vm, njs_v uint32_t size; njs_regexp_pattern_t *pattern; - pattern = value->data.u.regexp->pattern; + pattern = njs_regexp_pattern(value); source = pattern->source; size = nxt_strlen(source); @@ -861,7 +859,7 @@ njs_regexp_prototype_test(njs_vm_t *vm, n = (string.length != 0); - pattern = args[0].data.u.regexp->pattern; + pattern = njs_regexp_pattern(&args[0]); if (nxt_regex_is_valid(&pattern->regex[n])) { ret = njs_regexp_match(vm, &pattern->regex[n], string.start, @@ -903,7 +901,7 @@ njs_regexp_prototype_exec(njs_vm_t *vm, value = &njs_string_undefined; } - regexp = args[0].data.u.regexp; + regexp = njs_regexp(&args[0]); regexp->string = *value; (void) njs_string_prop(&string, value); diff -r 4c9047471ed0 -r b946c1073968 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 08 17:51:35 2019 +0300 +++ b/njs/njs_string.c Mon Jul 08 17:51:58 2019 +0300 @@ -2567,7 +2567,7 @@ njs_string_prototype_search(njs_vm_t *vm switch (args[1].type) { case NJS_REGEXP: - pattern = args[1].data.u.regexp->pattern; + pattern = njs_regexp_pattern(&args[1]); break; case NJS_STRING: @@ -2638,7 +2638,7 @@ njs_string_prototype_match(njs_vm_t *vm, if (nargs > 1) { if (njs_is_regexp(&args[1])) { - pattern = args[1].data.u.regexp->pattern; + pattern = njs_regexp_pattern(&args[1]); if (pattern->global) { return njs_string_match_multiple(vm, args, pattern); @@ -2867,7 +2867,7 @@ found: goto done; case NJS_REGEXP: - pattern = args[1].data.u.regexp->pattern; + pattern = njs_regexp_pattern(&args[1]); if (!nxt_regex_is_valid(&pattern->regex[type])) { goto single; @@ -2986,7 +2986,7 @@ njs_string_prototype_replace(njs_vm_t *v } if (njs_is_regexp(&args[1])) { - regex = &args[1].data.u.regexp->pattern->regex[r->type]; + regex = &njs_regexp_pattern(&args[1])->regex[r->type]; if (!nxt_regex_is_valid(regex)) { goto original; @@ -3076,7 +3076,7 @@ njs_string_replace_regexp(njs_vm_t *vm, njs_regexp_pattern_t *pattern; njs_string_replace_part_t replace; - pattern = args[1].data.u.regexp->pattern; + pattern = njs_regexp_pattern(&args[1]); end = r->part[0].start + r->part[0].size; replace = r->part[1]; @@ -3266,7 +3266,7 @@ njs_string_replace_regexp_continuation(n if (njs_is_string(&r->retval)) { njs_string_replacement_copy(&r->part[r->empty ? 0 : 1], &r->retval); - if (args[1].data.u.regexp->pattern->global) { + if (njs_regexp_pattern(&args[1])->global) { r->part += 2; if (r->part[0].start > (string.start + string.size)) { diff -r 4c9047471ed0 -r b946c1073968 njs/njs_value.h --- a/njs/njs_value.h Mon Jul 08 17:51:35 2019 +0300 +++ b/njs/njs_value.h Mon Jul 08 17:51:58 2019 +0300 @@ -544,6 +544,14 @@ typedef enum { ((value)->data.u.date) +#define njs_regexp(value) \ + ((value)->data.u.regexp) + + +#define njs_regexp_pattern(value) \ + ((value)->data.u.regexp->pattern) + + #define njs_object_value(_value) \ (&(_value)->data.u.object_value->value) @@ -629,6 +637,15 @@ njs_set_date(njs_value_t *value, njs_dat nxt_inline void +njs_set_regexp(njs_value_t *value, njs_regexp_t *regexp) +{ + value->data.u.regexp = regexp; + value->type = NJS_REGEXP; + value->data.truth = 1; +} + + +nxt_inline void njs_set_object_value(njs_value_t *value, njs_object_value_t *object_value) { value->data.u.object_value = object_value; diff -r 4c9047471ed0 -r b946c1073968 njs/njs_vm.c --- a/njs/njs_vm.c Mon Jul 08 17:51:35 2019 +0300 +++ b/njs/njs_vm.c Mon Jul 08 17:51:58 2019 +0300 @@ -354,9 +354,7 @@ njs_vmcode_regexp(njs_vm_t *vm, njs_valu regexp = njs_regexp_alloc(vm, code->pattern); if (nxt_fast_path(regexp != NULL)) { - vm->retval.data.u.regexp = regexp; - vm->retval.type = NJS_REGEXP; - vm->retval.data.truth = 1; + njs_set_regexp(&vm->retval, regexp); return sizeof(njs_vmcode_regexp_t); } From mdounin at mdounin.ru Tue Jul 9 13:11:28 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 09 Jul 2019 13:11:28 +0000 Subject: [nginx] Version bump. Message-ID: details: https://hg.nginx.org/nginx/rev/58ec5c9da8cb branches: changeset: 7520:58ec5c9da8cb user: Maxim Dounin date: Tue Jul 09 16:01:32 2019 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1017001 -#define NGINX_VERSION "1.17.1" +#define nginx_version 1017002 +#define NGINX_VERSION "1.17.2" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Tue Jul 9 13:11:30 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 09 Jul 2019 13:11:30 +0000 Subject: [nginx] Typo. Message-ID: details: https://hg.nginx.org/nginx/rev/b0245dbd3655 branches: changeset: 7521:b0245dbd3655 user: Maxim Dounin date: Tue Jul 09 16:03:25 2019 +0300 description: Typo. diffstat: docs/xml/nginx/changes.xml | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -34,7 +34,7 @@ Thanks to Niklas Keller. ? ??????? ???????? ??? ????????? segmentation fault, ???? ?????????????? ??????????? ? ????????? image_filter, -? ?????? ? ????? 415 ???????????????? ? ?????? ????????? error_page; +? ?????? ? ????? 415 ???????????????? ? ??????? ????????? error_page; ?????? ????????? ? 1.11.10. From mdounin at mdounin.ru Tue Jul 9 13:11:32 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 09 Jul 2019 13:11:32 +0000 Subject: [nginx] Contrib: vim syntax, update core and 3rd party module directives. Message-ID: details: https://hg.nginx.org/nginx/rev/97ce2512373d branches: changeset: 7522:97ce2512373d user: Gena Makhomed date: Sun Jun 30 10:39:01 2019 +0300 description: Contrib: vim syntax, update core and 3rd party module directives. diffstat: contrib/vim/syntax/nginx.vim | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (43 lines): diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim +++ b/contrib/vim/syntax/nginx.vim @@ -333,6 +333,7 @@ syn keyword ngxDirective contained js_ac syn keyword ngxDirective contained js_content syn keyword ngxDirective contained js_filter syn keyword ngxDirective contained js_include +syn keyword ngxDirective contained js_path syn keyword ngxDirective contained js_preread syn keyword ngxDirective contained js_set syn keyword ngxDirective contained keepalive @@ -353,6 +354,7 @@ syn keyword ngxDirective contained limit syn keyword ngxDirective contained limit_rate syn keyword ngxDirective contained limit_rate_after syn keyword ngxDirective contained limit_req +syn keyword ngxDirective contained limit_req_dry_run syn keyword ngxDirective contained limit_req_log_level syn keyword ngxDirective contained limit_req_status syn keyword ngxDirective contained limit_req_zone @@ -472,6 +474,7 @@ syn keyword ngxDirective contained proxy syn keyword ngxDirective contained proxy_responses syn keyword ngxDirective contained proxy_send_lowat syn keyword ngxDirective contained proxy_send_timeout +syn keyword ngxDirective contained proxy_session_drop syn keyword ngxDirective contained proxy_set_body syn keyword ngxDirective contained proxy_set_header syn keyword ngxDirective contained proxy_socket_keepalive @@ -1325,6 +1328,7 @@ syn keyword ngxDirectiveThirdParty conta syn keyword ngxDirectiveThirdParty contained lua_code_cache syn keyword ngxDirectiveThirdParty contained lua_fake_shm syn keyword ngxDirectiveThirdParty contained lua_http10_buffering +syn keyword ngxDirectiveThirdParty contained lua_load_resty_core syn keyword ngxDirectiveThirdParty contained lua_malloc_trim syn keyword ngxDirectiveThirdParty contained lua_max_pending_timers syn keyword ngxDirectiveThirdParty contained lua_max_running_timers @@ -1779,6 +1783,7 @@ syn keyword ngxDirectiveThirdParty conta syn keyword ngxDirectiveThirdParty contained vod_fallback_upstream_location syn keyword ngxDirectiveThirdParty contained vod_force_continuous_timestamps syn keyword ngxDirectiveThirdParty contained vod_force_playlist_type_vod +syn keyword ngxDirectiveThirdParty contained vod_force_sequence_index syn keyword ngxDirectiveThirdParty contained vod_gop_look_ahead syn keyword ngxDirectiveThirdParty contained vod_gop_look_behind syn keyword ngxDirectiveThirdParty contained vod_ignore_edit_list From mdounin at mdounin.ru Tue Jul 9 13:11:52 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 9 Jul 2019 16:11:52 +0300 Subject: [PATCH] Contrib: vim syntax, update core and 3rd party module directives. In-Reply-To: References: Message-ID: <20190709131152.GZ1877@mdounin.ru> Hello! On Sun, Jun 30, 2019 at 10:44:14AM +0300, Gena Makhomed wrote: > # HG changeset patch > # User Gena Makhomed > # Date 1561880341 -10800 > # Sun Jun 30 10:39:01 2019 +0300 > # Node ID f298b850ea1a8499b3ea51bde571d010dc7dfc69 > # Parent 35ea9229c71a9207a24e51f327e1749e3accb26c > Contrib: vim syntax, update core and 3rd party module directives. > > diff -r 35ea9229c71a -r f298b850ea1a contrib/vim/syntax/nginx.vim > --- a/contrib/vim/syntax/nginx.vim Tue Jun 25 15:19:45 2019 +0300 > +++ b/contrib/vim/syntax/nginx.vim Sun Jun 30 10:39:01 2019 +0300 > @@ -333,6 +333,7 @@ > syn keyword ngxDirective contained js_content > syn keyword ngxDirective contained js_filter > syn keyword ngxDirective contained js_include > +syn keyword ngxDirective contained js_path [...] Committed, thnx. -- Maxim Dounin http://mdounin.ru/ From alexander.borisov at nginx.com Wed Jul 10 16:56:20 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Wed, 10 Jul 2019 16:56:20 +0000 Subject: [njs] Added UTF8 validation for string literals. Message-ID: details: https://hg.nginx.org/njs/rev/f1a70d67646d branches: changeset: 1037:f1a70d67646d user: Alexander Borisov date: Wed Jul 10 14:20:53 2019 +0300 description: Added UTF8 validation for string literals. All bad UTF-8 characters are replaced by '\uFFFD' (REPLACEMENT CHARACTER). diffstat: njs/njs_parser_terminal.c | 60 +++++++++++++-------- njs/test/njs_unit_test.c | 81 +++++++++++++++++++++++++++++ nxt/nxt_utf8.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++ nxt/nxt_utf8.h | 6 ++ 4 files changed, 250 insertions(+), 22 deletions(-) diffs (362 lines): diff -r b946c1073968 -r f1a70d67646d njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Mon Jul 08 17:51:58 2019 +0300 +++ b/njs/njs_parser_terminal.c Wed Jul 10 14:20:53 2019 +0300 @@ -907,31 +907,35 @@ done: nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value) { - u_char *p; - ssize_t length; - nxt_str_t *src; + u_char *dst; + ssize_t size, length; + uint32_t cp; + nxt_str_t *src; + const u_char *p, *end; src = njs_parser_text(vm->parser); - length = nxt_utf8_length(src->start, src->length); + length = nxt_utf8_safe_length(src->start, src->length, &size); - if (nxt_slow_path(length < 0)) { - length = 0; + dst = njs_string_alloc(vm, value, size, length); + if (nxt_slow_path(dst == NULL)) { + return NXT_ERROR; } - p = njs_string_alloc(vm, value, src->length, length); - - if (nxt_fast_path(p != NULL)) { - memcpy(p, src->start, src->length); + p = src->start; + end = src->start + src->length; - if (length > NJS_STRING_MAP_STRIDE && (size_t) length != src->length) { - njs_string_offset_map_init(p, src->length); - } + while (p < end) { + cp = nxt_utf8_safe_decode(&p, end); - return NXT_OK; + dst = nxt_utf8_encode(dst, cp); } - return NXT_ERROR; + if (size > NJS_STRING_MAP_STRIDE && size != length) { + njs_string_offset_map_init(value->long_string.data->start, size); + } + + return NXT_OK; } @@ -1042,11 +1046,27 @@ njs_parser_escape_string_create(njs_vm_t continue; default: + if (c >= 0x80) { + src--; + goto utf8_copy; + } + break; } } - *dst++ = c; + if (c < 0x80) { + *dst++ = c; + + continue; + } + + utf8_copy: + + src--; + + cp = nxt_utf8_safe_decode2(&src, end); + dst = nxt_utf8_encode(dst, cp); continue; @@ -1166,13 +1186,9 @@ njs_parser_escape_string_calc_length(njs } if (*src >= 0x80) { - ptr = src; + cp = nxt_utf8_safe_decode2(&src, end); - if (nxt_slow_path(nxt_utf8_decode(&src, end) == 0xffffffff)) { - goto invalid; - } - - size += src - ptr; + size += nxt_utf8_size(cp); length++; continue; diff -r b946c1073968 -r f1a70d67646d njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Jul 08 17:51:58 2019 +0300 +++ b/njs/test/njs_unit_test.c Wed Jul 10 14:20:53 2019 +0300 @@ -4367,6 +4367,48 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = '123'\n[2].toString();a"), nxt_string("3") }, + { nxt_string("'\xE5\x96\x9C\xE3\x81\xB6'"), + nxt_string("??") }, + + /* Broken UTF-8 literals.*/ + + { nxt_string("'\x96\xE5\x9C\xE3\x81\xB6'"), + nxt_string("???") }, + + { nxt_string("'\x96\xE5\x9C'"), + nxt_string("??") }, + + { nxt_string("'\x96\xE5'"), + nxt_string("??") }, + + { nxt_string("'\x96'"), + nxt_string("?") }, + + { nxt_string("'\xF3'"), + nxt_string("?") }, + + { nxt_string("'\xF3\xFF'"), + nxt_string("??") }, + + { nxt_string("'\x96\x96\xE5\x9C\xE3\x81\xB6'"), + nxt_string("????") }, + + { nxt_string("'\x9C\x96\xE5\xE3\x81\xB6'"), + nxt_string("????") }, + + { nxt_string("'\xE5\x9C\xE3\x81\xB6'"), + nxt_string("??") }, + + { nxt_string("'\xEF\xBF\xBD\xE3\x81\xB6'"), + nxt_string("??") }, + + { nxt_string("'\xE5\xF6\x9C\xE3\x81\xB6'"), + nxt_string("????") }, + + { nxt_string("var a = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xF3'; " + "[a.length, a[33], a[34]]"), + nxt_string("35,a,?") }, + /* Escape strings. */ { nxt_string("'\\a \\' \\\" \\\\ \\0 \\b \\f \\n \\r \\t \\v'"), @@ -4495,6 +4537,45 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\\u{D800}\\u{'"), nxt_string("SyntaxError: Invalid Unicode code point \"\\u{D800}\\u{\" in 1") }, + /* Broken UTF-8 literals.*/ + + { nxt_string("'\\a\x96\xE5\x9C\xE3\x81\xB6'"), + nxt_string("a???") }, + + { nxt_string("'\x96\\a\xE5\x9C'"), + nxt_string("?a?") }, + + { nxt_string("'\x96\xE5\\a'"), + nxt_string("??a") }, + + { nxt_string("'\\a\x96\\a'"), + nxt_string("a?a") }, + + { nxt_string("'\xF3\\a'"), + nxt_string("?a") }, + + { nxt_string("'\xF3\\a\xFF'"), + nxt_string("?a?") }, + + { nxt_string("'\\a\x96\x96\xE5\x9C\xE3\x81\xB6'"), + nxt_string("a????") }, + + { nxt_string("'\\a\x9C\x96\xE5\xE3\x81\xB6'"), + nxt_string("a????") }, + + { nxt_string("'\\a\xE5\x9C\xE3\x81\xB6'"), + nxt_string("a??") }, + + { nxt_string("'\\a\xEF\xBF\xBD\xE3\x81\xB6'"), + nxt_string("a??") }, + + { nxt_string("'\\a\xE5\xF6\x9C\xE3\x81\xB6'"), + nxt_string("a????") }, + + { nxt_string("var a = '\\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xF3'; " + "[a.length, a[34], a[35]]"), + nxt_string("36,a,?") }, + { nxt_string("''.hasOwnProperty('length')"), nxt_string("true") }, diff -r b946c1073968 -r f1a70d67646d nxt/nxt_utf8.c --- a/nxt/nxt_utf8.c Mon Jul 08 17:51:58 2019 +0300 +++ b/nxt/nxt_utf8.c Wed Jul 10 14:20:53 2019 +0300 @@ -163,6 +163,103 @@ nxt_utf8_decode2(const u_char **start, c } +uint32_t +nxt_utf8_safe_decode(const u_char **start, const u_char *end) +{ + uint32_t u; + + u = (uint32_t) **start; + + if (u < 0x80) { + (*start)++; + return u; + } + + return nxt_utf8_safe_decode2(start, end); +} + + +uint32_t +nxt_utf8_safe_decode2(const u_char **start, const u_char *end) +{ + u_char c; + size_t n; + uint32_t u, overlong; + const u_char *p; + + p = *start; + u = (uint32_t) *p; + + if (u >= 0xE0) { + + if (u >= 0xF0) { + + if (nxt_slow_path(u > 0xF4)) { + /* + * The maximum valid Unicode character is 0x10FFFF + * which is encoded as 0xF4 0x8F 0xBF 0xBF. + */ + goto fail_one; + } + + u &= 0x07; + overlong = 0x00FFFF; + n = 3; + + } else { + u &= 0x0F; + overlong = 0x07FF; + n = 2; + } + + } else if (u >= 0xC2) { + + /* 0x80 is encoded as 0xC2 0x80. */ + + u &= 0x1F; + overlong = 0x007F; + n = 1; + + } else { + /* u <= 0xC2 */ + goto fail_one; + } + + p++; + + while (p < end && n != 0) { + c = *p++; + /* + * The byte must in the 0x80 - 0xBF range. + * Values below 0x80 become >= 0x80. + */ + c = c - 0x80; + + if (nxt_slow_path(c > 0x3F)) { + *start = --p; + return NXT_UTF8_REPLACEMENT; + } + + u = (u << 6) | c; + n--; + } + + *start = p; + + if (n == 0 && overlong < u && u < 0x110000) { + return u; + } + + return NXT_UTF8_REPLACEMENT; + +fail_one: + + (*start)++; + + return NXT_UTF8_REPLACEMENT; +} + + /* * nxt_utf8_casecmp() tests only up to the minimum of given lengths, but * requires lengths of both strings because otherwise nxt_utf8_decode2() @@ -279,6 +376,34 @@ nxt_utf8_length(const u_char *p, size_t } +ssize_t +nxt_utf8_safe_length(const u_char *p, size_t len, ssize_t *out_size) +{ + ssize_t size, length; + uint32_t codepoint; + const u_char *end; + + size = 0; + length = 0; + + end = p + len; + + while (p < end) { + codepoint = nxt_utf8_safe_decode(&p, end); + + size += nxt_utf8_size(codepoint); + + length++; + } + + if (out_size != NULL) { + *out_size = size; + } + + return length; +} + + nxt_bool_t nxt_utf8_is_valid(const u_char *p, size_t len) { diff -r b946c1073968 -r f1a70d67646d nxt/nxt_utf8.h --- a/nxt/nxt_utf8.h Mon Jul 08 17:51:58 2019 +0300 +++ b/nxt/nxt_utf8.h Wed Jul 10 14:20:53 2019 +0300 @@ -21,6 +21,10 @@ NXT_EXPORT u_char *nxt_utf8_encode(u_char *p, uint32_t u); NXT_EXPORT uint32_t nxt_utf8_decode(const u_char **start, const u_char *end); NXT_EXPORT uint32_t nxt_utf8_decode2(const u_char **start, const u_char *end); +NXT_EXPORT uint32_t nxt_utf8_safe_decode(const u_char **start, + const u_char *end); +NXT_EXPORT uint32_t nxt_utf8_safe_decode2(const u_char **start, + const u_char *end); NXT_EXPORT nxt_int_t nxt_utf8_casecmp(const u_char *start1, const u_char *start2, size_t len1, size_t len2); NXT_EXPORT uint32_t nxt_utf8_lower_case(const u_char **start, @@ -28,6 +32,8 @@ NXT_EXPORT uint32_t nxt_utf8_lower_case( NXT_EXPORT uint32_t nxt_utf8_upper_case(const u_char **start, const u_char *end); NXT_EXPORT ssize_t nxt_utf8_length(const u_char *p, size_t len); +NXT_EXPORT ssize_t nxt_utf8_safe_length(const u_char *p, size_t len, + ssize_t *out_size); NXT_EXPORT nxt_bool_t nxt_utf8_is_valid(const u_char *p, size_t len); From alexander.borisov at nginx.com Wed Jul 10 18:54:58 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Wed, 10 Jul 2019 18:54:58 +0000 Subject: [njs] Fixed UTF-8 character escaping. Message-ID: details: https://hg.nginx.org/njs/rev/4a4d55f968a0 branches: changeset: 1038:4a4d55f968a0 user: Alexander Borisov date: Wed Jul 10 21:54:33 2019 +0300 description: Fixed UTF-8 character escaping. diffstat: njs/njs_parser_terminal.c | 1 - njs/test/njs_unit_test.c | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletions(-) diffs (27 lines): diff -r f1a70d67646d -r 4a4d55f968a0 njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Wed Jul 10 14:20:53 2019 +0300 +++ b/njs/njs_parser_terminal.c Wed Jul 10 21:54:33 2019 +0300 @@ -1047,7 +1047,6 @@ njs_parser_escape_string_create(njs_vm_t default: if (c >= 0x80) { - src--; goto utf8_copy; } diff -r f1a70d67646d -r 4a4d55f968a0 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Jul 10 14:20:53 2019 +0300 +++ b/njs/test/njs_unit_test.c Wed Jul 10 21:54:33 2019 +0300 @@ -4537,6 +4537,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\\u{D800}\\u{'"), nxt_string("SyntaxError: Invalid Unicode code point \"\\u{D800}\\u{\" in 1") }, + { nxt_string("'?' !== '\\?'"), + nxt_string("false") }, + + { nxt_string("'r' !== '\\r'"), + nxt_string("true") }, + /* Broken UTF-8 literals.*/ { nxt_string("'\\a\x96\xE5\x9C\xE3\x81\xB6'"), From xeioex at nginx.com Thu Jul 11 12:34:04 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Thu, 11 Jul 2019 12:34:04 +0000 Subject: [njs] Fixed Object.values() and Object.entries() for shared objects. Message-ID: details: https://hg.nginx.org/njs/rev/b4e326104195 branches: changeset: 1039:b4e326104195 user: Dmitry Volyntsev date: Thu Jul 11 15:33:40 2019 +0300 description: Fixed Object.values() and Object.entries() for shared objects. Previously, there was a mismatch between njs_object_enumerate_object_length() and njs_object_own_enumerate_object() in the way they enumerated values. This closes #194, #195, #196 issues on Github. diffstat: njs/njs_object.c | 110 ++++++++++++++++++++++------------------------ njs/test/njs_unit_test.c | 9 +++ 2 files changed, 62 insertions(+), 57 deletions(-) diffs (154 lines): diff -r 4a4d55f968a0 -r b4e326104195 njs/njs_object.c --- a/njs/njs_object.c Wed Jul 10 21:54:33 2019 +0300 +++ b/njs/njs_object.c Thu Jul 11 15:33:40 2019 +0300 @@ -978,29 +978,27 @@ njs_object_own_enumerate_object(njs_vm_t } } - if (nxt_slow_path(all)) { - nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); - hash = &object->shared_hash; - - for ( ;; ) { - prop = nxt_lvlhsh_each(hash, &lhe); - - if (prop == NULL) { - break; - } - - lhq.key_hash = lhe.key_hash; - njs_string_get(&prop->name, &lhq.key); - - lhq.proto = &njs_object_hash_proto; - ret = nxt_lvlhsh_find(&object->hash, &lhq); - - if (ret != NXT_OK) { - ext_prop = njs_object_exist_in_proto(parent, object, &lhq); - - if (ext_prop == NULL) { - *item++ = prop->value; - } + nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + hash = &object->shared_hash; + + for ( ;; ) { + prop = nxt_lvlhsh_each(hash, &lhe); + + if (prop == NULL) { + break; + } + + lhq.key_hash = lhe.key_hash; + njs_string_get(&prop->name, &lhq.key); + + lhq.proto = &njs_object_hash_proto; + ret = nxt_lvlhsh_find(&object->hash, &lhq); + + if (ret != NXT_OK) { + ext_prop = njs_object_exist_in_proto(parent, object, &lhq); + + if (ext_prop == NULL && (prop->enumerable || all)) { + *item++ = prop->value; } } } @@ -1039,41 +1037,39 @@ njs_object_own_enumerate_object(njs_vm_t } } - if (nxt_slow_path(all)) { - nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); - hash = &object->shared_hash; - - for ( ;; ) { - prop = nxt_lvlhsh_each(hash, &lhe); - - if (prop == NULL) { - break; - } - - lhq.key_hash = lhe.key_hash; - njs_string_get(&prop->name, &lhq.key); - - lhq.proto = &njs_object_hash_proto; - ret = nxt_lvlhsh_find(&object->hash, &lhq); - - if (ret != NXT_OK) { - ext_prop = njs_object_exist_in_proto(parent, object, &lhq); - - if (ext_prop == NULL) { - entry = njs_array_alloc(vm, 2, 0); - if (nxt_slow_path(entry == NULL)) { - return NJS_ERROR; - } - - njs_string_copy(&entry->start[0], &prop->name); - - /* GC: retain. */ - entry->start[1] = prop->value; - - njs_set_array(item, entry); - - item++; + nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + hash = &object->shared_hash; + + for ( ;; ) { + prop = nxt_lvlhsh_each(hash, &lhe); + + if (prop == NULL) { + break; + } + + lhq.key_hash = lhe.key_hash; + njs_string_get(&prop->name, &lhq.key); + + lhq.proto = &njs_object_hash_proto; + ret = nxt_lvlhsh_find(&object->hash, &lhq); + + if (ret != NXT_OK && (prop->enumerable || all)) { + ext_prop = njs_object_exist_in_proto(parent, object, &lhq); + + if (ext_prop == NULL) { + entry = njs_array_alloc(vm, 2, 0); + if (nxt_slow_path(entry == NULL)) { + return NJS_ERROR; } + + njs_string_copy(&entry->start[0], &prop->name); + + /* GC: retain. */ + entry->start[1] = prop->value; + + njs_set_array(item, entry); + + item++; } } } diff -r 4a4d55f968a0 -r b4e326104195 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Jul 10 21:54:33 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu Jul 11 15:33:40 2019 +0300 @@ -9251,6 +9251,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("Object.values(1)"), nxt_string("") }, + { nxt_string("Object.values(njs)[0] === njs.version"), + nxt_string("true") }, + + { nxt_string("Object.values(process)"), + nxt_string("") }, + { nxt_string("Object.values()"), nxt_string("TypeError: cannot convert undefined argument to object") }, @@ -9274,6 +9280,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("Object.entries(true)"), nxt_string("") }, + { nxt_string("Object.entries(njs)[0][1] === njs.version"), + nxt_string("true") }, + { nxt_string("Object.entries()"), nxt_string("TypeError: cannot convert undefined argument to object") }, From alexander.borisov at nginx.com Thu Jul 11 12:43:48 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Thu, 11 Jul 2019 12:43:48 +0000 Subject: [njs] Fixed used of uninitialized memory in String.prototype.match(). Message-ID: details: https://hg.nginx.org/njs/rev/b5f72739c00e branches: changeset: 1040:b5f72739c00e user: Alexander Borisov date: Thu Jul 11 15:42:33 2019 +0300 description: Fixed used of uninitialized memory in String.prototype.match(). diffstat: njs/njs_string.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diffs (20 lines): diff -r b4e326104195 -r b5f72739c00e njs/njs_string.c --- a/njs/njs_string.c Thu Jul 11 15:33:40 2019 +0300 +++ b/njs/njs_string.c Thu Jul 11 15:42:33 2019 +0300 @@ -2734,8 +2734,14 @@ njs_string_match_multiple(njs_vm_t *vm, start = p + captures[0]; if (captures[1] == 0) { - p = nxt_utf8_next(start, end); - string.size = end - p; + if (start < end) { + p = nxt_utf8_next(start, end); + string.size = end - p; + + } else { + /* To exit the loop. */ + p++; + } size = 0; length = 0; From vbart at nginx.com Thu Jul 11 13:11:11 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 11 Jul 2019 13:11:11 +0000 Subject: [njs] Optimized inlining of njs_values_strict_equal(). Message-ID: details: https://hg.nginx.org/njs/rev/ea18aa7693da branches: changeset: 1041:ea18aa7693da user: Valentin Bartenev date: Thu Jul 11 16:10:33 2019 +0300 description: Optimized inlining of njs_values_strict_equal(). This function is often called inside loops and basically it does only a few cmp instructions that can be inlined. The more complex part related to comparing of two strings is functionally identical to njs_string_eq(), but contains an optimization that avoids memcmp() when strings have different lengths. This optimization has been merged into njs_string_eq(). No functional changes. diffstat: njs/njs_string.c | 24 ++++++++++++++++++- njs/njs_string.h | 1 - njs/njs_value.c | 71 -------------------------------------------------------- njs/njs_value.h | 29 +++++++++++++++++++++- 4 files changed, 50 insertions(+), 75 deletions(-) diffs (186 lines): diff -r b5f72739c00e -r ea18aa7693da njs/njs_string.c --- a/njs/njs_string.c Thu Jul 11 15:42:33 2019 +0300 +++ b/njs/njs_string.c Thu Jul 11 16:10:33 2019 +0300 @@ -689,7 +689,7 @@ njs_string_instance_length(njs_vm_t *vm, nxt_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2) { - size_t size; + size_t size, length1, length2; const u_char *start1, *start2; size = v1->short_string.size; @@ -699,6 +699,17 @@ njs_string_eq(const njs_value_t *v1, con } if (size != NJS_STRING_LONG) { + length1 = v1->short_string.length; + length2 = v2->short_string.length; + + /* + * Using full memcmp() comparison if at least one string + * is a Byte string. + */ + if (length1 != 0 && length2 != 0 && length1 != length2) { + return 0; + } + start1 = v1->short_string.start; start2 = v2->short_string.start; @@ -709,6 +720,17 @@ njs_string_eq(const njs_value_t *v1, con return 0; } + length1 = v1->long_string.data->length; + length2 = v2->long_string.data->length; + + /* + * Using full memcmp() comparison if at least one string + * is a Byte string. + */ + if (length1 != 0 && length2 != 0 && length1 != length2) { + return 0; + } + start1 = v1->long_string.data->start; start2 = v2->long_string.data->start; } diff -r b5f72739c00e -r ea18aa7693da njs/njs_string.h --- a/njs/njs_string.h Thu Jul 11 15:42:33 2019 +0300 +++ b/njs/njs_string.h Thu Jul 11 16:10:33 2019 +0300 @@ -168,7 +168,6 @@ njs_ret_t njs_string_validate(njs_vm_t * size_t njs_string_prop(njs_string_prop_t *string, const njs_value_t *value); njs_ret_t njs_string_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -nxt_bool_t njs_string_eq(const njs_value_t *val1, const njs_value_t *val2); nxt_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2); void njs_string_slice_string_prop(njs_string_prop_t *dst, const njs_string_prop_t *string, const njs_slice_prop_t *slice); diff -r b5f72739c00e -r ea18aa7693da njs/njs_value.c --- a/njs/njs_value.c Thu Jul 11 15:42:33 2019 +0300 +++ b/njs/njs_value.c Thu Jul 11 16:10:33 2019 +0300 @@ -91,77 +91,6 @@ njs_value_release(njs_vm_t *vm, njs_valu } -nxt_bool_t -njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2) -{ - size_t size, length1, length2; - const u_char *start1, *start2; - - if (val1->type != val2->type) { - return 0; - } - - if (njs_is_numeric(val1)) { - - if (njs_is_undefined(val1)) { - return 1; - } - - /* Infinities are handled correctly by comparision. */ - return (njs_number(val1) == njs_number(val2)); - } - - if (njs_is_string(val1)) { - size = val1->short_string.size; - - if (size != val2->short_string.size) { - return 0; - } - - if (size != NJS_STRING_LONG) { - length1 = val1->short_string.length; - length2 = val2->short_string.length; - - /* - * Using full memcmp() comparison if at least one string - * is a Byte string. - */ - if (length1 != 0 && length2 != 0 && length1 != length2) { - return 0; - } - - start1 = val1->short_string.start; - start2 = val2->short_string.start; - - } else { - size = val1->long_string.size; - - if (size != val2->long_string.size) { - return 0; - } - - length1 = val1->long_string.data->length; - length2 = val2->long_string.data->length; - - /* - * Using full memcmp() comparison if at least one string - * is a Byte string. - */ - if (length1 != 0 && length2 != 0 && length1 != length2) { - return 0; - } - - start1 = val1->long_string.data->start; - start2 = val2->long_string.data->start; - } - - return (memcmp(start1, start2, size) == 0); - } - - return (njs_object(val1) == njs_object(val2)); -} - - /* * A hint value is 0 for numbers and 1 for strings. The value chooses * method calls order specified by ECMAScript 5.1: "valueOf", "toString" diff -r b5f72739c00e -r ea18aa7693da njs/njs_value.h --- a/njs/njs_value.h Thu Jul 11 15:42:33 2019 +0300 +++ b/njs/njs_value.h Thu Jul 11 16:10:33 2019 +0300 @@ -685,8 +685,6 @@ njs_set_object_value(njs_value_t *value, void njs_value_retain(njs_value_t *value); void njs_value_release(njs_vm_t *vm, njs_value_t *value); -nxt_bool_t njs_values_strict_equal(const njs_value_t *val1, - const njs_value_t *val2); njs_ret_t njs_value_to_primitive(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint); njs_array_t *njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value, @@ -696,6 +694,33 @@ njs_array_t *njs_value_own_enumerate(njs const char *njs_type_string(njs_value_type_t type); const char *njs_arg_type_string(uint8_t arg); +nxt_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2); + + +nxt_inline nxt_bool_t +njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2) +{ + if (val1->type != val2->type) { + return 0; + } + + if (njs_is_numeric(val1)) { + + if (njs_is_undefined(val1)) { + return 1; + } + + /* Infinities are handled correctly by comparision. */ + return (njs_number(val1) == njs_number(val2)); + } + + if (njs_is_string(val1)) { + return njs_string_eq(val1, val2); + } + + return (njs_object(val1) == njs_object(val2)); +} + extern const njs_value_t njs_value_null; extern const njs_value_t njs_value_undefined; From xeioex at nginx.com Thu Jul 11 18:30:11 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Thu, 11 Jul 2019 18:30:11 +0000 Subject: [njs] Fixed Array.prototype.lastIndexOf() with undefined arguments. Message-ID: details: https://hg.nginx.org/njs/rev/71e6a00bd921 branches: changeset: 1042:71e6a00bd921 user: Dmitry Volyntsev date: Thu Jul 11 21:29:59 2019 +0300 description: Fixed Array.prototype.lastIndexOf() with undefined arguments. diffstat: njs/njs_array.c | 52 +++++++++++++++++++++++++---------------------- njs/test/njs_unit_test.c | 15 +++++++++++++ 2 files changed, 43 insertions(+), 24 deletions(-) diffs (116 lines): diff -r ea18aa7693da -r 71e6a00bd921 njs/njs_array.c --- a/njs/njs_array.c Thu Jul 11 16:10:33 2019 +0300 +++ b/njs/njs_array.c Thu Jul 11 21:29:59 2019 +0300 @@ -1280,52 +1280,56 @@ static njs_ret_t njs_array_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t i, n, index, length; - njs_value_t *value, *start; - njs_array_t *array; + nxt_int_t k, n, index, length; + njs_value_t *start; + njs_array_t *array; + const njs_value_t *this, *value; index = -1; - if (nargs < 2 || !njs_is_array(&args[0])) { + this = njs_arg(args, nargs, 0); + + if (!njs_is_array(this)) { goto done; } - array = njs_array(&args[0]); + array = njs_array(this); length = array->length; if (length == 0) { goto done; } - i = length - 1; - if (nargs > 2) { - n = njs_number(&args[2]); - - if (n < 0) { - i = n + length; - - if (i < 0) { - goto done; - } - - } else if (n < length) { - i = n; + n = njs_primitive_value_to_integer(njs_argument(args, 2)); + + } else { + n = length - 1; + } + + if (n >= 0) { + k = nxt_min(n, length - 1); + + } else { + k = n + length; + + if (k < 0) { + goto done; } } - value = &args[1]; + value = njs_arg(args, nargs, 1); start = array->start; do { - if (njs_values_strict_equal(value, &start[i])) { - index = i; + if (njs_values_strict_equal(value, &start[k])) { + index = k; break; } - i--; - - } while (i >= 0); + k--; + + } while (k >= 0); done: diff -r ea18aa7693da -r 71e6a00bd921 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Jul 11 16:10:33 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu Jul 11 21:29:59 2019 +0300 @@ -3810,6 +3810,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("[].lastIndexOf(1, -1)"), nxt_string("-1") }, + { nxt_string("[undefined].lastIndexOf()"), + nxt_string("0") }, + + { nxt_string("[undefined].lastIndexOf(undefined)"), + nxt_string("0") }, + { nxt_string("var a = [1,2,3,4]; a.lastIndexOf()"), nxt_string("-1") }, @@ -3837,6 +3843,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, -10)"), nxt_string("-1") }, + { nxt_string("[1,2,1].lastIndexOf(2,undefined)"), + nxt_string("-1") }, + + { nxt_string("[1,2,1].lastIndexOf(1,undefined)"), + nxt_string("0") }, + + { nxt_string("[1,2,1].lastIndexOf(1)"), + nxt_string("2") }, + { nxt_string("[1,2,3,4].includes()"), nxt_string("false") }, From iii at linux.ibm.com Fri Jul 12 11:04:51 2019 From: iii at linux.ibm.com (Ilya Leoshkevich) Date: Fri, 12 Jul 2019 13:04:51 +0200 Subject: [PATCH v2] Gzip: use zlib to write header and trailer Message-ID: <0a056523895149d727a7.1562929491@white> # HG changeset patch # User Ilya Leoshkevich # Date 1562928188 -7200 # Fri Jul 12 12:43:08 2019 +0200 # Node ID 0a056523895149d727a703242f2e2b579cfec9da # Parent 97ce2512373d7278f765f587d4cf087065a55e7c Gzip: use zlib to write header and trailer When nginx is used with zlib patched with [1], which provides integration with the future IBM Z hardware deflate acceleration, it ends up computing CRC32 twice: one time in hardware, which always does this, and one time in software by explicitly calling crc32(). crc32() calls were added in changesets 133:b27548f540ad ("nginx-0.0.1- 2003-09-24-23:51:12 import") and 134:d57c6835225c ("nginx-0.0.1- 2003-09-26-09:45:21 import") as part of gzip wrapping feature - back then zlib did not support it. However, since then gzip wrapping was implemented in zlib v1.2.0.4, and it's already being used by nginx for log compression. This patch replaces hand-written gzip wrapping with the one provided by zlib. It simplifies the code, and makes it avoid computing CRC32 twice when using hardware acceleration. [1] https://github.com/madler/zlib/pull/410 v1->v2: Resent in hg format, replaced git mirror commit references to hg changeset references in the commit message. The code is unchanged. diff -r 97ce2512373d -r 0a0565238951 src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c Sun Jun 30 10:39:01 2019 +0300 +++ b/src/http/modules/ngx_http_gzip_filter_module.c Fri Jul 12 12:43:08 2019 +0200 @@ -55,44 +55,23 @@ unsigned redo:1; unsigned done:1; unsigned nomem:1; - unsigned gzheader:1; unsigned buffering:1; unsigned intel:1; size_t zin; size_t zout; - uint32_t crc32; z_stream zstream; ngx_http_request_t *request; } ngx_http_gzip_ctx_t; -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) - -struct gztrailer { - uint32_t crc32; - uint32_t zlen; -}; - -#else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */ - -struct gztrailer { - u_char crc32[4]; - u_char zlen[4]; -}; - -#endif - - static void ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_buffer(ngx_http_gzip_ctx_t *ctx, ngx_chain_t *in); static ngx_int_t ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); -static ngx_int_t ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, - ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, @@ -446,12 +425,6 @@ return ctx->busy ? NGX_AGAIN : NGX_OK; } - if (!ctx->gzheader) { - if (ngx_http_gzip_filter_gzheader(r, ctx) != NGX_OK) { - goto failed; - } - } - rc = ngx_http_next_body_filter(r, ctx->out); if (rc == NGX_ERROR) { @@ -643,7 +616,7 @@ ctx->zstream.opaque = ctx; rc = deflateInit2(&ctx->zstream, (int) conf->level, Z_DEFLATED, - - ctx->wbits, ctx->memlevel, Z_DEFAULT_STRATEGY); + ctx->wbits + 16, ctx->memlevel, Z_DEFAULT_STRATEGY); if (rc != Z_OK) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, @@ -652,7 +625,6 @@ } ctx->last_out = &ctx->out; - ctx->crc32 = crc32(0L, Z_NULL, 0); ctx->flush = Z_NO_FLUSH; return NGX_OK; @@ -660,38 +632,6 @@ static ngx_int_t -ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) -{ - ngx_buf_t *b; - ngx_chain_t *cl; - static u_char gzheader[10] = - { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; - - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - b->memory = 1; - b->pos = gzheader; - b->last = b->pos + 10; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - cl->next = ctx->out; - ctx->out = cl; - - ctx->gzheader = 1; - - return NGX_OK; -} - - -static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { ngx_chain_t *cl; @@ -745,12 +685,7 @@ ctx->flush = Z_SYNC_FLUSH; } - if (ctx->zstream.avail_in) { - - ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in, - ctx->zstream.avail_in); - - } else if (ctx->flush == Z_NO_FLUSH) { + if (!ctx->zstream.avail_in && ctx->flush == Z_NO_FLUSH) { return NGX_AGAIN; } @@ -933,12 +868,10 @@ ngx_http_gzip_ctx_t *ctx) { int rc; - ngx_buf_t *b; ngx_chain_t *cl; - struct gztrailer *trailer; ctx->zin = ctx->zstream.total_in; - ctx->zout = 10 + ctx->zstream.total_out + 8; + ctx->zout = ctx->zstream.total_out; rc = deflateEnd(&ctx->zstream); @@ -960,50 +893,7 @@ *ctx->last_out = cl; ctx->last_out = &cl->next; - if (ctx->zstream.avail_out >= 8) { - trailer = (struct gztrailer *) ctx->out_buf->last; - ctx->out_buf->last += 8; - ctx->out_buf->last_buf = 1; - - } else { - b = ngx_create_temp_buf(r->pool, 8); - if (b == NULL) { - return NGX_ERROR; - } - - b->last_buf = 1; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - cl->next = NULL; - *ctx->last_out = cl; - ctx->last_out = &cl->next; - trailer = (struct gztrailer *) b->pos; - b->last += 8; - } - -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) - - trailer->crc32 = ctx->crc32; - trailer->zlen = ctx->zin; - -#else - - trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff); - trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff); - trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff); - trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff); - - trailer->zlen[0] = (u_char) (ctx->zin & 0xff); - trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff); - trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff); - trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff); - -#endif + ctx->out_buf->last_buf = 1; ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; From mdounin at mdounin.ru Fri Jul 12 14:24:54 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 17:24:54 +0300 Subject: HTTP/2: allow unlimited number of requests in connection In-Reply-To: References: <20190629100516.GY1877@mdounin.ru> Message-ID: <20190712142454.GM1877@mdounin.ru> Hello! On Mon, Jul 01, 2019 at 11:24:28AM +0200, Michael W?rtinger wrote: > thanks a lot for your reply. Could you please elaborate a little bit > which memory resources need to be freed periodically? How much memory > can be held by a connection? What's the worst case scenario? > We are currently running it in production with http2_max_requests set > to a value so high that the connection practically lives forever and > so far we cannot spot any problems but maybe we're missing something? And example of "wost case" can be seen here: http://mailman.nginx.org/pipermail/nginx/2018-July/056525.html Memory can be allocated from the connection memory pool. And this memory have to be freed at some point - so you have to close the connection to do this. And that's why number of requests in a particular connection is limited by default. Whether or not memory allocations happens in your particular use case - doesn't really matter, especially given that things can change with seamingly minor configuration and/or client behaviour changes. In most cases we try to limit allocations from the connection memory pool to a minimum, yet it is not always possible/convinient to completely avoid allocations from connection memory pool. This allows processing of thousands of requests on a single connection without observable memory impact. Likely millions will also work except may be in some specific use cases, yet I wouldn't recommend allowing that many requests, just to be on the safe side. -- Maxim Dounin http://mdounin.ru/ From mdounin at mdounin.ru Fri Jul 12 14:53:49 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:49 +0000 Subject: [nginx] Perl: removed unneeded NGX_DONE test. Message-ID: details: https://hg.nginx.org/nginx/rev/919a5c6c828c branches: changeset: 7523:919a5c6c828c user: Maxim Dounin date: Thu Jul 11 23:20:08 2019 +0300 description: Perl: removed unneeded NGX_DONE test. The NGX_DONE test in ngx_http_perl_handle_request() was introduced in 1702:86bb52e28ce0, which also modified ngx_http_perl_call_handler() to return NGX_DONE with c->destroyed. The latter part was then removed in 3050:f54b02dbb12b, so NGX_DONE test is no longer needed. diffstat: src/http/modules/perl/ngx_http_perl_module.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diffs (15 lines): diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -228,11 +228,6 @@ ngx_http_perl_handle_request(ngx_http_re ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl handler done: %i", rc); - if (rc == NGX_DONE) { - ngx_http_finalize_request(r, rc); - return; - } - if (rc > 600) { rc = NGX_OK; } From mdounin at mdounin.ru Fri Jul 12 14:53:51 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:51 +0000 Subject: [nginx] Perl: reworked perl module to pass ctx instead of request. Message-ID: details: https://hg.nginx.org/nginx/rev/deebe988cbd7 branches: changeset: 7524:deebe988cbd7 user: Maxim Dounin date: Fri Jul 12 11:29:22 2019 +0300 description: Perl: reworked perl module to pass ctx instead of request. This ensures that correct ctx is always available, including after filter finalization. In particular, this fixes a segmentation fault with the following configuration: location / { image_filter test; perl 'sub { my $r = shift; $r->send_http_header(); $r->print("foo\n"); $r->print("bar\n"); }'; } This also seems to be the only way to correctly handle filter finalization in various complex cases, for example, when embedded perl is used both in the original handler and in an error page called after filter finalization. diffstat: src/http/modules/perl/nginx.xs | 180 ++++++++++++++------------ src/http/modules/perl/ngx_http_perl_module.c | 26 ++- src/http/modules/perl/ngx_http_perl_module.h | 2 + 3 files changed, 114 insertions(+), 94 deletions(-) diffs (552 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -15,8 +15,10 @@ #include "XSUB.h" -#define ngx_http_perl_set_request(r) \ - r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) +#define ngx_http_perl_set_request(r, ctx) \ + \ + ctx = INT2PTR(ngx_http_perl_ctx_t *, SvIV((SV *) SvRV(ST(0)))); \ + r = ctx->request #define ngx_http_perl_set_targ(p, len) \ @@ -64,14 +66,12 @@ ngx_http_perl_sv2str(pTHX_ ngx_http_requ static ngx_int_t -ngx_http_perl_output(ngx_http_request_t *r, ngx_buf_t *b) +ngx_http_perl_output(ngx_http_request_t *r, ngx_http_perl_ctx_t *ctx, + ngx_buf_t *b) { - ngx_chain_t out; + ngx_chain_t out; #if (NGX_HTTP_SSI) - ngx_chain_t *cl; - ngx_http_perl_ctx_t *ctx; - - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); + ngx_chain_t *cl; if (ctx->ssi) { cl = ngx_alloc_chain_link(r->pool); @@ -105,9 +105,10 @@ void status(r, code) CODE: - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); r->headers_out.status = SvIV(ST(1)); @@ -121,10 +122,11 @@ void send_http_header(r, ...) CODE: - ngx_http_request_t *r; - SV *sv; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + SV *sv; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); if (r->headers_out.status == 0) { r->headers_out.status = NGX_HTTP_OK; @@ -157,9 +159,10 @@ header_only(r) CODE: dXSTARG; - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); sv_upgrade(TARG, SVt_IV); sv_setiv(TARG, r->header_only); @@ -172,9 +175,10 @@ uri(r) CODE: dXSTARG; - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); ngx_http_perl_set_targ(r->uri.data, r->uri.len); ST(0) = TARG; @@ -185,9 +189,10 @@ args(r) CODE: dXSTARG; - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); ngx_http_perl_set_targ(r->args.data, r->args.len); ST(0) = TARG; @@ -198,9 +203,10 @@ request_method(r) CODE: dXSTARG; - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); ngx_http_perl_set_targ(r->method_name.data, r->method_name.len); ST(0) = TARG; @@ -211,9 +217,10 @@ remote_addr(r) CODE: dXSTARG; - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); ngx_http_perl_set_targ(r->connection->addr_text.data, r->connection->addr_text.len); @@ -226,6 +233,7 @@ header_in(r, key) dXSTARG; ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; SV *key; u_char *p, *lowcase_key, *value, sep; STRLEN len; @@ -237,7 +245,7 @@ header_in(r, key) ngx_http_header_t *hh; ngx_http_core_main_conf_t *cmcf; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); key = ST(1); @@ -374,13 +382,12 @@ has_request_body(r, next) ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { XSRETURN_UNDEF; } - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); ctx->next = SvRV(ST(1)); r->request_body_in_single_buf = 1; @@ -404,13 +411,14 @@ request_body(r) CODE: dXSTARG; - ngx_http_request_t *r; - u_char *p, *data; - size_t len; - ngx_buf_t *buf; - ngx_chain_t *cl; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + u_char *p, *data; + size_t len; + ngx_buf_t *buf; + ngx_chain_t *cl; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); if (r->request_body == NULL || r->request_body->temp_file @@ -465,9 +473,10 @@ request_body_file(r) CODE: dXSTARG; - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); if (r->request_body == NULL || r->request_body->temp_file == NULL) { XSRETURN_UNDEF; @@ -483,9 +492,10 @@ void discard_request_body(r) CODE: - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); ngx_http_discard_request_body(r); @@ -494,12 +504,13 @@ void header_out(r, key, value) CODE: - ngx_http_request_t *r; - SV *key; - SV *value; - ngx_table_elt_t *header; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + SV *key; + SV *value; + ngx_table_elt_t *header; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); key = ST(1); value = ST(2); @@ -542,13 +553,12 @@ filename(r) CODE: dXSTARG; - size_t root; ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; + size_t root; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); if (ctx->filename.data) { goto done; } @@ -571,15 +581,16 @@ void print(r, ...) CODE: - ngx_http_request_t *r; - SV *sv; - int i; - u_char *p; - size_t size; - STRLEN len; - ngx_buf_t *b; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + SV *sv; + int i; + u_char *p; + size_t size; + STRLEN len; + ngx_buf_t *b; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); if (items == 2) { @@ -660,7 +671,7 @@ print(r, ...) out: - (void) ngx_http_perl_output(r, b); + (void) ngx_http_perl_output(r, ctx, b); void @@ -668,6 +679,7 @@ sendfile(r, filename, offset = -1, bytes CODE: ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; char *filename; off_t offset; size_t bytes; @@ -676,7 +688,7 @@ sendfile(r, filename, offset = -1, bytes ngx_open_file_info_t of; ngx_http_core_loc_conf_t *clcf; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); filename = SvPV_nolen(ST(1)); @@ -750,17 +762,18 @@ sendfile(r, filename, offset = -1, bytes b->file->log = r->connection->log; b->file->directio = of.is_directio; - (void) ngx_http_perl_output(r, b); + (void) ngx_http_perl_output(r, ctx, b); void flush(r) CODE: - ngx_http_request_t *r; - ngx_buf_t *b; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + ngx_buf_t *b; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); b = ngx_calloc_buf(r->pool); if (b == NULL) { @@ -771,7 +784,7 @@ flush(r) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); - (void) ngx_http_perl_output(r, b); + (void) ngx_http_perl_output(r, ctx, b); XSRETURN_EMPTY; @@ -781,16 +794,14 @@ internal_redirect(r, uri) CODE: ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; SV *uri; ngx_uint_t i; - ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); uri = ST(1); - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); - if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { XSRETURN_EMPTY; } @@ -811,9 +822,10 @@ void allow_ranges(r) CODE: - ngx_http_request_t *r; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); r->allow_ranges = 1; @@ -823,13 +835,14 @@ unescape(r, text, type = 0) CODE: dXSTARG; - ngx_http_request_t *r; - SV *text; - int type; - u_char *p, *dst, *src; - STRLEN len; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + SV *text; + int type; + u_char *p, *dst, *src; + STRLEN len; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); text = ST(1); @@ -858,16 +871,16 @@ variable(r, name, value = NULL) dXSTARG; ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; SV *name, *value; u_char *p, *lowcase; STRLEN len; ngx_str_t var, val; ngx_uint_t i, hash; ngx_http_perl_var_t *v; - ngx_http_perl_ctx_t *ctx; ngx_http_variable_value_t *vv; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); name = ST(1); @@ -919,8 +932,6 @@ variable(r, name, value = NULL) if (vv->not_found) { - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); - if (ctx->variables) { v = ctx->variables->elts; @@ -991,18 +1002,16 @@ sleep(r, sleep, next) CODE: ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; ngx_msec_t sleep; - ngx_http_perl_ctx_t *ctx; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); sleep = (ngx_msec_t) SvIV(ST(1)); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl sleep: %M", sleep); - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); - ctx->next = SvRV(ST(2)); r->connection->write->delayed = 1; @@ -1016,13 +1025,14 @@ void log_error(r, err, msg) CODE: - ngx_http_request_t *r; - SV *err, *msg; - u_char *p; - STRLEN len; - ngx_err_t e; + ngx_http_request_t *r; + ngx_http_perl_ctx_t *ctx; + SV *err, *msg; + u_char *p; + STRLEN len; + ngx_err_t e; - ngx_http_perl_set_request(r); + ngx_http_perl_set_request(r, ctx); err = ST(1); diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -43,7 +43,8 @@ static PerlInterpreter *ngx_http_perl_cr static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log); static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, - HV *nginx, SV *sub, SV **args, ngx_str_t *handler, ngx_str_t *rv); + ngx_http_perl_ctx_t *ctx, HV *nginx, SV *sub, SV **args, + ngx_str_t *handler, ngx_str_t *rv); static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv); static ngx_int_t ngx_http_perl_preconfiguration(ngx_conf_t *cf); @@ -199,6 +200,8 @@ ngx_http_perl_handle_request(ngx_http_re } ngx_http_set_ctx(r, ctx, ngx_http_perl_module); + + ctx->request = r; } pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); @@ -220,8 +223,8 @@ ngx_http_perl_handle_request(ngx_http_re ctx->next = NULL; } - rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler, - NULL); + rc = ngx_http_perl_call_handler(aTHX_ r, ctx, pmcf->nginx, sub, NULL, + handler, NULL); } @@ -309,6 +312,8 @@ ngx_http_perl_variable(ngx_http_request_ } ngx_http_set_ctx(r, ctx, ngx_http_perl_module); + + ctx->request = r; } pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); @@ -321,7 +326,7 @@ ngx_http_perl_variable(ngx_http_request_ PERL_SET_CONTEXT(pmcf->perl); PERL_SET_INTERP(pmcf->perl); - rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL, + rc = ngx_http_perl_call_handler(aTHX_ r, ctx, pmcf->nginx, pv->sub, NULL, &pv->handler, &value); } @@ -372,6 +377,8 @@ ngx_http_perl_ssi(ngx_http_request_t *r, } ngx_http_set_ctx(r, ctx, ngx_http_perl_module); + + ctx->request = r; } pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); @@ -430,8 +437,8 @@ ngx_http_perl_ssi(ngx_http_request_t *r, asv = NULL; } - rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sv, asv, handler, - NULL); + rc = ngx_http_perl_call_handler(aTHX_ r, ctx, pmcf->nginx, sv, asv, + handler, NULL); SvREFCNT_dec(sv); @@ -667,8 +674,9 @@ ngx_http_perl_run_requires(pTHX_ ngx_arr static ngx_int_t -ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub, - SV **args, ngx_str_t *handler, ngx_str_t *rv) +ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, + ngx_http_perl_ctx_t *ctx, HV *nginx, SV *sub, SV **args, + ngx_str_t *handler, ngx_str_t *rv) { SV *sv; int n, status; @@ -687,7 +695,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt PUSHMARK(sp); - sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx)); + sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(ctx))), nginx)); XPUSHs(sv); if (args) { diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -21,6 +21,8 @@ typedef ngx_http_request_t *nginx; typedef struct { + ngx_http_request_t *request; + ngx_str_t filename; ngx_str_t redirect_uri; ngx_str_t redirect_args; From mdounin at mdounin.ru Fri Jul 12 14:53:52 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:52 +0000 Subject: [nginx] Perl: propagate errors. Message-ID: details: https://hg.nginx.org/nginx/rev/575480d3fd01 branches: changeset: 7525:575480d3fd01 user: Maxim Dounin date: Fri Jul 12 13:56:21 2019 +0300 description: Perl: propagate errors. When an error happens, the ctx->error bit is now set, and croak() is called to terminate further processing. The ctx->error bit is checked in ngx_http_perl_call_handler() to cancel further processing, and is also checked in various output functions - to make sure these won't be called if croak() was handled by an eval{} in perl code. In particular, this ensures that output chain won't be called after errors, as filters might not expect this to happen. This fixes some segmentation faults under low memory conditions. Also this stops request processing after filter finalization or request body reading errors. For cases where an HTTP error status can be additionally returned (for example, 416 (Requested Range Not Satisfiable) from the range filter), the ctx->status field is also added. diffstat: src/http/modules/perl/nginx.xs | 72 +++++++++++++++++++++++++-- src/http/modules/perl/ngx_http_perl_module.c | 20 +++++++ src/http/modules/perl/ngx_http_perl_module.h | 5 +- 3 files changed, 90 insertions(+), 7 deletions(-) diffs (239 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -125,9 +125,14 @@ send_http_header(r, ...) ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; SV *sv; + ngx_int_t rc; ngx_http_perl_set_request(r, ctx); + if (ctx->error) { + croak("send_http_header(): called after error"); + } + if (r->headers_out.status == 0) { r->headers_out.status = NGX_HTTP_OK; } @@ -151,7 +156,13 @@ send_http_header(r, ...) r->disable_not_modified = 1; - (void) ngx_http_send_header(r); + rc = ngx_http_send_header(r); + + if (rc == NGX_ERROR || rc > NGX_OK) { + ctx->error = 1; + ctx->status = rc; + croak("ngx_http_send_header() failed"); + } void @@ -381,6 +392,7 @@ has_request_body(r, next) dXSTARG; ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; + ngx_int_t rc; ngx_http_perl_set_request(r, ctx); @@ -398,7 +410,14 @@ has_request_body(r, next) r->request_body_file_log_level = 0; } - ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); + rc = ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + ctx->error = 1; + ctx->status = rc; + ctx->next = NULL; + croak("ngx_http_read_client_request_body() failed"); + } sv_upgrade(TARG, SVt_IV); sv_setiv(TARG, 1); @@ -494,10 +513,17 @@ discard_request_body(r) ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; + ngx_int_t rc; ngx_http_perl_set_request(r, ctx); - ngx_http_discard_request_body(r); + rc = ngx_http_discard_request_body(r); + + if (rc != NGX_OK) { + ctx->error = 1; + ctx->status = rc; + croak("ngx_http_discard_request_body() failed"); + } void @@ -512,6 +538,10 @@ header_out(r, key, value) ngx_http_perl_set_request(r, ctx); + if (ctx->error) { + croak("header_out(): called after error"); + } + key = ST(1); value = ST(2); @@ -588,10 +618,15 @@ print(r, ...) u_char *p; size_t size; STRLEN len; + ngx_int_t rc; ngx_buf_t *b; ngx_http_perl_set_request(r, ctx); + if (ctx->error) { + croak("print(): called after error"); + } + if (items == 2) { /* @@ -671,7 +706,12 @@ print(r, ...) out: - (void) ngx_http_perl_output(r, ctx, b); + rc = ngx_http_perl_output(r, ctx, b); + + if (rc == NGX_ERROR) { + ctx->error = 1; + croak("ngx_http_perl_output() failed"); + } void @@ -683,6 +723,7 @@ sendfile(r, filename, offset = -1, bytes char *filename; off_t offset; size_t bytes; + ngx_int_t rc; ngx_str_t path; ngx_buf_t *b; ngx_open_file_info_t of; @@ -690,6 +731,10 @@ sendfile(r, filename, offset = -1, bytes ngx_http_perl_set_request(r, ctx); + if (ctx->error) { + croak("sendfile(): called after error"); + } + filename = SvPV_nolen(ST(1)); if (filename == NULL) { @@ -762,7 +807,12 @@ sendfile(r, filename, offset = -1, bytes b->file->log = r->connection->log; b->file->directio = of.is_directio; - (void) ngx_http_perl_output(r, ctx, b); + rc = ngx_http_perl_output(r, ctx, b); + + if (rc == NGX_ERROR) { + ctx->error = 1; + croak("ngx_http_perl_output() failed"); + } void @@ -771,10 +821,15 @@ flush(r) ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; + ngx_int_t rc; ngx_buf_t *b; ngx_http_perl_set_request(r, ctx); + if (ctx->error) { + croak("flush(): called after error"); + } + b = ngx_calloc_buf(r->pool); if (b == NULL) { XSRETURN_EMPTY; @@ -784,7 +839,12 @@ flush(r) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); - (void) ngx_http_perl_output(r, ctx, b); + rc = ngx_http_perl_output(r, ctx, b); + + if (rc == NGX_ERROR) { + ctx->error = 1; + croak("ngx_http_perl_output() failed"); + } XSRETURN_EMPTY; diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -246,6 +246,11 @@ ngx_http_perl_handle_request(ngx_http_re ctx->filename.data = NULL; ctx->redirect_uri.len = 0; + if (rc == NGX_ERROR) { + ngx_http_finalize_request(r, rc); + return; + } + if (ctx->done || ctx->next) { ngx_http_finalize_request(r, NGX_DONE); return; @@ -690,6 +695,9 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt status = 0; + ctx->error = 0; + ctx->status = NGX_OK; + ENTER; SAVETMPS; @@ -739,6 +747,18 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt FREETMPS; LEAVE; + if (ctx->error) { + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "call_sv: error, %d", ctx->status); + + if (ctx->status != NGX_OK) { + return ctx->status; + } + + return NGX_ERROR; + } + /* check $@ */ if (SvTRUE(ERRSV)) { diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -29,7 +29,10 @@ typedef struct { SV *next; - ngx_uint_t done; /* unsigned done:1; */ + ngx_int_t status; + + unsigned done:1; + unsigned error:1; ngx_array_t *variables; /* array of ngx_http_perl_var_t */ From mdounin at mdounin.ru Fri Jul 12 14:53:54 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:54 +0000 Subject: [nginx] Perl: handling of allocation errors. Message-ID: details: https://hg.nginx.org/nginx/rev/8125552a10ca branches: changeset: 7526:8125552a10ca user: Maxim Dounin date: Fri Jul 12 13:56:23 2019 +0300 description: Perl: handling of allocation errors. Previously, allocation errors in nginx.xs were more or less ignored, potentially resulting in incorrect code execution in specific low-memory conditions. This is changed to use ctx->error bit and croak(), similarly to how output errors are now handled. Note that this is mostly a cosmetic change, as Perl itself exits on memory allocation errors, and hence nginx with Perl is hardly usable in low-memory conditions. diffstat: src/http/modules/perl/nginx.xs | 76 ++++++++++++++++++++++++++++------------- 1 files changed, 51 insertions(+), 25 deletions(-) diffs (239 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -143,14 +143,16 @@ send_http_header(r, ...) if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) != NGX_OK) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_http_perl_sv2str() failed"); } r->headers_out.content_type_len = r->headers_out.content_type.len; } else { if (ngx_http_set_content_type(r) != NGX_OK) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_http_set_content_type() failed"); } } @@ -270,7 +272,8 @@ header_in(r, key) lowcase_key = ngx_pnalloc(r->pool, len); if (lowcase_key == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_pnalloc() failed"); } hash = ngx_hash_strlow(lowcase_key, p, len); @@ -330,7 +333,8 @@ header_in(r, key) value = ngx_pnalloc(r->pool, size); if (value == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_pnalloc() failed"); } p = value; @@ -465,7 +469,8 @@ request_body(r) p = ngx_pnalloc(r->pool, len); if (p == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_pnalloc() failed"); } data = p; @@ -547,19 +552,22 @@ header_out(r, key, value) header = ngx_list_push(&r->headers_out.headers); if (header == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_list_push() failed"); } header->hash = 1; if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { header->hash = 0; - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_http_perl_sv2str() failed"); } if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { header->hash = 0; - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_http_perl_sv2str() failed"); } if (header->key.len == sizeof("Content-Length") - 1 @@ -594,7 +602,8 @@ filename(r) } if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_http_map_uri_to_path() failed"); } ctx->filename.len--; @@ -650,7 +659,8 @@ print(r, ...) b = ngx_calloc_buf(r->pool); if (b == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_calloc_buf() failed"); } b->memory = 1; @@ -690,7 +700,8 @@ print(r, ...) b = ngx_create_temp_buf(r->pool, size); if (b == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_create_temp_buf() failed"); } for (i = 1; i < items; i++) { @@ -746,19 +757,22 @@ sendfile(r, filename, offset = -1, bytes b = ngx_calloc_buf(r->pool); if (b == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_calloc_buf() failed"); } b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); if (b->file == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_pcalloc() failed"); } path.len = ngx_strlen(filename); path.data = ngx_pnalloc(r->pool, path.len + 1); if (path.data == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_pnalloc() failed"); } (void) ngx_cpystrn(path.data, (u_char *) filename, path.len + 1); @@ -775,19 +789,23 @@ sendfile(r, filename, offset = -1, bytes of.events = clcf->open_file_cache_events; if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_http_set_disable_symlinks() failed"); } if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { if (of.err == 0) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_open_cached_file() failed"); } ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, "%s \"%s\" failed", of.failed, filename); - XSRETURN_EMPTY; + + ctx->error = 1; + croak("ngx_open_cached_file() failed"); } if (offset == -1) { @@ -832,7 +850,8 @@ flush(r) b = ngx_calloc_buf(r->pool); if (b == NULL) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_calloc_buf() failed"); } b->flush = 1; @@ -863,7 +882,8 @@ internal_redirect(r, uri) uri = ST(1); if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { - XSRETURN_EMPTY; + ctx->error = 1; + croak("ngx_http_perl_sv2str() failed"); } for (i = 0; i < ctx->redirect_uri.len; i++) { @@ -910,7 +930,8 @@ unescape(r, text, type = 0) p = ngx_pnalloc(r->pool, len + 1); if (p == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_pnalloc() failed"); } dst = p; @@ -959,7 +980,8 @@ variable(r, name, value = NULL) } if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_http_perl_sv2str() failed"); } } @@ -967,7 +989,8 @@ variable(r, name, value = NULL) lowcase = ngx_pnalloc(r->pool, len); if (lowcase == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_pnalloc() failed"); } hash = ngx_hash_strlow(lowcase, p, len); @@ -987,7 +1010,8 @@ variable(r, name, value = NULL) vv = ngx_http_get_variable(r, &var, hash); if (vv == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_http_get_variable() failed"); } if (vv->not_found) { @@ -1020,13 +1044,15 @@ variable(r, name, value = NULL) ctx->variables = ngx_array_create(r->pool, 1, sizeof(ngx_http_perl_var_t)); if (ctx->variables == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_array_create() failed"); } } v = ngx_array_push(ctx->variables); if (v == NULL) { - XSRETURN_UNDEF; + ctx->error = 1; + croak("ngx_array_push() failed"); } v->hash = hash; From mdounin at mdounin.ru Fri Jul 12 14:53:55 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:55 +0000 Subject: [nginx] Perl: protection against duplicate $r->sleep() calls. Message-ID: details: https://hg.nginx.org/nginx/rev/02cd116ebe2a branches: changeset: 7527:02cd116ebe2a user: Maxim Dounin date: Fri Jul 12 15:34:37 2019 +0300 description: Perl: protection against duplicate $r->sleep() calls. Duplicate $r->sleep() and/or $r->has_request_body() calls result in undefined behaviour (in practice, connection leaks were observed). To prevent this, croak() added in appropriate places. diffstat: src/http/modules/perl/nginx.xs | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diffs (25 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -400,6 +400,10 @@ has_request_body(r, next) ngx_http_perl_set_request(r, ctx); + if (ctx->next) { + croak("has_request_body(): another handler active"); + } + if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { XSRETURN_UNDEF; } @@ -1093,6 +1097,10 @@ sleep(r, sleep, next) ngx_http_perl_set_request(r, ctx); + if (ctx->next) { + croak("sleep(): another handler active"); + } + sleep = (ngx_msec_t) SvIV(ST(1)); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, From mdounin at mdounin.ru Fri Jul 12 14:53:59 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:59 +0000 Subject: [nginx] Perl: avoid redirects on errors. Message-ID: details: https://hg.nginx.org/nginx/rev/d758d04e0790 branches: changeset: 7529:d758d04e0790 user: Maxim Dounin date: Fri Jul 12 15:38:27 2019 +0300 description: Perl: avoid redirects on errors. Previously, redirects scheduled with $r->internal_redirect() were followed even if the code then died. Now these are ignored and nginx will return an error instead. diffstat: src/http/modules/perl/ngx_http_perl_module.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -778,6 +778,8 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt return NGX_ERROR; } + ctx->redirect_uri.len = 0; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } From mdounin at mdounin.ru Fri Jul 12 14:53:57 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:53:57 +0000 Subject: [nginx] Perl: disabled unrelated calls from variable handlers. Message-ID: details: https://hg.nginx.org/nginx/rev/0cb693b4cbbb branches: changeset: 7528:0cb693b4cbbb user: Maxim Dounin date: Fri Jul 12 15:35:31 2019 +0300 description: Perl: disabled unrelated calls from variable handlers. Variable handlers are not expected to send anything to the client, cannot sleep or read body, and are not expected to modify the request. Added appropriate protection to prevent accidental foot shooting. diffstat: src/http/modules/perl/nginx.xs | 44 ++++++++++++++++++++++++++++ src/http/modules/perl/ngx_http_perl_module.c | 5 +++ src/http/modules/perl/ngx_http_perl_module.h | 1 + 3 files changed, 50 insertions(+), 0 deletions(-) diffs (164 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -110,6 +110,10 @@ status(r, code) ngx_http_perl_set_request(r, ctx); + if (ctx->variable) { + croak("status(): cannot be used in variable handler"); + } + r->headers_out.status = SvIV(ST(1)); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -133,6 +137,10 @@ send_http_header(r, ...) croak("send_http_header(): called after error"); } + if (ctx->variable) { + croak("send_http_header(): cannot be used in variable handler"); + } + if (r->headers_out.status == 0) { r->headers_out.status = NGX_HTTP_OK; } @@ -400,6 +408,10 @@ has_request_body(r, next) ngx_http_perl_set_request(r, ctx); + if (ctx->variable) { + croak("has_request_body(): cannot be used in variable handler"); + } + if (ctx->next) { croak("has_request_body(): another handler active"); } @@ -526,6 +538,10 @@ discard_request_body(r) ngx_http_perl_set_request(r, ctx); + if (ctx->variable) { + croak("discard_request_body(): cannot be used in variable handler"); + } + rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { @@ -551,6 +567,10 @@ header_out(r, key, value) croak("header_out(): called after error"); } + if (ctx->variable) { + croak("header_out(): cannot be used in variable handler"); + } + key = ST(1); value = ST(2); @@ -640,6 +660,10 @@ print(r, ...) croak("print(): called after error"); } + if (ctx->variable) { + croak("print(): cannot be used in variable handler"); + } + if (items == 2) { /* @@ -750,6 +774,10 @@ sendfile(r, filename, offset = -1, bytes croak("sendfile(): called after error"); } + if (ctx->variable) { + croak("sendfile(): cannot be used in variable handler"); + } + filename = SvPV_nolen(ST(1)); if (filename == NULL) { @@ -852,6 +880,10 @@ flush(r) croak("flush(): called after error"); } + if (ctx->variable) { + croak("flush(): cannot be used in variable handler"); + } + b = ngx_calloc_buf(r->pool); if (b == NULL) { ctx->error = 1; @@ -883,6 +915,10 @@ internal_redirect(r, uri) ngx_http_perl_set_request(r, ctx); + if (ctx->variable) { + croak("internal_redirect(): cannot be used in variable handler"); + } + uri = ST(1); if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { @@ -911,6 +947,10 @@ allow_ranges(r) ngx_http_perl_set_request(r, ctx); + if (ctx->variable) { + croak("allow_ranges(): cannot be used in variable handler"); + } + r->allow_ranges = 1; @@ -1097,6 +1137,10 @@ sleep(r, sleep, next) ngx_http_perl_set_request(r, ctx); + if (ctx->variable) { + croak("sleep(): cannot be used in variable handler"); + } + if (ctx->next) { croak("sleep(): another handler active"); } diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -302,6 +302,7 @@ ngx_http_perl_variable(ngx_http_request_ ngx_int_t rc; ngx_str_t value; + ngx_uint_t saved; ngx_http_perl_ctx_t *ctx; ngx_http_perl_main_conf_t *pmcf; @@ -321,6 +322,9 @@ ngx_http_perl_variable(ngx_http_request_ ctx->request = r; } + saved = ctx->variable; + ctx->variable = 1; + pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); value.data = NULL; @@ -347,6 +351,7 @@ ngx_http_perl_variable(ngx_http_request_ v->not_found = 1; } + ctx->variable = saved; ctx->filename.data = NULL; ctx->redirect_uri.len = 0; diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -33,6 +33,7 @@ typedef struct { unsigned done:1; unsigned error:1; + unsigned variable:1; ngx_array_t *variables; /* array of ngx_http_perl_var_t */ From mdounin at mdounin.ru Fri Jul 12 14:54:00 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:54:00 +0000 Subject: [nginx] Perl: avoid returning 500 if header was already sent. Message-ID: details: https://hg.nginx.org/nginx/rev/fd9252844ec1 branches: changeset: 7530:fd9252844ec1 user: Maxim Dounin date: Fri Jul 12 15:39:25 2019 +0300 description: Perl: avoid returning 500 if header was already sent. Returning NGX_HTTP_INTERNAL_SERVER_ERROR if a perl code died after sending header will lead to a "header already sent" alert. To avoid it, we now check if header was already sent, and return NGX_ERROR instead if it was. diffstat: src/http/modules/perl/nginx.xs | 2 ++ src/http/modules/perl/ngx_http_perl_module.c | 4 ++++ src/http/modules/perl/ngx_http_perl_module.h | 1 + 3 files changed, 7 insertions(+), 0 deletions(-) diffs (37 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -164,6 +164,8 @@ send_http_header(r, ...) } } + ctx->header_sent = 1; + r->disable_not_modified = 1; rc = ngx_http_send_header(r); diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -780,6 +780,10 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt ctx->redirect_uri.len = 0; + if (ctx->header_sent) { + return NGX_ERROR; + } + return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -34,6 +34,7 @@ typedef struct { unsigned done:1; unsigned error:1; unsigned variable:1; + unsigned header_sent:1; ngx_array_t *variables; /* array of ngx_http_perl_var_t */ From mdounin at mdounin.ru Fri Jul 12 14:54:02 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:54:02 +0000 Subject: [nginx] Perl: additional ctx->header_sent checks. Message-ID: details: https://hg.nginx.org/nginx/rev/ede052c67512 branches: changeset: 7531:ede052c67512 user: Maxim Dounin date: Fri Jul 12 15:39:25 2019 +0300 description: Perl: additional ctx->header_sent checks. As we now have ctx->header_sent flag, it is further used to prevent duplicate $r->send_http_header() calls, prevent output before sending header, and $r->internal_redirect() after sending header. Further, $r->send_http_header() protected from calls after $r->internal_redirect(). diffstat: src/http/modules/perl/nginx.xs | 24 ++++++++++++++++++++++++ src/http/modules/perl/ngx_http_perl_module.c | 1 + 2 files changed, 25 insertions(+), 0 deletions(-) diffs (73 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -141,6 +141,14 @@ send_http_header(r, ...) croak("send_http_header(): cannot be used in variable handler"); } + if (ctx->header_sent) { + croak("send_http_header(): header already sent"); + } + + if (ctx->redirect_uri.len) { + croak("send_http_header(): cannot be used with internal_redirect()"); + } + if (r->headers_out.status == 0) { r->headers_out.status = NGX_HTTP_OK; } @@ -666,6 +674,10 @@ print(r, ...) croak("print(): cannot be used in variable handler"); } + if (!ctx->header_sent) { + croak("print(): header not sent"); + } + if (items == 2) { /* @@ -780,6 +792,10 @@ sendfile(r, filename, offset = -1, bytes croak("sendfile(): cannot be used in variable handler"); } + if (!ctx->header_sent) { + croak("sendfile(): header not sent"); + } + filename = SvPV_nolen(ST(1)); if (filename == NULL) { @@ -886,6 +902,10 @@ flush(r) croak("flush(): cannot be used in variable handler"); } + if (!ctx->header_sent) { + croak("flush(): header not sent"); + } + b = ngx_calloc_buf(r->pool); if (b == NULL) { ctx->error = 1; @@ -921,6 +941,10 @@ internal_redirect(r, uri) croak("internal_redirect(): cannot be used in variable handler"); } + if (ctx->header_sent) { + croak("internal_redirect(): header already sent"); + } + uri = ST(1); if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -394,6 +394,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); ctx->ssi = ssi_ctx; + ctx->header_sent = 1; handler = params[NGX_HTTP_PERL_SSI_SUB]; handler->data[handler->len] = '\0'; From mdounin at mdounin.ru Fri Jul 12 14:54:03 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:54:03 +0000 Subject: [nginx] Perl: expect escaped URIs in $r->internal_redirect(). Message-ID: details: https://hg.nginx.org/nginx/rev/975d7ab37b39 branches: changeset: 7532:975d7ab37b39 user: Maxim Dounin date: Fri Jul 12 15:39:26 2019 +0300 description: Perl: expect escaped URIs in $r->internal_redirect(). Similarly to the change in 5491:74bfa803a5aa (1.5.9), we should accept properly escaped URIs and unescape them as needed, else it is not possible to handle URIs with question marks. diffstat: src/http/modules/perl/nginx.xs | 11 ----------- src/http/modules/perl/ngx_http_perl_module.c | 10 +++++++++- src/http/modules/perl/ngx_http_perl_module.h | 1 - 3 files changed, 9 insertions(+), 13 deletions(-) diffs (66 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -952,17 +952,6 @@ internal_redirect(r, uri) croak("ngx_http_perl_sv2str() failed"); } - for (i = 0; i < ctx->redirect_uri.len; i++) { - if (ctx->redirect_uri.data[i] == '?') { - - ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1); - ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1]; - ctx->redirect_uri.len = i; - - XSRETURN_EMPTY; - } - } - void allow_ranges(r) diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -184,6 +184,7 @@ ngx_http_perl_handle_request(ngx_http_re SV *sub; ngx_int_t rc; ngx_str_t uri, args, *handler; + ngx_uint_t flags; ngx_http_perl_ctx_t *ctx; ngx_http_perl_loc_conf_t *plcf; ngx_http_perl_main_conf_t *pmcf; @@ -237,7 +238,6 @@ ngx_http_perl_handle_request(ngx_http_re if (ctx->redirect_uri.len) { uri = ctx->redirect_uri; - args = ctx->redirect_args; } else { uri.len = 0; @@ -257,6 +257,14 @@ ngx_http_perl_handle_request(ngx_http_re } if (uri.len) { + ngx_str_null(&args); + flags = NGX_HTTP_LOG_UNSAFE; + + if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + ngx_http_internal_redirect(r, &uri, &args); ngx_http_finalize_request(r, NGX_DONE); return; diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -25,7 +25,6 @@ typedef struct { ngx_str_t filename; ngx_str_t redirect_uri; - ngx_str_t redirect_args; SV *next; From mdounin at mdounin.ru Fri Jul 12 14:54:05 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 14:54:05 +0000 Subject: [nginx] Perl: named locations in $r->internal_redirect(). Message-ID: details: https://hg.nginx.org/nginx/rev/5f642712e7ad branches: changeset: 7533:5f642712e7ad user: Maxim Dounin date: Fri Jul 12 15:39:28 2019 +0300 description: Perl: named locations in $r->internal_redirect(). diffstat: src/http/modules/perl/ngx_http_perl_module.c | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) diffs (31 lines): diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -257,15 +257,21 @@ ngx_http_perl_handle_request(ngx_http_re } if (uri.len) { - ngx_str_null(&args); - flags = NGX_HTTP_LOG_UNSAFE; + if (uri.data[0] == '@') { + ngx_http_named_location(r, &uri); + + } else { + ngx_str_null(&args); + flags = NGX_HTTP_LOG_UNSAFE; - if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; + if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + ngx_http_internal_redirect(r, &uri, &args); } - ngx_http_internal_redirect(r, &uri, &args); ngx_http_finalize_request(r, NGX_DONE); return; } From mdounin at mdounin.ru Fri Jul 12 19:28:32 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 19:28:32 +0000 Subject: [nginx] Gzip: use zlib to write header and trailer. Message-ID: details: https://hg.nginx.org/nginx/rev/ac5a741d39cf branches: changeset: 7534:ac5a741d39cf user: Ilya Leoshkevich date: Fri Jul 12 12:43:08 2019 +0200 description: Gzip: use zlib to write header and trailer. When nginx is used with zlib patched with [1], which provides integration with the future IBM Z hardware deflate acceleration, it ends up computing CRC32 twice: one time in hardware, which always does this, and one time in software by explicitly calling crc32(). crc32() calls were added in changesets 133:b27548f540ad ("nginx-0.0.1- 2003-09-24-23:51:12 import") and 134:d57c6835225c ("nginx-0.0.1- 2003-09-26-09:45:21 import") as part of gzip wrapping feature - back then zlib did not support it. However, since then gzip wrapping was implemented in zlib v1.2.0.4, and it's already being used by nginx for log compression. This patch replaces hand-written gzip wrapping with the one provided by zlib. It simplifies the code, and makes it avoid computing CRC32 twice when using hardware acceleration. [1] https://github.com/madler/zlib/pull/410 diffstat: src/http/modules/ngx_http_gzip_filter_module.c | 124 +----------------------- 1 files changed, 7 insertions(+), 117 deletions(-) diffs (203 lines): diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -55,44 +55,23 @@ typedef struct { unsigned redo:1; unsigned done:1; unsigned nomem:1; - unsigned gzheader:1; unsigned buffering:1; unsigned intel:1; size_t zin; size_t zout; - uint32_t crc32; z_stream zstream; ngx_http_request_t *request; } ngx_http_gzip_ctx_t; -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) - -struct gztrailer { - uint32_t crc32; - uint32_t zlen; -}; - -#else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */ - -struct gztrailer { - u_char crc32[4]; - u_char zlen[4]; -}; - -#endif - - static void ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_buffer(ngx_http_gzip_ctx_t *ctx, ngx_chain_t *in); static ngx_int_t ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); -static ngx_int_t ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, - ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx); static ngx_int_t ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, @@ -446,12 +425,6 @@ ngx_http_gzip_body_filter(ngx_http_reque return ctx->busy ? NGX_AGAIN : NGX_OK; } - if (!ctx->gzheader) { - if (ngx_http_gzip_filter_gzheader(r, ctx) != NGX_OK) { - goto failed; - } - } - rc = ngx_http_next_body_filter(r, ctx->out); if (rc == NGX_ERROR) { @@ -643,7 +616,7 @@ ngx_http_gzip_filter_deflate_start(ngx_h ctx->zstream.opaque = ctx; rc = deflateInit2(&ctx->zstream, (int) conf->level, Z_DEFLATED, - - ctx->wbits, ctx->memlevel, Z_DEFAULT_STRATEGY); + ctx->wbits + 16, ctx->memlevel, Z_DEFAULT_STRATEGY); if (rc != Z_OK) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, @@ -652,7 +625,6 @@ ngx_http_gzip_filter_deflate_start(ngx_h } ctx->last_out = &ctx->out; - ctx->crc32 = crc32(0L, Z_NULL, 0); ctx->flush = Z_NO_FLUSH; return NGX_OK; @@ -660,38 +632,6 @@ ngx_http_gzip_filter_deflate_start(ngx_h static ngx_int_t -ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) -{ - ngx_buf_t *b; - ngx_chain_t *cl; - static u_char gzheader[10] = - { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; - - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - b->memory = 1; - b->pos = gzheader; - b->last = b->pos + 10; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - cl->next = ctx->out; - ctx->out = cl; - - ctx->gzheader = 1; - - return NGX_OK; -} - - -static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { ngx_chain_t *cl; @@ -743,14 +683,9 @@ ngx_http_gzip_filter_add_data(ngx_http_r } else if (ctx->in_buf->flush) { ctx->flush = Z_SYNC_FLUSH; - } - if (ctx->zstream.avail_in) { - - ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in, - ctx->zstream.avail_in); - - } else if (ctx->flush == Z_NO_FLUSH) { + } else if (ctx->zstream.avail_in == 0) { + /* ctx->flush == Z_NO_FLUSH */ return NGX_AGAIN; } @@ -932,13 +867,11 @@ static ngx_int_t ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { - int rc; - ngx_buf_t *b; - ngx_chain_t *cl; - struct gztrailer *trailer; + int rc; + ngx_chain_t *cl; ctx->zin = ctx->zstream.total_in; - ctx->zout = 10 + ctx->zstream.total_out + 8; + ctx->zout = ctx->zstream.total_out; rc = deflateEnd(&ctx->zstream); @@ -960,50 +893,7 @@ ngx_http_gzip_filter_deflate_end(ngx_htt *ctx->last_out = cl; ctx->last_out = &cl->next; - if (ctx->zstream.avail_out >= 8) { - trailer = (struct gztrailer *) ctx->out_buf->last; - ctx->out_buf->last += 8; - ctx->out_buf->last_buf = 1; - - } else { - b = ngx_create_temp_buf(r->pool, 8); - if (b == NULL) { - return NGX_ERROR; - } - - b->last_buf = 1; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - cl->next = NULL; - *ctx->last_out = cl; - ctx->last_out = &cl->next; - trailer = (struct gztrailer *) b->pos; - b->last += 8; - } - -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) - - trailer->crc32 = ctx->crc32; - trailer->zlen = ctx->zin; - -#else - - trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff); - trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff); - trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff); - trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff); - - trailer->zlen[0] = (u_char) (ctx->zin & 0xff); - trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff); - trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff); - trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff); - -#endif + ctx->out_buf->last_buf = 1; ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; From mdounin at mdounin.ru Fri Jul 12 19:29:24 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Jul 2019 22:29:24 +0300 Subject: [PATCH v2] Gzip: use zlib to write header and trailer In-Reply-To: <0a056523895149d727a7.1562929491@white> References: <0a056523895149d727a7.1562929491@white> Message-ID: <20190712192924.GO1877@mdounin.ru> Hello! On Fri, Jul 12, 2019 at 01:04:51PM +0200, Ilya Leoshkevich wrote: > # HG changeset patch > # User Ilya Leoshkevich > # Date 1562928188 -7200 > # Fri Jul 12 12:43:08 2019 +0200 > # Node ID 0a056523895149d727a703242f2e2b579cfec9da > # Parent 97ce2512373d7278f765f587d4cf087065a55e7c > Gzip: use zlib to write header and trailer > > When nginx is used with zlib patched with [1], which provides > integration with the future IBM Z hardware deflate acceleration, it ends > up computing CRC32 twice: one time in hardware, which always does this, > and one time in software by explicitly calling crc32(). > > crc32() calls were added in changesets 133:b27548f540ad ("nginx-0.0.1- > 2003-09-24-23:51:12 import") and 134:d57c6835225c ("nginx-0.0.1- > 2003-09-26-09:45:21 import") as part of gzip wrapping feature - back > then zlib did not support it. > > However, since then gzip wrapping was implemented in zlib v1.2.0.4, > and it's already being used by nginx for log compression. > > This patch replaces hand-written gzip wrapping with the one provided by > zlib. It simplifies the code, and makes it avoid computing CRC32 twice > when using hardware acceleration. > > [1] https://github.com/madler/zlib/pull/410 > > v1->v2: Resent in hg format, replaced git mirror commit references to hg > changeset references in the commit message. The code is unchanged. [...] Committed (with minor changes), thanks. -- Maxim Dounin http://mdounin.ru/ From xeioex at nginx.com Fri Jul 12 20:31:13 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 12 Jul 2019 20:31:13 +0000 Subject: [njs] Allowing to configure ar binary. Message-ID: details: https://hg.nginx.org/njs/rev/8cfbc7785708 branches: changeset: 1043:8cfbc7785708 user: Dmitry Volyntsev date: Fri Jul 12 21:18:30 2019 +0300 description: Allowing to configure ar binary. diffstat: auto/make | 5 +++-- configure | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diffs (40 lines): diff -r 71e6a00bd921 -r 8cfbc7785708 auto/make --- a/auto/make Thu Jul 11 21:29:59 2019 +0300 +++ b/auto/make Fri Jul 12 21:18:30 2019 +0300 @@ -15,6 +15,7 @@ cat << END > $NXT_MAKEFILE # This file is auto-generated by configure NXT_CC = ${CC} +NXT_AR = ${AR} NXT_CFLAGS = ${NXT_CFLAGS} ${CFLAGS} default: $NXT_DEFAULT_TARGET @@ -57,7 +58,7 @@ libnxt: $NXT_BUILD_DIR/libnxt.a $NXT_BUILD_DIR/libnxt.a: \\ $NXT_BUILD_DIR/nxt_auto_config.h \\ \$(NXT_LIB_OBJS) - ar -r -c $NXT_BUILD_DIR/libnxt.a \\ + \$(NXT_AR) -r -c $NXT_BUILD_DIR/libnxt.a \\ \$(NXT_LIB_OBJS) END @@ -136,7 +137,7 @@ libnjs: $NXT_BUILD_DIR/libnjs.a \$(NXT_LIB_OBJS) \\ \$(NJS_LIB_OBJS) - ar -r -c $NXT_BUILD_DIR/libnjs.a \\ + \$(NXT_AR) -r -c $NXT_BUILD_DIR/libnjs.a \\ \$(NXT_LIB_OBJS) \\ \$(NJS_LIB_OBJS) diff -r 71e6a00bd921 -r 8cfbc7785708 configure --- a/configure Thu Jul 11 21:29:59 2019 +0300 +++ b/configure Fri Jul 12 21:18:30 2019 +0300 @@ -22,6 +22,7 @@ NXT_TEST_LIBS=${NXT_TEST_LIBS=} # Initialize variables with default if they are not defined. CC=${CC:-cc} +AR=${AR:-ar} NXT_CFLAGS=${NXT_CFLAGS=} NXT_CC_OPT=${NXT_CC_OPT:--O} NXT_LD_OPT=${NXT_CC_OPT:--O} From xeioex at nginx.com Fri Jul 12 20:31:14 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 12 Jul 2019 20:31:14 +0000 Subject: [njs] Improved typeof for internal types. Message-ID: details: https://hg.nginx.org/njs/rev/b0084c55d444 branches: changeset: 1044:b0084c55d444 user: Dmitry Volyntsev date: Fri Jul 12 23:30:22 2019 +0300 description: Improved typeof for internal types. diffstat: njs/njs_value.c | 3 +++ njs/njs_value.h | 3 +++ njs/njs_vm.c | 6 +++--- njs/test/njs_unit_test.c | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diffs (54 lines): diff -r 8cfbc7785708 -r b0084c55d444 njs/njs_value.c --- a/njs/njs_value.c Fri Jul 12 21:18:30 2019 +0300 +++ b/njs/njs_value.c Fri Jul 12 23:30:22 2019 +0300 @@ -31,6 +31,9 @@ const njs_value_t njs_string_plus_infin njs_string("Infinity"); const njs_value_t njs_string_nan = njs_string("NaN"); const njs_value_t njs_string_string = njs_string("string"); +const njs_value_t njs_string_data = njs_string("data"); +const njs_value_t njs_string_external = njs_string("external"); +const njs_value_t njs_string_invalid = njs_string("invalid"); const njs_value_t njs_string_object = njs_string("object"); const njs_value_t njs_string_function = njs_string("function"); const njs_value_t njs_string_memory_error = njs_string("MemoryError"); diff -r 8cfbc7785708 -r b0084c55d444 njs/njs_value.h --- a/njs/njs_value.h Fri Jul 12 21:18:30 2019 +0300 +++ b/njs/njs_value.h Fri Jul 12 23:30:22 2019 +0300 @@ -743,6 +743,9 @@ extern const njs_value_t njs_string_min extern const njs_value_t njs_string_plus_infinity; extern const njs_value_t njs_string_nan; extern const njs_value_t njs_string_string; +extern const njs_value_t njs_string_data; +extern const njs_value_t njs_string_external; +extern const njs_value_t njs_string_invalid; extern const njs_value_t njs_string_object; extern const njs_value_t njs_string_function; extern const njs_value_t njs_string_memory_error; diff -r 8cfbc7785708 -r b0084c55d444 njs/njs_vm.c --- a/njs/njs_vm.c Fri Jul 12 21:18:30 2019 +0300 +++ b/njs/njs_vm.c Fri Jul 12 23:30:22 2019 +0300 @@ -982,9 +982,9 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_valu &njs_string_boolean, &njs_string_number, &njs_string_string, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, + &njs_string_data, + &njs_string_external, + &njs_string_invalid, &njs_string_undefined, &njs_string_undefined, &njs_string_undefined, diff -r 8cfbc7785708 -r b0084c55d444 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Jul 12 21:18:30 2019 +0300 +++ b/njs/test/njs_unit_test.c Fri Jul 12 23:30:22 2019 +0300 @@ -4998,7 +4998,7 @@ static njs_unit_test_t njs_test[] = /* Externals. */ { nxt_string("typeof $r"), - nxt_string("undefined") }, + nxt_string("external") }, { nxt_string("var a = $r.uri, s = a.fromUTF8(); s.length +' '+ s"), nxt_string("3 ???") }, From xeioex at nginx.com Mon Jul 15 13:21:53 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 15 Jul 2019 13:21:53 +0000 Subject: [njs] Tests: passing unit tests options in a struct. Message-ID: details: https://hg.nginx.org/njs/rev/9fc79481e32d branches: changeset: 1045:9fc79481e32d user: Dmitry Volyntsev date: Mon Jul 15 15:54:41 2019 +0300 description: Tests: passing unit tests options in a struct. diffstat: njs/test/njs_unit_test.c | 99 ++++++++++++++++++++++++----------------------- 1 files changed, 51 insertions(+), 48 deletions(-) diffs (237 lines): diff -r b0084c55d444 -r 9fc79481e32d njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Jul 12 23:30:22 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon Jul 15 15:54:41 2019 +0300 @@ -13853,9 +13853,15 @@ njs_externals_init(njs_vm_t *vm) } +typedef struct { + nxt_bool_t disassemble; + nxt_bool_t verbose; + nxt_bool_t module; +} njs_opts_t; + + static nxt_int_t -njs_unit_test(njs_unit_test_t tests[], size_t num, nxt_bool_t module, - nxt_bool_t disassemble, nxt_bool_t verbose) +njs_unit_test(njs_unit_test_t tests[], size_t num, njs_opts_t *opts) { u_char *start; njs_vm_t *vm, *nvm; @@ -13872,13 +13878,13 @@ njs_unit_test(njs_unit_test_t tests[], s for (i = 0; i < num; i++) { - if (verbose) { + if (opts->verbose) { nxt_printf("\"%V\"\n", &tests[i].script); } nxt_memzero(&options, sizeof(njs_vm_opt_t)); - options.module = module; + options.module = opts->module; vm = njs_vm_create(&options); if (vm == NULL) { @@ -13896,7 +13902,7 @@ njs_unit_test(njs_unit_test_t tests[], s ret = njs_vm_compile(vm, &start, start + tests[i].script.length); if (ret == NXT_OK) { - if (disassemble) { + if (opts->disassemble) { njs_disassembler(vm); } @@ -13957,7 +13963,7 @@ done: static nxt_int_t -njs_timezone_optional_test(nxt_bool_t disassemble, nxt_bool_t verbose) +njs_timezone_optional_test(njs_opts_t *opts) { size_t size; u_char buf[16]; @@ -13978,8 +13984,7 @@ njs_timezone_optional_test(nxt_bool_t di size = strftime((char *) buf, sizeof(buf), "%z", &tm); if (memcmp(buf, "+1245", size) == 0) { - ret = njs_unit_test(njs_tz_test, nxt_nitems(njs_tz_test), 0, - disassemble, verbose); + ret = njs_unit_test(njs_tz_test, nxt_nitems(njs_tz_test), opts); if (ret != NXT_OK) { return ret; } @@ -13995,7 +14000,7 @@ njs_timezone_optional_test(nxt_bool_t di static nxt_int_t -njs_regexp_optional_test(nxt_bool_t disassemble, nxt_bool_t verbose) +njs_regexp_optional_test(njs_opts_t *opts) { int erroff; pcre *re1, *re2; @@ -14020,8 +14025,7 @@ njs_regexp_optional_test(nxt_bool_t disa &errstr, &erroff, NULL); if (re1 == NULL && re2 != NULL) { - ret = njs_unit_test(njs_regexp_test, nxt_nitems(njs_regexp_test), 0, - disassemble, verbose); + ret = njs_unit_test(njs_regexp_test, nxt_nitems(njs_regexp_test), opts); if (ret != NXT_OK) { return ret; } @@ -14045,7 +14049,7 @@ njs_regexp_optional_test(nxt_bool_t disa static nxt_int_t -njs_vm_json_test(nxt_bool_t disassemble, nxt_bool_t verbose) +njs_vm_json_test(njs_opts_t *opts) { njs_vm_t *vm; nxt_int_t ret, rc; @@ -14168,8 +14172,7 @@ done: static nxt_int_t -njs_vm_object_alloc_test(njs_vm_t * vm, nxt_bool_t disassemble, - nxt_bool_t verbose) +njs_vm_object_alloc_test(njs_vm_t * vm, njs_opts_t *opts) { njs_ret_t ret; njs_value_t args[2], obj; @@ -14206,8 +14209,7 @@ njs_vm_object_alloc_test(njs_vm_t * vm, static nxt_int_t -nxt_file_basename_test(njs_vm_t * vm, nxt_bool_t disassemble, - nxt_bool_t verbose) +nxt_file_basename_test(njs_vm_t * vm, njs_opts_t *opts) { nxt_str_t name; nxt_bool_t success; @@ -14249,8 +14251,7 @@ nxt_file_basename_test(njs_vm_t * vm, nx static nxt_int_t -nxt_file_dirname_test(njs_vm_t * vm, nxt_bool_t disassemble, - nxt_bool_t verbose) +nxt_file_dirname_test(njs_vm_t * vm, njs_opts_t *opts) { nxt_str_t name; nxt_bool_t success; @@ -14293,7 +14294,7 @@ nxt_file_dirname_test(njs_vm_t * vm, nxt static nxt_int_t -njs_api_test(nxt_bool_t disassemble, nxt_bool_t verbose) +njs_api_test(njs_opts_t *opts) { njs_vm_t *vm; nxt_int_t ret, rc; @@ -14301,7 +14302,7 @@ njs_api_test(nxt_bool_t disassemble, nxt njs_vm_opt_t options; static const struct { - nxt_int_t (*test)(njs_vm_t *, nxt_bool_t, nxt_bool_t); + nxt_int_t (*test)(njs_vm_t *, njs_opts_t *); nxt_str_t name; } tests[] = { { njs_vm_object_alloc_test, @@ -14324,7 +14325,7 @@ njs_api_test(nxt_bool_t disassemble, nxt goto done; } - ret = tests[i].test(vm, disassemble, verbose); + ret = tests[i].test(vm, opts); if (nxt_slow_path(ret != NXT_OK)) { nxt_printf("njs_api_test: \"%V\" test failed\n", &tests[i].name); goto done; @@ -14354,20 +14355,19 @@ int nxt_cdecl main(int argc, char **argv) { nxt_int_t ret; - nxt_bool_t disassemble, verbose; - - disassemble = 0; - verbose = 0; + njs_opts_t opts; + + nxt_memzero(&opts, sizeof(njs_opts_t)); if (argc > 1) { switch (argv[1][0]) { case 'd': - disassemble = 1; + opts.disassemble = 1; break; case 'v': - verbose = 1; + opts.verbose = 1; break; default: @@ -14380,36 +14380,39 @@ main(int argc, char **argv) /* script tests. */ - ret = njs_unit_test(njs_test, nxt_nitems(njs_test), 0, disassemble, - verbose); + ret = njs_unit_test(njs_test, nxt_nitems(njs_test), &opts); + if (ret != NXT_OK) { + return ret; + } + + ret = njs_timezone_optional_test(&opts); + if (ret != NXT_OK) { + return ret; + } + + ret = njs_regexp_optional_test(&opts); + if (ret != NXT_OK) { + return ret; + } + + ret = njs_vm_json_test(&opts); + if (ret != NXT_OK) { + return ret; + } + + ret = njs_api_test(&opts); if (ret != NXT_OK) { return ret; } /* module tests. */ - ret = njs_unit_test(njs_module_test, nxt_nitems(njs_module_test), 1, - disassemble, verbose); - if (ret != NXT_OK) { - return ret; - } - - ret = njs_timezone_optional_test(disassemble, verbose); - if (ret != NXT_OK) { - return ret; - } - - ret = njs_regexp_optional_test(disassemble, verbose); + opts.module = 1; + + ret = njs_unit_test(njs_module_test, nxt_nitems(njs_module_test), &opts); if (ret != NXT_OK) { return ret; } nxt_printf("njs unit tests passed\n"); - - ret = njs_vm_json_test(disassemble, verbose); - if (ret != NXT_OK) { - return ret; - } - - return njs_api_test(disassemble, verbose); } From xeioex at nginx.com Mon Jul 15 13:21:54 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 15 Jul 2019 13:21:54 +0000 Subject: [njs] Tests: reporting unit tests statistics. Message-ID: details: https://hg.nginx.org/njs/rev/e89f5a5709e0 branches: changeset: 1046:e89f5a5709e0 user: Dmitry Volyntsev date: Mon Jul 15 16:20:41 2019 +0300 description: Tests: reporting unit tests statistics. diffstat: njs/test/njs_unit_test.c | 168 +++++++++++++++++++++++++++++----------------- 1 files changed, 107 insertions(+), 61 deletions(-) diffs (399 lines): diff -r 9fc79481e32d -r e89f5a5709e0 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Jul 15 15:54:41 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon Jul 15 16:20:41 2019 +0300 @@ -13860,20 +13860,43 @@ typedef struct { } njs_opts_t; +typedef struct { + nxt_uint_t passed; + nxt_uint_t failed; +} njs_stat_t; + + +static void +njs_unit_test_report(const char *msg, njs_stat_t *prev, njs_stat_t *current) +{ + njs_stat_t stat; + + stat.failed = current->failed - prev->failed; + stat.passed = current->passed - prev->passed; + + nxt_printf("%s: %s [%d/%d]\n", msg, stat.failed ? "FAILED" : "PASSED", + stat.passed, stat.passed + stat.failed); +} + + static nxt_int_t -njs_unit_test(njs_unit_test_t tests[], size_t num, njs_opts_t *opts) +njs_unit_test(njs_unit_test_t tests[], size_t num, const char *name, + njs_opts_t *opts, njs_stat_t *stat) { u_char *start; njs_vm_t *vm, *nvm; nxt_int_t ret, rc; nxt_str_t s; nxt_uint_t i; + njs_stat_t prev; nxt_bool_t success; njs_vm_opt_t options; vm = NULL; nvm = NULL; + prev = *stat; + rc = NXT_ERROR; for (i = 0; i < num; i++) { @@ -13928,22 +13951,23 @@ njs_unit_test(njs_unit_test_t tests[], s success = nxt_strstr_eq(&tests[i].ret, &s); - if (success) { - if (nvm != NULL) { - njs_vm_destroy(nvm); - nvm = NULL; - } - - njs_vm_destroy(vm); - vm = NULL; - - continue; + if (!success) { + nxt_printf("njs(\"%V\")\nexpected: \"%V\"\n got: \"%V\"\n", + &tests[i].script, &tests[i].ret, &s); + + stat->failed++; + + } else { + stat->passed++; } - nxt_printf("njs(\"%V\")\nexpected: \"%V\"\n got: \"%V\"\n", - &tests[i].script, &tests[i].ret, &s); - - goto done; + if (nvm != NULL) { + njs_vm_destroy(nvm); + nvm = NULL; + } + + njs_vm_destroy(vm); + vm = NULL; } rc = NXT_OK; @@ -13958,12 +13982,14 @@ done: njs_vm_destroy(vm); } + njs_unit_test_report(name, &prev, stat); + return rc; } static nxt_int_t -njs_timezone_optional_test(njs_opts_t *opts) +njs_timezone_optional_test(njs_opts_t *opts, njs_stat_t *stat) { size_t size; u_char buf[16]; @@ -13984,13 +14010,12 @@ njs_timezone_optional_test(njs_opts_t *o size = strftime((char *) buf, sizeof(buf), "%z", &tm); if (memcmp(buf, "+1245", size) == 0) { - ret = njs_unit_test(njs_tz_test, nxt_nitems(njs_tz_test), opts); + ret = njs_unit_test(njs_tz_test, nxt_nitems(njs_tz_test), + "timezone tests", opts, stat); if (ret != NXT_OK) { return ret; } - nxt_printf("njs timezone tests passed\n"); - } else { nxt_printf("njs timezone tests skipped, timezone is unavailable\n"); } @@ -14000,7 +14025,7 @@ njs_timezone_optional_test(njs_opts_t *o static nxt_int_t -njs_regexp_optional_test(njs_opts_t *opts) +njs_regexp_optional_test(njs_opts_t *opts, njs_stat_t *stat) { int erroff; pcre *re1, *re2; @@ -14025,13 +14050,12 @@ njs_regexp_optional_test(njs_opts_t *opt &errstr, &erroff, NULL); if (re1 == NULL && re2 != NULL) { - ret = njs_unit_test(njs_regexp_test, nxt_nitems(njs_regexp_test), opts); + ret = njs_unit_test(njs_regexp_test, nxt_nitems(njs_regexp_test), + "unicode regexp tests", opts, stat); if (ret != NXT_OK) { return ret; } - nxt_printf("njs unicode regexp tests passed\n"); - } else { nxt_printf("njs unicode regexp tests skipped, libpcre fails\n"); } @@ -14049,15 +14073,16 @@ njs_regexp_optional_test(njs_opts_t *opt static nxt_int_t -njs_vm_json_test(njs_opts_t *opts) +njs_vm_json_test(njs_opts_t *opts, njs_stat_t *stat) { - njs_vm_t *vm; - nxt_int_t ret, rc; - nxt_str_t s, *script; - nxt_uint_t i; - nxt_bool_t success; - njs_value_t args[3]; - njs_vm_opt_t options; + njs_vm_t *vm; + nxt_int_t ret, rc; + nxt_str_t s, *script; + nxt_uint_t i; + nxt_bool_t success; + njs_stat_t prev; + njs_value_t args[3]; + njs_vm_opt_t options; static const nxt_str_t fname = nxt_string("replacer"); static const nxt_str_t iname = nxt_string("indent"); @@ -14081,6 +14106,8 @@ njs_vm_json_test(njs_opts_t *opts) vm = NULL; + prev = *stat; + rc = NXT_ERROR; for (i = 0; i < nxt_nitems(tests); i++) { @@ -14140,21 +14167,22 @@ njs_vm_json_test(njs_opts_t *opts) "expected: \"%V\"\n got: \"%V\"\n", script, &tests[i].ret, &s); - goto done; + stat->failed++; + + } else { + stat->passed++; } njs_vm_destroy(vm); vm = NULL; + } rc = NXT_OK; done: - if (rc == NXT_OK) { - nxt_printf("njs_vm_json_test passed\n"); - - } else { + if (rc != NXT_OK) { if (njs_vm_retval_string(vm, &s) != NXT_OK) { nxt_printf("njs_vm_retval_string() failed\n"); @@ -14163,6 +14191,8 @@ done: } } + njs_unit_test_report("VM json API tests", &prev, stat); + if (vm != NULL) { njs_vm_destroy(vm); } @@ -14172,7 +14202,7 @@ done: static nxt_int_t -njs_vm_object_alloc_test(njs_vm_t * vm, njs_opts_t *opts) +njs_vm_object_alloc_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat) { njs_ret_t ret; njs_value_t args[2], obj; @@ -14201,15 +14231,18 @@ njs_vm_object_alloc_test(njs_vm_t * vm, ret = njs_vm_object_alloc(vm, &obj, &num_key, &args[0], &bool_key, &args[1], NULL); if (ret != NJS_OK) { - return NXT_ERROR; + stat->failed++; + return NXT_OK; } + stat->passed++; + return NXT_OK; } static nxt_int_t -nxt_file_basename_test(njs_vm_t * vm, njs_opts_t *opts) +nxt_file_basename_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat) { nxt_str_t name; nxt_bool_t success; @@ -14242,7 +14275,11 @@ nxt_file_basename_test(njs_vm_t * vm, nj nxt_printf("nxt_file_basename_test(\"%V\"):\n" "expected: \"%V\"\n got: \"%V\"\n", &tests[i].path, &tests[i].expected, &name); - return NXT_ERROR; + + stat->failed++; + + } else { + stat->passed++; } } @@ -14251,7 +14288,7 @@ nxt_file_basename_test(njs_vm_t * vm, nj static nxt_int_t -nxt_file_dirname_test(njs_vm_t * vm, njs_opts_t *opts) +nxt_file_dirname_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat) { nxt_str_t name; nxt_bool_t success; @@ -14285,8 +14322,12 @@ nxt_file_dirname_test(njs_vm_t * vm, njs nxt_printf("nxt_file_dirname_test(\"%V\"):\n" "expected: \"%V\"\n got: \"%V\"\n", &tests[i].path, &tests[i].expected, &name); - return NXT_ERROR; + + stat->failed++; + } else { + stat->passed++; } + } return NXT_OK; @@ -14294,15 +14335,16 @@ nxt_file_dirname_test(njs_vm_t * vm, njs static nxt_int_t -njs_api_test(njs_opts_t *opts) +njs_api_test(njs_opts_t *opts, njs_stat_t *stat) { njs_vm_t *vm; nxt_int_t ret, rc; nxt_uint_t i; + njs_stat_t prev; njs_vm_opt_t options; static const struct { - nxt_int_t (*test)(njs_vm_t *, njs_opts_t *); + nxt_int_t (*test)(njs_vm_t *, njs_opts_t *, njs_stat_t *stat); nxt_str_t name; } tests[] = { { njs_vm_object_alloc_test, @@ -14313,11 +14355,13 @@ njs_api_test(njs_opts_t *opts) nxt_string("nxt_file_dirname_test") }, }; - rc = NXT_ERROR; - vm = NULL; nxt_memzero(&options, sizeof(njs_vm_opt_t)); + prev = *stat; + + rc = NXT_ERROR; + for (i = 0; i < nxt_nitems(tests); i++) { vm = njs_vm_create(&options); if (vm == NULL) { @@ -14325,7 +14369,7 @@ njs_api_test(njs_opts_t *opts) goto done; } - ret = tests[i].test(vm, opts); + ret = tests[i].test(vm, opts, stat); if (nxt_slow_path(ret != NXT_OK)) { nxt_printf("njs_api_test: \"%V\" test failed\n", &tests[i].name); goto done; @@ -14339,9 +14383,7 @@ njs_api_test(njs_opts_t *opts) done: - if (rc == NXT_OK) { - nxt_printf("njs_api_test passed\n"); - } + njs_unit_test_report("API tests", &prev, stat); if (vm != NULL) { njs_vm_destroy(vm); @@ -14356,6 +14398,7 @@ main(int argc, char **argv) { nxt_int_t ret; njs_opts_t opts; + njs_stat_t stat; nxt_memzero(&opts, sizeof(njs_opts_t)); @@ -14378,41 +14421,44 @@ main(int argc, char **argv) (void) putenv((char *) "TZ=UTC"); tzset(); - /* script tests. */ - - ret = njs_unit_test(njs_test, nxt_nitems(njs_test), &opts); + nxt_memzero(&stat, sizeof(njs_stat_t)); + + ret = njs_unit_test(njs_test, nxt_nitems(njs_test), "script tests", + &opts, &stat); if (ret != NXT_OK) { return ret; } - ret = njs_timezone_optional_test(&opts); + ret = njs_timezone_optional_test(&opts, &stat); if (ret != NXT_OK) { return ret; } - ret = njs_regexp_optional_test(&opts); + ret = njs_regexp_optional_test(&opts, &stat); if (ret != NXT_OK) { return ret; } - ret = njs_vm_json_test(&opts); + ret = njs_vm_json_test(&opts, &stat); if (ret != NXT_OK) { return ret; } - ret = njs_api_test(&opts); + ret = njs_api_test(&opts, &stat); if (ret != NXT_OK) { return ret; } - /* module tests. */ - opts.module = 1; - ret = njs_unit_test(njs_module_test, nxt_nitems(njs_module_test), &opts); + ret = njs_unit_test(njs_module_test, nxt_nitems(njs_module_test), + "module tests", &opts, &stat); if (ret != NXT_OK) { return ret; } - nxt_printf("njs unit tests passed\n"); + nxt_printf("TOTAL: %s [%ui/%ui]\n", stat.failed ? "FAILED" : "PASSED", + stat.passed, stat.passed + stat.failed); + + return stat.failed ? EXIT_FAILURE : EXIT_SUCCESS; } From alexander.borisov at nginx.com Mon Jul 15 14:45:45 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Mon, 15 Jul 2019 14:45:45 +0000 Subject: [njs] Fixed incorrect optimization in njs_string_to_c_string(). Message-ID: details: https://hg.nginx.org/njs/rev/3b3e3c133d13 branches: changeset: 1047:3b3e3c133d13 user: Alexander Borisov date: Mon Jul 15 17:45:23 2019 +0300 description: Fixed incorrect optimization in njs_string_to_c_string(). diffstat: njs/njs_string.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (14 lines): diff -r e89f5a5709e0 -r 3b3e3c133d13 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 15 16:20:41 2019 +0300 +++ b/njs/njs_string.c Mon Jul 15 17:45:23 2019 +0300 @@ -3942,10 +3942,6 @@ njs_string_to_c_string(njs_vm_t *vm, njs } else { start = value->long_string.data->start; size = value->long_string.size; - - if (start[size] == '\0') { - return start; - } } data = nxt_mp_alloc(vm->mem_pool, size + 1); From xeioex at nginx.com Mon Jul 15 15:10:29 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 15 Jul 2019 15:10:29 +0000 Subject: [njs] Added memory-sanitizer support. Message-ID: details: https://hg.nginx.org/njs/rev/3594adcc9b05 branches: changeset: 1048:3594adcc9b05 user: Dmitry Volyntsev date: Mon Jul 15 17:46:37 2019 +0300 description: Added memory-sanitizer support. diffstat: auto/clang | 13 +++++++++++++ njs/test/njs_unit_test.c | 16 ++++++++++++++++ nxt/nxt_clang.h | 7 +++++++ 3 files changed, 36 insertions(+), 0 deletions(-) diffs (147 lines): diff -r 3b3e3c133d13 -r 3594adcc9b05 auto/clang --- a/auto/clang Mon Jul 15 17:45:23 2019 +0300 +++ b/auto/clang Mon Jul 15 17:46:37 2019 +0300 @@ -304,6 +304,19 @@ else fi +nxt_feature="Memory sanitizer" +nxt_feature_name=NXT_HAVE_MEMORY_SANITIZER +nxt_feature_run=yes +nxt_feature_incs= +nxt_feature_libs= +nxt_feature_test="#include + int main(int argc, char *argv[]) { + __msan_unpoison(argv, sizeof(char *)); + return 0; + }" +. auto/feature + + nxt_feature="NAN to uint conversion" nxt_feature_name=NXT_NAN_TO_UINT_CONVERSION nxt_feature_run=value diff -r 3b3e3c133d13 -r 3594adcc9b05 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Jul 15 17:45:23 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon Jul 15 17:46:37 2019 +0300 @@ -4,6 +4,8 @@ * Copyright (C) NGINX, Inc. */ +#include + #include #include #include @@ -5229,6 +5231,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("String.fromCharCode(945, 946, 947)"), nxt_string("???") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long test under MSAN */ { nxt_string("(function() {" " var n;" " for (n = 0; n <= 1114111; n++) {" @@ -5238,6 +5241,7 @@ static njs_unit_test_t njs_test[] = " return -1" "})()"), nxt_string("-1") }, +#endif { nxt_string("var a = 'abcdef'; function f(a) {" "return a.slice(a.indexOf('cd')) } f(a)"), @@ -5436,6 +5440,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\x00?????????'.toUpperCase().length"), nxt_string("10") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long test under MSAN */ { nxt_string("var a = [], code;" "for (code = 0; code <= 1114111; code++) {" " var s = String.fromCharCode(code);" @@ -5453,6 +5458,7 @@ static njs_unit_test_t njs_test[] = " a.push(code);" "} a"), nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, +#endif { nxt_string("'abc'.trim()"), nxt_string("abc") }, @@ -7449,8 +7455,10 @@ static njs_unit_test_t njs_test[] = { nxt_string("/abc/i.test('ABC')"), nxt_string("true") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* FIXME */ { nxt_string("/???/i.test('???')"), nxt_string("true") }, +#endif { nxt_string("/\\x80/.test('\\u0080')"), nxt_string("true") }, @@ -7483,11 +7491,13 @@ static njs_unit_test_t njs_test[] = { nxt_string("var r = /3/g; r.exec('123') +' '+ r.exec('3')"), nxt_string("3 null") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* FIXME */ { nxt_string("var r = /??/ig;" "var a = r.exec('???');" "r.lastIndex +' '+ a +' '+ " "r.source +' '+ r.source.length +' '+ r"), nxt_string("3 ?? ?? 2 /??/gi") }, +#endif { nxt_string("var r = /\\x80/g; r.exec('\\u0081\\u0080'.toBytes());" "r.lastIndex +' '+ r.source +' '+ r.source.length +' '+ r"), @@ -7498,10 +7508,12 @@ static njs_unit_test_t njs_test[] = * It fails at least in 8.1 and works at least in 8.31. */ +#if (!NXT_HAVE_MEMORY_SANITIZER) /* FIXME */ { nxt_string("var r = /????/ig;" "var a = r.exec('???????????????????????????????????');" "r.lastIndex +' '+ a +' '+ r.source +' '+ r"), nxt_string("35 ???? ???? /????/gi") }, +#endif { nxt_string("var r = /quick\\s(brown).+?(jumps)/ig;" "var a = r.exec('The Quick Brown Fox Jumps Over The Lazy Dog');" @@ -7513,6 +7525,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var r = /a/.exec('a'); ['groups' in r, typeof r.groups]"), nxt_string("true,undefined") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* PCRE bug in groups code */ { nxt_string("var r = /(?[0-9]{2})\\/(?[0-9]{2})\\/(?[0-9]{4})/;" "var g = r.exec('12/31/1986').groups;" "g.d + '.' + g.m + '.' + g.y"), @@ -7521,6 +7534,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var g = /(?(?no)?(?yes)?)/.exec('yes').groups;" "[Object.keys(g).length,'no' in g, typeof g.no, g.yes, g.r]"), nxt_string("3,true,undefined,yes,yes") }, +#endif { nxt_string("var s; var r = /./g; while (s = r.exec('abc')); s"), nxt_string("null") }, @@ -11564,8 +11578,10 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow(-3, 0.1)"), nxt_string("NaN") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* intentional use of uninitialized stack */ { nxt_string("var a = Math.random(); a >= 0 && a < 1"), nxt_string("true") }, +#endif { nxt_string("Math.round()"), nxt_string("NaN") }, diff -r 3b3e3c133d13 -r 3594adcc9b05 nxt/nxt_clang.h --- a/nxt/nxt_clang.h Mon Jul 15 17:45:23 2019 +0300 +++ b/nxt/nxt_clang.h Mon Jul 15 17:46:37 2019 +0300 @@ -150,4 +150,11 @@ nxt_leading_zeros64(uint64_t x) #endif +#if (NXT_HAVE_MEMORY_SANITIZER) +#include + +#define nxt_msan_unpoison(ptr, size) __msan_unpoison(ptr, size) +#endif + + #endif /* _NXT_CLANG_H_INCLUDED_ */ From xeioex at nginx.com Mon Jul 15 17:23:30 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 15 Jul 2019 17:23:30 +0000 Subject: [njs] Unifying makefile target names. Message-ID: details: https://hg.nginx.org/njs/rev/18396fcfd53b branches: changeset: 1050:18396fcfd53b user: Dmitry Volyntsev date: Mon Jul 15 19:20:55 2019 +0300 description: Unifying makefile target names. diffstat: auto/expect | 4 ++-- auto/make | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (33 lines): diff -r d1fb99f23174 -r 18396fcfd53b auto/expect --- a/auto/expect Mon Jul 15 18:46:31 2019 +0300 +++ b/auto/expect Mon Jul 15 19:20:55 2019 +0300 @@ -20,7 +20,7 @@ fi if [ $nxt_found = yes -a $NXT_HAVE_READLINE = YES ]; then cat << END >> $NXT_MAKEFILE -njs_expect_test: njs njs/test/njs_expect_test.exp +expect_test: njs njs/test/njs_expect_test.exp INPUTRC=njs/test/inputrc PATH=$NXT_BUILD_DIR:\$(PATH) \ expect -f njs/test/njs_expect_test.exp END @@ -30,7 +30,7 @@ else cat << END >> $NXT_MAKEFILE -njs_expect_test: +expect_test: @echo "Skipping expect tests" END diff -r d1fb99f23174 -r 18396fcfd53b auto/make --- a/auto/make Mon Jul 15 18:46:31 2019 +0300 +++ b/auto/make Mon Jul 15 19:20:55 2019 +0300 @@ -244,7 +244,7 @@ unit_test: $NXT_BUILD_DIR/nxt_auto_confi $NXT_BUILD_DIR/njs_unit_test $NXT_BUILD_DIR/njs_interactive_test -test: njs_expect_test unit_test +test: expect_test unit_test benchmark: $NXT_BUILD_DIR/nxt_auto_config.h \\ $NXT_BUILD_DIR/njs_benchmark From xeioex at nginx.com Mon Jul 15 17:23:29 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 15 Jul 2019 17:23:29 +0000 Subject: [njs] Added unit_test target. Message-ID: details: https://hg.nginx.org/njs/rev/d1fb99f23174 branches: changeset: 1049:d1fb99f23174 user: Dmitry Volyntsev date: Mon Jul 15 18:46:31 2019 +0300 description: Added unit_test target. diffstat: auto/make | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 3594adcc9b05 -r d1fb99f23174 auto/make --- a/auto/make Mon Jul 15 17:46:37 2019 +0300 +++ b/auto/make Mon Jul 15 18:46:31 2019 +0300 @@ -237,14 +237,15 @@ lib_test: $NXT_BUILD_DIR/nxt_auto_config $NXT_BUILD_DIR/lvlhsh_unit_test $NXT_BUILD_DIR/utf8_unit_test -test: $NXT_BUILD_DIR/nxt_auto_config.h \\ - njs_expect_test \\ +unit_test: $NXT_BUILD_DIR/nxt_auto_config.h \\ $NXT_BUILD_DIR/njs_unit_test \\ $NXT_BUILD_DIR/njs_interactive_test $NXT_BUILD_DIR/njs_unit_test $NXT_BUILD_DIR/njs_interactive_test +test: njs_expect_test unit_test + benchmark: $NXT_BUILD_DIR/nxt_auto_config.h \\ $NXT_BUILD_DIR/njs_benchmark From xeioex at nginx.com Tue Jul 16 10:01:11 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 16 Jul 2019 10:01:11 +0000 Subject: [njs] Avoiding aligned attribute detection skip on ppc64le platforms. Message-ID: details: https://hg.nginx.org/njs/rev/f98e8a101b02 branches: changeset: 1051:f98e8a101b02 user: Dmitry Volyntsev date: Tue Jul 16 12:57:29 2019 +0300 description: Avoiding aligned attribute detection skip on ppc64le platforms. diffstat: auto/clang | 33 ++++++++++----------------------- 1 files changed, 10 insertions(+), 23 deletions(-) diffs (44 lines): diff -r 18396fcfd53b -r f98e8a101b02 auto/clang --- a/auto/clang Mon Jul 15 19:20:55 2019 +0300 +++ b/auto/clang Tue Jul 16 12:57:29 2019 +0300 @@ -278,30 +278,17 @@ nxt_feature_test="#include . auto/feature -nxt_os="$NXT_SYSTEM/$NXT_SYSTEM_PLATFORM" - -if [ "$nxt_os" = "Linux/ppc64le" ]; then - - # Old GNU ld linker may hang on Linux ppc64le platform - # if some of these features are enabled. - - echo "checking for GCC __attribute__ aligned is disabled for $nxt_os." - -else +nxt_feature="GCC __attribute__ aligned" +nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_ALIGNED +nxt_feature_run=no +nxt_feature_path= +nxt_feature_libs= +nxt_feature_test="int n __attribute__ ((aligned(64))); - nxt_feature="GCC __attribute__ aligned" - nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_ALIGNED - nxt_feature_run=no - nxt_feature_path= - nxt_feature_libs= - nxt_feature_test="int n __attribute__ ((aligned(64))); - - int main(void) { - return 0; - }" - . auto/feature - -fi + int main(void) { + return 0; + }" +. auto/feature nxt_feature="Memory sanitizer" From alexander.borisov at nginx.com Tue Jul 16 14:32:51 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Tue, 16 Jul 2019 14:32:51 +0000 Subject: [njs] Fixed String.prototype.replace() for byte strings with regex arg. Message-ID: details: https://hg.nginx.org/njs/rev/9e6098cb3b2e branches: changeset: 1052:9e6098cb3b2e user: Alexander Borisov date: Tue Jul 16 17:32:10 2019 +0300 description: Fixed String.prototype.replace() for byte strings with regex arg. diffstat: njs/njs_string.c | 3 ++- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletions(-) diffs (26 lines): diff -r f98e8a101b02 -r 9e6098cb3b2e njs/njs_string.c --- a/njs/njs_string.c Tue Jul 16 12:57:29 2019 +0300 +++ b/njs/njs_string.c Tue Jul 16 17:32:10 2019 +0300 @@ -3160,7 +3160,8 @@ njs_string_replace_regexp(njs_vm_t *vm, start = r->part[0].start; if (start < end) { - p = (u_char *) nxt_utf8_next(start, end); + p = (r->utf8 != NJS_STRING_BYTE) + ? (u_char *) nxt_utf8_next(start, end) : start + 1; r->part[1].start = start; r->part[1].size = p - start; diff -r f98e8a101b02 -r 9e6098cb3b2e njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 16 12:57:29 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue Jul 16 17:32:10 2019 +0300 @@ -5681,6 +5681,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("typeof '0'.replace(/^/g, '$0')"), nxt_string("string") }, + { nxt_string("typeof String.bytesFrom(Array(15).fill(0xE3)).replace(/^/g, 1)"), + nxt_string("string") }, + { nxt_string("/]/"), nxt_string("/\\]/") }, From alexander.borisov at nginx.com Tue Jul 16 14:32:51 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Tue, 16 Jul 2019 14:32:51 +0000 Subject: [njs] Fixed String.prototype.match() for byte strings with regex arg. Message-ID: details: https://hg.nginx.org/njs/rev/8ac396f1a20c branches: changeset: 1053:8ac396f1a20c user: Alexander Borisov date: Tue Jul 16 17:32:11 2019 +0300 description: Fixed String.prototype.match() for byte strings with regex arg. diffstat: njs/njs_string.c | 3 ++- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletions(-) diffs (26 lines): diff -r 9e6098cb3b2e -r 8ac396f1a20c njs/njs_string.c --- a/njs/njs_string.c Tue Jul 16 17:32:10 2019 +0300 +++ b/njs/njs_string.c Tue Jul 16 17:32:11 2019 +0300 @@ -2757,7 +2757,8 @@ njs_string_match_multiple(njs_vm_t *vm, if (captures[1] == 0) { if (start < end) { - p = nxt_utf8_next(start, end); + p = (utf8 != NJS_STRING_BYTE) ? nxt_utf8_next(start, end) + : start + 1; string.size = end - p; } else { diff -r 9e6098cb3b2e -r 8ac396f1a20c njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 16 17:32:10 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue Jul 16 17:32:11 2019 +0300 @@ -5832,6 +5832,9 @@ static njs_unit_test_t njs_test[] = "a +' '+ a.length"), nxt_string("?? 4") }, + { nxt_string("typeof String.bytesFrom(Array(15).fill(0xE3)).match(/^/g)"), + nxt_string("object") }, + { nxt_string("'abc'.split()"), nxt_string("abc") }, From alexander.borisov at nginx.com Tue Jul 16 14:32:51 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Tue, 16 Jul 2019 14:32:51 +0000 Subject: [njs] Fixed parsing of "$&" substitutions in String.prototype.replace(). Message-ID: details: https://hg.nginx.org/njs/rev/738f2410b532 branches: changeset: 1054:738f2410b532 user: Alexander Borisov date: Tue Jul 16 17:32:11 2019 +0300 description: Fixed parsing of "$&" substitutions in String.prototype.replace(). diffstat: njs/njs_string.c | 3 --- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diffs (26 lines): diff -r 8ac396f1a20c -r 738f2410b532 njs/njs_string.c --- a/njs/njs_string.c Tue Jul 16 17:32:11 2019 +0300 +++ b/njs/njs_string.c Tue Jul 16 17:32:11 2019 +0300 @@ -3513,9 +3513,6 @@ skip: type *= 2; - } else if (c == '&') { - type = 0; - } else if (c == '`') { type = NJS_SUBST_PRECEDING; diff -r 8ac396f1a20c -r 738f2410b532 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 16 17:32:11 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue Jul 16 17:32:11 2019 +0300 @@ -5684,6 +5684,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("typeof String.bytesFrom(Array(15).fill(0xE3)).replace(/^/g, 1)"), nxt_string("string") }, + { nxt_string("typeof '0'.replace(/^/g, '$&')"), + nxt_string("string") }, + { nxt_string("/]/"), nxt_string("/\\]/") }, From alexander.borisov at nginx.com Tue Jul 16 14:32:51 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Tue, 16 Jul 2019 14:32:51 +0000 Subject: [njs] Fixed String.prototype.substring() with empty substring. Message-ID: details: https://hg.nginx.org/njs/rev/84eda5521a44 branches: changeset: 1055:84eda5521a44 user: Alexander Borisov date: Tue Jul 16 17:32:12 2019 +0300 description: Fixed String.prototype.substring() with empty substring. diffstat: njs/njs_string.c | 4 ++-- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diffs (29 lines): diff -r 738f2410b532 -r 84eda5521a44 njs/njs_string.c --- a/njs/njs_string.c Tue Jul 16 17:32:11 2019 +0300 +++ b/njs/njs_string.c Tue Jul 16 17:32:12 2019 +0300 @@ -1357,10 +1357,10 @@ njs_string_slice_string_prop(njs_string_ p = start; n = length; - do { + while (n != 0 && p < end) { p = nxt_utf8_next(p, end); n--; - } while (n != 0 && p < end); + } size = p - start; length -= n; diff -r 738f2410b532 -r 84eda5521a44 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 16 17:32:11 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue Jul 16 17:32:12 2019 +0300 @@ -4822,6 +4822,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abcdefgh'.substring(100, 120)"), nxt_string("") }, + { nxt_string("'?'.repeat(32).substring(32)"), + nxt_string("") }, + { nxt_string("'abcdefghijklmno'.slice(NaN, 5)"), nxt_string("abcde") }, From xeioex at nginx.com Wed Jul 17 13:28:39 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 17 Jul 2019 13:28:39 +0000 Subject: [njs] Using hand-written nxt_explicit_memzero() with memory-sanitizer. Message-ID: details: https://hg.nginx.org/njs/rev/377db9ae390d branches: changeset: 1056:377db9ae390d user: Dmitry Volyntsev date: Wed Jul 17 16:28:30 2019 +0300 description: Using hand-written nxt_explicit_memzero() with memory-sanitizer. To avoid false-positive results. diffstat: nxt/nxt_string.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 84eda5521a44 -r 377db9ae390d nxt/nxt_string.h --- a/nxt/nxt_string.h Tue Jul 16 17:32:12 2019 +0300 +++ b/nxt/nxt_string.h Wed Jul 17 16:28:30 2019 +0300 @@ -87,7 +87,7 @@ nxt_memzero(buf, length) (void) memset(buf, 0, length) -#if (NXT_HAVE_EXPLICIT_BZERO) +#if (NXT_HAVE_EXPLICIT_BZERO && !NXT_HAVE_MEMORY_SANITIZER) #define \ nxt_explicit_memzero(buf, length) \ explicit_bzero(buf, length) From mdounin at mdounin.ru Wed Jul 17 14:01:54 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 17 Jul 2019 14:01:54 +0000 Subject: [nginx] Perl: removed unused variable, forgotten in 975d7ab37b39. Message-ID: details: https://hg.nginx.org/nginx/rev/56b4fb46ba7d branches: changeset: 7535:56b4fb46ba7d user: Maxim Dounin date: Wed Jul 17 17:00:57 2019 +0300 description: Perl: removed unused variable, forgotten in 975d7ab37b39. diffstat: src/http/modules/perl/nginx.xs | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -933,7 +933,6 @@ internal_redirect(r, uri) ngx_http_request_t *r; ngx_http_perl_ctx_t *ctx; SV *uri; - ngx_uint_t i; ngx_http_perl_set_request(r, ctx); From eran.kornblau at kaltura.com Wed Jul 17 14:35:02 2019 From: eran.kornblau at kaltura.com (Eran Kornblau) Date: Wed, 17 Jul 2019 14:35:02 +0000 Subject: Question about ngx_handle_write_event In-Reply-To: <20190703010425.GL1877@mdounin.ru> References: <20190703010425.GL1877@mdounin.ru> Message-ID: > > Hello! > > On Mon, Jul 01, 2019 at 07:23:11PM +0000, Eran Kornblau wrote: > > > Something is unclear to me regarding the use of this function, the > > development guide says - "the functions ngx_handle_read_event(rev, > > flags) and ngx_handle_write_event(wev, lowat) must be called after handling an I/O socket notification or calling any I/O functions on that socket" > > > > If my module finished sending all the data it had, and is now waiting > > for more data to arrive (on some other socket) does it still have to call ngx_handle_write_event? > > Yes. In particular, this is required with level-tiggered event methods, such as select and poll, to remove the socket from the event list if it was previously added there. > Thank you, Maxim. I'm looking at ngx_ssl_ocsp_write_handler, and I see that ngx_handle_write_event is called only when the request is fully sent - it is not called in case of NGX_AGAIN / partial send. Is this a bug, or am I still missing something? Also, isn't there a need to call ngx_send repeatedly in a loop, if it somehow returns n < size? (I see there is such a loop in ngx_linux_sendfile_chain for example) Thanks again, Eran > -- > Maxim Dounin > https://eur02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmdounin.ru%2F&data=02%7C01%7Ceran.kornblau%40kaltura.com%7Cca0c3fc4e662486d250f08d6ff526888%7C0c503748de3f4e2597e26819d53a42b6%7C0%7C0%7C636977126739804073&sdata=Gw248oHqO6ojiJelD70OYUwQCrjdreGQWU%2BtFcRsMTA%3D&reserved=0 > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > https://eur02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmailman.nginx.org%2Fmailman%2Flistinfo%2Fnginx-devel&data=02%7C01%7Ceran.kornblau%40kaltura.com%7Cca0c3fc4e662486d250f08d6ff526888%7C0c503748de3f4e2597e26819d53a42b6%7C0%7C0%7C636977126739804073&sdata=Ils4vNfi01%2BW6ciLmOOK%2BniHIQhJoL5%2BjrDua0diycQ%3D&reserved=0 > From alexander.borisov at nginx.com Wed Jul 17 15:21:26 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Wed, 17 Jul 2019 15:21:26 +0000 Subject: [njs] Added support '$&' substitution in String.prototype.replace(). Message-ID: details: https://hg.nginx.org/njs/rev/0960f0568b94 branches: changeset: 1057:0960f0568b94 user: Alexander Borisov date: Wed Jul 17 14:24:00 2019 +0300 description: Added support '$&' substitution in String.prototype.replace(). diffstat: njs/njs_string.c | 25 ++++++++++++++----------- njs/test/njs_unit_test.c | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 15 deletions(-) diffs (119 lines): diff -r 377db9ae390d -r 0960f0568b94 njs/njs_string.c --- a/njs/njs_string.c Wed Jul 17 16:28:30 2019 +0300 +++ b/njs/njs_string.c Wed Jul 17 14:24:00 2019 +0300 @@ -3516,6 +3516,9 @@ skip: } else if (c == '`') { type = NJS_SUBST_PRECEDING; + } else if (c == '&') { + type = 0; + } else if (c == '\'') { type = NJS_SUBST_FOLLOWING; @@ -3540,12 +3543,13 @@ static njs_ret_t njs_string_replace_substitute(njs_vm_t *vm, njs_string_replace_t *r, int *captures) { - uint32_t i, n, last, index; + int *capture; + uint32_t i, n, last; const u_char *end; njs_string_subst_t *s; njs_string_replace_part_t *part, *subject; - index = 0; + capture = NULL; last = r->substitutions->items; end = r->part[0].start + r->part[0].size; @@ -3607,15 +3611,14 @@ njs_string_replace_substitute(njs_vm_t * break; /* - * "$n" substitutions. - * "$&" is the same as "$0", the "$0" however is not supported. + * "$n" and "$&" substitutions. */ default: if (captures[n] == captures[n + 1]) { /* Empty match. */ - if (captures[n - 1] == captures[n]) { + if (n > 0 && captures[n - 1] == captures[n]) { /* * Consecutive empty matches as in @@ -3626,11 +3629,11 @@ njs_string_replace_substitute(njs_vm_t * break; } - index = n; + capture = &captures[n]; continue; } - if (index != 0) { + if (capture != NULL) { /* * Inserting a single character after a series of @@ -3638,14 +3641,14 @@ njs_string_replace_substitute(njs_vm_t * */ if (part->start < end) { - part->start = r->part[0].start + captures[index]; + part->start = r->part[0].start + *capture; part->size = nxt_utf8_next(part->start, end) - part->start; } else { part->size = 0; } - index = 0; + capture = NULL; break; } @@ -3658,8 +3661,8 @@ njs_string_replace_substitute(njs_vm_t * part++; } - if (index != 0) { - part->start = r->part[0].start + captures[index]; + if (capture != NULL) { + part->start = r->part[0].start + *capture; if (part->start < end) { part->size = nxt_utf8_next(part->start, end) - part->start; diff -r 377db9ae390d -r 0960f0568b94 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Jul 17 16:28:30 2019 +0300 +++ b/njs/test/njs_unit_test.c Wed Jul 17 14:24:00 2019 +0300 @@ -5681,14 +5681,22 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc'.replace(/(a*)/g, function v0() {return '124'})"), nxt_string("124124b124c124") }, - { nxt_string("typeof '0'.replace(/^/g, '$0')"), - nxt_string("string") }, + { nxt_string("'abc'.replace(/b/g, '$0')"), + nxt_string("a$0c") }, { nxt_string("typeof String.bytesFrom(Array(15).fill(0xE3)).replace(/^/g, 1)"), nxt_string("string") }, - { nxt_string("typeof '0'.replace(/^/g, '$&')"), - nxt_string("string") }, +#if 0 /* FIXME: PCRE limitation */ + { nxt_string("'abc'.replace(/^/g, '|$&|')"), + nxt_string("||abc") }, +#endif + + { nxt_string("'abc'.replace(/b/g, '|$&|')"), + nxt_string("a|b|c") }, + + { nxt_string("'ABC'.replace(/((A)B)/g, '($1|$&|$2)')"), + nxt_string("(AB|AB|A)C") }, { nxt_string("/]/"), nxt_string("/\\]/") }, From mdounin at mdounin.ru Wed Jul 17 16:02:38 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 17 Jul 2019 19:02:38 +0300 Subject: Question about ngx_handle_write_event In-Reply-To: References: <20190703010425.GL1877@mdounin.ru> Message-ID: <20190717160238.GV1877@mdounin.ru> Hello! On Wed, Jul 17, 2019 at 02:35:02PM +0000, Eran Kornblau wrote: > > > > Hello! > > > > On Mon, Jul 01, 2019 at 07:23:11PM +0000, Eran Kornblau wrote: > > > > > Something is unclear to me regarding the use of this function, the > > > development guide says - "the functions ngx_handle_read_event(rev, > > > flags) and ngx_handle_write_event(wev, lowat) must be called after handling an I/O socket notification or calling any I/O functions on that socket" > > > > > > If my module finished sending all the data it had, and is now waiting > > > for more data to arrive (on some other socket) does it still have to call ngx_handle_write_event? > > > > Yes. In particular, this is required with level-tiggered event methods, such as select and poll, to remove the socket from the event list if it was previously added there. > > > > Thank you, Maxim. > > I'm looking at ngx_ssl_ocsp_write_handler, and I see that ngx_handle_write_event is called only when the request is fully sent - > it is not called in case of NGX_AGAIN / partial send. > Is this a bug, or am I still missing something? Sort of. As write event is initially added when a connection is created, and never removed by the relevant code - ngx_handle_write_event() is not needed unless we've sent all the request and want to disable the event. That is, this shouldn't be a problem with currrent code, as everything will work as intended. In more complex code ngx_handle_write_event() call is likely to be required after all write events, not just when you've done with writing. This might be a bug with oneshot events though, but oneshot events are buggy regardless of this particular problem. > Also, isn't there a need to call ngx_send repeatedly in a loop, if it somehow returns n < size? > (I see there is such a loop in ngx_linux_sendfile_chain for example) No. Calling send functions again is only needed to handle EINTR signals, and this is something nginx low-level functions do for you. -- Maxim Dounin http://mdounin.ru/ From alexander.borisov at nginx.com Thu Jul 18 13:18:48 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Thu, 18 Jul 2019 13:18:48 +0000 Subject: [njs] Fixed typo in njs_parser_string_create() introduced in f1a70d67646d. Message-ID: details: https://hg.nginx.org/njs/rev/57cf608a29b5 branches: changeset: 1058:57cf608a29b5 user: Alexander Borisov date: Thu Jul 18 16:18:19 2019 +0300 description: Fixed typo in njs_parser_string_create() introduced in f1a70d67646d. diffstat: njs/njs_parser_terminal.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0960f0568b94 -r 57cf608a29b5 njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Wed Jul 17 14:24:00 2019 +0300 +++ b/njs/njs_parser_terminal.c Thu Jul 18 16:18:19 2019 +0300 @@ -931,7 +931,7 @@ njs_parser_string_create(njs_vm_t *vm, n dst = nxt_utf8_encode(dst, cp); } - if (size > NJS_STRING_MAP_STRIDE && size != length) { + if (length > NJS_STRING_MAP_STRIDE && size != length) { njs_string_offset_map_init(value->long_string.data->start, size); } From mdounin at mdounin.ru Thu Jul 18 15:28:35 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 Jul 2019 15:28:35 +0000 Subject: [nginx] Core: fixed segfault with too large bucket sizes (ticket #1806). Message-ID: details: https://hg.nginx.org/nginx/rev/c3f60d618c17 branches: changeset: 7536:c3f60d618c17 user: Maxim Dounin date: Thu Jul 18 18:27:44 2019 +0300 description: Core: fixed segfault with too large bucket sizes (ticket #1806). To save memory hash code uses u_short to store resulting bucket sizes, so maximum bucket size is limited to 65536 minus ngx_cacheline_size (larger values will be aligned to 65536 which will overflow u_short). However, there were no checks to enforce this, and using larger bucket sizes resulted in overflows and segmentation faults. Appropriate safety checks to enforce this added to ngx_hash_init(). diffstat: src/core/ngx_hash.c | 30 +++++++++++++++++++++++++----- 1 files changed, 25 insertions(+), 5 deletions(-) diffs (61 lines): diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c --- a/src/core/ngx_hash.c +++ b/src/core/ngx_hash.c @@ -265,6 +265,14 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng return NGX_ERROR; } + if (hinit->bucket_size > 65536 - ngx_cacheline_size) { + ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, + "could not build %s, too large " + "%s_bucket_size: %i", + hinit->name, hinit->name, hinit->bucket_size); + return NGX_ERROR; + } + for (n = 0; n < nelts; n++) { if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *)) { @@ -300,17 +308,19 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng } key = names[n].key_hash % size; - test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); + len = test[key] + NGX_HASH_ELT_SIZE(&names[n]); #if 0 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, - "%ui: %ui %ui \"%V\"", - size, key, test[key], &names[n].key); + "%ui: %ui %uz \"%V\"", + size, key, len, &names[n].key); #endif - if (test[key] > (u_short) bucket_size) { + if (len > bucket_size) { goto next; } + + test[key] = (u_short) len; } goto found; @@ -341,7 +351,17 @@ found: } key = names[n].key_hash % size; - test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); + len = test[key] + NGX_HASH_ELT_SIZE(&names[n]); + + if (len > 65536 - ngx_cacheline_size) { + ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, + "could not build %s, you should " + "increase %s_max_size: %i", + hinit->name, hinit->name, hinit->max_size); + return NGX_ERROR; + } + + test[key] = (u_short) len; } len = 0; From mdounin at mdounin.ru Thu Jul 18 15:28:37 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 Jul 2019 15:28:37 +0000 Subject: [nginx] HTTP/2: return error on output on closed stream. Message-ID: details: https://hg.nginx.org/nginx/rev/01e26357916a branches: changeset: 7537:01e26357916a user: Maxim Dounin date: Thu Jul 18 18:27:50 2019 +0300 description: HTTP/2: return error on output on closed stream. Without this, an (incorrect) output on a closed stream could result in a socket leak. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -1444,6 +1444,12 @@ ngx_http_v2_send_chain(ngx_connection_t if (in == NULL || stream->out_closed) { + if (size) { + ngx_log_error(NGX_LOG_ERR, fc->log, 0, + "output on closed stream"); + return NGX_CHAIN_ERROR; + } + if (stream->queued) { fc->write->active = 1; fc->write->ready = 0; From mdounin at mdounin.ru Thu Jul 18 15:28:38 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 Jul 2019 15:28:38 +0000 Subject: [nginx] Upstream: fixed EOF handling in unbuffered and upgraded modes. Message-ID: details: https://hg.nginx.org/nginx/rev/08ed570ad93c branches: changeset: 7538:08ed570ad93c user: Maxim Dounin date: Thu Jul 18 18:27:52 2019 +0300 description: Upstream: fixed EOF handling in unbuffered and upgraded modes. With level-triggered event methods it is important to specify the NGX_CLOSE_EVENT flag to ngx_handle_read_event(), otherwise the event won't be removed, resulting in CPU hog. Reported by Patrick Wollgast. diffstat: src/http/ngx_http_upstream.c | 29 ++++++++++++++++++++++++++--- 1 files changed, 26 insertions(+), 3 deletions(-) diffs (67 lines): diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -3334,6 +3334,7 @@ ngx_http_upstream_process_upgraded(ngx_h size_t size; ssize_t n; ngx_buf_t *b; + ngx_uint_t flags; ngx_connection_t *c, *downstream, *upstream, *dst, *src; ngx_http_upstream_t *u; ngx_http_core_loc_conf_t *clcf; @@ -3472,7 +3473,14 @@ ngx_http_upstream_process_upgraded(ngx_h ngx_del_timer(upstream->write); } - if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { + if (upstream->read->eof || upstream->read->error) { + flags = NGX_CLOSE_EVENT; + + } else { + flags = 0; + } + + if (ngx_handle_read_event(upstream->read, flags) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -3491,7 +3499,14 @@ ngx_http_upstream_process_upgraded(ngx_h return; } - if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) { + if (downstream->read->eof || downstream->read->error) { + flags = NGX_CLOSE_EVENT; + + } else { + flags = 0; + } + + if (ngx_handle_read_event(downstream->read, flags) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -3563,6 +3578,7 @@ ngx_http_upstream_process_non_buffered_r ssize_t n; ngx_buf_t *b; ngx_int_t rc; + ngx_uint_t flags; ngx_connection_t *downstream, *upstream; ngx_http_upstream_t *u; ngx_http_core_loc_conf_t *clcf; @@ -3666,7 +3682,14 @@ ngx_http_upstream_process_non_buffered_r ngx_del_timer(downstream->write); } - if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { + if (upstream->read->eof || upstream->read->error) { + flags = NGX_CLOSE_EVENT; + + } else { + flags = 0; + } + + if (ngx_handle_read_event(upstream->read, flags) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } From mdounin at mdounin.ru Thu Jul 18 15:28:40 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 Jul 2019 15:28:40 +0000 Subject: [nginx] SSI: avoid potential buffer overflow. Message-ID: details: https://hg.nginx.org/nginx/rev/d75153522557 branches: changeset: 7539:d75153522557 user: Maxim Dounin date: Thu Jul 18 18:27:53 2019 +0300 description: SSI: avoid potential buffer overflow. When "-" follows a parameter of maximum length, a single byte buffer overflow happens, since the error branch does not check parameter length. Fix is to avoid saving "-" to the parameter key, and instead use an error message with "-" explicitly written. The message is mostly identical to one used in similar cases in the preequal state. Reported by Patrick Wollgast. diffstat: src/http/modules/ngx_http_ssi_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (15 lines): diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -1254,9 +1254,9 @@ ngx_http_ssi_parse(ngx_http_request_t *r case '-': state = ssi_error_end0_state; - ctx->param->key.data[ctx->param->key.len++] = ch; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "invalid \"%V\" parameter in \"%V\" SSI command", + "unexpected \"-\" symbol after \"%V\" " + "parameter in \"%V\" SSI command", &ctx->param->key, &ctx->command); break; From mdounin at mdounin.ru Thu Jul 18 15:28:41 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 Jul 2019 15:28:41 +0000 Subject: [nginx] Xslt: fixed potential buffer overflow with null character. Message-ID: details: https://hg.nginx.org/nginx/rev/9a970c905045 branches: changeset: 7540:9a970c905045 user: Maxim Dounin date: Thu Jul 18 18:27:54 2019 +0300 description: Xslt: fixed potential buffer overflow with null character. Due to shortcomings of the ccv->zero flag implementation in complex value interface, length of the resulting string from ngx_http_complex_value() might either not include terminating null character or include it, so the only safe way to work with the result is to use it as a null-terminated string. Reported by Patrick Wollgast. diffstat: src/http/modules/ngx_http_xslt_filter_module.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diffs (30 lines): diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -628,7 +628,7 @@ static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params, ngx_uint_t final) { - u_char *p, *last, *value, *dst, *src, **s; + u_char *p, *value, *dst, *src, **s; size_t len; ngx_uint_t i; ngx_str_t string; @@ -698,8 +698,6 @@ ngx_http_xslt_params(ngx_http_request_t ngx_memcpy(p, string.data, string.len + 1); } - last = p + string.len; - while (p && *p) { value = p; @@ -729,7 +727,7 @@ ngx_http_xslt_params(ngx_http_request_t *p++ = '\0'; } else { - len = last - value; + len = ngx_strlen(value); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, From teward at thomas-ward.net Thu Jul 18 20:01:39 2019 From: teward at thomas-ward.net (Thomas Ward) Date: Thu, 18 Jul 2019 16:01:39 -0400 Subject: TLS1.3 Message-ID: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> Hello. Downstream, in Ubuntu, we've got NGINX 1.14.0 in the repositories, and TLS 1.3 enabled in the bionic-updates repository due to OpenSSL being bumped to 1.1.1.? We don't currently have a mechanism This means that TLS1.3 is "on by default" with the standard config being rolled.? And nginx cannot control TLS1.3 because it's built against the previous 1.1.0 libs. A request to do a no-change rebuild to allow NGINX has been blocked because we're concerned about other TLS 1.3 behaviorisms and whether there's any other TLS related behaviors we need to be concerned about doing a no-change rebuild against OpenSSL 1.1.1 with this library version. There's a few considerations here.? We need to make certain that such a rebuild to allow NGINX to control TLS 1.3 protocol or ciphers isn't going to introduce any additional TLS1.3 behaviors or feature functionality that otherwise would not be controlled by OpenSSL under the hood. Is the NGINX team aware of any such 'extra' behaviors regarding TLS 1.3 which would be altered or introduced by a rebuild of the 1.14.0 packages against OpenSSL 1.1.1 which would otherwise block such a rebuild? Thomas -------------- next part -------------- An HTML attachment was scrubbed... URL: From pgnet.dev at gmail.com Thu Jul 18 20:09:52 2019 From: pgnet.dev at gmail.com (PGNet Dev) Date: Thu, 18 Jul 2019 13:09:52 -0700 Subject: TLS1.3 In-Reply-To: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> References: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> Message-ID: <6ac3b9ed-79d4-7dba-5007-d52edf95373b@gmail.com> On 7/18/19 1:01 PM, Thomas Ward wrote: > There's a few considerations here.? We need to make certain that such a > rebuild to allow NGINX to control TLS 1.3 protocol or ciphers isn't > going to introduce any additional TLS1.3 behaviors or feature > functionality that otherwise would not be controlled by OpenSSL under Offhand, have you already demonstrated to your satisfaction that TLSv1.3 served-up in Nginx is, in fact, using the TLSv1.3 ciphers? Regardless of any 'additional' "behaviors or feature or functionality"? Atm, in some simple testing I'm seeing that it doesn't -- and looking for any evidence, anectdotal or otherwise, that it does so I can narrow down if it's 'me' ... From teward at thomas-ward.net Thu Jul 18 20:15:54 2019 From: teward at thomas-ward.net (Thomas Ward) Date: Thu, 18 Jul 2019 16:15:54 -0400 Subject: TLS1.3 In-Reply-To: <6ac3b9ed-79d4-7dba-5007-d52edf95373b@gmail.com> References: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> <6ac3b9ed-79d4-7dba-5007-d52edf95373b@gmail.com> Message-ID: <001e0f6c-e5b9-c0ad-621e-150f401b90e7@thomas-ward.net> Might be helpful to point at? https://trac.nginx.org/nginx/ticket/1654#comment:2 and other issues which have spurned the request to rebuild downstream. Which, given that NGINX built against 1.1.0 downstream and OpenSSL downstream in Ubuntu with 1.1.1 is set such that TLS 1.3 is "on by default" and therefore is just 'available' and enabled but not able to be controlled/disabled by NGINX directly, it DOES work with TLS1.3 connections and ciphers.? We just can't manipulate things. The developer concern downstream is this rebuild won't introduce any other TLS 1.3 behaviors not already present as a result of OpenSSL being "TLS1.3 Enabled By Default" which is the current situation. Thomas On 7/18/19 4:09 PM, PGNet Dev wrote: > On 7/18/19 1:01 PM, Thomas Ward wrote: >> There's a few considerations here.? We need to make certain that such >> a rebuild to allow NGINX to control TLS 1.3 protocol or ciphers isn't >> going to introduce any additional TLS1.3 behaviors or feature >> functionality that otherwise would not be controlled by OpenSSL under > > Offhand, have you already demonstrated to your satisfaction that > TLSv1.3 served-up in Nginx is, in fact, using the TLSv1.3 ciphers?? > Regardless of any 'additional' "behaviors or feature or functionality"? > > Atm, in some simple testing I'm seeing that it doesn't -- and looking > for any evidence, anectdotal or otherwise, that it does so I can > narrow down if it's 'me' ... > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pgnet.dev at gmail.com Thu Jul 18 20:25:45 2019 From: pgnet.dev at gmail.com (PGNet Dev) Date: Thu, 18 Jul 2019 13:25:45 -0700 Subject: TLS1.3 In-Reply-To: <001e0f6c-e5b9-c0ad-621e-150f401b90e7@thomas-ward.net> References: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> <6ac3b9ed-79d4-7dba-5007-d52edf95373b@gmail.com> <001e0f6c-e5b9-c0ad-621e-150f401b90e7@thomas-ward.net> Message-ID: On 7/18/19 1:15 PM, Thomas Ward wrote: > Might be helpful to point at > https://trac.nginx.org/nginx/ticket/1654#comment:2 and other issues > which have spurned the request to rebuild downstream. > > Which, given that NGINX built against 1.1.0 downstream and OpenSSL > downstream in Ubuntu with 1.1.1 is set such that TLS 1.3 is "on by > default" and therefore is just 'available' and enabled but not able to > be controlled/disabled by NGINX directly, it DOES work with TLS1.3 > connections and ciphers.? We just can't manipulate things. > > The developer concern downstream is this rebuild won't introduce any > other TLS 1.3 behaviors not already present as a result of OpenSSL being > "TLS1.3 Enabled By Default" which is the current situation. Thanks for the trac link. fwiw, here I've nginx -V nginx version: nginx/1.17.1 (local build) built with OpenSSL 1.1.1c 28 May 2019 TLS SNI support enabled ... yet, despite the build, I'm seeing some problems with TLSv1.3 cipher usage/config in Nginx. cref: https://mta.openssl.org/pipermail/openssl-users/2019-July/010881.html I've _just_ started poking around with that, and don't know what/where the problem lies atm. It _seems_ to me an issue with Nginx, but I simply am unsure ... Perhaps something i the trac issue will light a bulb for me; I'll take a closer look. Thx o/ From mdounin at mdounin.ru Fri Jul 19 15:16:12 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 Jul 2019 15:16:12 +0000 Subject: [nginx] Core: fixed memory leak on error, missed in c3f60d618c17. Message-ID: details: https://hg.nginx.org/nginx/rev/eb9c7fb796d5 branches: changeset: 7541:eb9c7fb796d5 user: Maxim Dounin date: Fri Jul 19 17:50:00 2019 +0300 description: Core: fixed memory leak on error, missed in c3f60d618c17. Found by Coverity (CID 1451664). diffstat: src/core/ngx_hash.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c --- a/src/core/ngx_hash.c +++ b/src/core/ngx_hash.c @@ -358,6 +358,7 @@ found: "could not build %s, you should " "increase %s_max_size: %i", hinit->name, hinit->name, hinit->max_size); + ngx_free(test); return NGX_ERROR; } From hongzhidao at gmail.com Fri Jul 19 15:26:38 2019 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Fri, 19 Jul 2019 23:26:38 +0800 Subject: cache: move open to thread pool In-Reply-To: References: <20180808181653.GX56558@mdounin.ru> <20180810113946.GG56558@mdounin.ru> <20180903160903.GI56558@mdounin.ru> <4ba7414a-0eba-6bd3-5a50-2eca591ac25e@nginx.com> <2a3577f6-4ad4-aa2d-80a2-7e9b715c070d@nginx.com> Message-ID: Hi. Will this patch be merged into the main branch? What is the latest patch? We can help with the test. Thanks. On Sat, Feb 9, 2019 at 6:40 AM Ka-Hing Cheung via nginx-devel < nginx-devel at nginx.org> wrote: > Unfortunately our test colo is not setup to do performance testing > (the traffic it receives varies too much). We do intend to merge this > to our production colos but there's no timeline yet. > > Yuchen (CC'ed) will be the main contact from now on as today is my > last day at Cloudflare. > > - Ka-Hing > > On Thu, Feb 7, 2019 at 5:39 AM Maxim Konovalov wrote: > > > > Great. Thanks for the testing! > > > > Did you see any measurable perf. metrics changes comparing to your > > aio open implementation or comparing to nginx without aio open support? > > > > We are still waiting for additional input from another tester, who > > expressed interest before. > > > > Thanks, > > > > Maxim > > > > On 07/02/2019 00:19, Ka-Hing Cheung wrote: > > > This has been running in our test colo for the past week with no ill > effects. > > > > > > On Wed, Jan 23, 2019 at 4:39 AM Maxim Konovalov > wrote: > > >> > > >> Hi Ka-Hing, > > >> > > >> Roman told me that the delta is because of your changes. > > >> > > >> Thanks for your time on that. Waiting for your testing results. > > >> > > >> Maxim > > >> > > >> On 22/01/2019 22:34, Ka-Hing Cheung via nginx-devel wrote: > > >>> I spoke too soon, just realized our test colo is running the patches > > >>> without aio_open on. Flipping that switch now. > > >>> > > >>> Also, including the patch that we applied on top in addition to the > > >>> massaging we did to resolve conflicts. I haven't dug too deep to see > > >>> if stock nginx also requires similar changes or they are only > > >>> necessary because of our other nginx changes: > > >>> > > >> [...] > > >> > > >> -- > > >> Maxim Konovalov > > > > > > -- > > Maxim Konovalov > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.borisov at nginx.com Fri Jul 19 15:52:55 2019 From: alexander.borisov at nginx.com (Alexander Borisov) Date: Fri, 19 Jul 2019 15:52:55 +0000 Subject: [njs] Fixed njs_string_slice(). Message-ID: details: https://hg.nginx.org/njs/rev/2fdad3cbbd74 branches: changeset: 1059:2fdad3cbbd74 user: Dmitry Volyntsev date: Thu Jul 18 21:12:25 2019 +0300 description: Fixed njs_string_slice(). Previously, njs_string_slice() when slice->start == slice->string_length may call njs_string_offset() with invalid index. This might result in invalid memory access in njs_string_offset() for native functions which use njs_string_slice(): String.prototype.substring() diffstat: njs/njs_string.c | 31 +++++++++++++++++++------------ njs/test/njs_unit_test.c | 3 +++ 2 files changed, 22 insertions(+), 12 deletions(-) diffs (55 lines): diff -r 57cf608a29b5 -r 2fdad3cbbd74 njs/njs_string.c --- a/njs/njs_string.c Thu Jul 18 16:18:19 2019 +0300 +++ b/njs/njs_string.c Thu Jul 18 21:12:25 2019 +0300 @@ -1351,19 +1351,26 @@ njs_string_slice_string_prop(njs_string_ } else { /* UTF-8 string. */ end = start + string->size; - start = njs_string_offset(start, end, slice->start); - - /* Evaluate size of the slice in bytes and ajdust length. */ - p = start; - n = length; - - while (n != 0 && p < end) { - p = nxt_utf8_next(p, end); - n--; + + if (slice->start < slice->string_length) { + start = njs_string_offset(start, end, slice->start); + + /* Evaluate size of the slice in bytes and adjust length. */ + p = start; + n = length; + + while (n != 0 && p < end) { + p = nxt_utf8_next(p, end); + n--; + } + + size = p - start; + length -= n; + + } else { + length = 0; + size = 0; } - - size = p - start; - length -= n; } dst->start = (u_char *) start; diff -r 57cf608a29b5 -r 2fdad3cbbd74 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Jul 18 16:18:19 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu Jul 18 21:12:25 2019 +0300 @@ -4825,6 +4825,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'?'.repeat(32).substring(32)"), nxt_string("") }, + { nxt_string("'?'.repeat(32).substring(32,32)"), + nxt_string("") }, + { nxt_string("'abcdefghijklmno'.slice(NaN, 5)"), nxt_string("abcde") }, From mdounin at mdounin.ru Fri Jul 19 16:09:41 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 Jul 2019 19:09:41 +0300 Subject: TLS1.3 In-Reply-To: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> References: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> Message-ID: <20190719160941.GD1877@mdounin.ru> Hello! On Thu, Jul 18, 2019 at 04:01:39PM -0400, Thomas Ward wrote: > Downstream, in Ubuntu, we've got NGINX 1.14.0 in the repositories, and > TLS 1.3 enabled in the bionic-updates repository due to OpenSSL being > bumped to 1.1.1.? We don't currently have a mechanism > > This means that TLS1.3 is "on by default" with the standard config being > rolled.? And nginx cannot control TLS1.3 because it's built against the > previous 1.1.0 libs. > > A request to do a no-change rebuild to allow NGINX has been blocked > because we're concerned about other TLS 1.3 behaviorisms and whether > there's any other TLS related behaviors we need to be concerned about > doing a no-change rebuild against OpenSSL 1.1.1 with this library version. So, you are: - Not concerned about switching OpenSSL library to 1.1.1, which is known to introduce multiple behaviour changes, including TLS 1.3 enabled by default. - Not concerned about using unsupported old nginx version. - But concerned about doing an nginx rebuild against the library you are running nginx with. That sounds even more interesting than switching to OpenSSL 1.1.1 alone. > There's a few considerations here.? We need to make certain that such a > rebuild to allow NGINX to control TLS 1.3 protocol or ciphers isn't > going to introduce any additional TLS1.3 behaviors or feature > functionality that otherwise would not be controlled by OpenSSL under > the hood. > > Is the NGINX team aware of any such 'extra' behaviors regarding TLS 1.3 > which would be altered or introduced by a rebuild of the 1.14.0 packages > against OpenSSL 1.1.1 which would otherwise block such a rebuild? TLS 1.3 is disabled by default in nginx, and that's probably the most serious change you'll encounter - after recompilation, TLS 1.3 will be disabled by default as it should. I'm not aware of any additional behaviour changes. -- Maxim Dounin http://mdounin.ru/ From teward at thomas-ward.net Fri Jul 19 16:11:48 2019 From: teward at thomas-ward.net (Thomas Ward) Date: Fri, 19 Jul 2019 12:11:48 -0400 Subject: TLS1.3 In-Reply-To: <20190719160941.GD1877@mdounin.ru> References: <7db1bfd9-976f-99a3-a49c-685035734e32@thomas-ward.net> <20190719160941.GD1877@mdounin.ru> Message-ID: <4d30da80-6d51-8152-96e9-692d4990c008@thomas-ward.net> On 7/19/19 12:09 PM, Maxim Dounin wrote: > Hello! > > On Thu, Jul 18, 2019 at 04:01:39PM -0400, Thomas Ward wrote: > >> Downstream, in Ubuntu, we've got NGINX 1.14.0 in the repositories, and >> TLS 1.3 enabled in the bionic-updates repository due to OpenSSL being >> bumped to 1.1.1.? We don't currently have a mechanism >> >> This means that TLS1.3 is "on by default" with the standard config being >> rolled.? And nginx cannot control TLS1.3 because it's built against the >> previous 1.1.0 libs. >> >> A request to do a no-change rebuild to allow NGINX has been blocked >> because we're concerned about other TLS 1.3 behaviorisms and whether >> there's any other TLS related behaviors we need to be concerned about >> doing a no-change rebuild against OpenSSL 1.1.1 with this library version. > So, you are: > > - Not concerned about switching OpenSSL library to 1.1.1, which is > known to introduce multiple behaviour changes, including > TLS 1.3 enabled by default. > > - Not concerned about using unsupported old nginx version. > > - But concerned about doing an nginx rebuild against the library > you are running nginx with. > > That sounds even more interesting than switching to OpenSSL 1.1.1 alone. That's a misconception - I'm working other mechanisms to provide 'updated' versions - but the problem is the 'stable release' process downstream (just like in Debian, CentOS, etc. it's a headache). > >> There's a few considerations here.? We need to make certain that such a >> rebuild to allow NGINX to control TLS 1.3 protocol or ciphers isn't >> going to introduce any additional TLS1.3 behaviors or feature >> functionality that otherwise would not be controlled by OpenSSL under >> the hood. >> >> Is the NGINX team aware of any such 'extra' behaviors regarding TLS 1.3 >> which would be altered or introduced by a rebuild of the 1.14.0 packages >> against OpenSSL 1.1.1 which would otherwise block such a rebuild? > TLS 1.3 is disabled by default in nginx, and that's probably the > most serious change you'll encounter - after recompilation, TLS > 1.3 will be disabled by default as it should. I'm not aware of > any additional behaviour changes. Thanks for this information - this is what I was primarily looking for an answer for. Thomas -------------- next part -------------- An HTML attachment was scrubbed... URL: From maxim at nginx.com Fri Jul 19 18:42:45 2019 From: maxim at nginx.com (Maxim Konovalov) Date: Fri, 19 Jul 2019 21:42:45 +0300 Subject: cache: move open to thread pool In-Reply-To: References: <20180903160903.GI56558@mdounin.ru> <4ba7414a-0eba-6bd3-5a50-2eca591ac25e@nginx.com> <2a3577f6-4ad4-aa2d-80a2-7e9b715c070d@nginx.com> Message-ID: <9aef70ef-db5f-d3af-bb09-44848477fab2@nginx.com> Hi hongzhidao, The patch wasn't merged as we didn't see much interest and real technical feedback from potential testers. The code adds additional complexity to the nginx core with all associated costs of maintaining the code virtually forever. In the same time at this point it brings no measurable value to the community. At least, we haven't seen any proofs that it does. The patch wasn't updated since that but I suspect it could be still applied to nginx, maybe with some minor tweaks. Maxim On 19/07/2019 18:26, ??? wrote: > Hi. > Will this patch be merged into the main branch? > What is the latest patch? We can help with the test. > Thanks. > > On Sat, Feb 9, 2019 at 6:40 AM Ka-Hing Cheung via nginx-devel > > wrote: > > Unfortunately our test colo is not setup to do performance testing > (the traffic it receives varies too much). We do intend to merge > this > to our production colos but there's no timeline yet. > > Yuchen (CC'ed) will be the main contact from now on as today is my > last day at Cloudflare. > > - Ka-Hing > > On Thu, Feb 7, 2019 at 5:39 AM Maxim Konovalov > wrote: > > > > Great.? Thanks for the testing! > > > > Did you see any measurable perf. metrics changes comparing to your > > aio open implementation or comparing to nginx without aio open > support? > > > > We are still waiting for additional input from another tester, who > > expressed interest before. > > > > Thanks, > > > > Maxim > > > > On 07/02/2019 00:19, Ka-Hing Cheung wrote: > > > This has been running in our test colo for the past week > with no ill effects. > > > > > > On Wed, Jan 23, 2019 at 4:39 AM Maxim Konovalov > > wrote: > > >> > > >> Hi Ka-Hing, > > >> > > >> Roman told me that the delta is because of your changes. > > >> > > >> Thanks for your time on that.? Waiting for your testing > results. > > >> > > >> Maxim > > >> > > >> On 22/01/2019 22:34, Ka-Hing Cheung via nginx-devel wrote: > > >>> I spoke too soon, just realized our test colo is running > the patches > > >>> without aio_open on. Flipping that switch now. > > >>> > > >>> Also, including the patch that we applied on top in > addition to the > > >>> massaging we did to resolve conflicts. I haven't dug too > deep to see > > >>> if stock nginx also requires similar changes or they are only > > >>> necessary because of our other nginx changes: > > >>> > > >> [...] > > >> > > >> -- > > >> Maxim Konovalov > > > > > > -- > > Maxim Konovalov > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Maxim Konovalov From xeioex at nginx.com Fri Jul 19 20:28:15 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 19 Jul 2019 20:28:15 +0000 Subject: [njs] Refactored working with non-primitive types. Message-ID: details: https://hg.nginx.org/njs/rev/201af81dfa9b branches: changeset: 1060:201af81dfa9b user: Dmitry Volyntsev date: Fri Jul 05 21:45:28 2019 +0300 description: Refactored working with non-primitive types. Traps mechanism is remove. diffstat: njs/njs.c | 2 - njs/njs_array.c | 47 +- njs/njs_date.c | 31 +- njs/njs_function.c | 108 ++- njs/njs_function.h | 50 +- njs/njs_math.c | 24 +- njs/njs_object.c | 2 - njs/njs_object_property.c | 14 +- njs/njs_regexp.c | 14 +- njs/njs_string.c | 74 +- njs/njs_string.h | 3 - njs/njs_value.c | 120 +- njs/njs_value.h | 137 ++- njs/njs_vm.c | 1451 ++++++++++++++++---------------------- njs/njs_vm.h | 32 +- njs/test/njs_interactive_test.c | 3 +- njs/test/njs_unit_test.c | 74 + 17 files changed, 1033 insertions(+), 1153 deletions(-) diffs (truncated from 3221 to 1000 lines): diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs.c --- a/njs/njs.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs.c Fri Jul 05 21:45:28 2019 +0300 @@ -984,8 +984,6 @@ again: /* value evaluation threw an exception. */ - vm->top_frame->trap_tries = 0; - src = &vm->retval; goto again; } diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_array.c --- a/njs/njs_array.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_array.c Fri Jul 05 21:45:28 2019 +0300 @@ -528,10 +528,7 @@ njs_array_prototype_slice(njs_vm_t *vm, ret = njs_value_property(vm, &args[0], &njs_string_length, &slice->length, 0); - if (nxt_slow_path(ret == NXT_ERROR - || ret == NJS_TRAP - || ret == NJS_APPLIED)) - { + if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) { return ret; } @@ -544,13 +541,16 @@ njs_array_prototype_slice_continuation(n nxt_uint_t nargs, njs_index_t unused) { int64_t start, end, length; + njs_ret_t ret; njs_array_slice_t *slice; slice = njs_vm_continuation(vm); if (nxt_slow_path(!njs_is_primitive(&slice->length))) { - njs_vm_trap_value(vm, &slice->length); - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &slice->length, &slice->length); + if (ret != NXT_OK) { + return ret; + } } start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1)); @@ -958,7 +958,7 @@ njs_array_prototype_reverse(njs_vm_t *vm static njs_ret_t njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, - njs_index_t retval) + njs_index_t unused) { njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; @@ -970,12 +970,12 @@ njs_array_prototype_to_string(njs_vm_t * prop = njs_object_property(vm, njs_object(&args[0]), &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { - return njs_function_replace(vm, njs_function(&prop->value), - args, nargs, retval); + return njs_function_call(vm, njs_function(&prop->value), args, + nargs, (njs_index_t) &vm->retval); } } - return njs_object_prototype_to_string(vm, args, nargs, retval); + return njs_object_prototype_to_string(vm, args, nargs, unused); } @@ -1063,6 +1063,7 @@ njs_array_prototype_join_continuation(nj u_char *p; size_t size, length, mask; uint32_t max; + njs_ret_t ret; nxt_uint_t i, n; njs_array_t *array; njs_value_t *value, *values; @@ -1089,9 +1090,10 @@ njs_array_prototype_join_continuation(nj value = &values[n++]; if (!njs_is_string(value)) { - njs_vm_trap_value(vm, value); - - return njs_trap(vm, NJS_TRAP_STRING_ARG); + ret = njs_value_to_string(vm, value, value); + if (ret != NXT_OK) { + return ret; + } } } @@ -1442,10 +1444,7 @@ njs_array_prototype_fill(njs_vm_t *vm, n ret = njs_value_property(vm, this, &njs_string_length, &fill->length, 0); - if (nxt_slow_path(ret == NXT_ERROR - || ret == NJS_TRAP - || ret == NJS_APPLIED)) - { + if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) { return ret; } } @@ -1459,6 +1458,7 @@ njs_array_prototype_fill_continuation(nj nxt_uint_t nargs, njs_index_t unused) { nxt_int_t i, start, end, length; + njs_ret_t ret; njs_array_t *array; njs_object_t *object; njs_array_fill_t *fill; @@ -1488,8 +1488,10 @@ njs_array_prototype_fill_continuation(nj } else { if (nxt_slow_path(!njs_is_primitive(&fill->length))) { - njs_vm_trap_value(vm, &fill->length); - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &fill->length, &fill->length); + if (ret != NXT_OK) { + return ret; + } } length = njs_primitive_value_to_length(&fill->length); @@ -2202,9 +2204,10 @@ njs_array_string_sort(njs_vm_t *vm, njs_ for (i = 1; i < nargs; i++) { if (!njs_is_string(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_STRING_ARG); + ret = njs_value_to_string(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } } diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_date.c --- a/njs/njs_date.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_date.c Fri Jul 05 21:45:28 2019 +0300 @@ -73,6 +73,7 @@ njs_date_constructor(njs_vm_t *vm, njs_v { double num, time; int64_t values[8]; + njs_ret_t ret; nxt_uint_t i, n; njs_date_t *date; struct tm tm; @@ -85,11 +86,14 @@ njs_date_constructor(njs_vm_t *vm, njs_v } else if (nargs == 2) { if (njs_is_object(&args[1])) { if (!njs_is_date(&args[1])) { - njs_vm_trap_value(vm, &args[1]); - - return njs_trap(vm, NJS_TRAP_PRIMITIVE_ARG); + ret = njs_value_to_primitive(vm, &args[1], &args[1], 0); + if (ret != NXT_OK) { + return ret; + } } - + } + + if (njs_is_date(&args[1])) { time = njs_date(&args[1])->time; } else if (njs_is_string(&args[1])) { @@ -108,9 +112,10 @@ njs_date_constructor(njs_vm_t *vm, njs_v for (i = 1; i < n; i++) { if (!njs_is_numeric(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } num = njs_number(&args[i]); @@ -171,6 +176,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * { double num, time; struct tm tm; + njs_ret_t ret; nxt_uint_t i, n; int32_t values[8]; @@ -183,9 +189,10 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * for (i = 1; i < n; i++) { if (!njs_is_numeric(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } num = njs_number(&args[i]); @@ -1902,8 +1909,8 @@ njs_date_prototype_to_json(njs_vm_t *vm, prop = njs_object_property(vm, njs_object(&args[0]), &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { - return njs_function_replace(vm, njs_function(&prop->value), - args, nargs, retval); + return njs_function_call(vm, njs_function(&prop->value), args, + nargs, (njs_index_t) &vm->retval); } } diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_function.c --- a/njs/njs_function.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_function.c Fri Jul 05 21:45:28 2019 +0300 @@ -473,6 +473,48 @@ njs_function_frame_alloc(njs_vm_t *vm, s njs_ret_t +njs_function_call(njs_vm_t *vm, njs_function_t *function, njs_value_t *args, + nxt_uint_t nargs, njs_index_t retval) +{ + u_char *return_address; + njs_ret_t ret; + njs_native_frame_t *frame; + njs_continuation_t *cont; + + ret = njs_function_frame(vm, function, &args[0], &args[1], nargs - 1, 0, 0); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + frame = vm->top_frame; + frame->call = 1; + + return_address = vm->current; + + if (function->native) { + + if (function->continuation_size != 0) { + cont = njs_vm_continuation(vm); + cont->return_address = return_address; + } + + ret = njs_function_native_call(vm, function->u.native, frame->arguments, + function->args_types, frame->nargs, + (njs_index_t) retval, return_address); + + } else { + ret = njs_function_lambda_call(vm, retval, return_address); + + if (nxt_fast_path(ret == NJS_APPLIED)) { + ret = njs_vmcode_run(vm); + } + } + + return ret; +} + + +njs_ret_t njs_function_lambda_call(njs_vm_t *vm, njs_index_t retval, u_char *return_address) { @@ -594,9 +636,9 @@ njs_function_native_call(njs_vm_t *vm, n * The callee arguments must be preserved * for NJS_APPLIED and NXT_AGAIN cases. */ - if (ret == NXT_OK) { - frame = vm->top_frame; + frame = vm->top_frame; + if (ret == NXT_OK || (frame->call && ret == NXT_ERROR)) { vm->top_frame = njs_function_previous_frame(frame); /* @@ -625,7 +667,7 @@ njs_function_native_call(njs_vm_t *vm, n njs_function_frame_free(vm, frame); - return NXT_OK; + return ret; } return ret; @@ -636,8 +678,8 @@ static njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args, uint8_t *args_types, nxt_uint_t nargs) { + njs_ret_t ret; nxt_uint_t n; - njs_trap_t trap; n = nxt_min(nargs, NJS_ARGS_TYPES_MAX); @@ -655,43 +697,47 @@ njs_normalize_args(njs_vm_t *vm, njs_val case NJS_STRING_ARG: - if (njs_is_string(args)) { - break; + if (!njs_is_string(args)) { + ret = njs_value_to_string(vm, args, args); + if (ret != NXT_OK) { + return ret; + } } - trap = NJS_TRAP_STRING_ARG; - goto trap; + break; case NJS_NUMBER_ARG: - if (njs_is_numeric(args)) { - break; + if (!njs_is_numeric(args)) { + ret = njs_value_to_numeric(vm, args, args); + if (ret != NXT_OK) { + return ret; + } } - trap = NJS_TRAP_NUMBER_ARG; - goto trap; + break; case NJS_INTEGER_ARG: - if (njs_is_numeric(args)) { - - /* Numbers are truncated to fit in 32-bit integers. */ + if (!njs_is_numeric(args)) { + ret = njs_value_to_numeric(vm, args, args); + if (ret != NXT_OK) { + return ret; + } + } - if (isnan(njs_number(args))) { - njs_number(args) = 0; + /* Numbers are truncated to fit in 32-bit integers. */ - } else if (njs_number(args) > 2147483647.0) { + if (!isnan(njs_number(args))) { + if (njs_number(args) > 2147483647.0) { njs_number(args) = 2147483647.0; } else if (njs_number(args) < -2147483648.0) { njs_number(args) = -2147483648.0; } - - break; } - trap = NJS_TRAP_NUMBER_ARG; - goto trap; + break; case NJS_FUNCTION_ARG: @@ -701,8 +747,10 @@ njs_normalize_args(njs_vm_t *vm, njs_val break; default: - trap = NJS_TRAP_STRING_ARG; - goto trap; + ret = njs_value_to_string(vm, args, args); + if (ret != NXT_OK) { + return ret; + } } break; @@ -716,8 +764,10 @@ njs_normalize_args(njs_vm_t *vm, njs_val break; default: - trap = NJS_TRAP_STRING_ARG; - goto trap; + ret = njs_value_to_string(vm, args, args); + if (ret != NXT_OK) { + return ret; + } } break; @@ -751,12 +801,6 @@ njs_normalize_args(njs_vm_t *vm, njs_val return NJS_OK; -trap: - - njs_vm_trap_value(vm, args); - - return njs_trap(vm, trap); - type_error: njs_type_error(vm, "cannot convert %s to %s", njs_type_string(args->type), diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_function.h --- a/njs/njs_function.h Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_function.h Fri Jul 05 21:45:28 2019 +0300 @@ -74,11 +74,6 @@ typedef struct { #define NJS_CONTINUATION_SIZE njs_continuation_size(njs_continuation_t) -#define njs_vm_trap_value(vm, val) \ - (vm)->top_frame->trap_scratch.data.u.value = val - - - typedef struct njs_exception_s njs_exception_t; struct njs_exception_s { @@ -92,10 +87,6 @@ struct njs_exception_s { struct njs_native_frame_s { - njs_value_t trap_scratch; - njs_value_t trap_values[2]; - u_char *trap_restart; - u_char *free; njs_function_t *function; @@ -118,14 +109,7 @@ struct njs_native_frame_s { /* Skip the Function.call() and Function.apply() methods frames. */ uint8_t skip; /* 1 bit */ - /* A number of trap tries, it can be no more than three. */ - uint8_t trap_tries; /* 2 bits */ - - /* - * The first operand in trap is reference to original value, - * it is used to increment or decrement this value. - */ - uint8_t trap_reference; /* 1 bit */ + uint8_t call; /* 1 bit */ }; @@ -168,6 +152,8 @@ njs_ret_t njs_function_lambda_frame(njs_ njs_ret_t njs_function_activate(njs_vm_t *vm, njs_function_t *function, const njs_value_t *this, const njs_value_t *args, nxt_uint_t nargs, njs_index_t retval, size_t advance); +njs_ret_t njs_function_call(njs_vm_t *vm, njs_function_t *function, + njs_value_t *args, nxt_uint_t nargs, njs_index_t retval); njs_ret_t njs_function_lambda_call(njs_vm_t *vm, njs_index_t retval, u_char *return_address); njs_ret_t njs_function_native_call(njs_vm_t *vm, njs_function_native_t native, @@ -215,36 +201,6 @@ njs_function_apply(njs_vm_t *vm, njs_fun } -/* - * Replaces the current function with a new one. - * Can only be used for continuation functions - * (data.u.function.continuation_size > 0). - */ -nxt_inline njs_ret_t -njs_function_replace(njs_vm_t *vm, njs_function_t *function, - const njs_value_t *args, nxt_uint_t nargs, njs_index_t retval) -{ - nxt_int_t ret; - - ret = njs_function_apply(vm, function, args, nargs, retval); - if (nxt_slow_path(ret == NXT_ERROR)) { - return ret; - } - - /* - * 1) njs_function_apply() allocs a new function frame, - * in order to preserve the retval of a new function and ignore - * retval of the current function during stack unwinding - * skip flag is needed. - * 2) it is also needed for correct callee arguments update in - * njs_function_native_call() see "Object((new Date(0)).toJSON())". - */ - vm->top_frame->previous->skip = 1; - - return NJS_APPLIED; -} - - nxt_inline njs_native_frame_t * njs_function_previous_frame(njs_native_frame_t *frame) { diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_math.c --- a/njs/njs_math.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_math.c Fri Jul 05 21:45:28 2019 +0300 @@ -359,13 +359,15 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ njs_index_t unused) { double num; + njs_ret_t ret; nxt_uint_t i; for (i = 1; i < nargs; i++) { if (!njs_is_numeric(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } } @@ -498,6 +500,7 @@ njs_object_math_max(njs_vm_t *vm, njs_va njs_index_t unused) { double num; + njs_ret_t ret; nxt_uint_t i; if (nargs > 1) { @@ -507,9 +510,10 @@ njs_object_math_max(njs_vm_t *vm, njs_va goto done; } else if (!njs_is_numeric(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } } @@ -536,14 +540,16 @@ njs_object_math_min(njs_vm_t *vm, njs_va njs_index_t unused) { double num; + njs_ret_t ret; nxt_uint_t i; if (nargs > 1) { for (i = 1; i < nargs; i++) { if (!njs_is_numeric(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } } diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_object.c --- a/njs/njs_object.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_object.c Fri Jul 05 21:45:28 2019 +0300 @@ -2140,7 +2140,6 @@ njs_object_prototype_has_own_property(nj vm->retval = njs_value_false; return NXT_OK; - case NJS_TRAP: case NXT_ERROR: default: return ret; @@ -2181,7 +2180,6 @@ njs_object_prototype_prop_is_enumerable( retval = &njs_value_false; break; - case NJS_TRAP: case NXT_ERROR: default: return ret; diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_object_property.c --- a/njs/njs_object_property.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_object_property.c Fri Jul 05 21:45:28 2019 +0300 @@ -38,7 +38,6 @@ static njs_object_prop_t *njs_descriptor * NXT_DECLINED property was not found in object, * if pq->lhq.value != NULL it contains retval of type * njs_object_prop_t * where prop->type is NJS_WHITEOUT - * NJS_TRAP the property trap must be called, * NXT_ERROR exception has been thrown. * * TODO: @@ -53,10 +52,16 @@ njs_property_query(njs_vm_t *vm, njs_pro uint32_t (*hash)(const void *, size_t); njs_ret_t ret; njs_object_t *obj; + njs_value_t prop; njs_function_t *function; if (nxt_slow_path(!njs_is_primitive(property))) { - return njs_trap(vm, NJS_TRAP_PROPERTY); + ret = njs_value_to_string(vm, &prop, (njs_value_t *) property); + if (ret != NXT_OK) { + return ret; + } + + property = ∝ } hash = nxt_djb_hash; @@ -473,7 +478,6 @@ njs_external_property_delete(njs_vm_t *v * retval will contain the property's value * * NXT_DECLINED property was not found in object - * NJS_TRAP the property trap must be called * NJS_APPLIED the property getter was applied * NXT_ERROR exception has been thrown. * retval will contain undefined @@ -553,7 +557,6 @@ njs_value_property(njs_vm_t *vm, const n return NXT_DECLINED; - case NJS_TRAP: case NXT_ERROR: default: @@ -566,7 +569,6 @@ njs_value_property(njs_vm_t *vm, const n /* * NXT_OK property has been set successfully - * NJS_TRAP the property trap must be called * NJS_APPLIED the property setter was applied * NXT_ERROR exception has been thrown. */ @@ -669,7 +671,6 @@ njs_value_property_set(njs_vm_t *vm, njs break; - case NJS_TRAP: case NXT_ERROR: default: @@ -1152,7 +1153,6 @@ njs_object_prop_descriptor(njs_vm_t *vm, *dest = njs_value_undefined; return NXT_OK; - case NJS_TRAP: case NXT_ERROR: default: return ret; diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_regexp.c --- a/njs/njs_regexp.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_regexp.c Fri Jul 05 21:45:28 2019 +0300 @@ -112,17 +112,19 @@ njs_regexp_constructor(njs_vm_t *vm, njs pattern = njs_arg(args, nargs, 1); if (!njs_is_regexp(pattern) && !njs_is_primitive(pattern)) { - njs_vm_trap_value(vm, &args[1]); - - return njs_trap(vm, NJS_TRAP_STRING_ARG); + ret = njs_value_to_string(vm, &args[1], &args[1]); + if (ret != NXT_OK) { + return ret; + } } flags = njs_arg(args, nargs, 2); if (!njs_is_primitive(flags)) { - njs_vm_trap_value(vm, &args[2]); - - return njs_trap(vm, NJS_TRAP_STRING_ARG); + ret = njs_value_to_string(vm, &args[2], &args[2]); + if (ret != NXT_OK) { + return ret; + } } re_flags = 0; diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_string.c --- a/njs/njs_string.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_string.c Fri Jul 05 21:45:28 2019 +0300 @@ -875,6 +875,7 @@ njs_string_prototype_concat(njs_vm_t *vm { u_char *p, *start; uint64_t size, length, mask; + njs_ret_t ret; nxt_uint_t i; njs_string_prop_t string; @@ -885,9 +886,10 @@ njs_string_prototype_concat(njs_vm_t *vm for (i = 0; i < nargs; i++) { if (!njs_is_string(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_STRING_ARG); + ret = njs_value_to_string(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } } @@ -1244,16 +1246,12 @@ njs_string_prototype_char_at(njs_vm_t *v slice.string_length = njs_string_prop(&string, &args[0]); - start = 0; + start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1)); length = 1; - if (nargs > 1) { - start = njs_number(&args[1]); - - if (start < 0 || start >= (ssize_t) slice.string_length) { - start = 0; - length = 0; - } + if (start < 0 || start >= (ssize_t) slice.string_length) { + start = 0; + length = 0; } slice.start = start; @@ -1409,15 +1407,11 @@ njs_string_prototype_char_code_at(njs_vm length = njs_string_prop(&string, &args[0]); - index = 0; - - if (nargs > 1) { - index = njs_number(&args[1]); - - if (nxt_slow_path(index < 0 || index >= length)) { - num = NAN; - goto done; - } + index = njs_primitive_value_to_integer(njs_arg(args, nargs, 1)); + + if (nxt_slow_path(index < 0 || index >= length)) { + num = NAN; + goto done; } if ((uint32_t) length == string.size) { @@ -1477,6 +1471,7 @@ njs_string_bytes_from_array(njs_vm_t *vm { u_char *p; uint32_t i, length; + njs_ret_t ret; njs_array_t *array; njs_value_t *octet; @@ -1485,9 +1480,10 @@ njs_string_bytes_from_array(njs_vm_t *vm for (i = 0; i < length; i++) { if (!njs_is_numeric(&array->start[i])) { - njs_vm_trap_value(vm, &array->start[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &array->start[i], &array->start[i]); + if (ret != NXT_OK) { + return ret; + } } } @@ -1713,13 +1709,15 @@ njs_string_from_char_code(njs_vm_t *vm, double num; size_t size; int32_t code; + njs_ret_t ret; nxt_uint_t i; for (i = 1; i < nargs; i++) { if (!njs_is_numeric(&args[i])) { - njs_vm_trap_value(vm, &args[i]); - - return njs_trap(vm, NJS_TRAP_NUMBER_ARG); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } } } @@ -2426,20 +2424,16 @@ njs_string_prototype_repeat(njs_vm_t *vm uint32_t size, length; njs_string_prop_t string; - n = 0; + n = njs_primitive_value_to_integer(njs_arg(args, nargs, 1)); (void) njs_string_prop(&string, &args[0]); - if (nargs > 1) { - max = (string.size > 1) ? NJS_STRING_MAX_LENGTH / string.size - : NJS_STRING_MAX_LENGTH; - - n = njs_number(&args[1]); - - if (nxt_slow_path(n < 0 || n >= max)) { - njs_range_error(vm, NULL); - return NXT_ERROR; - } + max = (string.size > 1) ? NJS_STRING_MAX_LENGTH / string.size + : NJS_STRING_MAX_LENGTH; + + if (nxt_slow_path(n < 0 || n >= max)) { + njs_range_error(vm, NULL); + return NXT_ERROR; } if (string.size == 0) { @@ -3427,8 +3421,10 @@ njs_string_replace_search_continuation(n r = njs_vm_continuation(vm); if (!njs_is_primitive(&r->retval)) { - njs_vm_trap_value(vm, &r->retval); - return njs_trap(vm, NJS_TRAP_STRING_ARG); + ret = njs_value_to_string(vm, &r->retval, &r->retval); + if (ret != NXT_OK) { + return ret; + } } ret = njs_primitive_value_to_string(vm, &string, &r->retval); diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_string.h --- a/njs/njs_string.h Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_string.h Fri Jul 05 21:45:28 2019 +0300 @@ -177,10 +177,7 @@ const u_char *njs_string_offset(const u_ size_t index); uint32_t njs_string_index(njs_string_prop_t *string, uint32_t offset); void njs_string_offset_map_init(const u_char *start, size_t size); -njs_ret_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, - const njs_value_t *src); double njs_string_to_index(const njs_value_t *value); -double njs_string_to_number(const njs_value_t *value, nxt_bool_t parse_float); const u_char *njs_string_to_c_string(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_value.c --- a/njs/njs_value.c Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_value.c Fri Jul 05 21:45:28 2019 +0300 @@ -101,14 +101,16 @@ njs_value_release(njs_vm_t *vm, njs_valu */ njs_ret_t -njs_value_to_primitive(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) +njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, + nxt_uint_t hint) { njs_ret_t ret; - njs_value_t *retval; - njs_function_t *function; + nxt_uint_t tries; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; + njs_value_t retval nxt_aligned(16); + static const uint32_t hashes[] = { NJS_VALUE_OF_HASH, NJS_TO_STRING_HASH, @@ -119,76 +121,56 @@ njs_value_to_primitive(njs_vm_t *vm, njs nxt_string("toString"), }; - if (!njs_is_primitive(value)) { - retval = &vm->top_frame->trap_scratch; - if (!njs_is_primitive(retval)) { - - for ( ;; ) { - ret = NXT_ERROR; - - if (njs_is_object(value) && vm->top_frame->trap_tries < 2) { - hint ^= vm->top_frame->trap_tries++; - - lhq.key_hash = hashes[hint]; - lhq.key = names[hint]; - - prop = njs_object_property(vm, njs_object(value), &lhq); - - if (nxt_fast_path(prop != NULL)) { - - if (!njs_is_function(&prop->value)) { - /* Try the second method. */ - continue; - } - - function = njs_function(&prop->value); - - ret = njs_function_apply(vm, function, value, 1, - (njs_index_t) retval); - /* - * njs_function_apply() can return - * NXT_OK, NJS_APPLIED, NXT_ERROR, NXT_AGAIN. - */ - if (nxt_fast_path(ret == NXT_OK)) { - - if (njs_is_primitive(&vm->retval)) { - retval = &vm->retval; - break; - } - - /* Try the second method. */ - continue; - } - - if (ret == NJS_APPLIED) { - /* - * A user-defined method or continuation have - * been prepared to run. The method will return - * to the current instruction and will restart it. - */ - ret = 0; - } - } - } - - if (ret == NXT_ERROR) { - njs_type_error(vm, - "Cannot convert object to primitive value"); - } - - return ret; - } - } - - *value = *retval; - - njs_set_invalid(retval); + if (njs_is_primitive(value)) { + /* GC */ + *dst = *value; + return NXT_OK; } - vm->top_frame->trap_tries = 0; + tries = 0; + + for ( ;; ) { + ret = NXT_ERROR; + + if (njs_is_object(value) && tries < 2) { + hint ^= tries++; + + lhq.key_hash = hashes[hint]; + lhq.key = names[hint]; + + prop = njs_object_property(vm, njs_object(value), &lhq); + + if (prop == NULL || !njs_is_function(&prop->value)) { + /* Try the second method. */ + continue; + } + + ret = njs_function_call(vm, njs_function(&prop->value), value, 1, + (njs_index_t) &retval); - return 1; + if (nxt_fast_path(ret == NXT_OK)) { + if (njs_is_primitive(&retval)) { + break; + } + + /* Try the second method. */ + continue; + } + + /* NXT_ERROR */ + + return ret; + } + + njs_type_error(vm, "Cannot convert object to primitive value"); + + return ret; + } + + *dst = retval; + + return NXT_OK; } diff -r 2fdad3cbbd74 -r 201af81dfa9b njs/njs_value.h --- a/njs/njs_value.h Thu Jul 18 21:12:25 2019 +0300 +++ b/njs/njs_value.h Fri Jul 05 21:45:28 2019 +0300 @@ -114,6 +114,9 @@ typedef struct njs_date_s nj typedef struct njs_property_next_s njs_property_next_t; typedef struct njs_object_init_s njs_object_init_t; +#if (!NXT_HAVE_GCC_ATTRIBUTE_ALIGNED) +#error "aligned attribute is required" +#endif union njs_value_s { /* @@ -560,10 +563,6 @@ typedef enum { *(value) = njs_value_undefined From xeioex at nginx.com Fri Jul 19 20:28:16 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 19 Jul 2019 20:28:16 +0000 Subject: [njs] Refactored working with function calls. Message-ID: details: https://hg.nginx.org/njs/rev/540f03725df2 branches: changeset: 1061:540f03725df2 user: hongzhidao date: Tue Jul 16 22:44:16 2019 -0400 description: Refactored working with function calls. 1) njs_continuation_t is removed (appropriate functions are rewritten). 2) all function calls are made syncronous. This closes #190 issue on Github. diffstat: njs/njs.c | 24 +- njs/njs_array.c | 1303 +++++++++++++++----------------------------- njs/njs_boolean.c | 4 +- njs/njs_builtin.c | 2 +- njs/njs_crypto.c | 16 +- njs/njs_date.c | 158 ++-- njs/njs_error.c | 7 +- njs/njs_fs.c | 66 +- njs/njs_function.c | 232 ++----- njs/njs_function.h | 75 +- njs/njs_json.c | 173 +++-- njs/njs_math.c | 126 ++-- njs/njs_number.c | 20 +- njs/njs_object.c | 42 +- njs/njs_object.h | 4 +- njs/njs_object_property.c | 18 +- njs/njs_regexp.c | 10 +- njs/njs_string.c | 133 +-- njs/njs_value.c | 7 +- njs/njs_value.h | 3 +- njs/njs_vm.c | 136 +--- njs/njs_vm.h | 11 +- njs/test/njs_unit_test.c | 9 +- 23 files changed, 986 insertions(+), 1593 deletions(-) diffs (truncated from 5002 to 1000 lines): diff -r 201af81dfa9b -r 540f03725df2 njs/njs.c --- a/njs/njs.c Fri Jul 05 21:45:28 2019 +0300 +++ b/njs/njs.c Tue Jul 16 22:44:16 2019 -0400 @@ -456,7 +456,7 @@ nxt_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args, nxt_uint_t nargs) { - return njs_vm_invoke(vm, function, args, nargs, NJS_INDEX_GLOBAL_RETVAL); + return njs_vm_invoke(vm, function, args, nargs, (njs_index_t) &vm->retval); } @@ -464,30 +464,18 @@ nxt_int_t njs_vm_invoke(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args, nxt_uint_t nargs, njs_index_t retval) { - u_char *current; njs_ret_t ret; njs_value_t *this; this = (njs_value_t *) &njs_value_undefined; - current = vm->current; - - vm->current = (u_char *) njs_continuation_nexus; - - ret = njs_function_activate(vm, function, this, args, nargs, retval, - sizeof(njs_vmcode_generic_t)); - - if (nxt_fast_path(ret == NJS_APPLIED)) { - ret = njs_vmcode_interpreter(vm); - - if (ret == NJS_STOP) { - ret = NXT_OK; - } + ret = njs_function_frame(vm, function, this, (njs_value_t *) args, nargs, + 0); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; } - vm->current = current; - - return ret; + return njs_function_frame_invoke(vm, retval); } diff -r 201af81dfa9b -r 540f03725df2 njs/njs_array.c --- a/njs/njs_array.c Fri Jul 05 21:45:28 2019 +0300 +++ b/njs/njs_array.c Tue Jul 16 22:44:16 2019 -0400 @@ -9,133 +9,9 @@ #include -typedef struct { - union { - njs_continuation_t cont; - u_char padding[NJS_CONTINUATION_SIZE]; - } u; - /* - * This retval value must be aligned so the continuation is padded - * to aligned size. - */ - njs_value_t length; -} njs_array_slice_t; - - -typedef struct { - union { - njs_continuation_t cont; - u_char padding[NJS_CONTINUATION_SIZE]; - } u; - - njs_value_t length; - nxt_int_t start; - nxt_int_t end; -} njs_array_fill_t; - - -typedef struct { - njs_continuation_t cont; - njs_value_t *values; - uint32_t max; -} njs_array_join_t; - - -typedef struct { - union { - njs_continuation_t cont; - u_char padding[NJS_CONTINUATION_SIZE]; - } u; - /* - * This retval value must be aligned so the continuation is padded - * to aligned size. - */ - njs_value_t retval; - - uint32_t index; - uint32_t length; -} njs_array_iter_t; - - -typedef struct { - njs_array_iter_t iter; - njs_value_t value; - njs_array_t *array; -} njs_array_filter_t; - - -typedef struct { - njs_array_iter_t iter; - njs_value_t value; -} njs_array_find_t; - - -typedef struct { - njs_array_iter_t iter; - njs_array_t *array; -} njs_array_map_t; - - -typedef struct { - union { - njs_continuation_t cont; - u_char padding[NJS_CONTINUATION_SIZE]; - } u; - /* - * This retval value must be aligned so the continuation is padded - * to aligned size. - */ - njs_value_t retval; - - njs_function_t *function; - uint32_t index; - uint32_t current; -} njs_array_sort_t; - - -static njs_ret_t njs_array_prototype_slice_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static njs_ret_t njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, int64_t start, int64_t length); -static njs_ret_t njs_array_prototype_join_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static njs_value_t *njs_array_copy(njs_value_t *dst, njs_value_t *src); -static njs_ret_t njs_array_prototype_fill_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_fill_object_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_for_each_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_some_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_every_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_filter_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_find_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_find_index_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_map_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static uint32_t njs_array_prototype_map_index(njs_array_t *array, - njs_array_map_t *map); -static njs_ret_t njs_array_iterator_args(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs); -static uint32_t njs_array_iterator_index(njs_array_t *array, - njs_array_iter_t *iter); -static njs_ret_t njs_array_iterator_apply(njs_vm_t *vm, - njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs); -static njs_ret_t njs_array_prototype_find_apply(njs_vm_t *vm, - njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs); -static njs_ret_t njs_array_prototype_reduce_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static njs_ret_t njs_array_prototype_reduce_right_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -static uint32_t njs_array_reduce_right_index(njs_array_t *array, - njs_array_iter_t *iter); -static njs_ret_t njs_array_prototype_sort_continuation(njs_vm_t *vm, - njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); njs_array_t * @@ -407,7 +283,7 @@ static const njs_object_prop_t njs_arra { .type = NJS_METHOD, .name = njs_string("isArray"), - .value = njs_native_function(njs_array_is_array, 0, 0), + .value = njs_native_function(njs_array_is_array, 0), .writable = 1, .configurable = 1, }, @@ -417,7 +293,7 @@ static const njs_object_prop_t njs_arra { .type = NJS_METHOD, .name = njs_string("of"), - .value = njs_native_function(njs_array_of, 0, 0), + .value = njs_native_function(njs_array_of, 0), .writable = 1, .configurable = 1, }, @@ -517,44 +393,26 @@ static njs_ret_t njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - njs_ret_t ret; - njs_array_slice_t *slice; - - static const njs_value_t njs_string_length = njs_string("length"); - - slice = njs_vm_continuation(vm); - slice->u.cont.function = njs_array_prototype_slice_continuation; - - ret = njs_value_property(vm, &args[0], &njs_string_length, &slice->length, - 0); - - if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) { + int64_t start, end, length; + njs_ret_t ret; + njs_value_t prop_length; + + static const njs_value_t string_length = njs_string("length"); + + ret = njs_value_property(vm, &args[0], &string_length, &prop_length); + if (nxt_slow_path(ret == NXT_ERROR)) { return ret; } - return njs_array_prototype_slice_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_slice_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - int64_t start, end, length; - njs_ret_t ret; - njs_array_slice_t *slice; - - slice = njs_vm_continuation(vm); - - if (nxt_slow_path(!njs_is_primitive(&slice->length))) { - ret = njs_value_to_numeric(vm, &slice->length, &slice->length); + if (nxt_slow_path(!njs_is_primitive(&prop_length))) { + ret = njs_value_to_numeric(vm, &prop_length, &prop_length); if (ret != NXT_OK) { return ret; } } start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1)); - length = njs_primitive_value_to_length(&slice->length); + length = njs_primitive_value_to_length(&prop_length); if (start < 0) { start += length; @@ -675,7 +533,7 @@ njs_array_prototype_slice_copy(njs_vm_t njs_uint32_to_string(&name, start++); value = &array->start[n++]; - ret = njs_value_property(vm, this, &name, value, 0); + ret = njs_value_property(vm, this, &name, value); if (ret != NXT_OK) { *value = njs_value_invalid; @@ -970,8 +828,8 @@ njs_array_prototype_to_string(njs_vm_t * prop = njs_object_property(vm, njs_object(&args[0]), &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { - return njs_function_call(vm, njs_function(&prop->value), args, - nargs, (njs_index_t) &vm->retval); + return njs_function_apply(vm, njs_function(&prop->value), args, + nargs, &vm->retval); } } @@ -983,26 +841,24 @@ static njs_ret_t njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - uint32_t max; - nxt_uint_t i, n; - njs_array_t *array; - njs_value_t *value, *values; - njs_array_join_t *join; - - if (!njs_is_array(&args[0])) { - goto empty; + u_char *p; + uint32_t max; + size_t size, length, mask; + njs_ret_t ret; + nxt_uint_t i, n; + njs_array_t *array; + njs_value_t *value, *values; + njs_string_prop_t separator, string; + + if (!njs_is_array(&args[0]) || njs_array_len(&args[0]) == 0) { + vm->retval = njs_string_empty; + return NXT_OK; } array = njs_array(&args[0]); - if (array->length == 0) { - goto empty; - } - - join = njs_vm_continuation(vm); - join->values = NULL; - join->max = 0; max = 0; + values = NULL; for (i = 0; i < array->length; i++) { value = &array->start[i]; @@ -1023,11 +879,6 @@ njs_array_prototype_join(njs_vm_t *vm, n return NXT_ERROR; } - join = njs_vm_continuation(vm); - join->cont.function = njs_array_prototype_join_continuation; - join->values = values; - join->max = max; - n = 0; for (i = 0; i < array->length; i++) { @@ -1046,34 +897,6 @@ njs_array_prototype_join(njs_vm_t *vm, n } } - return njs_array_prototype_join_continuation(vm, args, nargs, unused); - -empty: - - vm->retval = njs_string_empty; - - return NXT_OK; -} - - -static njs_ret_t -njs_array_prototype_join_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - u_char *p; - size_t size, length, mask; - uint32_t max; - njs_ret_t ret; - nxt_uint_t i, n; - njs_array_t *array; - njs_value_t *value, *values; - njs_array_join_t *join; - njs_string_prop_t separator, string; - - join = njs_vm_continuation(vm); - values = join->values; - max = join->max; - size = 0; length = 0; n = 0; @@ -1422,11 +1245,14 @@ static njs_ret_t njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - njs_ret_t ret; - njs_value_t *this; - njs_array_fill_t *fill; - - static const njs_value_t njs_string_length = njs_string("length"); + njs_ret_t ret; + nxt_int_t i, start, end, length; + njs_array_t *array; + njs_value_t name, prop_length; + njs_object_t *object; + const njs_value_t *this, *value; + + static const njs_value_t string_length = njs_string("length"); this = (njs_value_t *) njs_arg(args, nargs, 0); @@ -1437,38 +1263,6 @@ njs_array_prototype_fill(njs_vm_t *vm, n return NJS_ERROR; } - } else if (!njs_is_array(this)) { - fill = njs_vm_continuation(vm); - fill->u.cont.function = njs_array_prototype_fill_continuation; - - ret = njs_value_property(vm, this, &njs_string_length, &fill->length, - 0); - - if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) { - return ret; - } - } - - return njs_array_prototype_fill_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_fill_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - nxt_int_t i, start, end, length; - njs_ret_t ret; - njs_array_t *array; - njs_object_t *object; - njs_array_fill_t *fill; - const njs_value_t *this, *value; - - array = NULL; - - this = njs_arg(args, nargs, 0); - - if (njs_is_primitive(this)) { object = njs_object_value_alloc(vm, this, this->type); if (nxt_slow_path(object == NULL)) { return NXT_ERROR; @@ -1479,22 +1273,26 @@ njs_array_prototype_fill_continuation(nj return NXT_OK; } - fill = njs_vm_continuation(vm); + array = NULL; if (njs_is_array(this)) { array = njs_array(this); length = array->length; } else { - - if (nxt_slow_path(!njs_is_primitive(&fill->length))) { - ret = njs_value_to_numeric(vm, &fill->length, &fill->length); + ret = njs_value_property(vm, this, &string_length, &prop_length); + if (nxt_slow_path(ret == NXT_ERROR)) { + return ret; + } + + if (nxt_slow_path(!njs_is_primitive(&prop_length))) { + ret = njs_value_to_numeric(vm, &prop_length, &prop_length); if (ret != NXT_OK) { return ret; } } - length = njs_primitive_value_to_length(&fill->length); + length = njs_primitive_value_to_length(&prop_length); } start = njs_primitive_value_to_integer(njs_arg(args, nargs, 2)); @@ -1521,81 +1319,79 @@ njs_array_prototype_fill_continuation(nj return NXT_OK; } - fill->u.cont.function = njs_array_prototype_fill_object_continuation; - fill->start = start; - fill->end = end; - - return njs_array_prototype_fill_object_continuation(vm, args, nargs, - unused); -} - - -static njs_ret_t -njs_array_prototype_fill_object_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - njs_ret_t ret; - nxt_int_t end; - njs_value_t name; - njs_array_fill_t *fill; - const njs_value_t *value; - - fill = njs_vm_continuation(vm); - end = fill->end; - - vm->retval = *njs_arg(args, nargs, 0); value = njs_arg(args, nargs, 1); - while (fill->start < end) { - njs_uint32_to_string(&name, fill->start++); - - ret = njs_value_property_set(vm, &vm->retval, &name, - (njs_value_t *) value, 0); - if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) { + while (start < end) { + njs_uint32_to_string(&name, start++); + + ret = njs_value_property_set(vm, (njs_value_t *) this, &name, + (njs_value_t *) value); + if (nxt_slow_path(ret == NXT_ERROR)) { return ret; } } + vm->retval = *this; + return NXT_OK; } +nxt_inline njs_ret_t +njs_array_iterator_call(njs_vm_t *vm, njs_function_t *function, + const njs_value_t *this_arg, njs_value_t *value, uint32_t n, + njs_value_t *array) +{ + njs_value_t arguments[3]; + + /* GC: array elt, array */ + + arguments[0] = *value; + njs_set_number(&arguments[1], n); + arguments[2] = *array; + + return njs_function_call(vm, function, (njs_value_t *) this_arg, + arguments, 3, &vm->retval); +} + + static njs_ret_t njs_array_prototype_for_each(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; - njs_array_iter_t *iter; - - ret = njs_array_iterator_args(vm, args, nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + uint32_t i, length; + nxt_int_t ret; + njs_value_t *array, *value; + njs_function_t *function; + const njs_value_t *this_arg; + + if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) { + njs_type_error(vm, "unexpected iterator arguments"); + return NXT_ERROR; } - iter = njs_vm_continuation(vm); - iter->u.cont.function = njs_array_prototype_for_each_continuation; - - return njs_array_prototype_for_each_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_for_each_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - uint32_t index; - njs_array_iter_t *iter; - - iter = njs_vm_continuation(vm); - - index = njs_array_iterator_index(njs_array(&args[0]), iter); - - if (index == NJS_ARRAY_INVALID_INDEX) { - vm->retval = njs_value_undefined; - return NXT_OK; + array = &args[0]; + length = njs_array_len(array); + function = njs_function(&args[1]); + this_arg = njs_arg(args, nargs, 2); + + for (i = 0; i < length; i++) { + value = &njs_array_start(array)[i]; + + if (njs_is_valid(value)) { + ret = njs_array_iterator_call(vm, function, this_arg, value, i, + array); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + } + + length = nxt_min(length, njs_array_len(array)); } - return njs_array_iterator_apply(vm, iter, args, nargs); + vm->retval = njs_value_undefined; + + return NXT_OK; } @@ -1603,43 +1399,41 @@ static njs_ret_t njs_array_prototype_some(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; - njs_array_iter_t *iter; - - ret = njs_array_iterator_args(vm, args, nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + uint32_t i, length; + nxt_int_t ret; + njs_value_t *array, *value; + njs_function_t *function; + const njs_value_t *this_arg, *retval; + + if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) { + njs_type_error(vm, "unexpected iterator arguments"); + return NXT_ERROR; } - iter = njs_vm_continuation(vm); - iter->u.cont.function = njs_array_prototype_some_continuation; - - return njs_array_prototype_some_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_some_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - uint32_t index; - njs_array_iter_t *iter; - const njs_value_t *retval; - - iter = njs_vm_continuation(vm); - - if (njs_is_true(&iter->retval)) { - retval = &njs_value_true; - - } else { - index = njs_array_iterator_index(njs_array(&args[0]), iter); - - if (index == NJS_ARRAY_INVALID_INDEX) { - retval = &njs_value_false; - - } else { - return njs_array_iterator_apply(vm, iter, args, nargs); + array = &args[0]; + length = njs_array_len(array); + function = njs_function(&args[1]); + this_arg = njs_arg(args, nargs, 2); + + retval = &njs_value_false; + + for (i = 0; i < length; i++) { + value = &njs_array_start(array)[i]; + + if (njs_is_valid(value)) { + ret = njs_array_iterator_call(vm, function, this_arg, value, i, + array); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + if (njs_is_true(&vm->retval)) { + retval = &njs_value_true; + break; + } } + + length = nxt_min(length, njs_array_len(array)); } vm->retval = *retval; @@ -1652,44 +1446,41 @@ static njs_ret_t njs_array_prototype_every(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; - njs_array_iter_t *iter; - - ret = njs_array_iterator_args(vm, args, nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + uint32_t i, length; + nxt_int_t ret; + njs_value_t *array, *value; + njs_function_t *function; + const njs_value_t *this_arg, *retval; + + if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) { + njs_type_error(vm, "unexpected iterator arguments"); + return NXT_ERROR; } - iter = njs_vm_continuation(vm); - iter->u.cont.function = njs_array_prototype_every_continuation; - iter->retval.data.truth = 1; - - return njs_array_prototype_every_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_every_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - uint32_t index; - njs_array_iter_t *iter; - const njs_value_t *retval; - - iter = njs_vm_continuation(vm); - - if (!njs_is_true(&iter->retval)) { - retval = &njs_value_false; - - } else { - index = njs_array_iterator_index(njs_array(&args[0]), iter); - - if (index == NJS_ARRAY_INVALID_INDEX) { - retval = &njs_value_true; - - } else { - return njs_array_iterator_apply(vm, iter, args, nargs); + array = &args[0]; + length = njs_array_len(array); + function = njs_function(&args[1]); + this_arg = njs_arg(args, nargs, 2); + + retval = &njs_value_true; + + for (i = 0; i < length; i++) { + value = &njs_array_start(array)[i]; + + if (njs_is_valid(value)) { + ret = njs_array_iterator_call(vm, function, this_arg, value, i, + array); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + if (!njs_is_true(&vm->retval)) { + retval = &njs_value_false; + break; + } } + + length = nxt_min(length, njs_array_len(array)); } vm->retval = *retval; @@ -1702,57 +1493,52 @@ static njs_ret_t njs_array_prototype_filter(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; - njs_array_filter_t *filter; - - ret = njs_array_iterator_args(vm, args, nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + uint32_t i, length; + nxt_int_t ret; + njs_array_t *retval; + njs_value_t *array, value; + njs_function_t *function; + const njs_value_t *this_arg; + + if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) { + njs_type_error(vm, "unexpected iterator arguments"); + return NXT_ERROR; } - filter = njs_vm_continuation(vm); - filter->iter.u.cont.function = njs_array_prototype_filter_continuation; - - filter->array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); - if (nxt_slow_path(filter->array == NULL)) { + array = &args[0]; + length = njs_array_len(array); + function = njs_function(&args[1]); + this_arg = njs_arg(args, nargs, 2); + + retval = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); + if (nxt_slow_path(retval == NULL)) { return NXT_ERROR; } - return njs_array_prototype_filter_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_filter_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - uint32_t index; - nxt_int_t ret; - njs_array_t *array; - njs_array_filter_t *filter; - - filter = njs_vm_continuation(vm); - - if (njs_is_true(&filter->iter.retval)) { - ret = njs_array_add(vm, filter->array, &filter->value); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + for (i = 0; i < length; i++) { + value = njs_array_start(array)[i]; + + if (njs_is_valid(&value)) { + ret = njs_array_iterator_call(vm, function, this_arg, &value, i, + array); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + if (njs_is_true(&vm->retval)) { + ret = njs_array_add(vm, retval, &value); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + } } + + length = nxt_min(length, njs_array_len(array)); } - array = njs_array(&args[0]); - index = njs_array_iterator_index(array, &filter->iter); - - if (index == NJS_ARRAY_INVALID_INDEX) { - njs_set_array(&vm->retval, filter->array); - - return NXT_OK; - } - - /* GC: filter->value */ - filter->value = array->start[index]; - - return njs_array_iterator_apply(vm, &filter->iter, args, nargs); + njs_set_array(&vm->retval, retval); + + return NXT_OK; } @@ -1760,50 +1546,42 @@ static njs_ret_t njs_array_prototype_find(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; - njs_array_find_t *find; - - ret = njs_array_iterator_args(vm, args, nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + uint32_t i, length; + nxt_int_t ret; + njs_value_t *array, value; + njs_function_t *function; + const njs_value_t *this_arg, *retval; + + if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) { + njs_type_error(vm, "unexpected iterator arguments"); + return NXT_ERROR; } - find = njs_vm_continuation(vm); - find->iter.u.cont.function = njs_array_prototype_find_continuation; - - return njs_array_prototype_find_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_find_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - njs_array_t *array; - njs_array_iter_t *iter; - njs_array_find_t *find; - const njs_value_t *retval; + array = &args[0]; + length = njs_array_len(array); + function = njs_function(&args[1]); + this_arg = njs_arg(args, nargs, 2); retval = &njs_value_undefined; - find = njs_vm_continuation(vm); - iter = &find->iter; - - if (!njs_is_true(&iter->retval)) { - array = njs_array(&args[0]); - iter->index++; - - if (iter->index < iter->length && iter->index < array->length) { - /* GC: find->value */ - find->value = array->start[iter->index]; - - return njs_array_prototype_find_apply(vm, iter, args, nargs); + for (i = 0; i < length; i++) { + value = njs_array_start(array)[i]; + + if (!njs_is_valid(&value)) { + value = njs_value_undefined; } - } else { - if (njs_is_valid(&find->value)) { - retval = &find->value; + ret = njs_array_iterator_call(vm, function, this_arg, &value, i, array); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; } + + if (njs_is_true(&vm->retval)) { + retval = &value; + break; + } + + length = nxt_min(length, njs_array_len(array)); } vm->retval = *retval; @@ -1816,41 +1594,43 @@ static njs_ret_t njs_array_prototype_find_index(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; - njs_array_iter_t *iter; - - ret = njs_array_iterator_args(vm, args, nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; + double index; + uint32_t i, length; + nxt_int_t ret; + njs_value_t *array, value; + njs_function_t *function; + const njs_value_t *this_arg; + + if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) { + njs_type_error(vm, "unexpected iterator arguments"); + return NXT_ERROR; } - iter = njs_vm_continuation(vm); - iter->u.cont.function = njs_array_prototype_find_index_continuation; - - return njs_array_prototype_find_index_continuation(vm, args, nargs, unused); -} - - -static njs_ret_t -njs_array_prototype_find_index_continuation(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, njs_index_t unused) -{ - double index; - njs_array_iter_t *iter; - - iter = njs_vm_continuation(vm); - index = iter->index; - - if (!njs_is_true(&iter->retval)) { - iter->index++; - - if (iter->index < iter->length - && iter->index < njs_array_len(&args[0])) - { - return njs_array_prototype_find_apply(vm, iter, args, nargs); + array = &args[0]; + length = njs_array_len(array); + function = njs_function(&args[1]); + this_arg = njs_arg(args, nargs, 2); + + index = -1; + + for (i = 0; i < length; i++) { + value = njs_array_start(array)[i]; + + if (!njs_is_valid(&value)) { + value = njs_value_undefined; } - index = -1; + ret = njs_array_iterator_call(vm, function, this_arg, &value, i, array); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + if (njs_is_true(&vm->retval)) { + index = i; + break; + } + + length = nxt_min(length, njs_array_len(array)); } njs_set_number(&vm->retval, index); @@ -1860,109 +1640,79 @@ njs_array_prototype_find_index_continuat From xeioex at nginx.com Fri Jul 19 20:28:16 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 19 Jul 2019 20:28:16 +0000 Subject: [njs] Added njs_set_int32() and njs_set_uint32() intrinsics. Message-ID: details: https://hg.nginx.org/njs/rev/8b977c78885f branches: changeset: 1062:8b977c78885f user: Dmitry Volyntsev date: Fri Jul 19 22:05:34 2019 +0300 description: Added njs_set_int32() and njs_set_uint32() intrinsics. diffstat: njs/njs_value.h | 18 ++++++++++++++++++ njs/njs_vm.c | 14 +++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diffs (94 lines): diff -r 540f03725df2 -r 8b977c78885f njs/njs_value.h --- a/njs/njs_value.h Tue Jul 16 22:44:16 2019 -0400 +++ b/njs/njs_value.h Fri Jul 19 22:05:34 2019 +0300 @@ -621,6 +621,24 @@ njs_set_number(njs_value_t *value, doubl nxt_inline void +njs_set_int32(njs_value_t *value, int32_t num) +{ + value->data.u.number = num; + value->type = NJS_NUMBER; + value->data.truth = (num != 0); +} + + +nxt_inline void +njs_set_uint32(njs_value_t *value, uint32_t num) +{ + value->data.u.number = num; + value->type = NJS_NUMBER; + value->data.truth = (num != 0); +} + + +nxt_inline void njs_set_data(njs_value_t *value, void *data) { value->data.u.data = data; diff -r 540f03725df2 -r 8b977c78885f njs/njs_vm.c --- a/njs/njs_vm.c Tue Jul 16 22:44:16 2019 -0400 +++ b/njs/njs_vm.c Fri Jul 19 22:05:34 2019 +0300 @@ -1375,7 +1375,7 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_ num1 = njs_number_to_int32(njs_number(val1)); num2 = njs_number_to_uint32(njs_number(val2)); - njs_set_number(&vm->retval, num1 << (num2 & 0x1f)); + njs_set_int32(&vm->retval, num1 << (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); } @@ -1409,7 +1409,7 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs num1 = njs_number_to_int32(njs_number(val1)); num2 = njs_number_to_uint32(njs_number(val2)); - njs_set_number(&vm->retval, num1 >> (num2 & 0x1f)); + njs_set_int32(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); } @@ -1443,7 +1443,7 @@ njs_vmcode_unsigned_right_shift(njs_vm_t num1 = njs_number_to_uint32(njs_number(val1)); num2 = njs_number_to_uint32(njs_number(val2)); - njs_set_number(&vm->retval, num1 >> (num2 & 0x1f)); + njs_set_uint32(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); } @@ -1505,7 +1505,7 @@ njs_vmcode_bitwise_not(njs_vm_t *vm, njs value = &numeric; } - njs_set_number(&vm->retval, ~njs_number_to_integer(njs_number(value))); + njs_set_int32(&vm->retval, ~njs_number_to_integer(njs_number(value))); return sizeof(njs_vmcode_2addr_t); } @@ -1538,7 +1538,7 @@ njs_vmcode_bitwise_and(njs_vm_t *vm, njs num1 = njs_number_to_integer(njs_number(val1)); num2 = njs_number_to_integer(njs_number(val2)); - njs_set_number(&vm->retval, num1 & num2); + njs_set_int32(&vm->retval, num1 & num2); return sizeof(njs_vmcode_3addr_t); } @@ -1571,7 +1571,7 @@ njs_vmcode_bitwise_xor(njs_vm_t *vm, njs num1 = njs_number_to_integer(njs_number(val1)); num2 = njs_number_to_integer(njs_number(val2)); - njs_set_number(&vm->retval, num1 ^ num2); + njs_set_int32(&vm->retval, num1 ^ num2); return sizeof(njs_vmcode_3addr_t); } @@ -1604,7 +1604,7 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ num1 = njs_number_to_integer(njs_number(val1)); num2 = njs_number_to_integer(njs_number(val2)); - njs_set_number(&vm->retval, num1 | num2); + njs_set_int32(&vm->retval, num1 | num2); return sizeof(njs_vmcode_3addr_t); } From xeioex at nginx.com Fri Jul 19 20:28:16 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 19 Jul 2019 20:28:16 +0000 Subject: [njs] Inlining call to hash function in njs_property_query(). Message-ID: details: https://hg.nginx.org/njs/rev/9da8ebc3dc07 branches: changeset: 1063:9da8ebc3dc07 user: Dmitry Volyntsev date: Fri Jul 19 23:27:53 2019 +0300 description: Inlining call to hash function in njs_property_query(). diffstat: njs/njs_object_property.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diffs (29 lines): diff -r 8b977c78885f -r 9da8ebc3dc07 njs/njs_object_property.c --- a/njs/njs_object_property.c Fri Jul 19 22:05:34 2019 +0300 +++ b/njs/njs_object_property.c Fri Jul 19 23:27:53 2019 +0300 @@ -49,7 +49,6 @@ njs_property_query(njs_vm_t *vm, njs_pro const njs_value_t *property) { uint32_t index; - uint32_t (*hash)(const void *, size_t); njs_ret_t ret; njs_object_t *obj; njs_value_t prop; @@ -64,8 +63,6 @@ njs_property_query(njs_vm_t *vm, njs_pro property = ∝ } - hash = nxt_djb_hash; - switch (object->type) { case NJS_BOOLEAN: @@ -140,7 +137,7 @@ njs_property_query(njs_vm_t *vm, njs_pro if (nxt_fast_path(ret == NXT_OK)) { njs_string_get(&pq->value, &pq->lhq.key); - pq->lhq.key_hash = hash(pq->lhq.key.start, pq->lhq.key.length); + pq->lhq.key_hash = nxt_djb_hash(pq->lhq.key.start, pq->lhq.key.length); if (obj == NULL) { pq->own = 1; From xeioex at nginx.com Fri Jul 19 21:31:14 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 19 Jul 2019 21:31:14 +0000 Subject: [njs] Added Object shorthand methods and computed property names. Message-ID: details: https://hg.nginx.org/njs/rev/97ab91a7c7f5 branches: changeset: 1064:97ab91a7c7f5 user: hongzhidao date: Tue Jul 02 22:24:11 2019 -0400 description: Added Object shorthand methods and computed property names. This closes #182 issue on Github. diffstat: njs/njs_parser.c | 4 +-- njs/njs_parser.h | 2 + njs/njs_parser_terminal.c | 57 ++++++++++++++++++++++++++++++++++++++++++---- njs/njs_vm.c | 5 +--- njs/test/njs_unit_test.c | 36 ++++++++++++++++++++++++++++- 5 files changed, 89 insertions(+), 15 deletions(-) diffs (190 lines): diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_parser.c --- a/njs/njs_parser.c Fri Jul 19 23:27:53 2019 +0300 +++ b/njs/njs_parser.c Tue Jul 02 22:24:11 2019 -0400 @@ -24,8 +24,6 @@ static njs_token_t njs_parser_labelled_s njs_parser_t *parser); static njs_token_t njs_parser_function_declaration(njs_vm_t *vm, njs_parser_t *parser); -static njs_token_t njs_parser_function_lambda(njs_vm_t *vm, - njs_parser_t *parser, njs_function_lambda_t *lambda, njs_token_t token); static njs_token_t njs_parser_lambda_arguments(njs_vm_t *vm, njs_parser_t *parser, njs_function_lambda_t *lambda, njs_index_t index, njs_token_t token); @@ -757,7 +755,7 @@ njs_parser_function_expression(njs_vm_t } -static njs_token_t +njs_token_t njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, njs_function_lambda_t *lambda, njs_token_t token) { diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_parser.h --- a/njs/njs_parser.h Fri Jul 19 23:27:53 2019 +0300 +++ b/njs/njs_parser.h Tue Jul 02 22:24:11 2019 -0400 @@ -95,6 +95,8 @@ njs_token_t njs_parser_template_literal( njs_parser_node_t *njs_parser_argument(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *expr, njs_index_t index); nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value); +njs_token_t njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, + njs_function_lambda_t *lambda, njs_token_t token); njs_token_t njs_parser_lambda_statements(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node); diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_parser_terminal.c --- a/njs/njs_parser_terminal.c Fri Jul 19 23:27:53 2019 +0300 +++ b/njs/njs_parser_terminal.c Tue Jul 02 22:24:11 2019 -0400 @@ -480,12 +480,13 @@ njs_parser_builtin(njs_vm_t *vm, njs_par static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) { - uint32_t hash, token_line; - nxt_int_t ret; - nxt_str_t name; - njs_token_t token, prop_token; - njs_lexer_t *lexer; - njs_parser_node_t *object, *property, *expression; + uint32_t hash, token_line; + nxt_int_t ret; + nxt_str_t name; + njs_token_t token, prop_token; + njs_lexer_t *lexer; + njs_parser_node_t *object, *property, *expression; + njs_function_lambda_t *lambda; lexer = parser->lexer; @@ -513,6 +514,26 @@ njs_parser_object(njs_vm_t *vm, njs_pars case NJS_TOKEN_CLOSE_BRACE: goto done; + case NJS_TOKEN_OPEN_BRACKET: + token = njs_parser_token(vm, parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + if (token == NJS_TOKEN_CLOSE_BRACKET) { + return NJS_TOKEN_ILLEGAL; + } + + token = njs_parser_assignment_expression(vm, parser, token); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + property = parser->node; + + token = njs_parser_match(vm, parser, token, NJS_TOKEN_CLOSE_BRACKET); + break; + case NJS_TOKEN_NUMBER: case NJS_TOKEN_STRING: case NJS_TOKEN_ESCAPE_STRING: @@ -576,6 +597,30 @@ njs_parser_object(njs_vm_t *vm, njs_pars expression = parser->node; break; + case NJS_TOKEN_OPEN_PARENTHESIS: + expression = njs_parser_node_new(vm, parser, + NJS_TOKEN_FUNCTION_EXPRESSION); + if (nxt_slow_path(expression == NULL)) { + return NJS_TOKEN_ERROR; + } + + expression->token_line = njs_parser_token_line(parser); + parser->node = expression; + + lambda = njs_function_lambda_alloc(vm, 0); + if (nxt_slow_path(lambda == NULL)) { + return NJS_TOKEN_ERROR; + } + + expression->u.value.data.u.lambda = lambda; + + token = njs_parser_function_lambda(vm, parser, lambda, token); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + break; + default: return NJS_TOKEN_ILLEGAL; } diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_vm.c --- a/njs/njs_vm.c Fri Jul 19 23:27:53 2019 +0300 +++ b/njs/njs_vm.c Tue Jul 02 22:24:11 2019 -0400 @@ -478,11 +478,8 @@ njs_vmcode_property_init(njs_vm_t *vm, n break; case NJS_OBJECT: - ret = njs_primitive_value_to_string(vm, &name, property); + ret = njs_value_to_string(vm, &name, property); if (nxt_slow_path(ret != NXT_OK)) { - njs_internal_error(vm, "failed conversion of type \"%s\" " - "to string while property initialization", - njs_type_string(property->type)); return NXT_ERROR; } diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Jul 19 23:27:53 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue Jul 02 22:24:11 2019 -0400 @@ -3126,7 +3126,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var x = { a: 1 }, b = delete x.a; x.a +' '+ b"), nxt_string("undefined true") }, - /* Shorthand Object literals. */ + /* Object shorthand property. */ { nxt_string("var a = 1; njs.dump({a})"), nxt_string("{a:1}") }, @@ -3173,6 +3173,38 @@ static njs_unit_test_t njs_test[] = { nxt_string("delete undefined"), nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, + /* Object shorthand methods. */ + + { nxt_string("var o = {m(){}}; new o.m();"), + nxt_string("TypeError: function is not a constructor") }, + + { nxt_string("var o = {sum(a, b){return a + b;}}; o.sum(1, 2)"), + nxt_string("3") }, + + /* Object computed property. */ + + { nxt_string("var o = { [0]: 1, [-0]: 2 }; o[0];"), + nxt_string("2") }, + + { nxt_string("var k = 'abc'.split('');var o = {[k[0]]: 'baz'}; o.a"), + nxt_string("baz") }, + + { nxt_string("var k = {}; var o = {[k]() {return 'baz'}}; o[k]()"), + nxt_string("baz") }, + + { nxt_string("njs.dump({[{toString(){return 'xx'}}]:1})"), + nxt_string("{xx:1}") }, + + { nxt_string("var o = {}; Object.defineProperty(o, 'toString', {value:()=>'xx'});" + "njs.dump({[o]:1})"), + nxt_string("{xx:1}") }, + + { nxt_string("({[{toString(){return {}}}]:1})"), + nxt_string("TypeError: Cannot convert object to primitive value") }, + + { nxt_string("var o = { [new Number(12345)]: 1000 }; o[12345]"), + nxt_string("1000") }, + /* ES5FIX: "SyntaxError". */ { nxt_string("delete NaN"), @@ -3248,7 +3280,7 @@ static njs_unit_test_t njs_test[] = nxt_string("4") }, { nxt_string("({[]:1})"), - nxt_string("SyntaxError: Unexpected token \"[\" in 1") }, + nxt_string("SyntaxError: Unexpected token \"]\" in 1") }, { nxt_string("({'AB\\ncd':1})['AB\\ncd']"), nxt_string("1") }, From hongzhidao at gmail.com Sat Jul 20 01:44:25 2019 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Sat, 20 Jul 2019 09:44:25 +0800 Subject: cache: move open to thread pool In-Reply-To: <9aef70ef-db5f-d3af-bb09-44848477fab2@nginx.com> References: <20180903160903.GI56558@mdounin.ru> <4ba7414a-0eba-6bd3-5a50-2eca591ac25e@nginx.com> <2a3577f6-4ad4-aa2d-80a2-7e9b715c070d@nginx.com> <9aef70ef-db5f-d3af-bb09-44848477fab2@nginx.com> Message-ID: > The patch wasn't updated since that but I suspect it could be still applied to nginx, maybe with some minor tweaks. We still appreciate your work. BTW, are the patches in the attachment up to date? If not, can you share the latest patch? We are happy to apply it and feedback if possible. When there are many static files and accesses, do you think it will works very well? On Sat, Jul 20, 2019 at 2:42 AM Maxim Konovalov wrote: > Hi hongzhidao, > > The patch wasn't merged as we didn't see much interest and real > technical feedback from potential testers. > > The code adds additional complexity to the nginx core with all > associated costs of maintaining the code virtually forever. In the > same time at this point it brings no measurable value to the > community. At least, we haven't seen any proofs that it does. > > The patch wasn't updated since that but I suspect it could be still > applied to nginx, maybe with some minor tweaks. > > Maxim > > On 19/07/2019 18:26, ??? wrote: > > Hi. > > Will this patch be merged into the main branch? > > What is the latest patch? We can help with the test. > > Thanks. > > > > On Sat, Feb 9, 2019 at 6:40 AM Ka-Hing Cheung via nginx-devel > > > wrote: > > > > Unfortunately our test colo is not setup to do performance testing > > (the traffic it receives varies too much). We do intend to merge > > this > > to our production colos but there's no timeline yet. > > > > Yuchen (CC'ed) will be the main contact from now on as today is my > > last day at Cloudflare. > > > > - Ka-Hing > > > > On Thu, Feb 7, 2019 at 5:39 AM Maxim Konovalov > > wrote: > > > > > > Great. Thanks for the testing! > > > > > > Did you see any measurable perf. metrics changes comparing to your > > > aio open implementation or comparing to nginx without aio open > > support? > > > > > > We are still waiting for additional input from another tester, who > > > expressed interest before. > > > > > > Thanks, > > > > > > Maxim > > > > > > On 07/02/2019 00:19, Ka-Hing Cheung wrote: > > > > This has been running in our test colo for the past week > > with no ill effects. > > > > > > > > On Wed, Jan 23, 2019 at 4:39 AM Maxim Konovalov > > > wrote: > > > >> > > > >> Hi Ka-Hing, > > > >> > > > >> Roman told me that the delta is because of your changes. > > > >> > > > >> Thanks for your time on that. Waiting for your testing > > results. > > > >> > > > >> Maxim > > > >> > > > >> On 22/01/2019 22:34, Ka-Hing Cheung via nginx-devel wrote: > > > >>> I spoke too soon, just realized our test colo is running > > the patches > > > >>> without aio_open on. Flipping that switch now. > > > >>> > > > >>> Also, including the patch that we applied on top in > > addition to the > > > >>> massaging we did to resolve conflicts. I haven't dug too > > deep to see > > > >>> if stock nginx also requires similar changes or they are only > > > >>> necessary because of our other nginx changes: > > > >>> > > > >> [...] > > > >> > > > >> -- > > > >> Maxim Konovalov > > > > > > > > > -- > > > Maxim Konovalov > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > -- > Maxim Konovalov > -------------- next part -------------- An HTML attachment was scrubbed... URL: From arut at nginx.com Mon Jul 22 14:05:23 2019 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 22 Jul 2019 17:05:23 +0300 Subject: cache: move open to thread pool In-Reply-To: References: <9aef70ef-db5f-d3af-bb09-44848477fab2@nginx.com> Message-ID: <20190722140523.GU61550@Romans-MacBook-Air.local> Hi, On Sat, Jul 20, 2019 at 09:44:25AM +0800, ??? wrote: > > The patch wasn't updated since that but I suspect it could be still > applied to nginx, maybe with some minor tweaks. > > We still appreciate your work. > > BTW, are the patches in the attachment up to date? > If not, can you share the latest patch? We had no patches since november 1, 2018. The last patch is in this message: http://mailman.nginx.org/pipermail/nginx-devel/2018-November/011538.html > We are happy to apply it and feedback if possible. > When there are many static files and accesses, do you think it will works > very well? We didn't have much feedback so far. So we would definitely appreciate your contribution to testing it. > On Sat, Jul 20, 2019 at 2:42 AM Maxim Konovalov wrote: > > > Hi hongzhidao, > > > > The patch wasn't merged as we didn't see much interest and real > > technical feedback from potential testers. > > > > The code adds additional complexity to the nginx core with all > > associated costs of maintaining the code virtually forever. In the > > same time at this point it brings no measurable value to the > > community. At least, we haven't seen any proofs that it does. > > > > The patch wasn't updated since that but I suspect it could be still > > applied to nginx, maybe with some minor tweaks. > > > > Maxim > > > > On 19/07/2019 18:26, ??? wrote: > > > Hi. > > > Will this patch be merged into the main branch? > > > What is the latest patch? We can help with the test. > > > Thanks. > > > > > > On Sat, Feb 9, 2019 at 6:40 AM Ka-Hing Cheung via nginx-devel > > > > wrote: > > > > > > Unfortunately our test colo is not setup to do performance testing > > > (the traffic it receives varies too much). We do intend to merge > > > this > > > to our production colos but there's no timeline yet. > > > > > > Yuchen (CC'ed) will be the main contact from now on as today is my > > > last day at Cloudflare. > > > > > > - Ka-Hing > > > > > > On Thu, Feb 7, 2019 at 5:39 AM Maxim Konovalov > > > wrote: > > > > > > > > Great. Thanks for the testing! > > > > > > > > Did you see any measurable perf. metrics changes comparing to your > > > > aio open implementation or comparing to nginx without aio open > > > support? > > > > > > > > We are still waiting for additional input from another tester, who > > > > expressed interest before. > > > > > > > > Thanks, > > > > > > > > Maxim > > > > > > > > On 07/02/2019 00:19, Ka-Hing Cheung wrote: > > > > > This has been running in our test colo for the past week > > > with no ill effects. > > > > > > > > > > On Wed, Jan 23, 2019 at 4:39 AM Maxim Konovalov > > > > wrote: > > > > >> > > > > >> Hi Ka-Hing, > > > > >> > > > > >> Roman told me that the delta is because of your changes. > > > > >> > > > > >> Thanks for your time on that. Waiting for your testing > > > results. > > > > >> > > > > >> Maxim > > > > >> > > > > >> On 22/01/2019 22:34, Ka-Hing Cheung via nginx-devel wrote: > > > > >>> I spoke too soon, just realized our test colo is running > > > the patches > > > > >>> without aio_open on. Flipping that switch now. > > > > >>> > > > > >>> Also, including the patch that we applied on top in > > > addition to the > > > > >>> massaging we did to resolve conflicts. I haven't dug too > > > deep to see > > > > >>> if stock nginx also requires similar changes or they are only > > > > >>> necessary because of our other nginx changes: > > > > >>> > > > > >> [...] > > > > >> > > > > >> -- > > > > >> Maxim Konovalov > > > > > > > > > > > > -- > > > > Maxim Konovalov > > > _______________________________________________ > > > nginx-devel mailing list > > > nginx-devel at nginx.org > > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > > _______________________________________________ > > > nginx-devel mailing list > > > nginx-devel at nginx.org > > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > > -- > > Maxim Konovalov > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- Roman Arutyunyan From xeioex at nginx.com Mon Jul 22 14:21:21 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 22 Jul 2019 14:21:21 +0000 Subject: [njs] Fixed property setter lookup. Message-ID: details: https://hg.nginx.org/njs/rev/82c03a8af063 branches: changeset: 1065:82c03a8af063 user: Artem S. Povalyukhin date: Sat Jul 20 13:31:59 2019 +0300 description: Fixed property setter lookup. diffstat: njs/njs_object_property.c | 12 ++++++------ njs/test/njs_unit_test.c | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diffs (43 lines): diff -r 97ab91a7c7f5 -r 82c03a8af063 njs/njs_object_property.c --- a/njs/njs_object_property.c Tue Jul 02 22:24:11 2019 -0400 +++ b/njs/njs_object_property.c Sat Jul 20 13:31:59 2019 +0300 @@ -599,7 +599,12 @@ njs_value_property_set(njs_vm_t *vm, njs return NXT_ERROR; } - } else if (!njs_is_function(&prop->setter)) { + } else { + if (njs_is_function(&prop->setter)) { + return njs_function_call(vm, njs_function(&prop->setter), + object, value, 1, &vm->retval); + } + njs_type_error(vm, "Cannot set property \"%V\" of %s which has only a getter", &pq.lhq.key, njs_type_string(object->type)); @@ -623,11 +628,6 @@ njs_value_property_set(njs_vm_t *vm, njs break; } - if (njs_is_function(&prop->setter)) { - return njs_function_call(vm, njs_function(&prop->setter), - object, value, 1, &vm->retval); - } - goto found; case NJS_PROPERTY_REF: diff -r 97ab91a7c7f5 -r 82c03a8af063 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jul 02 22:24:11 2019 -0400 +++ b/njs/test/njs_unit_test.c Sat Jul 20 13:31:59 2019 +0300 @@ -9629,6 +9629,10 @@ static njs_unit_test_t njs_test[] = "Object.defineProperty(o, 'a', {get:()=>1}); o.a = 2"), nxt_string("TypeError: Cannot set property \"a\" of object which has only a getter") }, + { nxt_string("var o = Object.create(Object.defineProperty({}, 'x', { set: function(v) { this.y = v; }})); " + "o.x = 123; Object.getOwnPropertyDescriptor(o, 'y').value"), + nxt_string("123") }, + { nxt_string("var o = {};" "Object.defineProperty(o, 'a', { configurable: true, value: 0 });" "Object.defineProperty(o, 'a', { value: 1 });" From hongzhidao at gmail.com Mon Jul 22 15:37:50 2019 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Mon, 22 Jul 2019 23:37:50 +0800 Subject: cache: move open to thread pool In-Reply-To: <20190722140523.GU61550@Romans-MacBook-Air.local> References: <9aef70ef-db5f-d3af-bb09-44848477fab2@nginx.com> <20190722140523.GU61550@Romans-MacBook-Air.local> Message-ID: Thanks again. On Mon, Jul 22, 2019 at 10:05 PM Roman Arutyunyan wrote: > Hi, > > On Sat, Jul 20, 2019 at 09:44:25AM +0800, ??? wrote: > > > The patch wasn't updated since that but I suspect it could be still > > applied to nginx, maybe with some minor tweaks. > > > > We still appreciate your work. > > > > BTW, are the patches in the attachment up to date? > > If not, can you share the latest patch? > > We had no patches since november 1, 2018. The last patch is in this > message: > > http://mailman.nginx.org/pipermail/nginx-devel/2018-November/011538.html > > > We are happy to apply it and feedback if possible. > > When there are many static files and accesses, do you think it will works > > very well? > > We didn't have much feedback so far. So we would definitely appreciate > your > contribution to testing it. > > > On Sat, Jul 20, 2019 at 2:42 AM Maxim Konovalov wrote: > > > > > Hi hongzhidao, > > > > > > The patch wasn't merged as we didn't see much interest and real > > > technical feedback from potential testers. > > > > > > The code adds additional complexity to the nginx core with all > > > associated costs of maintaining the code virtually forever. In the > > > same time at this point it brings no measurable value to the > > > community. At least, we haven't seen any proofs that it does. > > > > > > The patch wasn't updated since that but I suspect it could be still > > > applied to nginx, maybe with some minor tweaks. > > > > > > Maxim > > > > > > On 19/07/2019 18:26, ??? wrote: > > > > Hi. > > > > Will this patch be merged into the main branch? > > > > What is the latest patch? We can help with the test. > > > > Thanks. > > > > > > > > On Sat, Feb 9, 2019 at 6:40 AM Ka-Hing Cheung via nginx-devel > > > > > wrote: > > > > > > > > Unfortunately our test colo is not setup to do performance > testing > > > > (the traffic it receives varies too much). We do intend to merge > > > > this > > > > to our production colos but there's no timeline yet. > > > > > > > > Yuchen (CC'ed) will be the main contact from now on as today is > my > > > > last day at Cloudflare. > > > > > > > > - Ka-Hing > > > > > > > > On Thu, Feb 7, 2019 at 5:39 AM Maxim Konovalov > > > > wrote: > > > > > > > > > > Great. Thanks for the testing! > > > > > > > > > > Did you see any measurable perf. metrics changes comparing to > your > > > > > aio open implementation or comparing to nginx without aio open > > > > support? > > > > > > > > > > We are still waiting for additional input from another tester, > who > > > > > expressed interest before. > > > > > > > > > > Thanks, > > > > > > > > > > Maxim > > > > > > > > > > On 07/02/2019 00:19, Ka-Hing Cheung wrote: > > > > > > This has been running in our test colo for the past week > > > > with no ill effects. > > > > > > > > > > > > On Wed, Jan 23, 2019 at 4:39 AM Maxim Konovalov > > > > > wrote: > > > > > >> > > > > > >> Hi Ka-Hing, > > > > > >> > > > > > >> Roman told me that the delta is because of your changes. > > > > > >> > > > > > >> Thanks for your time on that. Waiting for your testing > > > > results. > > > > > >> > > > > > >> Maxim > > > > > >> > > > > > >> On 22/01/2019 22:34, Ka-Hing Cheung via nginx-devel wrote: > > > > > >>> I spoke too soon, just realized our test colo is running > > > > the patches > > > > > >>> without aio_open on. Flipping that switch now. > > > > > >>> > > > > > >>> Also, including the patch that we applied on top in > > > > addition to the > > > > > >>> massaging we did to resolve conflicts. I haven't dug too > > > > deep to see > > > > > >>> if stock nginx also requires similar changes or they are > only > > > > > >>> necessary because of our other nginx changes: > > > > > >>> > > > > > >> [...] > > > > > >> > > > > > >> -- > > > > > >> Maxim Konovalov > > > > > > > > > > > > > > > -- > > > > > Maxim Konovalov > > > > _______________________________________________ > > > > nginx-devel mailing list > > > > nginx-devel at nginx.org > > > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > > > > > _______________________________________________ > > > > nginx-devel mailing list > > > > nginx-devel at nginx.org > > > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > > > > > > -- > > > Maxim Konovalov > > > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > -- > Roman Arutyunyan > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Jul 23 12:09:13 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 23 Jul 2019 12:09:13 +0000 Subject: [nginx] nginx-1.17.2-RELEASE Message-ID: details: https://hg.nginx.org/nginx/rev/2fc9f853a6b7 branches: changeset: 7542:2fc9f853a6b7 user: Maxim Dounin date: Tue Jul 23 15:01:47 2019 +0300 description: nginx-1.17.2-RELEASE diffstat: docs/xml/nginx/changes.xml | 89 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 89 insertions(+), 0 deletions(-) diffs (99 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,95 @@ + + + + +??????????? ?????????????? ?????? zlib—1.2.0.4.
+??????? ???? ??????????. +
+ +minimum supported zlib version is 1.2.0.4.
+Thanks to Ilya Leoshkevich. +
+
+ + + +????? $r->internal_redirect() ??????????? ????? +?????? ??????? ?????????????? URI. + + +the $r->internal_redirect() embedded perl method +now expects escaped URIs. + + + + + +?????? ? ??????? ?????? $r->internal_redirect() ??????????? ????? +????? ??????? ? ??????????? location. + + +it is now possible to switch to a named location +using the $r->internal_redirect() embedded perl method. + + + + + +? ????????? ?????? ?? ?????????? ?????. + + +in error handling in embedded perl. + + + + + +?? ?????? ??? ?? ????? ???????????????? ??? ????????? segmentation fault, +???? ? ???????????? ?????????????? ???????? hash bucket size ?????? 64 ????????. + + +a segmentation fault might occur on start or during reconfiguration +if hash bucket size larger than 64 kilobytes was used in the configuration. + + + + + +??? ????????????? ??????? ????????? ?????????? select, poll ? /dev/poll +nginx ??? ????????? ????????? ?? ????? ????????????????? ????????????? +? ??? ????????????? WebSocket-??????????. + + +nginx might hog CPU during unbuffered proxying +and when proxying WebSocket connections +if the select, poll, or /dev/poll methods were used. + + + + + +? ?????? ngx_http_xslt_filter_module. + + +in the ngx_http_xslt_filter_module. + + + + + +? ?????? ngx_http_ssi_filter_module. + + +in the ngx_http_ssi_filter_module. + + + +
+ + From mdounin at mdounin.ru Tue Jul 23 12:09:15 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 23 Jul 2019 12:09:15 +0000 Subject: [nginx] release-1.17.2 tag Message-ID: details: https://hg.nginx.org/nginx/rev/e7181cfe9212 branches: changeset: 7543:e7181cfe9212 user: Maxim Dounin date: Tue Jul 23 15:01:47 2019 +0300 description: release-1.17.2 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -440,3 +440,4 @@ 5155d0296a5ef9841f035920527ffdb771076b44 0130ca3d58437b3c7c707cdddd813d530c68da9a release-1.15.12 054c1c46395caff79bb4caf16f40b331f71bb6dd release-1.17.0 7816bd7dabf6ee86c53c073b90a7143161546e06 release-1.17.1 +2fc9f853a6b7cd29dc84e0af2ed3cf78e0da6ca8 release-1.17.2 From xeioex at nginx.com Tue Jul 23 17:02:48 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 23 Jul 2019 17:02:48 +0000 Subject: [njs] Moving njs.c functions into njs_vm.c and njs_value.c Message-ID: details: https://hg.nginx.org/njs/rev/427edfbe6762 branches: changeset: 1067:427edfbe6762 user: Dmitry Volyntsev date: Tue Jul 23 19:42:25 2019 +0300 description: Moving njs.c functions into njs_vm.c and njs_value.c NO functional changes. diffstat: auto/sources | 1 - njs/njs.c | 1105 ------------------------------------------------------- njs/njs_value.c | 123 ++++++ njs/njs_vm.c | 975 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1098 insertions(+), 1106 deletions(-) diffs (truncated from 2249 to 1000 lines): diff -r 7fd8df281a37 -r 427edfbe6762 auto/sources --- a/auto/sources Tue Jul 23 17:53:00 2019 +0300 +++ b/auto/sources Tue Jul 23 19:42:25 2019 +0300 @@ -29,7 +29,6 @@ NXT_TEST_SRCS=" \ " NJS_LIB_SRCS=" \ - njs/njs.c \ njs/njs_value.c \ njs/njs_vm.c \ njs/njs_vmcode.c \ diff -r 7fd8df281a37 -r 427edfbe6762 njs/njs.c --- a/njs/njs.c Tue Jul 23 17:53:00 2019 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1105 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#include -#include -#include - - -static nxt_int_t njs_vm_init(njs_vm_t *vm); -static nxt_int_t njs_vm_handle_events(njs_vm_t *vm); - - -static void * -njs_alloc(void *mem, size_t size) -{ - return nxt_malloc(size); -} - - -static void * -njs_zalloc(void *mem, size_t size) -{ - void *p; - - p = nxt_malloc(size); - - if (p != NULL) { - nxt_memzero(p, size); - } - - return p; -} - - -static void * -njs_align(void *mem, size_t alignment, size_t size) -{ - return nxt_memalign(alignment, size); -} - - -static void -njs_free(void *mem, void *p) -{ - nxt_free(p); -} - - -const nxt_mem_proto_t njs_vm_mp_proto = { - njs_alloc, - njs_zalloc, - njs_align, - NULL, - njs_free, - NULL, - NULL, -}; - - -static void * -njs_array_mem_alloc(void *mem, size_t size) -{ - return nxt_mp_alloc(mem, size); -} - - -static void -njs_array_mem_free(void *mem, void *p) -{ - nxt_mp_free(mem, p); -} - - -const nxt_mem_proto_t njs_array_mem_proto = { - njs_array_mem_alloc, - NULL, - NULL, - NULL, - njs_array_mem_free, - NULL, - NULL, -}; - - -njs_vm_t * -njs_vm_create(njs_vm_opt_t *options) -{ - nxt_mp_t *mp; - njs_vm_t *vm; - nxt_int_t ret; - nxt_array_t *debug; - njs_regexp_pattern_t *pattern; - - mp = nxt_mp_create(&njs_vm_mp_proto, NULL, NULL, 2 * nxt_pagesize(), - 128, 512, 16); - if (nxt_slow_path(mp == NULL)) { - return NULL; - } - - vm = nxt_mp_zalign(mp, sizeof(njs_value_t), sizeof(njs_vm_t)); - - if (nxt_fast_path(vm != NULL)) { - vm->mem_pool = mp; - - ret = njs_regexp_init(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return NULL; - } - - vm->options = *options; - - if (options->shared != NULL) { - vm->shared = options->shared; - - } else { - vm->shared = nxt_mp_zalloc(mp, sizeof(njs_vm_shared_t)); - if (nxt_slow_path(vm->shared == NULL)) { - return NULL; - } - - options->shared = vm->shared; - - nxt_lvlhsh_init(&vm->shared->keywords_hash); - - ret = njs_lexer_keywords_init(mp, &vm->shared->keywords_hash); - if (nxt_slow_path(ret != NXT_OK)) { - return NULL; - } - - nxt_lvlhsh_init(&vm->shared->values_hash); - - pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", - nxt_length("(?:)"), 0); - if (nxt_slow_path(pattern == NULL)) { - return NULL; - } - - vm->shared->empty_regexp_pattern = pattern; - - nxt_lvlhsh_init(&vm->modules_hash); - - ret = njs_builtin_objects_create(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return NULL; - } - } - - nxt_lvlhsh_init(&vm->values_hash); - - vm->external = options->external; - - vm->external_objects = nxt_array_create(4, sizeof(void *), - &njs_array_mem_proto, - vm->mem_pool); - if (nxt_slow_path(vm->external_objects == NULL)) { - return NULL; - } - - nxt_lvlhsh_init(&vm->externals_hash); - nxt_lvlhsh_init(&vm->external_prototypes_hash); - - vm->trace.level = NXT_LEVEL_TRACE; - vm->trace.size = 2048; - vm->trace.handler = njs_parser_trace_handler; - vm->trace.data = vm; - - if (options->backtrace) { - debug = nxt_array_create(4, sizeof(njs_function_debug_t), - &njs_array_mem_proto, vm->mem_pool); - if (nxt_slow_path(debug == NULL)) { - return NULL; - } - - vm->debug = debug; - } - - if (options->accumulative) { - ret = njs_vm_init(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return NULL; - } - } - } - - return vm; -} - - -void -njs_vm_destroy(njs_vm_t *vm) -{ - njs_event_t *event; - nxt_lvlhsh_each_t lhe; - - if (njs_waiting_events(vm)) { - nxt_lvlhsh_each_init(&lhe, &njs_event_hash_proto); - - for ( ;; ) { - event = nxt_lvlhsh_each(&vm->events_hash, &lhe); - - if (event == NULL) { - break; - } - - njs_del_event(vm, event, NJS_EVENT_RELEASE); - } - } - - nxt_mp_destroy(vm->mem_pool); -} - - -nxt_int_t -njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end) -{ - nxt_int_t ret; - njs_lexer_t lexer; - njs_parser_t *parser, *prev; - njs_generator_t generator; - njs_parser_scope_t *scope; - - if (vm->parser != NULL && !vm->options.accumulative) { - return NJS_ERROR; - } - - if (vm->modules != NULL && vm->options.accumulative) { - njs_module_reset(vm); - } - - parser = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_parser_t)); - if (nxt_slow_path(parser == NULL)) { - return NJS_ERROR; - } - - prev = vm->parser; - vm->parser = parser; - - ret = njs_lexer_init(vm, &lexer, &vm->options.file, *start, end); - if (nxt_slow_path(ret != NXT_OK)) { - return NJS_ERROR; - } - - parser->lexer = &lexer; - - if (vm->backtrace != NULL) { - nxt_array_reset(vm->backtrace); - } - - vm->retval = njs_value_undefined; - - ret = njs_parser(vm, parser, prev); - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } - - parser->lexer = NULL; - - scope = parser->scope; - - ret = njs_variables_scope_reference(vm, scope); - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } - - *start = lexer.start; - - /* - * Reset the code array to prevent it from being disassembled - * again in the next iteration of the accumulative mode. - */ - vm->code = NULL; - - nxt_memzero(&generator, sizeof(njs_generator_t)); - - ret = njs_generate_scope(vm, &generator, scope, &njs_entry_main); - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } - - vm->current = generator.code_start; - vm->global_scope = generator.local_scope; - vm->scope_size = generator.scope_size; - - vm->variables_hash = scope->variables; - - if (vm->options.init) { - ret = njs_vm_init(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - } - - return NJS_OK; - -fail: - - vm->parser = prev; - - return NXT_ERROR; -} - - -njs_vm_t * -njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external) -{ - nxt_mp_t *nmp; - njs_vm_t *nvm; - uint32_t items; - nxt_int_t ret; - nxt_array_t *externals; - - nxt_thread_log_debug("CLONE:"); - - if (vm->options.accumulative) { - return NULL; - } - - nmp = nxt_mp_create(&njs_vm_mp_proto, NULL, NULL, 2 * nxt_pagesize(), - 128, 512, 16); - if (nxt_slow_path(nmp == NULL)) { - return NULL; - } - - nvm = nxt_mp_zalign(nmp, sizeof(njs_value_t), sizeof(njs_vm_t)); - - if (nxt_fast_path(nvm != NULL)) { - nvm->mem_pool = nmp; - - nvm->shared = vm->shared; - - nvm->trace = vm->trace; - nvm->trace.data = nvm; - - nvm->variables_hash = vm->variables_hash; - nvm->values_hash = vm->values_hash; - - nvm->modules = vm->modules; - nvm->modules_hash = vm->modules_hash; - - nvm->externals_hash = vm->externals_hash; - nvm->external_prototypes_hash = vm->external_prototypes_hash; - - items = vm->external_objects->items; - externals = nxt_array_create(items + 4, sizeof(void *), - &njs_array_mem_proto, nvm->mem_pool); - - if (nxt_slow_path(externals == NULL)) { - return NULL; - } - - if (items > 0) { - memcpy(externals->start, vm->external_objects->start, - items * sizeof(void *)); - externals->items = items; - } - - nvm->external_objects = externals; - - nvm->options = vm->options; - - nvm->current = vm->current; - - nvm->external = external; - - nvm->global_scope = vm->global_scope; - nvm->scope_size = vm->scope_size; - - nvm->debug = vm->debug; - - ret = njs_vm_init(nvm); - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } - - return nvm; - } - -fail: - - nxt_mp_destroy(nmp); - - return NULL; -} - - -static nxt_int_t -njs_vm_init(njs_vm_t *vm) -{ - size_t size, scope_size; - u_char *values; - nxt_int_t ret; - njs_frame_t *frame; - nxt_array_t *backtrace; - - scope_size = vm->scope_size + NJS_INDEX_GLOBAL_OFFSET; - - size = NJS_GLOBAL_FRAME_SIZE + scope_size + NJS_FRAME_SPARE_SIZE; - size = nxt_align_size(size, NJS_FRAME_SPARE_SIZE); - - frame = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t), size); - if (nxt_slow_path(frame == NULL)) { - return NXT_ERROR; - } - - nxt_memzero(frame, NJS_GLOBAL_FRAME_SIZE); - - vm->top_frame = &frame->native; - vm->active_frame = frame; - - frame->native.size = size; - frame->native.free_size = size - (NJS_GLOBAL_FRAME_SIZE + scope_size); - - values = (u_char *) frame + NJS_GLOBAL_FRAME_SIZE; - - frame->native.free = values + scope_size; - - vm->scopes[NJS_SCOPE_GLOBAL] = (njs_value_t *) values; - memcpy(values + NJS_INDEX_GLOBAL_OFFSET, vm->global_scope, - vm->scope_size); - - ret = njs_regexp_init(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - - ret = njs_builtin_objects_clone(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - - nxt_lvlhsh_init(&vm->events_hash); - nxt_queue_init(&vm->posted_events); - - if (vm->debug != NULL) { - backtrace = nxt_array_create(4, sizeof(njs_backtrace_entry_t), - &njs_array_mem_proto, vm->mem_pool); - if (nxt_slow_path(backtrace == NULL)) { - return NXT_ERROR; - } - - vm->backtrace = backtrace; - } - - if (njs_is_null(&vm->retval)) { - vm->retval = njs_value_undefined; - } - - return NXT_OK; -} - - -nxt_int_t -njs_vm_call(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args, - nxt_uint_t nargs) -{ - return njs_vm_invoke(vm, function, args, nargs, (njs_index_t) &vm->retval); -} - - -nxt_int_t -njs_vm_invoke(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args, - nxt_uint_t nargs, njs_index_t retval) -{ - njs_ret_t ret; - njs_value_t *this; - - this = (njs_value_t *) &njs_value_undefined; - - ret = njs_function_frame(vm, function, this, (njs_value_t *) args, nargs, - 0); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - return njs_function_frame_invoke(vm, retval); -} - - -njs_vm_event_t -njs_vm_add_event(njs_vm_t *vm, njs_function_t *function, nxt_uint_t once, - njs_host_event_t host_ev, njs_event_destructor_t destructor) -{ - njs_event_t *event; - - event = nxt_mp_alloc(vm->mem_pool, sizeof(njs_event_t)); - if (nxt_slow_path(event == NULL)) { - return NULL; - } - - event->host_event = host_ev; - event->destructor = destructor; - event->function = function; - event->once = once; - event->posted = 0; - event->nargs = 0; - event->args = NULL; - - if (njs_add_event(vm, event) != NJS_OK) { - return NULL; - } - - return event; -} - - -void -njs_vm_del_event(njs_vm_t *vm, njs_vm_event_t vm_event) -{ - njs_event_t *event; - - event = (njs_event_t *) vm_event; - - njs_del_event(vm, event, NJS_EVENT_RELEASE | NJS_EVENT_DELETE); -} - - -nxt_int_t -njs_vm_waiting(njs_vm_t *vm) -{ - return njs_waiting_events(vm); -} - - -nxt_int_t -njs_vm_posted(njs_vm_t *vm) -{ - return njs_posted_events(vm); -} - - -nxt_int_t -njs_vm_post_event(njs_vm_t *vm, njs_vm_event_t vm_event, - const njs_value_t *args, nxt_uint_t nargs) -{ - njs_event_t *event; - - event = (njs_event_t *) vm_event; - - if (nargs != 0 && !event->posted) { - event->nargs = nargs; - event->args = nxt_mp_alloc(vm->mem_pool, sizeof(njs_value_t) * nargs); - if (nxt_slow_path(event->args == NULL)) { - return NJS_ERROR; - } - - memcpy(event->args, args, sizeof(njs_value_t) * nargs); - } - - if (!event->posted) { - event->posted = 1; - nxt_queue_insert_tail(&vm->posted_events, &event->link); - } - - return NJS_OK; -} - - -nxt_int_t -njs_vm_run(njs_vm_t *vm) -{ - if (nxt_slow_path(vm->backtrace != NULL)) { - nxt_array_reset(vm->backtrace); - } - - return njs_vm_handle_events(vm); -} - - -nxt_int_t -njs_vm_start(njs_vm_t *vm) -{ - njs_ret_t ret; - - ret = njs_module_load(vm); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - ret = njs_vmcode_interpreter(vm); - - if (ret == NJS_STOP) { - ret = NJS_OK; - } - - return ret; -} - - -static nxt_int_t -njs_vm_handle_events(njs_vm_t *vm) -{ - nxt_int_t ret; - njs_event_t *ev; - nxt_queue_t *events; - nxt_queue_link_t *link; - - events = &vm->posted_events; - - for ( ;; ) { - link = nxt_queue_first(events); - - if (link == nxt_queue_tail(events)) { - break; - } - - ev = nxt_queue_link_data(link, njs_event_t, link); - - if (ev->once) { - njs_del_event(vm, ev, NJS_EVENT_RELEASE | NJS_EVENT_DELETE); - - } else { - ev->posted = 0; - nxt_queue_remove(&ev->link); - } - - ret = njs_vm_call(vm, ev->function, ev->args, ev->nargs); - - if (ret == NJS_ERROR) { - return ret; - } - } - - return njs_posted_events(vm) ? NJS_AGAIN : NJS_OK; -} - - -nxt_int_t -njs_vm_add_path(njs_vm_t *vm, const nxt_str_t *path) -{ - nxt_str_t *item; - - if (vm->paths == NULL) { - vm->paths = nxt_array_create(4, sizeof(nxt_str_t), - &njs_array_mem_proto, vm->mem_pool); - if (nxt_slow_path(vm->paths == NULL)) { - return NXT_ERROR; - } - } - - item = nxt_array_add(vm->paths, &njs_array_mem_proto, vm->mem_pool); - if (nxt_slow_path(item == NULL)) { - return NXT_ERROR; - } - - *item = *path; - - return NXT_OK; -} - - -njs_value_t * -njs_vm_retval(njs_vm_t *vm) -{ - return &vm->retval; -} - - -void -njs_vm_retval_set(njs_vm_t *vm, const njs_value_t *value) -{ - vm->retval = *value; -} - - -void -njs_value_undefined_set(njs_value_t *value) -{ - njs_set_undefined(value); -} - - -void -njs_value_boolean_set(njs_value_t *value, int yn) -{ - njs_set_boolean(value, yn); -} - - -void -njs_value_number_set(njs_value_t *value, double num) -{ - njs_set_number(value, num); -} - - -void -njs_value_data_set(njs_value_t *value, void *data) -{ - njs_set_data(value, data); -} - - -njs_ret_t -njs_vm_value_string_set(njs_vm_t *vm, njs_value_t *value, const u_char *start, - uint32_t size) -{ - return njs_string_set(vm, value, start, size); -} - - -u_char * -njs_vm_value_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size) -{ - return njs_string_alloc(vm, value, size, 0); -} - - -nxt_noinline void -njs_vm_value_error_set(njs_vm_t *vm, njs_value_t *value, const char *fmt, ...) -{ - va_list args; - u_char buf[NXT_MAX_ERROR_STR], *p; - - p = buf; - - if (fmt != NULL) { - va_start(args, fmt); - p = nxt_vsprintf(buf, buf + sizeof(buf), fmt, args); - va_end(args); - } - - njs_error_new(vm, value, NJS_OBJECT_ERROR, buf, p - buf); -} - - -uint8_t -njs_value_bool(const njs_value_t *value) -{ - return njs_bool(value); -} - - -double -njs_value_number(const njs_value_t *value) -{ - return njs_number(value); -} - - -void * -njs_value_data(const njs_value_t *value) -{ - return njs_data(value); -} - - -njs_function_t * -njs_value_function(const njs_value_t *value) -{ - return njs_function(value); -} - - -nxt_int_t -njs_value_is_null(const njs_value_t *value) -{ - return njs_is_null(value); -} - - -nxt_int_t -njs_value_is_undefined(const njs_value_t *value) -{ - return njs_is_undefined(value); -} - - -nxt_int_t -njs_value_is_null_or_undefined(const njs_value_t *value) -{ - return njs_is_null_or_undefined(value); -} - - -nxt_int_t -njs_value_is_boolean(const njs_value_t *value) -{ - return njs_is_boolean(value); -} - - -nxt_int_t -njs_value_is_number(const njs_value_t *value) -{ - return njs_is_number(value); -} - - -nxt_int_t -njs_value_is_valid_number(const njs_value_t *value) -{ - return njs_is_number(value) - && !isnan(njs_number(value)) - && !isinf(njs_number(value)); -} - - -nxt_int_t -njs_value_is_string(const njs_value_t *value) -{ - return njs_is_string(value); -} - - -nxt_int_t -njs_value_is_object(const njs_value_t *value) -{ - return njs_is_object(value); -} - - -nxt_int_t -njs_value_is_function(const njs_value_t *value) -{ - return njs_is_function(value); -} - - -nxt_noinline void -njs_vm_memory_error(njs_vm_t *vm) -{ - njs_memory_error_set(vm, &vm->retval); -} - - -nxt_array_t * -njs_vm_backtrace(njs_vm_t *vm) -{ - if (vm->backtrace != NULL && !nxt_array_is_empty(vm->backtrace)) { - return vm->backtrace; - } - - return NULL; -} - - -static njs_ret_t -njs_vm_backtrace_dump(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src) -{ - u_char *p, *start, *end; - size_t len, count; - nxt_uint_t i; - nxt_array_t *backtrace; - njs_backtrace_entry_t *be, *prev; - - backtrace = njs_vm_backtrace(vm); - - len = dst->length + 1; - - count = 0; - prev = NULL; - - be = backtrace->start; - - for (i = 0; i < backtrace->items; i++) { - if (i != 0 && prev->name.start == be->name.start - && prev->line == be->line) - { - count++; - - } else { - - if (count != 0) { - len += nxt_length(" repeats times\n") - + NXT_INT_T_LEN; - count = 0; - } - - len += be->name.length + nxt_length(" at ()\n"); - - if (be->line != 0) { - len += be->file.length + NXT_INT_T_LEN + 1; - - } else { - len += nxt_length("native"); - } - } - - prev = be; - be++; - } - - p = nxt_mp_alloc(vm->mem_pool, len); - if (p == NULL) { - njs_memory_error(vm); - return NXT_ERROR; - } - - start = p; - end = start + len; - - p = nxt_cpymem(p, dst->start, dst->length); - *p++ = '\n'; - - count = 0; - prev = NULL; - - be = backtrace->start; - - for (i = 0; i < backtrace->items; i++) { - if (i != 0 && prev->name.start == be->name.start - && prev->line == be->line) - { - count++; - - } else { - if (count != 0) { - p = nxt_sprintf(p, end, " repeats %uz times\n", - count); - count = 0; - } - - p = nxt_sprintf(p, end, " at %V ", &be->name); - - if (be->line != 0) { - p = nxt_sprintf(p, end, "(%V:%uD)\n", &be->file, - be->line); - - } else { - p = nxt_sprintf(p, end, "(native)\n"); - } - } - - prev = be; - be++; - } - - dst->start = start; - dst->length = p - dst->start; - - return NXT_OK; -} - - -njs_ret_t -njs_vm_value_string(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src) -{ - njs_ret_t ret; - nxt_uint_t exception; - - if (nxt_slow_path(src->type == NJS_NUMBER - && njs_number(src) == 0 - && signbit(njs_number(src)))) - { - njs_string_get(&njs_string_minus_zero, dst); - return NXT_OK; - } - - exception = 1; - -again: - - ret = njs_vm_value_to_string(vm, dst, src); - - if (nxt_fast_path(ret == NXT_OK)) { - - if (njs_vm_backtrace(vm) != NULL) { - ret = njs_vm_backtrace_dump(vm, dst, src); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - } - - return NXT_OK; - } - - if (exception) { - exception = 0; - - /* value evaluation threw an exception. */ - - src = &vm->retval; - goto again; - } - - dst->length = 0; - dst->start = NULL; - - return NXT_ERROR; -} - - From xeioex at nginx.com Tue Jul 23 17:02:48 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 23 Jul 2019 17:02:48 +0000 Subject: [njs] Splitting vmcode functionality from njs_vm.c into njs_vmcode.c Message-ID: details: https://hg.nginx.org/njs/rev/7fd8df281a37 branches: changeset: 1066:7fd8df281a37 user: Dmitry Volyntsev date: Tue Jul 23 17:53:00 2019 +0300 description: Splitting vmcode functionality from njs_vm.c into njs_vmcode.c No functional changes. diffstat: auto/sources | 1 + njs/njs_core.h | 1 + njs/njs_vm.c | 2435 +----------------------------------------------------- njs/njs_vm.h | 414 +--------- njs/njs_vmcode.c | 2385 ++++++++++++++++++++++++++++++++++++++++++++++++++++ njs/njs_vmcode.h | 443 +++++++++ 6 files changed, 2832 insertions(+), 2847 deletions(-) diffs (truncated from 5768 to 1000 lines): diff -r 82c03a8af063 -r 7fd8df281a37 auto/sources --- a/auto/sources Sat Jul 20 13:31:59 2019 +0300 +++ b/auto/sources Tue Jul 23 17:53:00 2019 +0300 @@ -32,6 +32,7 @@ NJS_LIB_SRCS=" \ njs/njs.c \ njs/njs_value.c \ njs/njs_vm.c \ + njs/njs_vmcode.c \ njs/njs_boolean.c \ njs/njs_number.c \ njs/njs_string.c \ diff -r 82c03a8af063 -r 7fd8df281a37 njs/njs_core.h --- a/njs/njs_core.h Sat Jul 20 13:31:59 2019 +0300 +++ b/njs/njs_core.h Tue Jul 23 17:53:00 2019 +0300 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff -r 82c03a8af063 -r 7fd8df281a37 njs/njs_vm.c --- a/njs/njs_vm.c Sat Jul 20 13:31:59 2019 +0300 +++ b/njs/njs_vm.c Tue Jul 23 17:53:00 2019 +0300 @@ -9,33 +9,6 @@ #include -struct njs_property_next_s { - uint32_t index; - njs_array_t *array; -}; - - -/* - * These functions are forbidden to inline to minimize JavaScript VM - * interpreter memory footprint. The size is less than 8K on AMD64 - * and should fit in CPU L1 instruction cache. - */ - -static njs_ret_t njs_string_concat(njs_vm_t *vm, njs_value_t *val1, - njs_value_t *val2); -static njs_ret_t njs_values_equal(njs_vm_t *vm, njs_value_t *val1, - njs_value_t *val2); -static njs_ret_t njs_primitive_values_compare(njs_vm_t *vm, njs_value_t *val1, - njs_value_t *val2); -static njs_ret_t njs_function_frame_create(njs_vm_t *vm, njs_value_t *value, - const njs_value_t *this, uintptr_t nargs, nxt_bool_t ctor); -static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value); - -static njs_ret_t njs_vm_add_backtrace_entry(njs_vm_t *vm, njs_frame_t *frame); - -void njs_debug(njs_index_t index, njs_value_t *value); - - const nxt_str_t njs_entry_main = nxt_string("main"); const nxt_str_t njs_entry_module = nxt_string("module"); const nxt_str_t njs_entry_native = nxt_string("native"); @@ -43,2126 +16,6 @@ const nxt_str_t njs_entry_unknown = const nxt_str_t njs_entry_anonymous = nxt_string("anonymous"); -/* - * The nJSVM is optimized for an ABIs where the first several arguments - * are passed in registers (AMD64, ARM32/64): two pointers to the operand - * values is passed as arguments although they are not always used. - */ - -nxt_int_t -njs_vmcode_interpreter(njs_vm_t *vm) -{ - u_char *catch, call; - njs_ret_t ret; - njs_value_t *retval, *value1, *value2; - njs_frame_t *frame; - njs_native_frame_t *previous; - njs_vmcode_generic_t *vmcode; - -start: - - for ( ;; ) { - - vmcode = (njs_vmcode_generic_t *) vm->current; - - /* - * The first operand is passed as is in value2 to - * njs_vmcode_jump(), - * njs_vmcode_if_true_jump(), - * njs_vmcode_if_false_jump(), - * njs_vmcode_validate(), - * njs_vmcode_function_frame(), - * njs_vmcode_function_call(), - * njs_vmcode_return(), - * njs_vmcode_try_start(), - * njs_vmcode_try_continue(), - * njs_vmcode_try_break(), - * njs_vmcode_try_end(), - * njs_vmcode_catch(). - * njs_vmcode_throw(). - * njs_vmcode_stop(). - */ - value2 = (njs_value_t *) vmcode->operand1; - value1 = NULL; - - switch (vmcode->code.operands) { - - case NJS_VMCODE_3OPERANDS: - value2 = njs_vmcode_operand(vm, vmcode->operand3); - - /* Fall through. */ - - case NJS_VMCODE_2OPERANDS: - value1 = njs_vmcode_operand(vm, vmcode->operand2); - } - - ret = vmcode->code.operation(vm, value1, value2); - - /* - * On success an operation returns size of the bytecode, - * a jump offset or zero after the call or return operations. - * Jumps can return a negative offset. Compilers can generate - * (ret < 0 && ret >= NJS_PREEMPT) - * as a single unsigned comparision. - */ - - if (nxt_slow_path(ret < 0 && ret >= NJS_PREEMPT)) { - break; - } - - vm->current += ret; - - if (vmcode->code.retval) { - retval = njs_vmcode_operand(vm, vmcode->operand1); - njs_release(vm, retval); - *retval = vm->retval; - } - } - - if (ret == NXT_ERROR) { - - for ( ;; ) { - frame = (njs_frame_t *) vm->top_frame; - - call = frame->native.call; - catch = frame->native.exception.catch; - - if (catch != NULL) { - vm->current = catch; - - if (vm->debug != NULL) { - nxt_array_reset(vm->backtrace); - } - - goto start; - } - - if (vm->debug != NULL - && njs_vm_add_backtrace_entry(vm, frame) != NXT_OK) - { - return NXT_ERROR; - } - - previous = frame->native.previous; - if (previous == NULL) { - return NXT_ERROR; - } - - njs_vm_scopes_restore(vm, frame, previous); - - if (frame->native.size != 0) { - vm->stack_size -= frame->native.size; - nxt_mp_free(vm->mem_pool, frame); - } - - if (call) { - return NXT_ERROR; - } - } - } - - /* NXT_ERROR, NJS_STOP. */ - - return ret; -} - - -nxt_int_t -njs_vmcode_run(njs_vm_t *vm) -{ - njs_ret_t ret; - - vm->top_frame->call = 1; - - if (nxt_slow_path(vm->count > 128)) { - njs_range_error(vm, "Maximum call stack size exceeded"); - return NXT_ERROR; - } - - vm->count++; - - ret = njs_vmcode_interpreter(vm); - if (ret == NJS_STOP) { - ret = NJS_OK; - } - - vm->count--; - - return ret; -} - - -njs_ret_t -njs_vmcode_object(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) -{ - njs_object_t *object; - - object = njs_object_alloc(vm); - - if (nxt_fast_path(object != NULL)) { - njs_set_object(&vm->retval, object); - - return sizeof(njs_vmcode_object_t); - } - - return NXT_ERROR; -} - - -njs_ret_t -njs_vmcode_array(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) -{ - uint32_t length; - njs_array_t *array; - njs_value_t *value; - njs_vmcode_array_t *code; - - code = (njs_vmcode_array_t *) vm->current; - - array = njs_array_alloc(vm, code->length, NJS_ARRAY_SPARE); - - if (nxt_fast_path(array != NULL)) { - - if (code->code.ctor) { - /* Array of the form [,,,], [1,,]. */ - value = array->start; - length = array->length; - - do { - njs_set_invalid(value); - value++; - length--; - } while (length != 0); - - } else { - /* Array of the form [], [,,1], [1,2,3]. */ - array->length = 0; - } - - njs_set_array(&vm->retval, array); - - return sizeof(njs_vmcode_array_t); - } - - return NXT_ERROR; -} - - -njs_ret_t -njs_vmcode_function(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) -{ - njs_function_t *function; - njs_function_lambda_t *lambda; - njs_vmcode_function_t *code; - - code = (njs_vmcode_function_t *) vm->current; - lambda = code->lambda; - - function = njs_function_alloc(vm, lambda, vm->active_frame->closures, 0); - if (nxt_slow_path(function == NULL)) { - return NXT_ERROR; - } - - njs_set_function(&vm->retval, function); - - return sizeof(njs_vmcode_function_t); -} - - -njs_ret_t -njs_vmcode_this(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) -{ - njs_frame_t *frame; - njs_value_t *value; - njs_vmcode_this_t *code; - - frame = (njs_frame_t *) vm->active_frame; - code = (njs_vmcode_this_t *) vm->current; - - value = njs_vmcode_operand(vm, code->dst); - *value = frame->native.arguments[0]; - - return sizeof(njs_vmcode_this_t); -} - - -njs_ret_t -njs_vmcode_arguments(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) -{ - nxt_int_t ret; - njs_frame_t *frame; - njs_value_t *value; - njs_vmcode_arguments_t *code; - - frame = (njs_frame_t *) vm->active_frame; - - if (frame->native.arguments_object == NULL) { - ret = njs_function_arguments_object_init(vm, &frame->native); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - } - - code = (njs_vmcode_arguments_t *) vm->current; - - value = njs_vmcode_operand(vm, code->dst); - njs_set_object(value, frame->native.arguments_object); - - return sizeof(njs_vmcode_arguments_t); -} - - -njs_ret_t -njs_vmcode_regexp(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) -{ - njs_regexp_t *regexp; - njs_vmcode_regexp_t *code; - - code = (njs_vmcode_regexp_t *) vm->current; - - regexp = njs_regexp_alloc(vm, code->pattern); - - if (nxt_fast_path(regexp != NULL)) { - njs_set_regexp(&vm->retval, regexp); - - return sizeof(njs_vmcode_regexp_t); - } - - return NXT_ERROR; -} - - -njs_ret_t -njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *invld1, - njs_value_t *retval) -{ - nxt_int_t ret; - njs_array_t *array; - njs_value_t *value; - - static const njs_function_t concat = { - .native = 1, - .args_offset = 1, - .u.native = njs_string_prototype_concat - }; - - value = njs_vmcode_operand(vm, retval); - - if (!njs_is_primitive(value)) { - array = njs_array(value); - - ret = njs_function_frame(vm, (njs_function_t *) &concat, - (njs_value_t *) &njs_string_empty, - array->start, array->length, 0); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - ret = njs_function_frame_invoke(vm, (njs_index_t) retval); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - } - - return sizeof(njs_vmcode_template_literal_t); -} - - -njs_ret_t -njs_vmcode_object_copy(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld) -{ - njs_object_t *object; - njs_function_t *function; - - switch (value->type) { - - case NJS_OBJECT: - object = njs_object_value_copy(vm, value); - if (nxt_slow_path(object == NULL)) { - return NXT_ERROR; - } - - break; - - case NJS_FUNCTION: - function = njs_function_value_copy(vm, value); - if (nxt_slow_path(function == NULL)) { - return NXT_ERROR; - } - - break; - - default: - break; - } - - vm->retval = *value; - - njs_retain(value); - - return sizeof(njs_vmcode_object_copy_t); -} - - -njs_ret_t -njs_vmcode_property_get(njs_vm_t *vm, njs_value_t *object, - njs_value_t *property) -{ - njs_ret_t ret; - njs_value_t *retval; - njs_vmcode_prop_get_t *code; - - code = (njs_vmcode_prop_get_t *) vm->current; - retval = njs_vmcode_operand(vm, code->value); - - ret = njs_value_property(vm, object, property, retval); - if (nxt_slow_path(ret == NXT_ERROR)) { - return ret; - } - - vm->retval = *retval; - - return sizeof(njs_vmcode_prop_get_t); -} - - -njs_ret_t -njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *object, - njs_value_t *property) -{ - uint32_t index, size; - njs_ret_t ret; - njs_array_t *array; - njs_value_t *init, *value, name; - njs_object_t *obj; - njs_object_prop_t *prop; - nxt_lvlhsh_query_t lhq; - njs_vmcode_prop_set_t *code; - - code = (njs_vmcode_prop_set_t *) vm->current; - init = njs_vmcode_operand(vm, code->value); - - switch (object->type) { - case NJS_ARRAY: - index = njs_value_to_index(property); - if (nxt_slow_path(index == NJS_ARRAY_INVALID_INDEX)) { - njs_internal_error(vm, - "invalid index while property initialization"); - return NXT_ERROR; - } - - array = object->data.u.array; - - if (index >= array->length) { - size = index - array->length; - - ret = njs_array_expand(vm, array, 0, size + 1); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - value = &array->start[array->length]; - - while (size != 0) { - njs_set_invalid(value); - value++; - size--; - } - - array->length = index + 1; - } - - /* GC: retain. */ - array->start[index] = *init; - - break; - - case NJS_OBJECT: - ret = njs_value_to_string(vm, &name, property); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - - njs_string_get(&name, &lhq.key); - lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; - - obj = njs_object(object); - - ret = nxt_lvlhsh_find(&obj->__proto__->shared_hash, &lhq); - if (ret == NXT_OK) { - prop = lhq.value; - - if (prop->type == NJS_PROPERTY_HANDLER) { - ret = prop->value.data.u.prop_handler(vm, object, init, - &vm->retval); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - break; - } - } - - prop = njs_object_prop_alloc(vm, &name, init, 1); - if (nxt_slow_path(prop == NULL)) { - return NXT_ERROR; - } - - lhq.value = prop; - lhq.replace = 1; - - ret = nxt_lvlhsh_insert(&obj->hash, &lhq); - if (nxt_slow_path(ret != NXT_OK)) { - njs_internal_error(vm, "lvlhsh insert/replace failed"); - return NXT_ERROR; - } - - break; - - default: - njs_internal_error(vm, "unexpected object type \"%s\" " - "while property initialization", - njs_type_string(object->type)); - - return NXT_ERROR; - } - - return sizeof(njs_vmcode_prop_set_t); -} - - -njs_ret_t -njs_vmcode_property_set(njs_vm_t *vm, njs_value_t *object, - njs_value_t *property) -{ - njs_ret_t ret; - njs_value_t *value; - njs_vmcode_prop_set_t *code; - - code = (njs_vmcode_prop_set_t *) vm->current; - value = njs_vmcode_operand(vm, code->value); - - ret = njs_value_property_set(vm, object, property, value); - if (nxt_slow_path(ret == NXT_ERROR)) { - return ret; - } - - return sizeof(njs_vmcode_prop_set_t); -} - - -njs_ret_t -njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *object, njs_value_t *property) -{ - njs_ret_t ret; - njs_object_prop_t *prop; - const njs_value_t *retval; - njs_property_query_t pq; - - retval = &njs_value_false; - - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); - - ret = njs_property_query(vm, &pq, object, property); - - switch (ret) { - - case NXT_OK: - prop = pq.lhq.value; - - if (!njs_is_valid(&prop->value)) { - break; - } - - retval = &njs_value_true; - break; - - case NXT_DECLINED: - if (!njs_is_object(object) && !njs_is_external(object)) { - njs_type_error(vm, "property in on a primitive value"); - - return NXT_ERROR; - } - - break; - - case NXT_ERROR: - default: - - return ret; - } - - vm->retval = *retval; - - return sizeof(njs_vmcode_3addr_t); -} - - -njs_ret_t -njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *object, - njs_value_t *property) -{ - njs_ret_t ret; - njs_object_prop_t *prop, *whipeout; - njs_property_query_t pq; - - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1); - - ret = njs_property_query(vm, &pq, object, property); - - switch (ret) { - - case NXT_OK: - prop = pq.lhq.value; - - if (nxt_slow_path(!prop->configurable)) { - njs_type_error(vm, "Cannot delete property \"%V\" of %s", - &pq.lhq.key, njs_type_string(object->type)); - return NXT_ERROR; - } - - if (nxt_slow_path(pq.shared)) { - whipeout = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t), - sizeof(njs_object_prop_t)); - if (nxt_slow_path(whipeout == NULL)) { - njs_memory_error(vm); - return NXT_ERROR; - } - - njs_set_invalid(&whipeout->value); - whipeout->name = prop->name; - whipeout->type = NJS_WHITEOUT; - - pq.lhq.replace = 0; - pq.lhq.value = whipeout; - pq.lhq.pool = vm->mem_pool; - - ret = nxt_lvlhsh_insert(&pq.prototype->hash, &pq.lhq); - if (nxt_slow_path(ret != NXT_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NXT_ERROR; - } - - break; - } - - switch (prop->type) { - case NJS_PROPERTY: - case NJS_METHOD: - break; - - case NJS_PROPERTY_REF: - njs_set_invalid(prop->value.data.u.value); - goto done; - - case NJS_PROPERTY_HANDLER: - ret = prop->value.data.u.prop_handler(vm, object, NULL, NULL); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - goto done; - - default: - njs_internal_error(vm, "unexpected property type \"%s\" " - "while deleting", - njs_prop_type_string(prop->type)); - - return NXT_ERROR; - } - - /* GC: release value. */ - prop->type = NJS_WHITEOUT; - njs_set_invalid(&prop->value); - - break; - - case NXT_DECLINED: - break; - - case NXT_ERROR: - default: - - return ret; - } - -done: - - vm->retval = njs_value_true; - - return sizeof(njs_vmcode_3addr_t); -} - - -njs_ret_t -njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object, - njs_value_t *invld) -{ - void *obj; - njs_ret_t ret; - njs_property_next_t *next; - const njs_extern_t *ext_proto; - njs_vmcode_prop_foreach_t *code; - - if (njs_is_external(object)) { - ext_proto = object->external.proto; - - if (ext_proto->foreach != NULL) { - obj = njs_extern_object(vm, object); - - ret = ext_proto->foreach(vm, obj, &vm->retval); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - } - - goto done; - } - - next = nxt_mp_alloc(vm->mem_pool, sizeof(njs_property_next_t)); - if (nxt_slow_path(next == NULL)) { - njs_memory_error(vm); - return NXT_ERROR; - } - - next->index = 0; - next->array = njs_value_enumerate(vm, object, NJS_ENUM_KEYS, 0); - if (nxt_slow_path(next->array == NULL)) { - njs_memory_error(vm); - return NXT_ERROR; - } - - vm->retval.data.u.next = next; - -done: - - code = (njs_vmcode_prop_foreach_t *) vm->current; - - return code->offset; -} - - -njs_ret_t -njs_vmcode_property_next(njs_vm_t *vm, njs_value_t *object, njs_value_t *value) -{ - void *obj; - njs_ret_t ret; - njs_value_t *retval; - njs_property_next_t *next; - const njs_extern_t *ext_proto; - njs_vmcode_prop_next_t *code; - - code = (njs_vmcode_prop_next_t *) vm->current; - retval = njs_vmcode_operand(vm, code->retval); - - if (njs_is_external(object)) { - ext_proto = object->external.proto; - - if (ext_proto->next != NULL) { - obj = njs_extern_object(vm, object); - - ret = ext_proto->next(vm, retval, obj, value); - - if (ret == NXT_OK) { - return code->offset; - } - - if (nxt_slow_path(ret == NXT_ERROR)) { - return ret; - } - - /* ret == NJS_DONE. */ - } - - return sizeof(njs_vmcode_prop_next_t); - } - - next = value->data.u.next; - - if (next->index < next->array->length) { - *retval = next->array->data[next->index++]; - - return code->offset; - } - - nxt_mp_free(vm->mem_pool, next); - - return sizeof(njs_vmcode_prop_next_t); -} - - -njs_ret_t -njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, - njs_value_t *constructor) -{ - nxt_int_t ret; - njs_value_t value; - njs_object_t *prototype, *proto; - const njs_value_t *retval; - - static njs_value_t prototype_string = njs_string("prototype"); - - if (!njs_is_function(constructor)) { - njs_type_error(vm, "right argument is not a function"); - return NXT_ERROR; - } - - retval = &njs_value_false; - - if (njs_is_object(object)) { - value = njs_value_undefined; - ret = njs_value_property(vm, constructor, &prototype_string, &value); - - if (nxt_slow_path(ret == NXT_ERROR)) { - return ret; - } - - if (nxt_fast_path(ret == NXT_OK)) { - - if (nxt_slow_path(!njs_is_object(&value))) { - njs_internal_error(vm, "prototype is not an object"); - return NXT_ERROR; - } - - prototype = njs_object(&value); - proto = njs_object(object); - - do { - proto = proto->__proto__; - - if (proto == prototype) { - retval = &njs_value_true; - break; - } - - } while (proto != NULL); - } - } - - vm->retval = *retval; - - return sizeof(njs_vmcode_instance_of_t); -} - - -njs_ret_t -njs_vmcode_increment(njs_vm_t *vm, njs_value_t *reference, njs_value_t *value) -{ - double num; - njs_ret_t ret; - njs_value_t numeric; - - if (nxt_slow_path(!njs_is_numeric(value))) { - ret = njs_value_to_numeric(vm, &numeric, value); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - num = njs_number(&numeric); - - } else { - num = njs_number(value); - } - - njs_release(vm, reference); - - njs_set_number(reference, num + 1.0); - vm->retval = *reference; - - return sizeof(njs_vmcode_3addr_t); -} - - -njs_ret_t -njs_vmcode_decrement(njs_vm_t *vm, njs_value_t *reference, njs_value_t *value) -{ - double num; - njs_ret_t ret; - njs_value_t numeric; - - if (nxt_slow_path(!njs_is_numeric(value))) { - ret = njs_value_to_numeric(vm, &numeric, value); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - num = njs_number(&numeric); - - } else { - num = njs_number(value); - } - - njs_release(vm, reference); - - njs_set_number(reference, num - 1.0); - vm->retval = *reference; - - return sizeof(njs_vmcode_3addr_t); -} - - -njs_ret_t -njs_vmcode_post_increment(njs_vm_t *vm, njs_value_t *reference, - njs_value_t *value) -{ - double num; - njs_ret_t ret; - njs_value_t numeric; - - if (nxt_slow_path(!njs_is_numeric(value))) { - ret = njs_value_to_numeric(vm, &numeric, value); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - num = njs_number(&numeric); - - } else { - num = njs_number(value); - } - - njs_release(vm, reference); - - njs_set_number(reference, num + 1.0); - njs_set_number(&vm->retval, num); - - return sizeof(njs_vmcode_3addr_t); -} - - -njs_ret_t -njs_vmcode_post_decrement(njs_vm_t *vm, njs_value_t *reference, - njs_value_t *value) -{ - double num; - njs_ret_t ret; - njs_value_t numeric; - - if (nxt_slow_path(!njs_is_numeric(value))) { - ret = njs_value_to_numeric(vm, &numeric, value); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - num = njs_number(&numeric); - - } else { - num = njs_number(value); - } - - njs_release(vm, reference); - - njs_set_number(reference, num - 1.0); - njs_set_number(&vm->retval, num); - - return sizeof(njs_vmcode_3addr_t); -} - - -njs_ret_t -njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld) -{ - /* ECMAScript 5.1: null, array and regexp are objects. */ - - static const njs_value_t *types[NJS_TYPE_MAX] = { - &njs_string_object, - &njs_string_undefined, - &njs_string_boolean, - &njs_string_number, - &njs_string_string, - &njs_string_data, - &njs_string_external, - &njs_string_invalid, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, From dnj0496 at gmail.com Wed Jul 24 01:17:36 2019 From: dnj0496 at gmail.com (Dk Jack) Date: Tue, 23 Jul 2019 18:17:36 -0700 Subject: connections in CLOSE_WAIT Message-ID: Hi, In my module, I am capturing the request body to check if the body contains some specific content. If the body does not contain the specific content then I pass on the request without modification. Otherwise, I send a HTTP_FORBIDDEN. I am using 'ngx_http_read_client_request_body' call to capture the body. Everything seems to be working fine. My requests are forwarded to the orgin server and my client is receiving the response from the origin server correctly. However, what I notice is that the nginx is not releasing the client side (see below). Nginx status module reports same number of active connections in 'writing' state. Is there something special I need to do in my module to ensure the connections are closed properly when I am capturing body? Any help is greatly appreciated. Thanks. Regards, Dk. [centos at ip-10-50-18-73 nginx]$ netstat -n | grep CLOSE_WAIT | head -4 tcp 1 0 10.50.18.73:443 10.50.30.239:60116 CLOSE_WAIT tcp 1 0 10.50.18.73:443 10.50.30.239:60092 CLOSE_WAIT tcp 1 0 10.50.18.73:443 10.50.30.239:60112 CLOSE_WAIT tcp 1 0 10.50.18.73:443 10.50.30.239:60054 CLOSE_WAIT [centos at ip-10-50-18-73 nginx]$ netstat -n | grep CLOSE_WAIT | wc -l 35 [centos at ip-10-50-18-73 nginx]$ [centos at ip-10-50-18-73 nginx]$ curl -k https://localhost/nginx_status Active connections: 37 server accepts handled requests 41 41 472 Reading: 0 Writing: 36 Waiting: 1 [centos at ip-10-50-18-73 nginx]$ -------------- next part -------------- An HTML attachment was scrubbed... URL: From hongzhidao at gmail.com Wed Jul 24 03:47:19 2019 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Wed, 24 Jul 2019 11:47:19 +0800 Subject: cache: move open to thread pool In-Reply-To: <20190722140523.GU61550@Romans-MacBook-Air.local> References: <9aef70ef-db5f-d3af-bb09-44848477fab2@nginx.com> <20190722140523.GU61550@Romans-MacBook-Air.local> Message-ID: Hi, I found an issue with the patch. 1. Reproduce (/usr/local/nginx/html/5M.txt, Just making `ngx_http_set_write_handler` be called.) telnet localhost 80 GET /5M.txt HTTP/1.1 HOST: 1.1.1.1 -- response-- GET /5M.txt HTTP/1.1 HOST: 1.1.1.1 --50 error-- /* happened in keepalive */ 2. Reason It happens in the case of keepalive. Since `ngx_http_set_write_handler` is called, c->write is active and ready, after receiving http request: ngx_http_static_handler is called { ngx_http_static_send(); // task has been added thread pool, but its event is not complete. r->write_event_handler = ngx_http_static_write_event_handler; } And the epoll write event is triggered. So ngx_http_static_write_event_handler is called again. But task->event.active is true. ngx_thread_task_post() will fail. Throws "task #%ui already active". 3. Early patch. ``` diff -r bd11e3399021 src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c Tue Oct 30 15:00:49 2018 +0300 +++ b/src/http/modules/ngx_http_static_module.c Tue Jul 23 23:46:22 2019 -0400 @@ -318,6 +318,12 @@ ngx_http_static_write_event_handler(ngx_ { ngx_int_t rc; + if (r->open_file_info.thread_task != NULL + && r->open_file_info.thread_task->event.complete == 0) + { + return; + } + rc = ngx_http_static_send(r); if (rc != NGX_DONE) { ``` Thanks. On Mon, Jul 22, 2019 at 10:05 PM Roman Arutyunyan wrote: > Hi, > > On Sat, Jul 20, 2019 at 09:44:25AM +0800, ??? wrote: > > > The patch wasn't updated since that but I suspect it could be still > > applied to nginx, maybe with some minor tweaks. > > > > We still appreciate your work. > > > > BTW, are the patches in the attachment up to date? > > If not, can you share the latest patch? > > We had no patches since november 1, 2018. The last patch is in this > message: > > http://mailman.nginx.org/pipermail/nginx-devel/2018-November/011538.html > > > We are happy to apply it and feedback if possible. > > When there are many static files and accesses, do you think it will works > > very well? > > We didn't have much feedback so far. So we would definitely appreciate > your > contribution to testing it. > > > On Sat, Jul 20, 2019 at 2:42 AM Maxim Konovalov wrote: > > > > > Hi hongzhidao, > > > > > > The patch wasn't merged as we didn't see much interest and real > > > technical feedback from potential testers. > > > > > > The code adds additional complexity to the nginx core with all > > > associated costs of maintaining the code virtually forever. In the > > > same time at this point it brings no measurable value to the > > > community. At least, we haven't seen any proofs that it does. > > > > > > The patch wasn't updated since that but I suspect it could be still > > > applied to nginx, maybe with some minor tweaks. > > > > > > Maxim > > > > > > On 19/07/2019 18:26, ??? wrote: > > > > Hi. > > > > Will this patch be merged into the main branch? > > > > What is the latest patch? We can help with the test. > > > > Thanks. > > > > > > > > On Sat, Feb 9, 2019 at 6:40 AM Ka-Hing Cheung via nginx-devel > > > > > wrote: > > > > > > > > Unfortunately our test colo is not setup to do performance > testing > > > > (the traffic it receives varies too much). We do intend to merge > > > > this > > > > to our production colos but there's no timeline yet. > > > > > > > > Yuchen (CC'ed) will be the main contact from now on as today is > my > > > > last day at Cloudflare. > > > > > > > > - Ka-Hing > > > > > > > > On Thu, Feb 7, 2019 at 5:39 AM Maxim Konovalov > > > > wrote: > > > > > > > > > > Great. Thanks for the testing! > > > > > > > > > > Did you see any measurable perf. metrics changes comparing to > your > > > > > aio open implementation or comparing to nginx without aio open > > > > support? > > > > > > > > > > We are still waiting for additional input from another tester, > who > > > > > expressed interest before. > > > > > > > > > > Thanks, > > > > > > > > > > Maxim > > > > > > > > > > On 07/02/2019 00:19, Ka-Hing Cheung wrote: > > > > > > This has been running in our test colo for the past week > > > > with no ill effects. > > > > > > > > > > > > On Wed, Jan 23, 2019 at 4:39 AM Maxim Konovalov > > > > > wrote: > > > > > >> > > > > > >> Hi Ka-Hing, > > > > > >> > > > > > >> Roman told me that the delta is because of your changes. > > > > > >> > > > > > >> Thanks for your time on that. Waiting for your testing > > > > results. > > > > > >> > > > > > >> Maxim > > > > > >> > > > > > >> On 22/01/2019 22:34, Ka-Hing Cheung via nginx-devel wrote: > > > > > >>> I spoke too soon, just realized our test colo is running > > > > the patches > > > > > >>> without aio_open on. Flipping that switch now. > > > > > >>> > > > > > >>> Also, including the patch that we applied on top in > > > > addition to the > > > > > >>> massaging we did to resolve conflicts. I haven't dug too > > > > deep to see > > > > > >>> if stock nginx also requires similar changes or they are > only > > > > > >>> necessary because of our other nginx changes: > > > > > >>> > > > > > >> [...] > > > > > >> > > > > > >> -- > > > > > >> Maxim Konovalov > > > > > > > > > > > > > > > -- > > > > > Maxim Konovalov > > > > _______________________________________________ > > > > nginx-devel mailing list > > > > nginx-devel at nginx.org > > > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > > > > > _______________________________________________ > > > > nginx-devel mailing list > > > > nginx-devel at nginx.org > > > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > > > > > > -- > > > Maxim Konovalov > > > > > > _______________________________________________ > > nginx-devel mailing list > > nginx-devel at nginx.org > > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > -- > Roman Arutyunyan > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From dnj0496 at gmail.com Wed Jul 24 23:14:53 2019 From: dnj0496 at gmail.com (Dk Jack) Date: Wed, 24 Jul 2019 16:14:53 -0700 Subject: connections in CLOSE_WAIT In-Reply-To: References: Message-ID: Could someone comment on my question below. What does it mean when the connections are stuck in 'Writing' state? Since the client has received the response, why is the nginx still stuck trying to write something. Any help in debugging or what to look for is greatly appreciated. Thanks. Dk. On Tue, Jul 23, 2019 at 6:17 PM Dk Jack wrote: > Hi, > In my module, I am capturing the request body to check if the body > contains some specific content. If the body does not contain the specific > content, I pass on the request without modification. Otherwise, I send a > HTTP_FORBIDDEN. I am using 'ngx_http_read_client_request_body' call to > capture the body. Everything seems to be working fine. My requests are > forwarded to the orgin server and my client is receiving the response from > the origin server correctly. > > However, what I notice is that the nginx is not releasing the client side > (see below). Nginx status module reports same number of active connections > in 'writing' state. Is there something special I need to do in my module to > ensure the connections are closed properly when I am capturing body? Any > help is greatly appreciated. Thanks. > > Regards, > Dk. > > [centos at ip-10-50-18-73 nginx]$ netstat -n | grep CLOSE_WAIT | head -4 > tcp 1 0 10.50.18.73:443 10.50.30.239:60116 > CLOSE_WAIT > tcp 1 0 10.50.18.73:443 10.50.30.239:60092 > CLOSE_WAIT > tcp 1 0 10.50.18.73:443 10.50.30.239:60112 > CLOSE_WAIT > tcp 1 0 10.50.18.73:443 10.50.30.239:60054 > CLOSE_WAIT > [centos at ip-10-50-18-73 nginx]$ netstat -n | grep CLOSE_WAIT | wc -l > 35 > [centos at ip-10-50-18-73 nginx]$ [centos at ip-10-50-18-73 nginx]$ curl -k > https://localhost/nginx_status > Active connections: 37 > server accepts handled requests > 41 41 472 > Reading: 0 Writing: 36 Waiting: 1 > [centos at ip-10-50-18-73 nginx]$ > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dnj0496 at gmail.com Thu Jul 25 02:51:25 2019 From: dnj0496 at gmail.com (Dk Jack) Date: Wed, 24 Jul 2019 19:51:25 -0700 Subject: connections in CLOSE_WAIT In-Reply-To: References: Message-ID: I was able to resolve this by invoking finalize_request. On Wed, Jul 24, 2019 at 4:14 PM Dk Jack wrote: > Could someone comment on my question below. What does it mean when the > connections are stuck in 'Writing' state? Since the client has received the > response, why is the nginx still stuck trying to write something. Any help > in debugging or what to look for is greatly appreciated. Thanks. > > Dk. > > On Tue, Jul 23, 2019 at 6:17 PM Dk Jack wrote: > >> Hi, >> In my module, I am capturing the request body to check if the body >> contains some specific content. If the body does not contain the specific >> content, I pass on the request without modification. Otherwise, I send a >> HTTP_FORBIDDEN. I am using 'ngx_http_read_client_request_body' call to >> capture the body. Everything seems to be working fine. My requests are >> forwarded to the orgin server and my client is receiving the response from >> the origin server correctly. >> >> However, what I notice is that the nginx is not releasing the client side >> (see below). Nginx status module reports same number of active connections >> in 'writing' state. Is there something special I need to do in my module to >> ensure the connections are closed properly when I am capturing body? Any >> help is greatly appreciated. Thanks. >> >> Regards, >> Dk. >> >> [centos at ip-10-50-18-73 nginx]$ netstat -n | grep CLOSE_WAIT | head -4 >> tcp 1 0 10.50.18.73:443 10.50.30.239:60116 >> CLOSE_WAIT >> tcp 1 0 10.50.18.73:443 10.50.30.239:60092 >> CLOSE_WAIT >> tcp 1 0 10.50.18.73:443 10.50.30.239:60112 >> CLOSE_WAIT >> tcp 1 0 10.50.18.73:443 10.50.30.239:60054 >> CLOSE_WAIT >> [centos at ip-10-50-18-73 nginx]$ netstat -n | grep CLOSE_WAIT | wc -l >> 35 >> [centos at ip-10-50-18-73 nginx]$ [centos at ip-10-50-18-73 nginx]$ curl -k >> https://localhost/nginx_status >> Active connections: 37 >> server accepts handled requests >> 41 41 472 >> Reading: 0 Writing: 36 Waiting: 1 >> [centos at ip-10-50-18-73 nginx]$ >> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From dnj0496 at gmail.com Thu Jul 25 06:07:30 2019 From: dnj0496 at gmail.com (Dk Jack) Date: Wed, 24 Jul 2019 23:07:30 -0700 Subject: Trying to understand request body handling. Message-ID: Hi, In my module I have the following requirements: - Inspect the contents of the POST body in the request - If the body content matches the configured regex, then take one of the following actions: - Return forbidden - Redirect to another location without using 302 - If the content doesn't match the configured regex, then simply forward the request to proxy_pass destination. I used 'ngx_http_read_client_request_body'function accumulate the body contents inspect it. I invoked this function from a pre-access handler. My request body handler callback gets called and I am able to inspect the body and I am able to take the actions I have mentioned above. However, it is not working completely as I expected. For example, when I return forbidden after body inspection, my client is receiving the forbidden message and the status code I've setup. However, the request seems to also get forwarded to the origin. In the error.log, I see 'header already sent while reading response from upstream' message. I see a similar issue when redirecting. The request is getting sent to origin server as well as the server I redirected to after inspection. Which leads me to believe that the request is being forwarded based on the proxy_pass rule while my module is still accumulating the body i.e before my body_complete handler is called. Is my understanding correct? If so, is there a way to stall the forwarding of the request till my module has completed the inspection? Is there something in the request I need to set in the earlier phases when I doing this sort of thing? I also modified my module to use body filters as described in https://nginx.org/en/docs/dev/development_guide.html#http_body_filters to see if it'd help my cause. However, I can't seem to get redirect working after inspecting the body. Any suggestions on the correct approach to solving my issues while adhering to requirements. Any help is greatly appreciated. Thanks. regards, Dk. -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Thu Jul 25 17:42:13 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 25 Jul 2019 17:42:13 +0000 Subject: [njs] Fixed one byte overread in njs_string_to_c_string(). Message-ID: details: https://hg.nginx.org/njs/rev/644af379d226 branches: changeset: 1068:644af379d226 user: Valentin Bartenev date: Thu Jul 25 20:17:42 2019 +0300 description: Fixed one byte overread in njs_string_to_c_string(). Short strings are packed quite tight in njs_value_t, so there's no one more byte to test. struct { njs_value_type_t type:8; uint8_t size:4; uint8_t length:4; u_char start[14]; } short_string; With 14 bytes string this occupies 16 bytes, which is equal to sizeof(njs_value_t). diffstat: njs/njs_string.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diffs (15 lines): diff -r 427edfbe6762 -r 644af379d226 njs/njs_string.c --- a/njs/njs_string.c Tue Jul 23 19:42:25 2019 +0300 +++ b/njs/njs_string.c Thu Jul 25 20:17:42 2019 +0300 @@ -3906,10 +3906,7 @@ njs_string_to_c_string(njs_vm_t *vm, njs start = value->short_string.start; size = value->short_string.size; - if (start[size] == '\0') { - return start; - - } else if (size < NJS_STRING_SHORT) { + if (size < NJS_STRING_SHORT) { start[size] = '\0'; return start; } From vbart at nginx.com Thu Jul 25 21:24:50 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 25 Jul 2019 21:24:50 +0000 Subject: [njs] Optimized nxt_dec_count() using bisection. Message-ID: details: https://hg.nginx.org/njs/rev/89082cb0bc84 branches: changeset: 1069:89082cb0bc84 user: Valentin Bartenev date: Thu Jul 25 22:07:57 2019 +0300 description: Optimized nxt_dec_count() using bisection. Previously, the number of comparisons required to count decimal numbers was equal to decimal numbers count. Now only 3 comparsions are needed for numbers with 1, 2, 3, 4, 5, or 6 decimal digits, and 4 comparsions are needed for numbers with 7, 8, 9, and 10 decimal digits. diffstat: nxt/nxt_dtoa.c | 30 ++++++++++++++++++++---------- 1 files changed, 20 insertions(+), 10 deletions(-) diffs (41 lines): diff -r 644af379d226 -r 89082cb0bc84 nxt/nxt_dtoa.c --- a/nxt/nxt_dtoa.c Thu Jul 25 20:17:42 2019 +0300 +++ b/nxt/nxt_dtoa.c Thu Jul 25 22:07:57 2019 +0300 @@ -61,17 +61,27 @@ nxt_grisu2_round(char *start, size_t len nxt_inline int nxt_dec_count(uint32_t n) { - if (n < 10) return 1; - if (n < 100) return 2; - if (n < 1000) return 3; - if (n < 10000) return 4; - if (n < 100000) return 5; - if (n < 1000000) return 6; - if (n < 10000000) return 7; - if (n < 100000000) return 8; - if (n < 1000000000) return 9; + if (n < 10000) { + if (n < 100) { + return (n < 10) ? 1 : 2; + + } else { + return (n < 1000) ? 3 : 4; + } - return 10; + } else { + if (n < 1000000) { + return (n < 100000) ? 5 : 6; + + } else { + if (n < 100000000) { + return (n < 10000000) ? 7 : 8; + + } else { + return (n < 1000000000) ? 9 : 10; + } + } + } } From grajulu7 at gmail.com Fri Jul 26 06:35:28 2019 From: grajulu7 at gmail.com (Govinda Rajulu) Date: Fri, 26 Jul 2019 12:05:28 +0530 Subject: Nginx: using sub-request call to make external server API POST response Message-ID: Hi Team, Can anyone please share some pointer on subrequest call for making POST API external server call? nginx config: location = /config_uri { proxy_pass http://external-server/config; } Thanks, Govinda P -------------- next part -------------- An HTML attachment was scrubbed... URL: From arut at nginx.com Fri Jul 26 06:41:10 2019 From: arut at nginx.com (Roman Arutyunyan) Date: Fri, 26 Jul 2019 09:41:10 +0300 Subject: Nginx: using sub-request call to make external server API POST response In-Reply-To: References: Message-ID: <20190726064110.GD61550@Romans-MacBook-Air.local> Hi, On Fri, Jul 26, 2019 at 12:05:28PM +0530, Govinda Rajulu wrote: > Hi Team, > Can anyone please share some pointer on subrequest call for making POST > API external server call? > > nginx config: > location = /config_uri { > proxy_pass http://external-server/config; > } > > Thanks, > Govinda P Use proxy_method and proxy_set_body: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_method http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_body -- Roman Arutyunyan From xeioex at nginx.com Fri Jul 26 17:49:19 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 26 Jul 2019 17:49:19 +0000 Subject: [njs] Refactored njs_vmcode_interpreter() for performance. Message-ID: details: https://hg.nginx.org/njs/rev/6aa2e67eaafc branches: changeset: 1070:6aa2e67eaafc user: Dmitry Volyntsev date: Fri Jul 26 20:37:13 2019 +0300 description: Refactored njs_vmcode_interpreter() for performance. 1) opcodes are rewritten using switch table. 2) often-used opcodes are prioritized and inlined. 3) similar opcodes are combined into unified handlers. 4) njs_vmcode_interpreter() return NJS_OK on success. NJS_STOP return code is removed. diffstat: njs/njs_disassembler.c | 140 +- njs/njs_function.c | 7 +- njs/njs_function.h | 2 +- njs/njs_generator.c | 100 +- njs/njs_parser.c | 2 +- njs/njs_parser_expression.c | 102 +- njs/njs_parser_terminal.c | 2 +- njs/njs_vm.c | 14 +- njs/njs_vm.h | 21 +- njs/njs_vmcode.c | 2057 +++++++++++++++++------------------------- njs/njs_vmcode.h | 252 +--- njs/test/njs_unit_test.c | 11 + 12 files changed, 1139 insertions(+), 1571 deletions(-) diffs (truncated from 3927 to 1000 lines): diff -r 89082cb0bc84 -r 6aa2e67eaafc njs/njs_disassembler.c --- a/njs/njs_disassembler.c Thu Jul 25 22:07:57 2019 +0300 +++ b/njs/njs_disassembler.c Fri Jul 26 20:37:13 2019 +0300 @@ -19,116 +19,116 @@ typedef struct { static njs_code_name_t code_names[] = { - { njs_vmcode_object, sizeof(njs_vmcode_object_t), + { NJS_VMCODE_OBJECT, sizeof(njs_vmcode_object_t), nxt_string("OBJECT ") }, - { njs_vmcode_function, sizeof(njs_vmcode_function_t), + { NJS_VMCODE_FUNCTION, sizeof(njs_vmcode_function_t), nxt_string("FUNCTION ") }, - { njs_vmcode_this, sizeof(njs_vmcode_this_t), + { NJS_VMCODE_THIS, sizeof(njs_vmcode_this_t), nxt_string("THIS ") }, - { njs_vmcode_arguments, sizeof(njs_vmcode_arguments_t), + { NJS_VMCODE_ARGUMENTS, sizeof(njs_vmcode_arguments_t), nxt_string("ARGUMENTS ") }, - { njs_vmcode_regexp, sizeof(njs_vmcode_regexp_t), + { NJS_VMCODE_REGEXP, sizeof(njs_vmcode_regexp_t), nxt_string("REGEXP ") }, - { njs_vmcode_template_literal, sizeof(njs_vmcode_template_literal_t), + { NJS_VMCODE_TEMPLATE_LITERAL, sizeof(njs_vmcode_template_literal_t), nxt_string("TEMPLATE LITERAL") }, - { njs_vmcode_object_copy, sizeof(njs_vmcode_object_copy_t), + { NJS_VMCODE_OBJECT_COPY, sizeof(njs_vmcode_object_copy_t), nxt_string("OBJECT COPY ") }, - { njs_vmcode_property_get, sizeof(njs_vmcode_prop_get_t), + { NJS_VMCODE_PROPERTY_GET, sizeof(njs_vmcode_prop_get_t), nxt_string("PROPERTY GET ") }, - { njs_vmcode_property_init, sizeof(njs_vmcode_prop_set_t), + { NJS_VMCODE_PROPERTY_INIT, sizeof(njs_vmcode_prop_set_t), nxt_string("PROPERTY INIT ") }, - { njs_vmcode_property_set, sizeof(njs_vmcode_prop_set_t), + { NJS_VMCODE_PROPERTY_SET, sizeof(njs_vmcode_prop_set_t), nxt_string("PROPERTY SET ") }, - { njs_vmcode_property_in, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_PROPERTY_IN, sizeof(njs_vmcode_3addr_t), nxt_string("PROPERTY IN ") }, - { njs_vmcode_property_delete, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_PROPERTY_DELETE, sizeof(njs_vmcode_3addr_t), nxt_string("PROPERTY DELETE ") }, - { njs_vmcode_instance_of, sizeof(njs_vmcode_instance_of_t), + { NJS_VMCODE_INSTANCE_OF, sizeof(njs_vmcode_instance_of_t), nxt_string("INSTANCE OF ") }, - { njs_vmcode_function_call, sizeof(njs_vmcode_function_call_t), + { NJS_VMCODE_FUNCTION_CALL, sizeof(njs_vmcode_function_call_t), nxt_string("FUNCTION CALL ") }, - { njs_vmcode_return, sizeof(njs_vmcode_return_t), + { NJS_VMCODE_RETURN, sizeof(njs_vmcode_return_t), nxt_string("RETURN ") }, - { njs_vmcode_stop, sizeof(njs_vmcode_stop_t), + { NJS_VMCODE_STOP, sizeof(njs_vmcode_stop_t), nxt_string("STOP ") }, - { njs_vmcode_increment, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_INCREMENT, sizeof(njs_vmcode_3addr_t), nxt_string("INC ") }, - { njs_vmcode_decrement, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_DECREMENT, sizeof(njs_vmcode_3addr_t), nxt_string("DEC ") }, - { njs_vmcode_post_increment, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_POST_INCREMENT, sizeof(njs_vmcode_3addr_t), nxt_string("POST INC ") }, - { njs_vmcode_post_decrement, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_POST_DECREMENT, sizeof(njs_vmcode_3addr_t), nxt_string("POST DEC ") }, - { njs_vmcode_delete, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_DELETE, sizeof(njs_vmcode_2addr_t), nxt_string("DELETE ") }, - { njs_vmcode_void, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_VOID, sizeof(njs_vmcode_2addr_t), nxt_string("VOID ") }, - { njs_vmcode_typeof, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_TYPEOF, sizeof(njs_vmcode_2addr_t), nxt_string("TYPEOF ") }, - { njs_vmcode_unary_plus, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_UNARY_PLUS, sizeof(njs_vmcode_2addr_t), nxt_string("PLUS ") }, - { njs_vmcode_unary_negation, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_UNARY_NEGATION, sizeof(njs_vmcode_2addr_t), nxt_string("NEGATION ") }, - { njs_vmcode_addition, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_ADDITION, sizeof(njs_vmcode_3addr_t), nxt_string("ADD ") }, - { njs_vmcode_substraction, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_SUBSTRACTION, sizeof(njs_vmcode_3addr_t), nxt_string("SUBSTRACT ") }, - { njs_vmcode_multiplication, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_MULTIPLICATION, sizeof(njs_vmcode_3addr_t), nxt_string("MULTIPLY ") }, - { njs_vmcode_exponentiation, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_EXPONENTIATION, sizeof(njs_vmcode_3addr_t), nxt_string("POWER ") }, - { njs_vmcode_division, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_DIVISION, sizeof(njs_vmcode_3addr_t), nxt_string("DIVIDE ") }, - { njs_vmcode_remainder, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_REMAINDER, sizeof(njs_vmcode_3addr_t), nxt_string("REMAINDER ") }, - { njs_vmcode_left_shift, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_LEFT_SHIFT, sizeof(njs_vmcode_3addr_t), nxt_string("LEFT SHIFT ") }, - { njs_vmcode_right_shift, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_RIGHT_SHIFT, sizeof(njs_vmcode_3addr_t), nxt_string("RIGHT SHIFT ") }, - { njs_vmcode_unsigned_right_shift, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_UNSIGNED_RIGHT_SHIFT, sizeof(njs_vmcode_3addr_t), nxt_string("USGN RIGHT SHIFT") }, - { njs_vmcode_logical_not, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_LOGICAL_NOT, sizeof(njs_vmcode_2addr_t), nxt_string("LOGICAL NOT ") }, - { njs_vmcode_bitwise_not, sizeof(njs_vmcode_2addr_t), + { NJS_VMCODE_BITWISE_NOT, sizeof(njs_vmcode_2addr_t), nxt_string("BINARY NOT ") }, - { njs_vmcode_bitwise_and, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_BITWISE_AND, sizeof(njs_vmcode_3addr_t), nxt_string("BINARY AND ") }, - { njs_vmcode_bitwise_xor, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_BITWISE_XOR, sizeof(njs_vmcode_3addr_t), nxt_string("BINARY XOR ") }, - { njs_vmcode_bitwise_or, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_BITWISE_OR, sizeof(njs_vmcode_3addr_t), nxt_string("BINARY OR ") }, - { njs_vmcode_equal, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_EQUAL, sizeof(njs_vmcode_3addr_t), nxt_string("EQUAL ") }, - { njs_vmcode_not_equal, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_NOT_EQUAL, sizeof(njs_vmcode_3addr_t), nxt_string("NOT EQUAL ") }, - { njs_vmcode_less, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_LESS, sizeof(njs_vmcode_3addr_t), nxt_string("LESS ") }, - { njs_vmcode_less_or_equal, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_LESS_OR_EQUAL, sizeof(njs_vmcode_3addr_t), nxt_string("LESS OR EQUAL ") }, - { njs_vmcode_greater, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_GREATER, sizeof(njs_vmcode_3addr_t), nxt_string("GREATER ") }, - { njs_vmcode_greater_or_equal, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_GREATER_OR_EQUAL, sizeof(njs_vmcode_3addr_t), nxt_string("GREATER OR EQUAL") }, - { njs_vmcode_strict_equal, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_STRICT_EQUAL, sizeof(njs_vmcode_3addr_t), nxt_string("STRICT EQUAL ") }, - { njs_vmcode_strict_not_equal, sizeof(njs_vmcode_3addr_t), + { NJS_VMCODE_STRICT_NOT_EQUAL, sizeof(njs_vmcode_3addr_t), nxt_string("STRICT NOT EQUAL") }, - { njs_vmcode_move, sizeof(njs_vmcode_move_t), + { NJS_VMCODE_MOVE, sizeof(njs_vmcode_move_t), nxt_string("MOVE ") }, - { njs_vmcode_throw, sizeof(njs_vmcode_throw_t), + { NJS_VMCODE_THROW, sizeof(njs_vmcode_throw_t), nxt_string("THROW ") }, }; @@ -140,8 +140,8 @@ njs_disassembler(njs_vm_t *vm) nxt_uint_t n; njs_vm_code_t *code; - code = vm->code->start; - n = vm->code->items; + code = vm->codes->start; + n = vm->codes->items; while (n != 0) { nxt_printf("%V:%V\n", &code->file, &code->name); @@ -191,7 +191,7 @@ njs_disassemble(u_char *start, u_char *e while (p < end) { operation = *(njs_vmcode_operation_t *) p; - if (operation == njs_vmcode_array) { + if (operation == NJS_VMCODE_ARRAY) { array = (njs_vmcode_array_t *) p; nxt_printf("%05uz ARRAY %04Xz %uz%s\n", @@ -203,7 +203,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_if_true_jump) { + if (operation == NJS_VMCODE_IF_TRUE_JUMP) { cond_jump = (njs_vmcode_cond_jump_t *) p; sign = (cond_jump->offset >= 0) ? "+" : ""; @@ -216,7 +216,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_if_false_jump) { + if (operation == NJS_VMCODE_IF_FALSE_JUMP) { cond_jump = (njs_vmcode_cond_jump_t *) p; sign = (cond_jump->offset >= 0) ? "+" : ""; @@ -229,7 +229,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_jump) { + if (operation == NJS_VMCODE_JUMP) { jump = (njs_vmcode_jump_t *) p; sign = (jump->offset >= 0) ? "+" : ""; @@ -241,7 +241,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_if_equal_jump) { + if (operation == NJS_VMCODE_IF_EQUAL_JUMP) { equal = (njs_vmcode_equal_jump_t *) p; nxt_printf("%05uz JUMP IF EQUAL %04Xz %04Xz +%uz\n", @@ -253,7 +253,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_test_if_true) { + if (operation == NJS_VMCODE_TEST_IF_TRUE) { test_jump = (njs_vmcode_test_jump_t *) p; nxt_printf("%05uz TEST IF TRUE %04Xz %04Xz +%uz\n", @@ -265,7 +265,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_test_if_false) { + if (operation == NJS_VMCODE_TEST_IF_FALSE) { test_jump = (njs_vmcode_test_jump_t *) p; nxt_printf("%05uz TEST IF FALSE %04Xz %04Xz +%uz\n", @@ -277,7 +277,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_function_frame) { + if (operation == NJS_VMCODE_FUNCTION_FRAME) { function = (njs_vmcode_function_frame_t *) p; nxt_printf("%05uz FUNCTION FRAME %04Xz %uz%s\n", @@ -289,7 +289,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_method_frame) { + if (operation == NJS_VMCODE_METHOD_FRAME) { method = (njs_vmcode_method_frame_t *) p; nxt_printf("%05uz METHOD FRAME %04Xz %04Xz %uz%s\n", @@ -301,7 +301,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_property_foreach) { + if (operation == NJS_VMCODE_PROPERTY_FOREACH) { prop_foreach = (njs_vmcode_prop_foreach_t *) p; nxt_printf("%05uz PROPERTY FOREACH %04Xz %04Xz +%uz\n", @@ -313,7 +313,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_property_next) { + if (operation == NJS_VMCODE_PROPERTY_NEXT) { prop_next = (njs_vmcode_prop_next_t *) p; nxt_printf("%05uz PROPERTY NEXT %04Xz %04Xz %04Xz %uz\n", @@ -326,7 +326,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_try_start) { + if (operation == NJS_VMCODE_TRY_START) { try_start = (njs_vmcode_try_start_t *) p; nxt_printf("%05uz TRY START %04Xz %04Xz +%uz\n", @@ -339,7 +339,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_try_break) { + if (operation == NJS_VMCODE_TRY_BREAK) { try_tramp = (njs_vmcode_try_trampoline_t *) p; nxt_printf("%05uz TRY BREAK %04Xz %uz\n", @@ -351,7 +351,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_try_continue) { + if (operation == NJS_VMCODE_TRY_CONTINUE) { try_tramp = (njs_vmcode_try_trampoline_t *) p; nxt_printf("%05uz TRY CONTINUE %04Xz %uz\n", @@ -363,7 +363,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_try_return) { + if (operation == NJS_VMCODE_TRY_RETURN) { try_return = (njs_vmcode_try_return_t *) p; nxt_printf("%05uz TRY RETURN %04Xz %04Xz +%uz\n", @@ -376,7 +376,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_catch) { + if (operation == NJS_VMCODE_CATCH) { catch = (njs_vmcode_catch_t *) p; nxt_printf("%05uz CATCH %04Xz +%uz\n", @@ -388,7 +388,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_try_end) { + if (operation == NJS_VMCODE_TRY_END) { try_end = (njs_vmcode_try_end_t *) p; nxt_printf("%05uz TRY END +%uz\n", @@ -399,7 +399,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_finally) { + if (operation == NJS_VMCODE_FINALLY) { finally = (njs_vmcode_finally_t *) p; nxt_printf("%05uz TRY FINALLY %04Xz %04Xz +%uz +%uz\n", @@ -413,7 +413,7 @@ njs_disassemble(u_char *start, u_char *e continue; } - if (operation == njs_vmcode_reference_error) { + if (operation == NJS_VMCODE_REFERENCE_ERROR) { nxt_printf("%05uz REFERENCE ERROR\n", p - start); p += sizeof(njs_vmcode_reference_error_t); diff -r 89082cb0bc84 -r 6aa2e67eaafc njs/njs_function.c --- a/njs/njs_function.c Thu Jul 25 22:07:57 2019 +0300 +++ b/njs/njs_function.c Fri Jul 26 20:37:13 2019 +0300 @@ -500,10 +500,7 @@ njs_function_lambda_call(njs_vm_t *vm) frame = (njs_frame_t *) vm->top_frame; function = frame->native.function; - frame->return_address = vm->current; - lambda = function->u.lambda; - vm->current = lambda->start; #if (NXT_DEBUG) vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = NULL; @@ -571,9 +568,11 @@ njs_function_lambda_call(njs_vm_t *vm) } } + frame->native.call = 1; + vm->active_frame = frame; - return njs_vmcode_run(vm); + return njs_vmcode_interpreter(vm, lambda->start); } diff -r 89082cb0bc84 -r 6aa2e67eaafc njs/njs_function.h --- a/njs/njs_function.h Thu Jul 25 22:07:57 2019 +0300 +++ b/njs/njs_function.h Fri Jul 26 20:37:13 2019 +0300 @@ -90,7 +90,7 @@ struct njs_native_frame_s { /* Skip the Function.call() and Function.apply() methods frames. */ uint8_t skip; /* 1 bit */ - uint8_t call; /* 1 bit */ + uint8_t call; /* 1 bit */ }; diff -r 89082cb0bc84 -r 6aa2e67eaafc njs/njs_generator.c --- a/njs/njs_generator.c Thu Jul 25 22:07:57 2019 +0300 +++ b/njs/njs_generator.c Fri Jul 26 20:37:13 2019 +0300 @@ -198,7 +198,7 @@ static nxt_int_t njs_generate_function_d #define njs_generate_code_jump(generator, _code, _offset) \ do { \ njs_generate_code(generator, njs_vmcode_jump_t, _code, \ - njs_vmcode_jump, 0, 0); \ + NJS_VMCODE_JUMP, 0, 0); \ _code->offset = _offset; \ } while (0) @@ -206,7 +206,7 @@ static nxt_int_t njs_generate_function_d #define njs_generate_code_move(generator, _code, _dst, _src) \ do { \ njs_generate_code(generator, njs_vmcode_move_t, _code, \ - njs_vmcode_move, 2, 1); \ + NJS_VMCODE_MOVE, 2, 1); \ _code->dst = _dst; \ _code->src = _src; \ } while (0) @@ -562,7 +562,7 @@ njs_generate_name(njs_vm_t *vm, njs_gene } njs_generate_code(generator, njs_vmcode_object_copy_t, copy, - njs_vmcode_object_copy, 2, 1); + NJS_VMCODE_OBJECT_COPY, 2, 1); copy->retval = node->index; copy->object = var->index; @@ -591,7 +591,7 @@ njs_generate_builtin_object(njs_vm_t *vm } njs_generate_code(generator, njs_vmcode_object_copy_t, copy, - njs_vmcode_object_copy, 2, 1); + NJS_VMCODE_OBJECT_COPY, 2, 1); copy->retval = node->index; copy->object = index; @@ -680,7 +680,7 @@ njs_generate_if_statement(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - njs_vmcode_if_false_jump, 2, 0); + NJS_VMCODE_IF_FALSE_JUMP, 2, 0); cond_jump->cond = node->left->index; ret = njs_generate_node_index_release(vm, generator, node->left); @@ -755,7 +755,7 @@ njs_generate_cond_expression(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - njs_vmcode_if_false_jump, 2, 0); + NJS_VMCODE_IF_FALSE_JUMP, 2, 0); cond_jump_offset = njs_code_offset(generator, cond_jump); cond_jump->cond = node->left->index; @@ -875,7 +875,7 @@ njs_generate_switch_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_equal_jump_t, equal, - njs_vmcode_if_equal_jump, 3, 0); + NJS_VMCODE_IF_EQUAL_JUMP, 3, 0); equal->offset = offsetof(njs_vmcode_equal_jump_t, offset); equal->value1 = index; equal->value2 = node->left->index; @@ -998,7 +998,7 @@ njs_generate_while_statement(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - njs_vmcode_if_true_jump, 2, 0); + NJS_VMCODE_IF_TRUE_JUMP, 2, 0); cond_jump->offset = loop_offset - njs_code_offset(generator, cond_jump); cond_jump->cond = condition->index; @@ -1044,7 +1044,7 @@ njs_generate_do_while_statement(njs_vm_t } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - njs_vmcode_if_true_jump, 2, 0); + NJS_VMCODE_IF_TRUE_JUMP, 2, 0); cond_jump->offset = loop_offset - njs_code_offset(generator, cond_jump); cond_jump->cond = condition->index; @@ -1138,7 +1138,7 @@ njs_generate_for_statement(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - njs_vmcode_if_true_jump, 2, 0); + NJS_VMCODE_IF_TRUE_JUMP, 2, 0); cond_jump->offset = loop_offset - njs_code_offset(generator, cond_jump); cond_jump->cond = condition->index; @@ -1183,7 +1183,7 @@ njs_generate_for_in_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_prop_foreach_t, prop_foreach, - njs_vmcode_property_foreach, 2, 1); + NJS_VMCODE_PROPERTY_FOREACH, 2, 1); prop_offset = njs_code_offset(generator, prop_foreach); prop_foreach->object = foreach->right->index; @@ -1215,7 +1215,7 @@ njs_generate_for_in_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_prop_next_t, prop_next, - njs_vmcode_property_next, 3, 0); + NJS_VMCODE_PROPERTY_NEXT, 3, 0); prop_offset = njs_code_offset(generator, prop_next); prop_next->retval = foreach->left->index; prop_next->object = foreach->right->index; @@ -1602,7 +1602,7 @@ njs_generate_stop_statement(njs_vm_t *vm if (nxt_fast_path(ret == NXT_OK)) { njs_generate_code(generator, njs_vmcode_stop_t, stop, - njs_vmcode_stop, 1, 0); + NJS_VMCODE_STOP, 1, 0); index = NJS_INDEX_NONE; node = node->right; @@ -1736,10 +1736,10 @@ njs_generate_assignment(njs_vm_t *vm, nj if (lvalue->token == NJS_TOKEN_PROPERTY_INIT) { njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - njs_vmcode_property_init, 3, 0); + NJS_VMCODE_PROPERTY_INIT, 3, 0); } else { njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - njs_vmcode_property_set, 3, 0); + NJS_VMCODE_PROPERTY_SET, 3, 0); } prop_set->value = expr->index; @@ -1781,7 +1781,7 @@ njs_generate_operation_assignment(njs_vm /* Preserve variable value if it may be changed by expression. */ njs_generate_code(generator, njs_vmcode_move_t, move, - njs_vmcode_move, 2, 1); + NJS_VMCODE_MOVE, 2, 1); move->src = lvalue->index; index = njs_generate_temp_index_get(vm, generator, expr); @@ -1841,7 +1841,7 @@ njs_generate_operation_assignment(njs_vm } njs_generate_code(generator, njs_vmcode_prop_get_t, prop_get, - njs_vmcode_property_get, 3, 1); + NJS_VMCODE_PROPERTY_GET, 3, 1); prop_get->value = index; prop_get->object = object->index; prop_get->property = property->index; @@ -1860,7 +1860,7 @@ njs_generate_operation_assignment(njs_vm code->src2 = expr->index; njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - njs_vmcode_property_set, 3, 0); + NJS_VMCODE_PROPERTY_SET, 3, 0); prop_set->value = node->index; prop_set->object = object->index; prop_set->property = property->index; @@ -1886,7 +1886,7 @@ njs_generate_object(njs_vm_t *vm, njs_ge } njs_generate_code(generator, njs_vmcode_object_t, object, - njs_vmcode_object, 1, 1); + NJS_VMCODE_OBJECT, 1, 1); object->retval = node->index; /* Initialize object. */ @@ -1906,7 +1906,7 @@ njs_generate_array(njs_vm_t *vm, njs_gen } njs_generate_code(generator, njs_vmcode_array_t, array, - njs_vmcode_array, 1, 1); + NJS_VMCODE_ARRAY, 1, 1); array->code.ctor = node->ctor; array->retval = node->index; array->length = node->u.length; @@ -1946,7 +1946,7 @@ njs_generate_function(njs_vm_t *vm, njs_ } njs_generate_code(generator, njs_vmcode_function_t, function, - njs_vmcode_function, 1, 1); + NJS_VMCODE_FUNCTION, 1, 1); function->lambda = lambda; node->index = njs_generate_object_dest_index(vm, generator, node); @@ -1972,7 +1972,7 @@ njs_generate_regexp(njs_vm_t *vm, njs_ge } njs_generate_code(generator, njs_vmcode_regexp_t, regexp, - njs_vmcode_regexp, 1, 1); + NJS_VMCODE_REGEXP, 1, 1); regexp->retval = node->index; regexp->pattern = node->u.value.data.u.data; @@ -1993,7 +1993,7 @@ njs_generate_template_literal(njs_vm_t * } njs_generate_code(generator, njs_vmcode_template_literal_t, code, - njs_vmcode_template_literal, 1, 1); + NJS_VMCODE_TEMPLATE_LITERAL, 1, 1); code->retval = node->left->index; node->index = node->left->index; @@ -2073,7 +2073,7 @@ njs_generate_3addr_operation(njs_vm_t *v if (nxt_slow_path(njs_parser_has_side_effect(right))) { njs_generate_code(generator, njs_vmcode_move_t, move, - njs_vmcode_move, 2, 1); + NJS_VMCODE_MOVE, 2, 1); move->src = left->index; index = njs_generate_node_temp_index_get(vm, generator, left); @@ -2273,7 +2273,7 @@ found: } njs_generate_code(generator, njs_vmcode_prop_get_t, prop_get, - njs_vmcode_property_get, 3, 1); + NJS_VMCODE_PROPERTY_GET, 3, 1); prop_get->value = index; prop_get->object = lvalue->left->index; prop_get->property = lvalue->right->index; @@ -2285,7 +2285,7 @@ found: code->src2 = index; njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - njs_vmcode_property_set, 3, 0); + NJS_VMCODE_PROPERTY_SET, 3, 0); prop_set->value = index; prop_set->object = lvalue->left->index; prop_set->property = lvalue->right->index; @@ -2430,15 +2430,15 @@ njs_generate_scope(njs_vm_t *vm, njs_gen *value++ = njs_value_undefined; } - if (vm->code == NULL) { - vm->code = nxt_array_create(4, sizeof(njs_vm_code_t), + if (vm->codes == NULL) { + vm->codes = nxt_array_create(4, sizeof(njs_vm_code_t), &njs_array_mem_proto, vm->mem_pool); - if (nxt_slow_path(vm->code == NULL)) { + if (nxt_slow_path(vm->codes == NULL)) { return NXT_ERROR; } } - code = nxt_array_add(vm->code, &njs_array_mem_proto, vm->mem_pool); + code = nxt_array_add(vm->codes, &njs_array_mem_proto, vm->mem_pool); if (nxt_slow_path(code == NULL)) { return NXT_ERROR; } @@ -2480,13 +2480,13 @@ njs_generate_lambda_variables(njs_vm_t * if (var->this_object) { njs_generate_code(generator, njs_vmcode_this_t, this, - njs_vmcode_this, 1, 0); + NJS_VMCODE_THIS, 1, 0); this->dst = var->index; } if (var->arguments_object) { njs_generate_code(generator, njs_vmcode_arguments_t, arguments, - njs_vmcode_arguments, 1, 0); + NJS_VMCODE_ARGUMENTS, 1, 0); arguments->dst = var->index; } } @@ -2524,7 +2524,7 @@ njs_generate_return_statement(njs_vm_t * if (nxt_fast_path(immediate == NULL)) { njs_generate_code(generator, njs_vmcode_return_t, code, - njs_vmcode_return, 1, 0); + NJS_VMCODE_RETURN, 1, 0); code->retval = index; node->index = index; @@ -2554,7 +2554,7 @@ njs_generate_return_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_try_return_t, try_return, - njs_vmcode_try_return, 2, 1); + NJS_VMCODE_TRY_RETURN, 2, 1); try_return->retval = index; try_return->save = top->index; try_return->offset = offsetof(njs_vmcode_try_return_t, offset); @@ -2603,7 +2603,7 @@ njs_generate_function_call(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_function_frame_t, func, - njs_vmcode_function_frame, 2, 0); + NJS_VMCODE_FUNCTION_FRAME, 2, 0); func_offset = njs_code_offset(generator, func); func->code.ctor = node->ctor; func->name = name->index; @@ -2647,7 +2647,7 @@ njs_generate_method_call(njs_vm_t *vm, n } njs_generate_code(generator, njs_vmcode_method_frame_t, method, - njs_vmcode_method_frame, 3, 0); + NJS_VMCODE_METHOD_FRAME, 3, 0); method_offset = njs_code_offset(generator, method); method->code.ctor = node->ctor; method->object = prop->left->index; @@ -2706,7 +2706,7 @@ njs_generate_call(njs_vm_t *vm, njs_gene node->index = retval; njs_generate_code(generator, njs_vmcode_function_call_t, call, - njs_vmcode_function_call, 1, 0); + NJS_VMCODE_FUNCTION_CALL, 1, 0); call->retval = retval; return nargs; @@ -2716,7 +2716,7 @@ njs_generate_call(njs_vm_t *vm, njs_gene #define njs_generate_code_catch(generator, _code, _exception) \ do { \ njs_generate_code(generator, njs_vmcode_catch_t, _code, \ - njs_vmcode_catch, 2, 0); \ + NJS_VMCODE_CATCH, 2, 0); \ _code->offset = sizeof(njs_vmcode_catch_t); \ _code->exception = _exception; \ } while (0) @@ -2725,7 +2725,7 @@ njs_generate_call(njs_vm_t *vm, njs_gene #define njs_generate_code_finally(generator, _code, _retval, _exit) \ do { \ njs_generate_code(generator, njs_vmcode_finally_t, _code, \ - njs_vmcode_finally, 2, 0); \ + NJS_VMCODE_FINALLY, 2, 0); \ _code->retval = _retval; \ _code->exit_value = _exit; \ _code->continue_offset = offsetof(njs_vmcode_finally_t, \ @@ -2755,7 +2755,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_vmcode_try_trampoline_t *try_break, *try_continue; njs_generate_code(generator, njs_vmcode_try_start_t, try_start, - njs_vmcode_try_start, 2, 0); + NJS_VMCODE_TRY_START, 2, 0); try_offset = njs_code_offset(generator, try_start); exception_index = njs_generate_temp_index_get(vm, generator, node); @@ -2795,7 +2795,7 @@ njs_generate_try_statement(njs_vm_t *vm, try_cont_label = undef_label; njs_generate_code(generator, njs_vmcode_try_end_t, try_end, - njs_vmcode_try_end, 0, 0); + NJS_VMCODE_TRY_END, 0, 0); try_end_offset = njs_code_offset(generator, try_end); if (try_block->exit != NULL) { @@ -2804,7 +2804,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_generate_patch_block(vm, generator, try_block->exit); njs_generate_code(generator, njs_vmcode_try_trampoline_t, try_break, - njs_vmcode_try_break, 2, 0); + NJS_VMCODE_TRY_BREAK, 2, 0); try_break->exit_value = exit_index; try_break->offset = -sizeof(njs_vmcode_try_end_t); @@ -2819,7 +2819,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_generate_patch_block(vm, generator, try_block->continuation); njs_generate_code(generator, njs_vmcode_try_trampoline_t, try_continue, - njs_vmcode_try_continue, 2, 0); + NJS_VMCODE_TRY_CONTINUE, 2, 0); try_continue->exit_value = exit_index; try_continue->offset = -sizeof(njs_vmcode_try_end_t); @@ -2924,7 +2924,7 @@ njs_generate_try_statement(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_try_end_t, catch_end, - njs_vmcode_try_end, 0, 0); + NJS_VMCODE_TRY_END, 0, 0); catch_end_offset = njs_code_offset(generator, catch_end); if (catch_block->exit != NULL) { @@ -2933,7 +2933,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_generate_patch_block(vm, generator, catch_block->exit); njs_generate_code(generator, njs_vmcode_try_trampoline_t, - try_break, njs_vmcode_try_break, 2, 0); + try_break, NJS_VMCODE_TRY_BREAK, 2, 0); try_break->exit_value = exit_index; @@ -2950,7 +2950,7 @@ njs_generate_try_statement(njs_vm_t *vm, catch_block->continuation); njs_generate_code(generator, njs_vmcode_try_trampoline_t, - try_continue, njs_vmcode_try_continue, 2, 0); + try_continue, NJS_VMCODE_TRY_CONTINUE, 2, 0); try_continue->exit_value = exit_index; @@ -3064,7 +3064,7 @@ njs_generate_throw_statement(njs_vm_t *v if (nxt_fast_path(ret == NXT_OK)) { njs_generate_code(generator, njs_vmcode_throw_t, throw, - njs_vmcode_throw, 1, 0); + NJS_VMCODE_THROW, 1, 0); node->index = node->right->index; throw->retval = node->index; @@ -3102,7 +3102,7 @@ njs_generate_import_statement(njs_vm_t * module = (njs_module_t *) expr->index; njs_generate_code(generator, njs_vmcode_object_copy_t, copy, - njs_vmcode_object_copy, 2, 1); + NJS_VMCODE_OBJECT_COPY, 2, 1); copy->retval = index; copy->object = module->index; @@ -3126,7 +3126,7 @@ njs_generate_export_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_return_t, code, - njs_vmcode_return, 1, 0); + NJS_VMCODE_RETURN, 1, 0); code->retval = obj->index; node->index = obj->index; @@ -3297,7 +3297,7 @@ njs_generate_reference_error(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_reference_error_t, ref_err, - njs_vmcode_reference_error, 0, 0); + NJS_VMCODE_REFERENCE_ERROR, 0, 0); ref_err->token_line = node->token_line; diff -r 89082cb0bc84 -r 6aa2e67eaafc njs/njs_parser.c --- a/njs/njs_parser.c Thu Jul 25 22:07:57 2019 +0300 +++ b/njs/njs_parser.c Fri Jul 26 20:37:13 2019 +0300 @@ -1097,7 +1097,7 @@ njs_parser_var_statement(njs_vm_t *vm, n return NJS_TOKEN_ERROR; } - assign->u.operation = njs_vmcode_move; + assign->u.operation = NJS_VMCODE_MOVE; assign->left = name; assign->right = expr; diff -r 89082cb0bc84 -r 6aa2e67eaafc njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Thu Jul 25 22:07:57 2019 +0300 +++ b/njs/njs_parser_expression.c Fri Jul 26 20:37:13 2019 +0300 @@ -74,9 +74,9 @@ static const njs_parser_expression_t njs_parser_exponential_expression, NULL, 3, { - { NJS_TOKEN_MULTIPLICATION, njs_vmcode_multiplication }, - { NJS_TOKEN_DIVISION, njs_vmcode_division }, - { NJS_TOKEN_REMAINDER, njs_vmcode_remainder }, + { NJS_TOKEN_MULTIPLICATION, NJS_VMCODE_MULTIPLICATION }, + { NJS_TOKEN_DIVISION, NJS_VMCODE_DIVISION }, + { NJS_TOKEN_REMAINDER, NJS_VMCODE_REMAINDER }, } }; @@ -87,8 +87,8 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_factor_expression, 2, { - { NJS_TOKEN_ADDITION, njs_vmcode_addition }, - { NJS_TOKEN_SUBSTRACTION, njs_vmcode_substraction }, + { NJS_TOKEN_ADDITION, NJS_VMCODE_ADDITION }, + { NJS_TOKEN_SUBSTRACTION, NJS_VMCODE_SUBSTRACTION }, } }; @@ -99,9 +99,9 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_addition_expression, 3, { - { NJS_TOKEN_LEFT_SHIFT, njs_vmcode_left_shift }, - { NJS_TOKEN_RIGHT_SHIFT, njs_vmcode_right_shift }, - { NJS_TOKEN_UNSIGNED_RIGHT_SHIFT, njs_vmcode_unsigned_right_shift }, + { NJS_TOKEN_LEFT_SHIFT, NJS_VMCODE_LEFT_SHIFT }, + { NJS_TOKEN_RIGHT_SHIFT, NJS_VMCODE_RIGHT_SHIFT }, + { NJS_TOKEN_UNSIGNED_RIGHT_SHIFT, NJS_VMCODE_UNSIGNED_RIGHT_SHIFT }, } }; @@ -112,12 +112,12 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_bitwise_shift_expression, 6, { - { NJS_TOKEN_LESS, njs_vmcode_less }, - { NJS_TOKEN_LESS_OR_EQUAL, njs_vmcode_less_or_equal }, - { NJS_TOKEN_GREATER, njs_vmcode_greater }, - { NJS_TOKEN_GREATER_OR_EQUAL, njs_vmcode_greater_or_equal }, - { NJS_TOKEN_IN, njs_vmcode_property_in }, - { NJS_TOKEN_INSTANCEOF, njs_vmcode_instance_of }, + { NJS_TOKEN_LESS, NJS_VMCODE_LESS }, + { NJS_TOKEN_LESS_OR_EQUAL, NJS_VMCODE_LESS_OR_EQUAL }, + { NJS_TOKEN_GREATER, NJS_VMCODE_GREATER }, + { NJS_TOKEN_GREATER_OR_EQUAL, NJS_VMCODE_GREATER_OR_EQUAL }, + { NJS_TOKEN_IN, NJS_VMCODE_PROPERTY_IN }, + { NJS_TOKEN_INSTANCEOF, NJS_VMCODE_INSTANCE_OF }, } }; @@ -128,10 +128,10 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_relational_expression, 4, { - { NJS_TOKEN_EQUAL, njs_vmcode_equal }, - { NJS_TOKEN_NOT_EQUAL, njs_vmcode_not_equal }, - { NJS_TOKEN_STRICT_EQUAL, njs_vmcode_strict_equal }, - { NJS_TOKEN_STRICT_NOT_EQUAL, njs_vmcode_strict_not_equal }, + { NJS_TOKEN_EQUAL, NJS_VMCODE_EQUAL }, + { NJS_TOKEN_NOT_EQUAL, NJS_VMCODE_NOT_EQUAL }, + { NJS_TOKEN_STRICT_EQUAL, NJS_VMCODE_STRICT_EQUAL }, + { NJS_TOKEN_STRICT_NOT_EQUAL, NJS_VMCODE_STRICT_NOT_EQUAL }, } }; @@ -142,7 +142,7 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_equality_expression, 1, { - { NJS_TOKEN_BITWISE_AND, njs_vmcode_bitwise_and }, + { NJS_TOKEN_BITWISE_AND, NJS_VMCODE_BITWISE_AND }, } }; @@ -153,7 +153,7 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_bitwise_and_expression, 1, { - { NJS_TOKEN_BITWISE_XOR, njs_vmcode_bitwise_xor }, + { NJS_TOKEN_BITWISE_XOR, NJS_VMCODE_BITWISE_XOR }, } }; @@ -164,7 +164,7 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_bitwise_xor_expression, 1, { - { NJS_TOKEN_BITWISE_OR, njs_vmcode_bitwise_or }, + { NJS_TOKEN_BITWISE_OR, NJS_VMCODE_BITWISE_OR }, } }; @@ -175,7 +175,7 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_bitwise_or_expression, 1, { - { NJS_TOKEN_LOGICAL_AND, njs_vmcode_test_if_false }, + { NJS_TOKEN_LOGICAL_AND, NJS_VMCODE_TEST_IF_FALSE }, } }; @@ -186,7 +186,7 @@ static const njs_parser_expression_t njs_parser_binary_expression, &njs_parser_logical_and_expression, 1, { - { NJS_TOKEN_LOGICAL_OR, njs_vmcode_test_if_true }, + { NJS_TOKEN_LOGICAL_OR, NJS_VMCODE_TEST_IF_TRUE }, } }; @@ -197,7 +197,7 @@ static const njs_parser_expression_t njs_parser_any_expression, NULL, 1, { - { NJS_TOKEN_COMMA, NULL }, + { NJS_TOKEN_COMMA, NJS_VMCODE_NOP }, } }; @@ -235,67 +235,67 @@ njs_parser_assignment_expression(njs_vm_ case NJS_TOKEN_ASSIGNMENT: nxt_thread_log_debug("JS: ="); - operation = njs_vmcode_move; + operation = NJS_VMCODE_MOVE; break; case NJS_TOKEN_ADDITION_ASSIGNMENT: nxt_thread_log_debug("JS: +="); - operation = njs_vmcode_addition; + operation = NJS_VMCODE_ADDITION; break; case NJS_TOKEN_SUBSTRACTION_ASSIGNMENT: nxt_thread_log_debug("JS: -="); - operation = njs_vmcode_substraction; + operation = NJS_VMCODE_SUBSTRACTION; break; case NJS_TOKEN_MULTIPLICATION_ASSIGNMENT: nxt_thread_log_debug("JS: *="); - operation = njs_vmcode_multiplication; + operation = NJS_VMCODE_MULTIPLICATION; break; case NJS_TOKEN_EXPONENTIATION_ASSIGNMENT: nxt_thread_log_debug("JS: **="); - operation = njs_vmcode_exponentiation; + operation = NJS_VMCODE_EXPONENTIATION; break; case NJS_TOKEN_DIVISION_ASSIGNMENT: nxt_thread_log_debug("JS: /="); - operation = njs_vmcode_division; + operation = NJS_VMCODE_DIVISION; break; case NJS_TOKEN_REMAINDER_ASSIGNMENT: nxt_thread_log_debug("JS: %="); From careygister at outlook.com Fri Jul 26 18:08:55 2019 From: careygister at outlook.com (Carey Gister) Date: Fri, 26 Jul 2019 18:08:55 +0000 Subject: RTMP with multiple worker processes and rtmp_auto_push Message-ID: Hi, I hope someone can help illuminate some background information related to this module. I understand that the rtmp_auto_push directive worked with multiple workers through nginx 1.7.x and then something changed in the nginx internals and it stopped working and was no longer supported for multiple workers. Can someone provide background on what changed that had this feature stop working? My manager has tasked me with getting this feature to work, if possible. Thanks, Carey Gister 415-310-5304 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dnj0496 at gmail.com Fri Jul 26 21:11:26 2019 From: dnj0496 at gmail.com (Dk Jack) Date: Fri, 26 Jul 2019 14:11:26 -0700 Subject: Trying to understand request body handling. In-Reply-To: References: Message-ID: Hi, Could someone respond to my question. Is it even possible to implement a module that meets my requirements (which I listed in my earlier post). Any response is greatly appreciated. Thanks. On Wed, Jul 24, 2019 at 11:07 PM Dk Jack wrote: > Hi, > In my module I have the following requirements: > > - Inspect the contents of the POST body in the request > - If the body content matches the configured regex, then take one of the > following actions: > - Return forbidden > - Redirect to another location without using 302 > - If the content doesn't match the configured regex, then simply forward > the request to proxy_pass destination. > > I used 'ngx_http_read_client_request_body'function accumulate the body > contents inspect it. I invoked this function from a pre-access handler. My > request body handler callback gets called and I am able to inspect the body > and I am able to take the actions I have mentioned above. > > However, it is not working completely as I expected. For example, when I > return forbidden after body inspection, my client is receiving the > forbidden message and the status code I've setup. However, the request > seems to also get forwarded to the origin. In the error.log, I see 'header > already sent while reading response from upstream' message. I see a similar > issue when redirecting. The request is getting sent to origin server as > well as the server I redirected to after inspection. Which leads me to > believe that the request is being forwarded based on the proxy_pass rule > while my module is still accumulating the body i.e before my body_complete > handler is called. Is my understanding correct? If so, is there a way to > stall the forwarding of the request till my module has completed the > inspection? Is there something in the request I need to set in the earlier > phases when I doing this sort of thing? > > I also modified my module to use body filters as described in > https://nginx.org/en/docs/dev/development_guide.html#http_body_filters to > see if it'd help my cause. However, I can't seem to get redirect working > after inspecting the body. Any suggestions on the correct approach to > solving my issues while adhering to requirements. Any help is greatly > appreciated. Thanks. > > regards, > Dk. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Sat Jul 27 00:59:30 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 27 Jul 2019 00:59:30 +0000 Subject: [njs] Style in nxt_unicode_upper_case.pl and nxt_unicode_upper_case.h. Message-ID: details: https://hg.nginx.org/njs/rev/0af076f81e2b branches: changeset: 1071:0af076f81e2b user: Valentin Bartenev date: Sat Jul 27 03:51:48 2019 +0300 description: Style in nxt_unicode_upper_case.pl and nxt_unicode_upper_case.h. diffstat: nxt/nxt_unicode_upper_case.h | 4 ++-- nxt/nxt_unicode_upper_case.pl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diffs (29 lines): diff -r 6aa2e67eaafc -r 0af076f81e2b nxt/nxt_unicode_upper_case.h --- a/nxt/nxt_unicode_upper_case.h Fri Jul 26 20:37:13 2019 +0300 +++ b/nxt/nxt_unicode_upper_case.h Sat Jul 27 03:51:48 2019 +0300 @@ -4,9 +4,9 @@ * 16496 bytes on 32-bit platforms, 18576 bytes on 64-bit platforms. */ -#define NXT_UNICODE_MAX_UPPER_CASE 0x1044f +#define NXT_UNICODE_MAX_UPPER_CASE 0x1044f -#define NXT_UNICODE_BLOCK_SIZE 128 +#define NXT_UNICODE_BLOCK_SIZE 128 static const uint32_t nxt_unicode_upper_case_block_000[128] diff -r 6aa2e67eaafc -r 0af076f81e2b nxt/nxt_unicode_upper_case.pl --- a/nxt/nxt_unicode_upper_case.pl Fri Jul 26 20:37:13 2019 +0300 +++ b/nxt/nxt_unicode_upper_case.pl Sat Jul 27 03:51:48 2019 +0300 @@ -48,8 +48,8 @@ printf("\n/*\n" . ($blocks - 1) * BLOCK_SIZE * 4 + $last_block_size + $max_block * 4, ($blocks - 1) * BLOCK_SIZE * 4 + $last_block_size + $max_block * 8); -printf("#define NXT_UNICODE_MAX_UPPER_CASE 0x%05x\n\n", $max_upper_case); -printf("#define NXT_UNICODE_BLOCK_SIZE %d\n\n\n", BLOCK_SIZE); +printf("#define NXT_UNICODE_MAX_UPPER_CASE 0x%05x\n\n", $max_upper_case); +printf("#define NXT_UNICODE_BLOCK_SIZE %d\n\n\n", BLOCK_SIZE); for my $block (sort { $a <=> $b } keys %blocks) { From vbart at nginx.com Sat Jul 27 00:59:31 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 27 Jul 2019 00:59:31 +0000 Subject: [njs] Unicode case tables updated to version 12.1 (May 2019). Message-ID: details: https://hg.nginx.org/njs/rev/dace17533126 branches: changeset: 1072:dace17533126 user: Valentin Bartenev date: Sat Jul 27 03:51:48 2019 +0300 description: Unicode case tables updated to version 12.1 (May 2019). diffstat: njs/test/njs_unit_test.c | 2 +- nxt/nxt_unicode_lower_case.h | 676 +++++++++++++++++++++++++++++++++++- nxt/nxt_unicode_upper_case.h | 789 ++++++++++++++++++++++++++++++++++++++++-- nxt/nxt_utf8.c | 2 +- 4 files changed, 1390 insertions(+), 79 deletions(-) diffs (truncated from 1674 to 1000 lines): diff -r 0af076f81e2b -r dace17533126 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Jul 27 03:51:48 2019 +0300 +++ b/njs/test/njs_unit_test.c Sat Jul 27 03:51:48 2019 +0300 @@ -5555,7 +5555,7 @@ static njs_unit_test_t njs_test[] = " if (s != n && s != n.toLowerCase())" " a.push(code);" "} a"), - nxt_string("181,305,383,453,456,459,498,837,962,976,977,981,982,1008,1009,1013,7835,8126") }, + nxt_string("181,305,383,453,456,459,498,837,962,976,977,981,982,1008,1009,1013,7296,7297,7298,7299,7300,7301,7302,7303,7304,7835,8126") }, { nxt_string("var a = [], code;" "for (code = 0; code <= 1114111; code++) {" diff -r 0af076f81e2b -r dace17533126 nxt/nxt_unicode_lower_case.h --- a/nxt/nxt_unicode_lower_case.h Sat Jul 27 03:51:48 2019 +0300 +++ b/nxt/nxt_unicode_lower_case.h Sat Jul 27 03:51:48 2019 +0300 @@ -1,10 +1,10 @@ /* - * 26 128-bytes blocks, 521 pointers. - * 14920 bytes on 32-bit platforms, 17000 bytes on 64-bit platforms. + * 33 128-bytes blocks, 979 pointers. + * 20330 bytes on 32-bit platforms, 24242 bytes on 64-bit platforms. */ -#define NXT_UNICODE_MAX_LOWER_CASE 0x10427 +#define NXT_UNICODE_MAX_LOWER_CASE 0x1e921 #define NXT_UNICODE_BLOCK_SIZE 128 @@ -137,7 +137,7 @@ static const uint32_t nxt_unicode_lower 0x00360, 0x00361, 0x00362, 0x00363, 0x00364, 0x00365, 0x00366, 0x00367, 0x00368, 0x00369, 0x0036a, 0x0036b, 0x0036c, 0x0036d, 0x0036e, 0x0036f, 0x00371, 0x00371, 0x00373, 0x00373, 0x00374, 0x00375, 0x00377, 0x00377, - 0x00378, 0x00379, 0x0037a, 0x0037b, 0x0037c, 0x0037d, 0x0037e, 0x0037f, + 0x00378, 0x00379, 0x0037a, 0x0037b, 0x0037c, 0x0037d, 0x0037e, 0x003f3, }; @@ -215,7 +215,7 @@ static const uint32_t nxt_unicode_lower 0x00511, 0x00511, 0x00513, 0x00513, 0x00515, 0x00515, 0x00517, 0x00517, 0x00519, 0x00519, 0x0051b, 0x0051b, 0x0051d, 0x0051d, 0x0051f, 0x0051f, 0x00521, 0x00521, 0x00523, 0x00523, 0x00525, 0x00525, 0x00527, 0x00527, - 0x00528, 0x00529, 0x0052a, 0x0052b, 0x0052c, 0x0052d, 0x0052e, 0x0052f, + 0x00529, 0x00529, 0x0052b, 0x0052b, 0x0052d, 0x0052d, 0x0052f, 0x0052f, 0x00530, 0x00561, 0x00562, 0x00563, 0x00564, 0x00565, 0x00566, 0x00567, 0x00568, 0x00569, 0x0056a, 0x0056b, 0x0056c, 0x0056d, 0x0056e, 0x0056f, 0x00570, 0x00571, 0x00572, 0x00573, 0x00574, 0x00575, 0x00576, 0x00577, @@ -251,6 +251,50 @@ static const uint32_t nxt_unicode_lower }; +static const uint32_t nxt_unicode_lower_case_block_027[128] + nxt_aligned(64) = +{ + 0x01380, 0x01381, 0x01382, 0x01383, 0x01384, 0x01385, 0x01386, 0x01387, + 0x01388, 0x01389, 0x0138a, 0x0138b, 0x0138c, 0x0138d, 0x0138e, 0x0138f, + 0x01390, 0x01391, 0x01392, 0x01393, 0x01394, 0x01395, 0x01396, 0x01397, + 0x01398, 0x01399, 0x0139a, 0x0139b, 0x0139c, 0x0139d, 0x0139e, 0x0139f, + 0x0ab70, 0x0ab71, 0x0ab72, 0x0ab73, 0x0ab74, 0x0ab75, 0x0ab76, 0x0ab77, + 0x0ab78, 0x0ab79, 0x0ab7a, 0x0ab7b, 0x0ab7c, 0x0ab7d, 0x0ab7e, 0x0ab7f, + 0x0ab80, 0x0ab81, 0x0ab82, 0x0ab83, 0x0ab84, 0x0ab85, 0x0ab86, 0x0ab87, + 0x0ab88, 0x0ab89, 0x0ab8a, 0x0ab8b, 0x0ab8c, 0x0ab8d, 0x0ab8e, 0x0ab8f, + 0x0ab90, 0x0ab91, 0x0ab92, 0x0ab93, 0x0ab94, 0x0ab95, 0x0ab96, 0x0ab97, + 0x0ab98, 0x0ab99, 0x0ab9a, 0x0ab9b, 0x0ab9c, 0x0ab9d, 0x0ab9e, 0x0ab9f, + 0x0aba0, 0x0aba1, 0x0aba2, 0x0aba3, 0x0aba4, 0x0aba5, 0x0aba6, 0x0aba7, + 0x0aba8, 0x0aba9, 0x0abaa, 0x0abab, 0x0abac, 0x0abad, 0x0abae, 0x0abaf, + 0x0abb0, 0x0abb1, 0x0abb2, 0x0abb3, 0x0abb4, 0x0abb5, 0x0abb6, 0x0abb7, + 0x0abb8, 0x0abb9, 0x0abba, 0x0abbb, 0x0abbc, 0x0abbd, 0x0abbe, 0x0abbf, + 0x013f8, 0x013f9, 0x013fa, 0x013fb, 0x013fc, 0x013fd, 0x013f6, 0x013f7, + 0x013f8, 0x013f9, 0x013fa, 0x013fb, 0x013fc, 0x013fd, 0x013fe, 0x013ff, +}; + + +static const uint32_t nxt_unicode_lower_case_block_039[128] + nxt_aligned(64) = +{ + 0x01c80, 0x01c81, 0x01c82, 0x01c83, 0x01c84, 0x01c85, 0x01c86, 0x01c87, + 0x01c88, 0x01c89, 0x01c8a, 0x01c8b, 0x01c8c, 0x01c8d, 0x01c8e, 0x01c8f, + 0x010d0, 0x010d1, 0x010d2, 0x010d3, 0x010d4, 0x010d5, 0x010d6, 0x010d7, + 0x010d8, 0x010d9, 0x010da, 0x010db, 0x010dc, 0x010dd, 0x010de, 0x010df, + 0x010e0, 0x010e1, 0x010e2, 0x010e3, 0x010e4, 0x010e5, 0x010e6, 0x010e7, + 0x010e8, 0x010e9, 0x010ea, 0x010eb, 0x010ec, 0x010ed, 0x010ee, 0x010ef, + 0x010f0, 0x010f1, 0x010f2, 0x010f3, 0x010f4, 0x010f5, 0x010f6, 0x010f7, + 0x010f8, 0x010f9, 0x010fa, 0x01cbb, 0x01cbc, 0x010fd, 0x010fe, 0x010ff, + 0x01cc0, 0x01cc1, 0x01cc2, 0x01cc3, 0x01cc4, 0x01cc5, 0x01cc6, 0x01cc7, + 0x01cc8, 0x01cc9, 0x01cca, 0x01ccb, 0x01ccc, 0x01ccd, 0x01cce, 0x01ccf, + 0x01cd0, 0x01cd1, 0x01cd2, 0x01cd3, 0x01cd4, 0x01cd5, 0x01cd6, 0x01cd7, + 0x01cd8, 0x01cd9, 0x01cda, 0x01cdb, 0x01cdc, 0x01cdd, 0x01cde, 0x01cdf, + 0x01ce0, 0x01ce1, 0x01ce2, 0x01ce3, 0x01ce4, 0x01ce5, 0x01ce6, 0x01ce7, + 0x01ce8, 0x01ce9, 0x01cea, 0x01ceb, 0x01cec, 0x01ced, 0x01cee, 0x01cef, + 0x01cf0, 0x01cf1, 0x01cf2, 0x01cf3, 0x01cf4, 0x01cf5, 0x01cf6, 0x01cf7, + 0x01cf8, 0x01cf9, 0x01cfa, 0x01cfb, 0x01cfc, 0x01cfd, 0x01cfe, 0x01cff, +}; + + static const uint32_t nxt_unicode_lower_case_block_03c[128] nxt_aligned(64) = { @@ -477,7 +521,7 @@ static const uint32_t nxt_unicode_lower 0x0a681, 0x0a681, 0x0a683, 0x0a683, 0x0a685, 0x0a685, 0x0a687, 0x0a687, 0x0a689, 0x0a689, 0x0a68b, 0x0a68b, 0x0a68d, 0x0a68d, 0x0a68f, 0x0a68f, 0x0a691, 0x0a691, 0x0a693, 0x0a693, 0x0a695, 0x0a695, 0x0a697, 0x0a697, - 0x0a698, 0x0a699, 0x0a69a, 0x0a69b, 0x0a69c, 0x0a69d, 0x0a69e, 0x0a69f, + 0x0a699, 0x0a699, 0x0a69b, 0x0a69b, 0x0a69c, 0x0a69d, 0x0a69e, 0x0a69f, 0x0a6a0, 0x0a6a1, 0x0a6a2, 0x0a6a3, 0x0a6a4, 0x0a6a5, 0x0a6a6, 0x0a6a7, 0x0a6a8, 0x0a6a9, 0x0a6aa, 0x0a6ab, 0x0a6ac, 0x0a6ad, 0x0a6ae, 0x0a6af, 0x0a6b0, 0x0a6b1, 0x0a6b2, 0x0a6b3, 0x0a6b4, 0x0a6b5, 0x0a6b6, 0x0a6b7, @@ -520,13 +564,13 @@ static const uint32_t nxt_unicode_lower { 0x0a781, 0x0a781, 0x0a783, 0x0a783, 0x0a785, 0x0a785, 0x0a787, 0x0a787, 0x0a788, 0x0a789, 0x0a78a, 0x0a78c, 0x0a78c, 0x00265, 0x0a78e, 0x0a78f, - 0x0a791, 0x0a791, 0x0a793, 0x0a793, 0x0a794, 0x0a795, 0x0a796, 0x0a797, - 0x0a798, 0x0a799, 0x0a79a, 0x0a79b, 0x0a79c, 0x0a79d, 0x0a79e, 0x0a79f, + 0x0a791, 0x0a791, 0x0a793, 0x0a793, 0x0a794, 0x0a795, 0x0a797, 0x0a797, + 0x0a799, 0x0a799, 0x0a79b, 0x0a79b, 0x0a79d, 0x0a79d, 0x0a79f, 0x0a79f, 0x0a7a1, 0x0a7a1, 0x0a7a3, 0x0a7a3, 0x0a7a5, 0x0a7a5, 0x0a7a7, 0x0a7a7, - 0x0a7a9, 0x0a7a9, 0x00266, 0x0a7ab, 0x0a7ac, 0x0a7ad, 0x0a7ae, 0x0a7af, - 0x0a7b0, 0x0a7b1, 0x0a7b2, 0x0a7b3, 0x0a7b4, 0x0a7b5, 0x0a7b6, 0x0a7b7, - 0x0a7b8, 0x0a7b9, 0x0a7ba, 0x0a7bb, 0x0a7bc, 0x0a7bd, 0x0a7be, 0x0a7bf, - 0x0a7c0, 0x0a7c1, 0x0a7c2, 0x0a7c3, 0x0a7c4, 0x0a7c5, 0x0a7c6, 0x0a7c7, + 0x0a7a9, 0x0a7a9, 0x00266, 0x0025c, 0x00261, 0x0026c, 0x0026a, 0x0a7af, + 0x0029e, 0x00287, 0x0029d, 0x0ab53, 0x0a7b5, 0x0a7b5, 0x0a7b7, 0x0a7b7, + 0x0a7b9, 0x0a7b9, 0x0a7bb, 0x0a7bb, 0x0a7bd, 0x0a7bd, 0x0a7bf, 0x0a7bf, + 0x0a7c0, 0x0a7c1, 0x0a7c3, 0x0a7c3, 0x0a794, 0x00282, 0x01d8e, 0x0a7c7, 0x0a7c8, 0x0a7c9, 0x0a7ca, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, 0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, 0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, @@ -559,7 +603,7 @@ static const uint32_t nxt_unicode_lower }; -static const uint32_t nxt_unicode_lower_case_block_208[40] +static const uint32_t nxt_unicode_lower_case_block_208[128] nxt_aligned(64) = { 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, @@ -567,6 +611,116 @@ static const uint32_t nxt_unicode_lower 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, + 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, + 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, + 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, + 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, + 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, + 0x10450, 0x10451, 0x10452, 0x10453, 0x10454, 0x10455, 0x10456, 0x10457, + 0x10458, 0x10459, 0x1045a, 0x1045b, 0x1045c, 0x1045d, 0x1045e, 0x1045f, + 0x10460, 0x10461, 0x10462, 0x10463, 0x10464, 0x10465, 0x10466, 0x10467, + 0x10468, 0x10469, 0x1046a, 0x1046b, 0x1046c, 0x1046d, 0x1046e, 0x1046f, + 0x10470, 0x10471, 0x10472, 0x10473, 0x10474, 0x10475, 0x10476, 0x10477, + 0x10478, 0x10479, 0x1047a, 0x1047b, 0x1047c, 0x1047d, 0x1047e, 0x1047f, +}; + + +static const uint32_t nxt_unicode_lower_case_block_209[128] + nxt_aligned(64) = +{ + 0x10480, 0x10481, 0x10482, 0x10483, 0x10484, 0x10485, 0x10486, 0x10487, + 0x10488, 0x10489, 0x1048a, 0x1048b, 0x1048c, 0x1048d, 0x1048e, 0x1048f, + 0x10490, 0x10491, 0x10492, 0x10493, 0x10494, 0x10495, 0x10496, 0x10497, + 0x10498, 0x10499, 0x1049a, 0x1049b, 0x1049c, 0x1049d, 0x1049e, 0x1049f, + 0x104a0, 0x104a1, 0x104a2, 0x104a3, 0x104a4, 0x104a5, 0x104a6, 0x104a7, + 0x104a8, 0x104a9, 0x104aa, 0x104ab, 0x104ac, 0x104ad, 0x104ae, 0x104af, + 0x104d8, 0x104d9, 0x104da, 0x104db, 0x104dc, 0x104dd, 0x104de, 0x104df, + 0x104e0, 0x104e1, 0x104e2, 0x104e3, 0x104e4, 0x104e5, 0x104e6, 0x104e7, + 0x104e8, 0x104e9, 0x104ea, 0x104eb, 0x104ec, 0x104ed, 0x104ee, 0x104ef, + 0x104f0, 0x104f1, 0x104f2, 0x104f3, 0x104f4, 0x104f5, 0x104f6, 0x104f7, + 0x104f8, 0x104f9, 0x104fa, 0x104fb, 0x104d4, 0x104d5, 0x104d6, 0x104d7, + 0x104d8, 0x104d9, 0x104da, 0x104db, 0x104dc, 0x104dd, 0x104de, 0x104df, + 0x104e0, 0x104e1, 0x104e2, 0x104e3, 0x104e4, 0x104e5, 0x104e6, 0x104e7, + 0x104e8, 0x104e9, 0x104ea, 0x104eb, 0x104ec, 0x104ed, 0x104ee, 0x104ef, + 0x104f0, 0x104f1, 0x104f2, 0x104f3, 0x104f4, 0x104f5, 0x104f6, 0x104f7, + 0x104f8, 0x104f9, 0x104fa, 0x104fb, 0x104fc, 0x104fd, 0x104fe, 0x104ff, +}; + + +static const uint32_t nxt_unicode_lower_case_block_219[128] + nxt_aligned(64) = +{ + 0x10cc0, 0x10cc1, 0x10cc2, 0x10cc3, 0x10cc4, 0x10cc5, 0x10cc6, 0x10cc7, + 0x10cc8, 0x10cc9, 0x10cca, 0x10ccb, 0x10ccc, 0x10ccd, 0x10cce, 0x10ccf, + 0x10cd0, 0x10cd1, 0x10cd2, 0x10cd3, 0x10cd4, 0x10cd5, 0x10cd6, 0x10cd7, + 0x10cd8, 0x10cd9, 0x10cda, 0x10cdb, 0x10cdc, 0x10cdd, 0x10cde, 0x10cdf, + 0x10ce0, 0x10ce1, 0x10ce2, 0x10ce3, 0x10ce4, 0x10ce5, 0x10ce6, 0x10ce7, + 0x10ce8, 0x10ce9, 0x10cea, 0x10ceb, 0x10cec, 0x10ced, 0x10cee, 0x10cef, + 0x10cf0, 0x10cf1, 0x10cf2, 0x10cb3, 0x10cb4, 0x10cb5, 0x10cb6, 0x10cb7, + 0x10cb8, 0x10cb9, 0x10cba, 0x10cbb, 0x10cbc, 0x10cbd, 0x10cbe, 0x10cbf, + 0x10cc0, 0x10cc1, 0x10cc2, 0x10cc3, 0x10cc4, 0x10cc5, 0x10cc6, 0x10cc7, + 0x10cc8, 0x10cc9, 0x10cca, 0x10ccb, 0x10ccc, 0x10ccd, 0x10cce, 0x10ccf, + 0x10cd0, 0x10cd1, 0x10cd2, 0x10cd3, 0x10cd4, 0x10cd5, 0x10cd6, 0x10cd7, + 0x10cd8, 0x10cd9, 0x10cda, 0x10cdb, 0x10cdc, 0x10cdd, 0x10cde, 0x10cdf, + 0x10ce0, 0x10ce1, 0x10ce2, 0x10ce3, 0x10ce4, 0x10ce5, 0x10ce6, 0x10ce7, + 0x10ce8, 0x10ce9, 0x10cea, 0x10ceb, 0x10cec, 0x10ced, 0x10cee, 0x10cef, + 0x10cf0, 0x10cf1, 0x10cf2, 0x10cf3, 0x10cf4, 0x10cf5, 0x10cf6, 0x10cf7, + 0x10cf8, 0x10cf9, 0x10cfa, 0x10cfb, 0x10cfc, 0x10cfd, 0x10cfe, 0x10cff, +}; + + +static const uint32_t nxt_unicode_lower_case_block_231[128] + nxt_aligned(64) = +{ + 0x11880, 0x11881, 0x11882, 0x11883, 0x11884, 0x11885, 0x11886, 0x11887, + 0x11888, 0x11889, 0x1188a, 0x1188b, 0x1188c, 0x1188d, 0x1188e, 0x1188f, + 0x11890, 0x11891, 0x11892, 0x11893, 0x11894, 0x11895, 0x11896, 0x11897, + 0x11898, 0x11899, 0x1189a, 0x1189b, 0x1189c, 0x1189d, 0x1189e, 0x1189f, + 0x118c0, 0x118c1, 0x118c2, 0x118c3, 0x118c4, 0x118c5, 0x118c6, 0x118c7, + 0x118c8, 0x118c9, 0x118ca, 0x118cb, 0x118cc, 0x118cd, 0x118ce, 0x118cf, + 0x118d0, 0x118d1, 0x118d2, 0x118d3, 0x118d4, 0x118d5, 0x118d6, 0x118d7, + 0x118d8, 0x118d9, 0x118da, 0x118db, 0x118dc, 0x118dd, 0x118de, 0x118df, + 0x118c0, 0x118c1, 0x118c2, 0x118c3, 0x118c4, 0x118c5, 0x118c6, 0x118c7, + 0x118c8, 0x118c9, 0x118ca, 0x118cb, 0x118cc, 0x118cd, 0x118ce, 0x118cf, + 0x118d0, 0x118d1, 0x118d2, 0x118d3, 0x118d4, 0x118d5, 0x118d6, 0x118d7, + 0x118d8, 0x118d9, 0x118da, 0x118db, 0x118dc, 0x118dd, 0x118de, 0x118df, + 0x118e0, 0x118e1, 0x118e2, 0x118e3, 0x118e4, 0x118e5, 0x118e6, 0x118e7, + 0x118e8, 0x118e9, 0x118ea, 0x118eb, 0x118ec, 0x118ed, 0x118ee, 0x118ef, + 0x118f0, 0x118f1, 0x118f2, 0x118f3, 0x118f4, 0x118f5, 0x118f6, 0x118f7, + 0x118f8, 0x118f9, 0x118fa, 0x118fb, 0x118fc, 0x118fd, 0x118fe, 0x118ff, +}; + + +static const uint32_t nxt_unicode_lower_case_block_2dc[128] + nxt_aligned(64) = +{ + 0x16e00, 0x16e01, 0x16e02, 0x16e03, 0x16e04, 0x16e05, 0x16e06, 0x16e07, + 0x16e08, 0x16e09, 0x16e0a, 0x16e0b, 0x16e0c, 0x16e0d, 0x16e0e, 0x16e0f, + 0x16e10, 0x16e11, 0x16e12, 0x16e13, 0x16e14, 0x16e15, 0x16e16, 0x16e17, + 0x16e18, 0x16e19, 0x16e1a, 0x16e1b, 0x16e1c, 0x16e1d, 0x16e1e, 0x16e1f, + 0x16e20, 0x16e21, 0x16e22, 0x16e23, 0x16e24, 0x16e25, 0x16e26, 0x16e27, + 0x16e28, 0x16e29, 0x16e2a, 0x16e2b, 0x16e2c, 0x16e2d, 0x16e2e, 0x16e2f, + 0x16e30, 0x16e31, 0x16e32, 0x16e33, 0x16e34, 0x16e35, 0x16e36, 0x16e37, + 0x16e38, 0x16e39, 0x16e3a, 0x16e3b, 0x16e3c, 0x16e3d, 0x16e3e, 0x16e3f, + 0x16e60, 0x16e61, 0x16e62, 0x16e63, 0x16e64, 0x16e65, 0x16e66, 0x16e67, + 0x16e68, 0x16e69, 0x16e6a, 0x16e6b, 0x16e6c, 0x16e6d, 0x16e6e, 0x16e6f, + 0x16e70, 0x16e71, 0x16e72, 0x16e73, 0x16e74, 0x16e75, 0x16e76, 0x16e77, + 0x16e78, 0x16e79, 0x16e7a, 0x16e7b, 0x16e7c, 0x16e7d, 0x16e7e, 0x16e7f, + 0x16e60, 0x16e61, 0x16e62, 0x16e63, 0x16e64, 0x16e65, 0x16e66, 0x16e67, + 0x16e68, 0x16e69, 0x16e6a, 0x16e6b, 0x16e6c, 0x16e6d, 0x16e6e, 0x16e6f, + 0x16e70, 0x16e71, 0x16e72, 0x16e73, 0x16e74, 0x16e75, 0x16e76, 0x16e77, + 0x16e78, 0x16e79, 0x16e7a, 0x16e7b, 0x16e7c, 0x16e7d, 0x16e7e, 0x16e7f, +}; + + +static const uint32_t nxt_unicode_lower_case_block_3d2[34] + nxt_aligned(64) = +{ + 0x1e922, 0x1e923, 0x1e924, 0x1e925, 0x1e926, 0x1e927, 0x1e928, 0x1e929, + 0x1e92a, 0x1e92b, 0x1e92c, 0x1e92d, 0x1e92e, 0x1e92f, 0x1e930, 0x1e931, + 0x1e932, 0x1e933, 0x1e934, 0x1e935, 0x1e936, 0x1e937, 0x1e938, 0x1e939, + 0x1e93a, 0x1e93b, 0x1e93c, 0x1e93d, 0x1e93e, 0x1e93f, 0x1e940, 0x1e941, + 0x1e942, 0x1e943, }; @@ -612,25 +766,25 @@ static const uint32_t *nxt_unicode_lowe NULL, NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + nxt_unicode_lower_case_block_027, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_lower_case_block_039, NULL, NULL, nxt_unicode_lower_case_block_03c, @@ -1094,4 +1248,462 @@ static const uint32_t *nxt_unicode_lowe NULL, NULL, nxt_unicode_lower_case_block_208, + nxt_unicode_lower_case_block_209, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_lower_case_block_219, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_lower_case_block_231, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_lower_case_block_2dc, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_lower_case_block_3d2, }; diff -r 0af076f81e2b -r dace17533126 nxt/nxt_unicode_upper_case.h --- a/nxt/nxt_unicode_upper_case.h Sat Jul 27 03:51:48 2019 +0300 +++ b/nxt/nxt_unicode_upper_case.h Sat Jul 27 03:51:48 2019 +0300 @@ -1,10 +1,10 @@ /* - * 29 128-bytes blocks, 521 pointers. - * 16496 bytes on 32-bit platforms, 18576 bytes on 64-bit platforms. + * 40 128-bytes blocks, 979 pointers. + * 23948 bytes on 32-bit platforms, 27860 bytes on 64-bit platforms. */ -#define NXT_UNICODE_MAX_UPPER_CASE 0x1044f +#define NXT_UNICODE_MAX_UPPER_CASE 0x1e943 #define NXT_UNICODE_BLOCK_SIZE 128 @@ -111,9 +111,9 @@ static const uint32_t nxt_unicode_upper 0x02c7f, 0x00241, 0x00241, 0x00243, 0x00244, 0x00245, 0x00246, 0x00246, 0x00248, 0x00248, 0x0024a, 0x0024a, 0x0024c, 0x0024c, 0x0024e, 0x0024e, 0x02c6f, 0x02c6d, 0x02c70, 0x00181, 0x00186, 0x00255, 0x00189, 0x0018a, - 0x00258, 0x0018f, 0x0025a, 0x00190, 0x0025c, 0x0025d, 0x0025e, 0x0025f, - 0x00193, 0x00261, 0x00262, 0x00194, 0x00264, 0x0a78d, 0x0a7aa, 0x00267, - 0x00197, 0x00196, 0x0026a, 0x02c62, 0x0026c, 0x0026d, 0x0026e, 0x0019c, + 0x00258, 0x0018f, 0x0025a, 0x00190, 0x0a7ab, 0x0025d, 0x0025e, 0x0025f, + 0x00193, 0x0a7ac, 0x00262, 0x00194, 0x00264, 0x0a78d, 0x0a7aa, 0x00267, + 0x00197, 0x00196, 0x0a7ae, 0x02c62, 0x0a7ad, 0x0026d, 0x0026e, 0x0019c, 0x00270, 0x02c6e, 0x0019d, 0x00273, 0x00274, 0x0019f, 0x00276, 0x00277, 0x00278, 0x00279, 0x0027a, 0x0027b, 0x0027c, 0x02c64, 0x0027e, 0x0027f, }; @@ -122,10 +122,10 @@ static const uint32_t nxt_unicode_upper static const uint32_t nxt_unicode_upper_case_block_005[128] nxt_aligned(64) = { - 0x001a6, 0x00281, 0x00282, 0x001a9, 0x00284, 0x00285, 0x00286, 0x00287, + 0x001a6, 0x00281, 0x0a7c5, 0x001a9, 0x00284, 0x00285, 0x00286, 0x0a7b1, 0x001ae, 0x00244, 0x001b1, 0x001b2, 0x00245, 0x0028d, 0x0028e, 0x0028f, 0x00290, 0x00291, 0x001b7, 0x00293, 0x00294, 0x00295, 0x00296, 0x00297, - 0x00298, 0x00299, 0x0029a, 0x0029b, 0x0029c, 0x0029d, 0x0029e, 0x0029f, + 0x00298, 0x00299, 0x0029a, 0x0029b, 0x0029c, 0x0a7b2, 0x0a7b0, 0x0029f, 0x002a0, 0x002a1, 0x002a2, 0x002a3, 0x002a4, 0x002a5, 0x002a6, 0x002a7, 0x002a8, 0x002a9, 0x002aa, 0x002ab, 0x002ac, 0x002ad, 0x002ae, 0x002af, 0x002b0, 0x002b1, 0x002b2, 0x002b3, 0x002b4, 0x002b5, 0x002b6, 0x002b7, @@ -180,7 +180,7 @@ static const uint32_t nxt_unicode_upper 0x003d8, 0x003d8, 0x003da, 0x003da, 0x003dc, 0x003dc, 0x003de, 0x003de, 0x003e0, 0x003e0, 0x003e2, 0x003e2, 0x003e4, 0x003e4, 0x003e6, 0x003e6, 0x003e8, 0x003e8, 0x003ea, 0x003ea, 0x003ec, 0x003ec, 0x003ee, 0x003ee, - 0x0039a, 0x003a1, 0x003f9, 0x003f3, 0x003f4, 0x00395, 0x003f6, 0x003f7, + 0x0039a, 0x003a1, 0x003f9, 0x0037f, 0x003f4, 0x00395, 0x003f6, 0x003f7, 0x003f7, 0x003f9, 0x003fa, 0x003fa, 0x003fc, 0x003fd, 0x003fe, 0x003ff, }; @@ -237,7 +237,7 @@ static const uint32_t nxt_unicode_upper 0x00510, 0x00510, 0x00512, 0x00512, 0x00514, 0x00514, 0x00516, 0x00516, 0x00518, 0x00518, 0x0051a, 0x0051a, 0x0051c, 0x0051c, 0x0051e, 0x0051e, 0x00520, 0x00520, 0x00522, 0x00522, 0x00524, 0x00524, 0x00526, 0x00526, - 0x00528, 0x00529, 0x0052a, 0x0052b, 0x0052c, 0x0052d, 0x0052e, 0x0052f, + 0x00528, 0x00528, 0x0052a, 0x0052a, 0x0052c, 0x0052c, 0x0052e, 0x0052e, 0x00530, 0x00531, 0x00532, 0x00533, 0x00534, 0x00535, 0x00536, 0x00537, 0x00538, 0x00539, 0x0053a, 0x0053b, 0x0053c, 0x0053d, 0x0053e, 0x0053f, 0x00540, 0x00541, 0x00542, 0x00543, 0x00544, 0x00545, 0x00546, 0x00547, @@ -273,6 +273,72 @@ static const uint32_t nxt_unicode_upper }; +static const uint32_t nxt_unicode_upper_case_block_021[128] + nxt_aligned(64) = +{ + 0x01080, 0x01081, 0x01082, 0x01083, 0x01084, 0x01085, 0x01086, 0x01087, + 0x01088, 0x01089, 0x0108a, 0x0108b, 0x0108c, 0x0108d, 0x0108e, 0x0108f, + 0x01090, 0x01091, 0x01092, 0x01093, 0x01094, 0x01095, 0x01096, 0x01097, + 0x01098, 0x01099, 0x0109a, 0x0109b, 0x0109c, 0x0109d, 0x0109e, 0x0109f, + 0x010a0, 0x010a1, 0x010a2, 0x010a3, 0x010a4, 0x010a5, 0x010a6, 0x010a7, + 0x010a8, 0x010a9, 0x010aa, 0x010ab, 0x010ac, 0x010ad, 0x010ae, 0x010af, + 0x010b0, 0x010b1, 0x010b2, 0x010b3, 0x010b4, 0x010b5, 0x010b6, 0x010b7, + 0x010b8, 0x010b9, 0x010ba, 0x010bb, 0x010bc, 0x010bd, 0x010be, 0x010bf, + 0x010c0, 0x010c1, 0x010c2, 0x010c3, 0x010c4, 0x010c5, 0x010c6, 0x010c7, + 0x010c8, 0x010c9, 0x010ca, 0x010cb, 0x010cc, 0x010cd, 0x010ce, 0x010cf, + 0x01c90, 0x01c91, 0x01c92, 0x01c93, 0x01c94, 0x01c95, 0x01c96, 0x01c97, + 0x01c98, 0x01c99, 0x01c9a, 0x01c9b, 0x01c9c, 0x01c9d, 0x01c9e, 0x01c9f, + 0x01ca0, 0x01ca1, 0x01ca2, 0x01ca3, 0x01ca4, 0x01ca5, 0x01ca6, 0x01ca7, + 0x01ca8, 0x01ca9, 0x01caa, 0x01cab, 0x01cac, 0x01cad, 0x01cae, 0x01caf, + 0x01cb0, 0x01cb1, 0x01cb2, 0x01cb3, 0x01cb4, 0x01cb5, 0x01cb6, 0x01cb7, + 0x01cb8, 0x01cb9, 0x01cba, 0x010fb, 0x010fc, 0x01cbd, 0x01cbe, 0x01cbf, +}; + + +static const uint32_t nxt_unicode_upper_case_block_027[128] + nxt_aligned(64) = +{ + 0x01380, 0x01381, 0x01382, 0x01383, 0x01384, 0x01385, 0x01386, 0x01387, + 0x01388, 0x01389, 0x0138a, 0x0138b, 0x0138c, 0x0138d, 0x0138e, 0x0138f, + 0x01390, 0x01391, 0x01392, 0x01393, 0x01394, 0x01395, 0x01396, 0x01397, + 0x01398, 0x01399, 0x0139a, 0x0139b, 0x0139c, 0x0139d, 0x0139e, 0x0139f, + 0x013a0, 0x013a1, 0x013a2, 0x013a3, 0x013a4, 0x013a5, 0x013a6, 0x013a7, + 0x013a8, 0x013a9, 0x013aa, 0x013ab, 0x013ac, 0x013ad, 0x013ae, 0x013af, + 0x013b0, 0x013b1, 0x013b2, 0x013b3, 0x013b4, 0x013b5, 0x013b6, 0x013b7, + 0x013b8, 0x013b9, 0x013ba, 0x013bb, 0x013bc, 0x013bd, 0x013be, 0x013bf, + 0x013c0, 0x013c1, 0x013c2, 0x013c3, 0x013c4, 0x013c5, 0x013c6, 0x013c7, + 0x013c8, 0x013c9, 0x013ca, 0x013cb, 0x013cc, 0x013cd, 0x013ce, 0x013cf, + 0x013d0, 0x013d1, 0x013d2, 0x013d3, 0x013d4, 0x013d5, 0x013d6, 0x013d7, + 0x013d8, 0x013d9, 0x013da, 0x013db, 0x013dc, 0x013dd, 0x013de, 0x013df, + 0x013e0, 0x013e1, 0x013e2, 0x013e3, 0x013e4, 0x013e5, 0x013e6, 0x013e7, + 0x013e8, 0x013e9, 0x013ea, 0x013eb, 0x013ec, 0x013ed, 0x013ee, 0x013ef, + 0x013f0, 0x013f1, 0x013f2, 0x013f3, 0x013f4, 0x013f5, 0x013f6, 0x013f7, + 0x013f0, 0x013f1, 0x013f2, 0x013f3, 0x013f4, 0x013f5, 0x013fe, 0x013ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_039[128] + nxt_aligned(64) = +{ + 0x00412, 0x00414, 0x0041e, 0x00421, 0x00422, 0x00422, 0x0042a, 0x00462, + 0x0a64a, 0x01c89, 0x01c8a, 0x01c8b, 0x01c8c, 0x01c8d, 0x01c8e, 0x01c8f, + 0x01c90, 0x01c91, 0x01c92, 0x01c93, 0x01c94, 0x01c95, 0x01c96, 0x01c97, + 0x01c98, 0x01c99, 0x01c9a, 0x01c9b, 0x01c9c, 0x01c9d, 0x01c9e, 0x01c9f, + 0x01ca0, 0x01ca1, 0x01ca2, 0x01ca3, 0x01ca4, 0x01ca5, 0x01ca6, 0x01ca7, + 0x01ca8, 0x01ca9, 0x01caa, 0x01cab, 0x01cac, 0x01cad, 0x01cae, 0x01caf, + 0x01cb0, 0x01cb1, 0x01cb2, 0x01cb3, 0x01cb4, 0x01cb5, 0x01cb6, 0x01cb7, + 0x01cb8, 0x01cb9, 0x01cba, 0x01cbb, 0x01cbc, 0x01cbd, 0x01cbe, 0x01cbf, + 0x01cc0, 0x01cc1, 0x01cc2, 0x01cc3, 0x01cc4, 0x01cc5, 0x01cc6, 0x01cc7, + 0x01cc8, 0x01cc9, 0x01cca, 0x01ccb, 0x01ccc, 0x01ccd, 0x01cce, 0x01ccf, + 0x01cd0, 0x01cd1, 0x01cd2, 0x01cd3, 0x01cd4, 0x01cd5, 0x01cd6, 0x01cd7, + 0x01cd8, 0x01cd9, 0x01cda, 0x01cdb, 0x01cdc, 0x01cdd, 0x01cde, 0x01cdf, + 0x01ce0, 0x01ce1, 0x01ce2, 0x01ce3, 0x01ce4, 0x01ce5, 0x01ce6, 0x01ce7, + 0x01ce8, 0x01ce9, 0x01cea, 0x01ceb, 0x01cec, 0x01ced, 0x01cee, 0x01cef, + 0x01cf0, 0x01cf1, 0x01cf2, 0x01cf3, 0x01cf4, 0x01cf5, 0x01cf6, 0x01cf7, + 0x01cf8, 0x01cf9, 0x01cfa, 0x01cfb, 0x01cfc, 0x01cfd, 0x01cfe, 0x01cff, +}; + + static const uint32_t nxt_unicode_upper_case_block_03a[128] nxt_aligned(64) = { @@ -295,6 +361,28 @@ static const uint32_t nxt_unicode_upper }; +static const uint32_t nxt_unicode_upper_case_block_03b[128] + nxt_aligned(64) = +{ + 0x01d80, 0x01d81, 0x01d82, 0x01d83, 0x01d84, 0x01d85, 0x01d86, 0x01d87, + 0x01d88, 0x01d89, 0x01d8a, 0x01d8b, 0x01d8c, 0x01d8d, 0x0a7c6, 0x01d8f, + 0x01d90, 0x01d91, 0x01d92, 0x01d93, 0x01d94, 0x01d95, 0x01d96, 0x01d97, + 0x01d98, 0x01d99, 0x01d9a, 0x01d9b, 0x01d9c, 0x01d9d, 0x01d9e, 0x01d9f, + 0x01da0, 0x01da1, 0x01da2, 0x01da3, 0x01da4, 0x01da5, 0x01da6, 0x01da7, + 0x01da8, 0x01da9, 0x01daa, 0x01dab, 0x01dac, 0x01dad, 0x01dae, 0x01daf, + 0x01db0, 0x01db1, 0x01db2, 0x01db3, 0x01db4, 0x01db5, 0x01db6, 0x01db7, + 0x01db8, 0x01db9, 0x01dba, 0x01dbb, 0x01dbc, 0x01dbd, 0x01dbe, 0x01dbf, + 0x01dc0, 0x01dc1, 0x01dc2, 0x01dc3, 0x01dc4, 0x01dc5, 0x01dc6, 0x01dc7, + 0x01dc8, 0x01dc9, 0x01dca, 0x01dcb, 0x01dcc, 0x01dcd, 0x01dce, 0x01dcf, + 0x01dd0, 0x01dd1, 0x01dd2, 0x01dd3, 0x01dd4, 0x01dd5, 0x01dd6, 0x01dd7, + 0x01dd8, 0x01dd9, 0x01dda, 0x01ddb, 0x01ddc, 0x01ddd, 0x01dde, 0x01ddf, + 0x01de0, 0x01de1, 0x01de2, 0x01de3, 0x01de4, 0x01de5, 0x01de6, 0x01de7, + 0x01de8, 0x01de9, 0x01dea, 0x01deb, 0x01dec, 0x01ded, 0x01dee, 0x01def, + 0x01df0, 0x01df1, 0x01df2, 0x01df3, 0x01df4, 0x01df5, 0x01df6, 0x01df7, + 0x01df8, 0x01df9, 0x01dfa, 0x01dfb, 0x01dfc, 0x01dfd, 0x01dfe, 0x01dff, +}; + + static const uint32_t nxt_unicode_upper_case_block_03c[128] nxt_aligned(64) = { @@ -543,7 +631,7 @@ static const uint32_t nxt_unicode_upper 0x0a680, 0x0a680, 0x0a682, 0x0a682, 0x0a684, 0x0a684, 0x0a686, 0x0a686, 0x0a688, 0x0a688, 0x0a68a, 0x0a68a, 0x0a68c, 0x0a68c, 0x0a68e, 0x0a68e, 0x0a690, 0x0a690, 0x0a692, 0x0a692, 0x0a694, 0x0a694, 0x0a696, 0x0a696, - 0x0a698, 0x0a699, 0x0a69a, 0x0a69b, 0x0a69c, 0x0a69d, 0x0a69e, 0x0a69f, + 0x0a698, 0x0a698, 0x0a69a, 0x0a69a, 0x0a69c, 0x0a69d, 0x0a69e, 0x0a69f, 0x0a6a0, 0x0a6a1, 0x0a6a2, 0x0a6a3, 0x0a6a4, 0x0a6a5, 0x0a6a6, 0x0a6a7, 0x0a6a8, 0x0a6a9, 0x0a6aa, 0x0a6ab, 0x0a6ac, 0x0a6ad, 0x0a6ae, 0x0a6af, 0x0a6b0, 0x0a6b1, 0x0a6b2, 0x0a6b3, 0x0a6b4, 0x0a6b5, 0x0a6b6, 0x0a6b7, @@ -586,13 +674,13 @@ static const uint32_t nxt_unicode_upper { 0x0a780, 0x0a780, 0x0a782, 0x0a782, 0x0a784, 0x0a784, 0x0a786, 0x0a786, 0x0a788, 0x0a789, 0x0a78a, 0x0a78b, 0x0a78b, 0x0a78d, 0x0a78e, 0x0a78f, - 0x0a790, 0x0a790, 0x0a792, 0x0a792, 0x0a794, 0x0a795, 0x0a796, 0x0a797, - 0x0a798, 0x0a799, 0x0a79a, 0x0a79b, 0x0a79c, 0x0a79d, 0x0a79e, 0x0a79f, + 0x0a790, 0x0a790, 0x0a792, 0x0a792, 0x0a7c4, 0x0a795, 0x0a796, 0x0a796, + 0x0a798, 0x0a798, 0x0a79a, 0x0a79a, 0x0a79c, 0x0a79c, 0x0a79e, 0x0a79e, 0x0a7a0, 0x0a7a0, 0x0a7a2, 0x0a7a2, 0x0a7a4, 0x0a7a4, 0x0a7a6, 0x0a7a6, 0x0a7a8, 0x0a7a8, 0x0a7aa, 0x0a7ab, 0x0a7ac, 0x0a7ad, 0x0a7ae, 0x0a7af, - 0x0a7b0, 0x0a7b1, 0x0a7b2, 0x0a7b3, 0x0a7b4, 0x0a7b5, 0x0a7b6, 0x0a7b7, - 0x0a7b8, 0x0a7b9, 0x0a7ba, 0x0a7bb, 0x0a7bc, 0x0a7bd, 0x0a7be, 0x0a7bf, - 0x0a7c0, 0x0a7c1, 0x0a7c2, 0x0a7c3, 0x0a7c4, 0x0a7c5, 0x0a7c6, 0x0a7c7, + 0x0a7b0, 0x0a7b1, 0x0a7b2, 0x0a7b3, 0x0a7b4, 0x0a7b4, 0x0a7b6, 0x0a7b6, + 0x0a7b8, 0x0a7b8, 0x0a7ba, 0x0a7ba, 0x0a7bc, 0x0a7bc, 0x0a7be, 0x0a7be, + 0x0a7c0, 0x0a7c1, 0x0a7c2, 0x0a7c2, 0x0a7c4, 0x0a7c5, 0x0a7c6, 0x0a7c7, 0x0a7c8, 0x0a7c9, 0x0a7ca, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, 0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, 0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, @@ -603,6 +691,50 @@ static const uint32_t nxt_unicode_upper }; +static const uint32_t nxt_unicode_upper_case_block_156[128] + nxt_aligned(64) = +{ + 0x0ab00, 0x0ab01, 0x0ab02, 0x0ab03, 0x0ab04, 0x0ab05, 0x0ab06, 0x0ab07, + 0x0ab08, 0x0ab09, 0x0ab0a, 0x0ab0b, 0x0ab0c, 0x0ab0d, 0x0ab0e, 0x0ab0f, + 0x0ab10, 0x0ab11, 0x0ab12, 0x0ab13, 0x0ab14, 0x0ab15, 0x0ab16, 0x0ab17, + 0x0ab18, 0x0ab19, 0x0ab1a, 0x0ab1b, 0x0ab1c, 0x0ab1d, 0x0ab1e, 0x0ab1f, + 0x0ab20, 0x0ab21, 0x0ab22, 0x0ab23, 0x0ab24, 0x0ab25, 0x0ab26, 0x0ab27, + 0x0ab28, 0x0ab29, 0x0ab2a, 0x0ab2b, 0x0ab2c, 0x0ab2d, 0x0ab2e, 0x0ab2f, + 0x0ab30, 0x0ab31, 0x0ab32, 0x0ab33, 0x0ab34, 0x0ab35, 0x0ab36, 0x0ab37, + 0x0ab38, 0x0ab39, 0x0ab3a, 0x0ab3b, 0x0ab3c, 0x0ab3d, 0x0ab3e, 0x0ab3f, + 0x0ab40, 0x0ab41, 0x0ab42, 0x0ab43, 0x0ab44, 0x0ab45, 0x0ab46, 0x0ab47, + 0x0ab48, 0x0ab49, 0x0ab4a, 0x0ab4b, 0x0ab4c, 0x0ab4d, 0x0ab4e, 0x0ab4f, + 0x0ab50, 0x0ab51, 0x0ab52, 0x0a7b3, 0x0ab54, 0x0ab55, 0x0ab56, 0x0ab57, + 0x0ab58, 0x0ab59, 0x0ab5a, 0x0ab5b, 0x0ab5c, 0x0ab5d, 0x0ab5e, 0x0ab5f, + 0x0ab60, 0x0ab61, 0x0ab62, 0x0ab63, 0x0ab64, 0x0ab65, 0x0ab66, 0x0ab67, + 0x0ab68, 0x0ab69, 0x0ab6a, 0x0ab6b, 0x0ab6c, 0x0ab6d, 0x0ab6e, 0x0ab6f, + 0x013a0, 0x013a1, 0x013a2, 0x013a3, 0x013a4, 0x013a5, 0x013a6, 0x013a7, + 0x013a8, 0x013a9, 0x013aa, 0x013ab, 0x013ac, 0x013ad, 0x013ae, 0x013af, +}; + + +static const uint32_t nxt_unicode_upper_case_block_157[128] + nxt_aligned(64) = +{ + 0x013b0, 0x013b1, 0x013b2, 0x013b3, 0x013b4, 0x013b5, 0x013b6, 0x013b7, + 0x013b8, 0x013b9, 0x013ba, 0x013bb, 0x013bc, 0x013bd, 0x013be, 0x013bf, + 0x013c0, 0x013c1, 0x013c2, 0x013c3, 0x013c4, 0x013c5, 0x013c6, 0x013c7, + 0x013c8, 0x013c9, 0x013ca, 0x013cb, 0x013cc, 0x013cd, 0x013ce, 0x013cf, + 0x013d0, 0x013d1, 0x013d2, 0x013d3, 0x013d4, 0x013d5, 0x013d6, 0x013d7, + 0x013d8, 0x013d9, 0x013da, 0x013db, 0x013dc, 0x013dd, 0x013de, 0x013df, + 0x013e0, 0x013e1, 0x013e2, 0x013e3, 0x013e4, 0x013e5, 0x013e6, 0x013e7, + 0x013e8, 0x013e9, 0x013ea, 0x013eb, 0x013ec, 0x013ed, 0x013ee, 0x013ef, + 0x0abc0, 0x0abc1, 0x0abc2, 0x0abc3, 0x0abc4, 0x0abc5, 0x0abc6, 0x0abc7, + 0x0abc8, 0x0abc9, 0x0abca, 0x0abcb, 0x0abcc, 0x0abcd, 0x0abce, 0x0abcf, + 0x0abd0, 0x0abd1, 0x0abd2, 0x0abd3, 0x0abd4, 0x0abd5, 0x0abd6, 0x0abd7, + 0x0abd8, 0x0abd9, 0x0abda, 0x0abdb, 0x0abdc, 0x0abdd, 0x0abde, 0x0abdf, + 0x0abe0, 0x0abe1, 0x0abe2, 0x0abe3, 0x0abe4, 0x0abe5, 0x0abe6, 0x0abe7, + 0x0abe8, 0x0abe9, 0x0abea, 0x0abeb, 0x0abec, 0x0abed, 0x0abee, 0x0abef, + 0x0abf0, 0x0abf1, 0x0abf2, 0x0abf3, 0x0abf4, 0x0abf5, 0x0abf6, 0x0abf7, + 0x0abf8, 0x0abf9, 0x0abfa, 0x0abfb, 0x0abfc, 0x0abfd, 0x0abfe, 0x0abff, +}; + + From xeioex at nginx.com Sat Jul 27 08:59:30 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Sat, 27 Jul 2019 08:59:30 +0000 Subject: [njs] Removed function call flag. Message-ID: details: https://hg.nginx.org/njs/rev/98c4858be02a branches: changeset: 1073:98c4858be02a user: hongzhidao date: Fri Jul 26 22:37:38 2019 -0400 description: Removed function call flag. diffstat: njs/njs_function.c | 2 -- njs/njs_function.h | 2 -- njs/njs_vmcode.c | 6 +++--- 3 files changed, 3 insertions(+), 7 deletions(-) diffs (54 lines): diff -r dace17533126 -r 98c4858be02a njs/njs_function.c --- a/njs/njs_function.c Sat Jul 27 03:51:48 2019 +0300 +++ b/njs/njs_function.c Fri Jul 26 22:37:38 2019 -0400 @@ -568,8 +568,6 @@ njs_function_lambda_call(njs_vm_t *vm) } } - frame->native.call = 1; - vm->active_frame = frame; return njs_vmcode_interpreter(vm, lambda->start); diff -r dace17533126 -r 98c4858be02a njs/njs_function.h --- a/njs/njs_function.h Sat Jul 27 03:51:48 2019 +0300 +++ b/njs/njs_function.h Fri Jul 26 22:37:38 2019 -0400 @@ -89,8 +89,6 @@ struct njs_native_frame_s { /* Skip the Function.call() and Function.apply() methods frames. */ uint8_t skip; /* 1 bit */ - - uint8_t call; /* 1 bit */ }; diff -r dace17533126 -r 98c4858be02a njs/njs_vmcode.c --- a/njs/njs_vmcode.c Sat Jul 27 03:51:48 2019 +0300 +++ b/njs/njs_vmcode.c Fri Jul 26 22:37:38 2019 -0400 @@ -87,7 +87,7 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_c uint32_t u32; njs_ret_t ret; nxt_uint_t hint; - nxt_bool_t valid, call; + nxt_bool_t valid, lambda_call; njs_value_t *retval, *value1, *value2, *src, *s1, *s2; njs_value_t numeric1, numeric2, primitive1, primitive2, dst; @@ -855,7 +855,7 @@ error: break; } - call = frame->native.call; + lambda_call = (frame == vm->active_frame); njs_vm_scopes_restore(vm, frame, previous); @@ -864,7 +864,7 @@ error: nxt_mp_free(vm->mem_pool, frame); } - if (call) { + if (lambda_call) { break; } } From xeioex at nginx.com Sat Jul 27 08:59:30 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Sat, 27 Jul 2019 08:59:30 +0000 Subject: [njs] Fixed Array.length setter. Message-ID: details: https://hg.nginx.org/njs/rev/ab9fc6079788 branches: changeset: 1074:ab9fc6079788 user: Artem S. Povalyukhin date: Fri Jul 26 07:24:36 2019 +0300 description: Fixed Array.length setter. This closes #26 and closes #27 issues on Github. diffstat: njs/njs_array.c | 21 ++++++++++++++------- njs/test/njs_unit_test.c | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diffs (80 lines): diff -r 98c4858be02a -r ab9fc6079788 njs/njs_array.c --- a/njs/njs_array.c Fri Jul 26 22:37:38 2019 -0400 +++ b/njs/njs_array.c Fri Jul 26 07:24:36 2019 +0300 @@ -318,10 +318,11 @@ njs_array_length(njs_vm_t *vm, njs_value njs_value_t *val; njs_array_t *array; njs_object_t *proto; + njs_value_t val_length; proto = njs_object(value); - if (setval == NULL) { + if (nxt_fast_path(setval == NULL)) { do { if (nxt_fast_path(proto->type == NJS_ARRAY)) { break; @@ -345,13 +346,19 @@ njs_array_length(njs_vm_t *vm, njs_value return NJS_DECLINED; } - if (!njs_is_number(setval)) { - njs_range_error(vm, "Invalid array length"); - return NJS_ERROR; + if (nxt_slow_path(!njs_is_number(setval))) { + ret = njs_value_to_numeric(vm, &val_length, setval); + if (ret != NXT_OK) { + return ret; + } + + num = njs_number(&val_length); + + } else { + num = njs_number(setval); } - num = njs_number(setval); - length = (uint32_t) num; + length = njs_number_to_uint32(num); if ((double) length != num) { njs_range_error(vm, "Invalid array length"); @@ -379,7 +386,7 @@ njs_array_length(njs_vm_t *vm, njs_value array->length = length; - njs_set_number(retval, length); + *retval = *setval; return NJS_OK; } diff -r 98c4858be02a -r ab9fc6079788 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Jul 26 22:37:38 2019 -0400 +++ b/njs/test/njs_unit_test.c Fri Jul 26 07:24:36 2019 +0300 @@ -3531,6 +3531,26 @@ static njs_unit_test_t njs_test[] = { nxt_string("[].length = -1"), nxt_string("RangeError: Invalid array length") }, + { nxt_string("var a = [1];" + "typeof (a.length = '') == 'string' && a.length == 0"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "typeof (a.length = Object(2)) == 'object' && a.length == 2"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "typeof (a.length = Object('2')) == 'object'"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "a.length = { valueOf: () => 2 }; a.length == 2"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "a.length = { toString: () => '2' }; a.length == 2"), + nxt_string("true") }, + { nxt_string("var a = []; a.length = 0; JSON.stringify(a)"), nxt_string("[]") }, From vbart at nginx.com Sat Jul 27 13:13:01 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 27 Jul 2019 13:13:01 +0000 Subject: [njs] Fixed String.fromCharCode() for code points > 65535 and NaN. Message-ID: details: https://hg.nginx.org/njs/rev/0b82f1c9268c branches: changeset: 1075:0b82f1c9268c user: Valentin Bartenev date: Sat Jul 27 16:12:26 2019 +0300 description: Fixed String.fromCharCode() for code points > 65535 and NaN. According to the specification the code units must be truncated to uint16. diffstat: njs/njs_number.h | 7 +++++++ njs/njs_string.c | 26 +++++--------------------- njs/test/njs_interactive_test.c | 4 ++-- njs/test/njs_unit_test.c | 28 +++++++++++++++------------- nxt/nxt_utf8.h | 4 ++++ 5 files changed, 33 insertions(+), 36 deletions(-) diffs (172 lines): diff -r ab9fc6079788 -r 0b82f1c9268c njs/njs_number.h --- a/njs/njs_number.h Fri Jul 26 07:24:36 2019 +0300 +++ b/njs/njs_number.h Sat Jul 27 16:12:26 2019 +0300 @@ -86,6 +86,13 @@ njs_number_to_uint32(double num) } +nxt_inline uint16_t +njs_number_to_uint16(double num) +{ + return (uint16_t) njs_number_to_int64(num); +} + + nxt_inline uint32_t njs_number_to_length(double num) { diff -r ab9fc6079788 -r 0b82f1c9268c njs/njs_string.c --- a/njs/njs_string.c Fri Jul 26 07:24:36 2019 +0300 +++ b/njs/njs_string.c Sat Jul 27 16:12:26 2019 +0300 @@ -1694,9 +1694,8 @@ njs_string_from_char_code(njs_vm_t *vm, nxt_uint_t nargs, njs_index_t unused) { u_char *p; - double num; size_t size; - int32_t code; + uint16_t code; njs_ret_t ret; nxt_uint_t i; @@ -1712,18 +1711,8 @@ njs_string_from_char_code(njs_vm_t *vm, size = 0; for (i = 1; i < nargs; i++) { - num = njs_number(&args[i]); - if (isnan(num)) { - goto range_error; - } - - code = num; - - if (code != num || code < 0 || code >= 0x110000) { - goto range_error; - } - - size += nxt_utf8_size(code); + code = njs_number_to_uint16(njs_number(&args[i])); + size += nxt_utf8_size_uint16(code); } p = njs_string_alloc(vm, &vm->retval, size, nargs - 1); @@ -1732,16 +1721,11 @@ njs_string_from_char_code(njs_vm_t *vm, } for (i = 1; i < nargs; i++) { - p = nxt_utf8_encode(p, njs_number(&args[i])); + code = njs_number_to_uint16(njs_number(&args[i])); + p = nxt_utf8_encode(p, code); } return NXT_OK; - -range_error: - - njs_range_error(vm, NULL); - - return NXT_ERROR; } diff -r ab9fc6079788 -r 0b82f1c9268c njs/test/njs_interactive_test.c --- a/njs/test/njs_interactive_test.c Fri Jul 26 07:24:36 2019 +0300 +++ b/njs/test/njs_interactive_test.c Sat Jul 27 16:12:26 2019 +0300 @@ -149,9 +149,9 @@ static njs_interactive_test_t njs_test[ " at f (:1)\n" " at main (native)\n") }, - { nxt_string("String.fromCharCode(3.14)" ENTER), + { nxt_string("''.repeat(-1)" ENTER), nxt_string("RangeError\n" - " at String.fromCharCode (native)\n" + " at String.prototype.repeat (native)\n" " at main (native)\n") }, { nxt_string("Math.log({}.a.a)" ENTER), diff -r ab9fc6079788 -r 0b82f1c9268c njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Jul 26 07:24:36 2019 +0300 +++ b/njs/test/njs_unit_test.c Sat Jul 27 16:12:26 2019 +0300 @@ -5345,11 +5345,17 @@ static njs_unit_test_t njs_test[] = " .length; a"), nxt_string("5") }, - { nxt_string("String.fromCharCode('_')"), - nxt_string("RangeError") }, - - { nxt_string("String.fromCharCode(3.14)"), - nxt_string("RangeError") }, + { nxt_string("String.fromCharCode('_').charCodeAt(0)"), + nxt_string("0") }, + + { nxt_string("String.fromCharCode(65.14)"), + nxt_string("A") }, + + { nxt_string("String.fromCharCode(65.14 + 65536)"), + nxt_string("A") }, + + { nxt_string("String.fromCharCode(2**53 + 10)"), + nxt_string("\n") }, { nxt_string("String.fromCharCode(65, 90)"), nxt_string("AZ") }, @@ -5357,17 +5363,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("String.fromCharCode(945, 946, 947)"), nxt_string("???") }, -#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long test under MSAN */ { nxt_string("(function() {" " var n;" - " for (n = 0; n <= 1114111; n++) {" + " for (n = 0; n <= 65536; n++) {" " if (String.fromCharCode(n).charCodeAt(0) !== n)" " return n;" " }" " return -1" "})()"), - nxt_string("-1") }, -#endif + nxt_string("65536") }, { nxt_string("var a = 'abcdef'; function f(a) {" "return a.slice(a.indexOf('cd')) } f(a)"), @@ -5567,9 +5571,8 @@ static njs_unit_test_t njs_test[] = nxt_string("10") }, #if 0 /* FIXME */ -#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long test under MSAN */ { nxt_string("var a = [], code;" - "for (code = 0; code <= 1114111; code++) {" + "for (code = 0; code < 65536; code++) {" " var s = String.fromCharCode(code);" " var n = s.toUpperCase();" " if (s != n && s != n.toLowerCase())" @@ -5578,7 +5581,7 @@ static njs_unit_test_t njs_test[] = nxt_string("181,305,383,453,456,459,498,837,962,976,977,981,982,1008,1009,1013,7296,7297,7298,7299,7300,7301,7302,7303,7304,7835,8126") }, { nxt_string("var a = [], code;" - "for (code = 0; code <= 1114111; code++) {" + "for (code = 0; code < 65536; code++) {" " var s = String.fromCharCode(code);" " var n = s.toLowerCase();" " if (s != n && s != n.toUpperCase())" @@ -5586,7 +5589,6 @@ static njs_unit_test_t njs_test[] = "} a"), nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, #endif -#endif { nxt_string("'abc'.trim()"), nxt_string("abc") }, diff -r ab9fc6079788 -r 0b82f1c9268c nxt/nxt_utf8.h --- a/nxt/nxt_utf8.h Fri Jul 26 07:24:36 2019 +0300 +++ b/nxt/nxt_utf8.h Sat Jul 27 16:12:26 2019 +0300 @@ -118,4 +118,8 @@ nxt_utf8_copy(u_char *dst, const u_char ((u < 0x80) ? 1 : ((u < 0x0800) ? 2 : ((u < 0x10000) ? 3 : 4))) +#define nxt_utf8_size_uint16(u) \ + ((u < 0x80) ? 1 : ((u < 0x0800) ? 2 : 3)) + + #endif /* _NXT_UTF8_H_INCLUDED_ */ From vbart at nginx.com Sat Jul 27 14:35:45 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 27 Jul 2019 14:35:45 +0000 Subject: [njs] Fixed String.toLowerCase() and String.toUpperCase(). Message-ID: details: https://hg.nginx.org/njs/rev/cba3bd29f263 branches: changeset: 1076:cba3bd29f263 user: Valentin Bartenev date: Sat Jul 27 17:03:02 2019 +0300 description: Fixed String.toLowerCase() and String.toUpperCase(). Previously these functions didn't took into account that the size of a string may change during case transformation resulting in buffer underflow or overflow. diffstat: njs/njs_string.c | 88 +++++++++++++++++++++++++++++++++-------------- njs/test/njs_unit_test.c | 11 ++++- 2 files changed, 71 insertions(+), 28 deletions(-) diffs (176 lines): diff -r 0b82f1c9268c -r cba3bd29f263 njs/njs_string.c --- a/njs/njs_string.c Sat Jul 27 16:12:26 2019 +0300 +++ b/njs/njs_string.c Sat Jul 27 17:03:02 2019 +0300 @@ -2171,24 +2171,24 @@ njs_string_prototype_to_lower_case(njs_v nxt_uint_t nargs, njs_index_t unused) { size_t size, length; - u_char *p, *start; + u_char *p; + uint32_t code; const u_char *s, *end; njs_string_prop_t string; (void) njs_string_prop(&string, &args[0]); - start = njs_string_alloc(vm, &vm->retval, string.size, string.length); - if (nxt_slow_path(start == NULL)) { - return NXT_ERROR; - } - - p = start; - s = string.start; - size = string.size; - - if (string.length == 0 || string.length == size) { + if (string.length == 0 || string.length == string.size) { /* Byte or ASCII string. */ + p = njs_string_alloc(vm, &vm->retval, string.size, string.length); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + s = string.start; + size = string.size; + while (size != 0) { *p++ = nxt_lower_case(*s++); size--; @@ -2196,11 +2196,29 @@ njs_string_prototype_to_lower_case(njs_v } else { /* UTF-8 string. */ - end = s + size; + s = string.start; + end = s + string.size; + length = string.length; + + size = 0; + + while (length != 0) { + code = nxt_utf8_lower_case(&s, end); + size += nxt_utf8_size(code); + length--; + } + + p = njs_string_alloc(vm, &vm->retval, size, string.length); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + s = string.start; length = string.length; while (length != 0) { - p = nxt_utf8_encode(p, nxt_utf8_lower_case(&s, end)); + code = nxt_utf8_lower_case(&s, end); + p = nxt_utf8_encode(p, code); length--; } } @@ -2220,24 +2238,24 @@ njs_string_prototype_to_upper_case(njs_v nxt_uint_t nargs, njs_index_t unused) { size_t size, length; - u_char *p, *start; + u_char *p; + uint32_t code; const u_char *s, *end; njs_string_prop_t string; (void) njs_string_prop(&string, &args[0]); - start = njs_string_alloc(vm, &vm->retval, string.size, string.length); - if (nxt_slow_path(start == NULL)) { - return NXT_ERROR; - } - - p = start; - s = string.start; - size = string.size; - - if (string.length == 0 || string.length == size) { + if (string.length == 0 || string.length == string.size) { /* Byte or ASCII string. */ + p = njs_string_alloc(vm, &vm->retval, string.size, string.length); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + s = string.start; + size = string.size; + while (size != 0) { *p++ = nxt_upper_case(*s++); size--; @@ -2245,11 +2263,29 @@ njs_string_prototype_to_upper_case(njs_v } else { /* UTF-8 string. */ - end = s + size; + s = string.start; + end = s + string.size; + length = string.length; + + size = 0; + + while (length != 0) { + code = nxt_utf8_upper_case(&s, end); + size += nxt_utf8_size(code); + length--; + } + + p = njs_string_alloc(vm, &vm->retval, size, string.length); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + s = string.start; length = string.length; while (length != 0) { - p = nxt_utf8_encode(p, nxt_utf8_upper_case(&s, end)); + code = nxt_utf8_upper_case(&s, end); + p = nxt_utf8_encode(p, code); length--; } } diff -r 0b82f1c9268c -r cba3bd29f263 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Jul 27 16:12:26 2019 +0300 +++ b/njs/test/njs_unit_test.c Sat Jul 27 17:03:02 2019 +0300 @@ -5561,16 +5561,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("'???'.toLowerCase()"), nxt_string("???") }, + { nxt_string("'?'.repeat(256).toLowerCase() === '?'.repeat(256)"), + nxt_string("true") }, + { nxt_string("'abc'.toUpperCase()"), nxt_string("ABC") }, { nxt_string("'???'.toUpperCase()"), nxt_string("???") }, + { nxt_string("'?'.repeat(256).toUpperCase() === '?'.repeat(256)"), + nxt_string("true") }, + { nxt_string("'\x00?????????'.toUpperCase().length"), nxt_string("10") }, -#if 0 /* FIXME */ + { nxt_string("['?', '?', '?'.toUpperCase(), '?'.toLowerCase()].map((v)=>v.toUTF8().length)"), + nxt_string("2,3,3,2") }, + { nxt_string("var a = [], code;" "for (code = 0; code < 65536; code++) {" " var s = String.fromCharCode(code);" @@ -5588,7 +5596,6 @@ static njs_unit_test_t njs_test[] = " a.push(code);" "} a"), nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, -#endif { nxt_string("'abc'.trim()"), nxt_string("abc") }, From vbart at nginx.com Sat Jul 27 18:13:50 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 27 Jul 2019 18:13:50 +0000 Subject: [njs] Fixed String.fromCodePoint(), broken after 0b82f1c9268c. Message-ID: details: https://hg.nginx.org/njs/rev/575c018f2206 branches: changeset: 1077:575c018f2206 user: Valentin Bartenev date: Sat Jul 27 21:12:32 2019 +0300 description: Fixed String.fromCodePoint(), broken after 0b82f1c9268c. As it turned out, fromCodePoint() has shared the same handler with fromCharCode(), but according to the specification these functions have different semantics. As a result, before 0b82f1c9268c both functions had behaviour of fromCodePoint(), while after the change they had behaviour of fromCharCode(). So, the fix is to revert back the code used before the change, but only for fromCodePoint(). diffstat: njs/njs_string.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++- njs/test/njs_unit_test.c | 44 ++++++++++++++++++++++++++++------- 2 files changed, 94 insertions(+), 10 deletions(-) diffs (174 lines): diff -r cba3bd29f263 -r 575c018f2206 njs/njs_string.c --- a/njs/njs_string.c Sat Jul 27 17:03:02 2019 +0300 +++ b/njs/njs_string.c Sat Jul 27 21:12:32 2019 +0300 @@ -58,6 +58,8 @@ static void njs_string_slice_args(njs_sl nxt_uint_t nargs); static njs_ret_t njs_string_from_char_code(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +static njs_ret_t njs_string_from_code_point(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); static njs_ret_t njs_string_bytes_from(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static njs_ret_t njs_string_bytes_from_array(njs_vm_t *vm, @@ -608,7 +610,7 @@ static const njs_object_prop_t njs_stri { .type = NJS_METHOD, .name = njs_string("fromCodePoint"), - .value = njs_native_function(njs_string_from_char_code, 0), + .value = njs_native_function(njs_string_from_code_point, 0), .writable = 1, .configurable = 1, }, @@ -1730,6 +1732,62 @@ njs_string_from_char_code(njs_vm_t *vm, static njs_ret_t +njs_string_from_code_point(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + u_char *p; + double num; + size_t size; + int32_t code; + njs_ret_t ret; + nxt_uint_t i; + + for (i = 1; i < nargs; i++) { + if (!njs_is_numeric(&args[i])) { + ret = njs_value_to_numeric(vm, &args[i], &args[i]); + if (ret != NXT_OK) { + return ret; + } + } + } + + size = 0; + + for (i = 1; i < nargs; i++) { + num = njs_number(&args[i]); + if (isnan(num)) { + goto range_error; + } + + code = num; + + if (code != num || code < 0 || code >= 0x110000) { + goto range_error; + } + + size += nxt_utf8_size(code); + } + + p = njs_string_alloc(vm, &vm->retval, size, nargs - 1); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + for (i = 1; i < nargs; i++) { + p = nxt_utf8_encode(p, njs_number(&args[i])); + } + + return NXT_OK; + +range_error: + + njs_range_error(vm, NULL); + + return NXT_ERROR; +} + + +static njs_ret_t njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { diff -r cba3bd29f263 -r 575c018f2206 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Jul 27 17:03:02 2019 +0300 +++ b/njs/test/njs_unit_test.c Sat Jul 27 21:12:32 2019 +0300 @@ -5348,20 +5348,32 @@ static njs_unit_test_t njs_test[] = { nxt_string("String.fromCharCode('_').charCodeAt(0)"), nxt_string("0") }, + { nxt_string("String.fromCodePoint('_')"), + nxt_string("RangeError") }, + { nxt_string("String.fromCharCode(65.14)"), nxt_string("A") }, + { nxt_string("String.fromCodePoint(3.14)"), + nxt_string("RangeError") }, + { nxt_string("String.fromCharCode(65.14 + 65536)"), nxt_string("A") }, + { nxt_string("String.fromCodePoint(65 + 65536)"), + nxt_string("?") }, + { nxt_string("String.fromCharCode(2**53 + 10)"), nxt_string("\n") }, - { nxt_string("String.fromCharCode(65, 90)"), - nxt_string("AZ") }, - - { nxt_string("String.fromCharCode(945, 946, 947)"), - nxt_string("???") }, + { nxt_string("String.fromCodePoint(1114111 + 1)"), + nxt_string("RangeError") }, + + { nxt_string("String.fromCharCode(65, 90) + String.fromCodePoint(65, 90)"), + nxt_string("AZAZ") }, + + { nxt_string("String.fromCharCode(945, 946, 947) + String.fromCodePoint(945, 946, 947)"), + nxt_string("??????") }, { nxt_string("(function() {" " var n;" @@ -5373,6 +5385,18 @@ static njs_unit_test_t njs_test[] = "})()"), nxt_string("65536") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long test under MSAN */ + { nxt_string("(function() {" + " var n;" + " for (n = 0; n <= 1114111; n++) {" + " if (String.fromCodePoint(n).codePointAt(0) !== n)" + " return n;" + " }" + " return -1" + "})()"), + nxt_string("-1") }, +#endif + { nxt_string("var a = 'abcdef'; function f(a) {" "return a.slice(a.indexOf('cd')) } f(a)"), nxt_string("cdef") }, @@ -5579,9 +5603,10 @@ static njs_unit_test_t njs_test[] = { nxt_string("['?', '?', '?'.toUpperCase(), '?'.toLowerCase()].map((v)=>v.toUTF8().length)"), nxt_string("2,3,3,2") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long tests under MSAN */ { nxt_string("var a = [], code;" - "for (code = 0; code < 65536; code++) {" - " var s = String.fromCharCode(code);" + "for (code = 0; code <= 1114111; code++) {" + " var s = String.fromCodePoint(code);" " var n = s.toUpperCase();" " if (s != n && s != n.toLowerCase())" " a.push(code);" @@ -5589,13 +5614,14 @@ static njs_unit_test_t njs_test[] = nxt_string("181,305,383,453,456,459,498,837,962,976,977,981,982,1008,1009,1013,7296,7297,7298,7299,7300,7301,7302,7303,7304,7835,8126") }, { nxt_string("var a = [], code;" - "for (code = 0; code < 65536; code++) {" - " var s = String.fromCharCode(code);" + "for (code = 0; code <= 1114111; code++) {" + " var s = String.fromCodePoint(code);" " var n = s.toLowerCase();" " if (s != n && s != n.toUpperCase())" " a.push(code);" "} a"), nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, +#endif { nxt_string("'abc'.trim()"), nxt_string("abc") }, From vbart at nginx.com Sun Jul 28 10:16:22 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sun, 28 Jul 2019 10:16:22 +0000 Subject: [njs] Updated the list of space separators in String.prototype.trim(). Message-ID: details: https://hg.nginx.org/njs/rev/ac39f4c902b5 branches: changeset: 1078:ac39f4c902b5 user: Valentin Bartenev date: Sun Jul 28 13:17:13 2019 +0300 description: Updated the list of space separators in String.prototype.trim(). According to the specification it must include all Unicode code points listed in the "Space_Separator" (Zs) category. diffstat: njs/njs_string.c | 30 ++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 10 ++++++++++ 2 files changed, 40 insertions(+), 0 deletions(-) diffs (71 lines): diff -r 575c018f2206 -r ac39f4c902b5 njs/njs_string.c --- a/njs/njs_string.c Sat Jul 27 21:12:32 2019 +0300 +++ b/njs/njs_string.c Sun Jul 28 13:17:13 2019 +0300 @@ -2425,8 +2425,23 @@ njs_string_prototype_trim(njs_vm_t *vm, case 0x000D: /* */ case 0x0020: /* */ case 0x00A0: /* */ + case 0x1680: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200A: case 0x2028: /* */ case 0x2029: /* */ + case 0x202F: + case 0x205F: + case 0x3000: case 0xFEFF: /* */ trim++; continue; @@ -2448,8 +2463,23 @@ njs_string_prototype_trim(njs_vm_t *vm, case 0x000D: /* */ case 0x0020: /* */ case 0x00A0: /* */ + case 0x1680: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200A: case 0x2028: /* */ case 0x2029: /* */ + case 0x202F: + case 0x205F: + case 0x3000: case 0xFEFF: /* */ trim++; continue; diff -r 575c018f2206 -r ac39f4c902b5 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Jul 27 21:12:32 2019 +0300 +++ b/njs/test/njs_unit_test.c Sun Jul 28 13:17:13 2019 +0300 @@ -5653,6 +5653,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\\u2029abc\\uFEFF\\u2028'.trim()"), nxt_string("abc") }, +#if (!NXT_HAVE_MEMORY_SANITIZER) /* very long test under MSAN */ + { nxt_string("var a = [], code;" + "for (code = 0; code <= 1114111; code++) {" + " var ws = String.fromCodePoint(code);" + " if ((ws + '-' + ws).trim() === '-')" + " a.push(code);" + "} a"), + nxt_string("9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288,65279") }, +#endif + { nxt_string("'abcdefgh'.search()"), nxt_string("0") }, From vbart at nginx.com Sun Jul 28 10:19:19 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sun, 28 Jul 2019 10:19:19 +0000 Subject: [njs] Added String.prototype.trimStrart() and String.prototype.trimEnd(). Message-ID: details: https://hg.nginx.org/njs/rev/258b1e34ca0f branches: changeset: 1079:258b1e34ca0f user: Valentin Bartenev date: Sun Jul 28 13:19:03 2019 +0300 description: Added String.prototype.trimStrart() and String.prototype.trimEnd(). diffstat: njs/njs_string.c | 248 ++++++++++++++++++++++++---------------------- njs/test/njs_unit_test.c | 12 +- nxt/nxt_string.h | 19 +++ nxt/nxt_utf8.h | 37 +++++++ 4 files changed, 189 insertions(+), 127 deletions(-) diffs (424 lines): diff -r ac39f4c902b5 -r 258b1e34ca0f njs/njs_string.c --- a/njs/njs_string.c Sun Jul 28 13:17:13 2019 +0300 +++ b/njs/njs_string.c Sun Jul 28 13:19:03 2019 +0300 @@ -10,6 +10,10 @@ #include +#define NJS_TRIM_START 1 +#define NJS_TRIM_END 2 + + typedef struct { u_char *start; size_t size; @@ -68,6 +72,8 @@ static njs_ret_t njs_string_bytes_from_s const njs_value_t *args, nxt_uint_t nargs); static njs_ret_t njs_string_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, nxt_bool_t starts); +static njs_ret_t njs_string_trim(njs_vm_t *vm, njs_value_t *value, + nxt_uint_t mode); static njs_ret_t njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, nxt_bool_t pad_start); static njs_ret_t njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args, @@ -2356,158 +2362,138 @@ static njs_ret_t njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { + return njs_string_trim(vm, &args[0], NJS_TRIM_START|NJS_TRIM_END); +} + + +static njs_ret_t +njs_string_prototype_trim_start(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + return njs_string_trim(vm, &args[0], NJS_TRIM_START); +} + + +static njs_ret_t +njs_string_prototype_trim_end(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + return njs_string_trim(vm, &args[0], NJS_TRIM_END); +} + + +static njs_ret_t +njs_string_trim(njs_vm_t *vm, njs_value_t *value, nxt_uint_t mode) +{ uint32_t u, trim, length; const u_char *p, *prev, *start, *end; njs_string_prop_t string; trim = 0; - njs_string_prop(&string, &args[0]); - - p = string.start; + njs_string_prop(&string, value); + + start = string.start; end = string.start + string.size; if (string.length == 0 || string.length == string.size) { /* Byte or ASCII string. */ - while (p < end) { - - switch (*p) { - case 0x09: /* */ - case 0x0A: /* */ - case 0x0B: /* */ - case 0x0C: /* */ - case 0x0D: /* */ - case 0x20: /* */ - case 0xA0: /* */ - trim++; - p++; - continue; - - default: - start = p; - p = end; - - for ( ;; ) { - p--; - - switch (*p) { - case 0x09: /* */ - case 0x0A: /* */ - case 0x0B: /* */ - case 0x0C: /* */ - case 0x0D: /* */ - case 0x20: /* */ - case 0xA0: /* */ - trim++; - continue; - - default: - p++; - goto done; - } + if (mode & NJS_TRIM_START) { + for ( ;; ) { + if (start == end) { + goto empty; + } + + if (nxt_is_whitespace(*start)) { + start++; + trim++; + continue; } + + break; + } + } + + if (mode & NJS_TRIM_END) { + for ( ;; ) { + if (start == end) { + goto empty; + } + + end--; + + if (nxt_is_whitespace(*end)) { + trim++; + continue; + } + + end++; + break; } } } else { /* UTF-8 string. */ - while (p < end) { - prev = p; - u = nxt_utf8_decode(&p, end); - - switch (u) { - case 0x0009: /* */ - case 0x000A: /* */ - case 0x000B: /* */ - case 0x000C: /* */ - case 0x000D: /* */ - case 0x0020: /* */ - case 0x00A0: /* */ - case 0x1680: - case 0x2000: - case 0x2001: - case 0x2002: - case 0x2003: - case 0x2004: - case 0x2005: - case 0x2006: - case 0x2007: - case 0x2008: - case 0x2009: - case 0x200A: - case 0x2028: /* */ - case 0x2029: /* */ - case 0x202F: - case 0x205F: - case 0x3000: - case 0xFEFF: /* */ - trim++; - continue; - - default: - start = prev; - prev = end; - - for ( ;; ) { - prev = nxt_utf8_prev(prev); - p = prev; - u = nxt_utf8_decode(&p, end); - - switch (u) { - case 0x0009: /* */ - case 0x000A: /* */ - case 0x000B: /* */ - case 0x000C: /* */ - case 0x000D: /* */ - case 0x0020: /* */ - case 0x00A0: /* */ - case 0x1680: - case 0x2000: - case 0x2001: - case 0x2002: - case 0x2003: - case 0x2004: - case 0x2005: - case 0x2006: - case 0x2007: - case 0x2008: - case 0x2009: - case 0x200A: - case 0x2028: /* */ - case 0x2029: /* */ - case 0x202F: - case 0x205F: - case 0x3000: - case 0xFEFF: /* */ - trim++; - continue; - - default: - goto done; - } + if (mode & NJS_TRIM_START) { + for ( ;; ) { + if (start == end) { + goto empty; + } + + p = start; + u = nxt_utf8_decode(&start, end); + + if (nxt_utf8_is_whitespace(u)) { + trim++; + continue; } + + start = p; + break; + } + } + + if (mode & NJS_TRIM_END) { + prev = end; + + for ( ;; ) { + if (start == prev) { + goto empty; + } + + prev = nxt_utf8_prev(prev); + p = prev; + u = nxt_utf8_decode(&p, end); + + if (nxt_utf8_is_whitespace(u)) { + trim++; + continue; + } + + end = p; + break; } } } - vm->retval = njs_string_empty; - - return NXT_OK; - -done: - if (trim == 0) { /* GC: retain. */ - vm->retval = args[0]; + vm->retval = *value; return NXT_OK; } length = (string.length != 0) ? string.length - trim : 0; - return njs_string_new(vm, &vm->retval, start, p - start, length); + return njs_string_new(vm, &vm->retval, start, end - start, length); + +empty: + + vm->retval = njs_string_empty; + + return NXT_OK; } @@ -4250,6 +4236,26 @@ static const njs_object_prop_t njs_stri .configurable = 1, }, + /* ES10. */ + { + .type = NJS_METHOD, + .name = njs_string("trimStart"), + .value = njs_native_function(njs_string_prototype_trim_start, + NJS_STRING_OBJECT_ARG), + .writable = 1, + .configurable = 1, + }, + + /* ES10. */ + { + .type = NJS_METHOD, + .name = njs_string("trimEnd"), + .value = njs_native_function(njs_string_prototype_trim_end, + NJS_STRING_OBJECT_ARG), + .writable = 1, + .configurable = 1, + }, + /* ES6. */ { .type = NJS_METHOD, diff -r ac39f4c902b5 -r 258b1e34ca0f njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sun Jul 28 13:17:13 2019 +0300 +++ b/njs/test/njs_unit_test.c Sun Jul 28 13:19:03 2019 +0300 @@ -5623,7 +5623,7 @@ static njs_unit_test_t njs_test[] = nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, #endif - { nxt_string("'abc'.trim()"), + { nxt_string("'abc'.trimStart().trim().trimEnd()"), nxt_string("abc") }, { nxt_string("''.trim()"), @@ -5632,22 +5632,22 @@ static njs_unit_test_t njs_test[] = { nxt_string("' '.trim()"), nxt_string("") }, - { nxt_string("'abc '.trim()"), + { nxt_string("'abc '.trimEnd()"), nxt_string("abc") }, - { nxt_string("' abc'.trim()"), + { nxt_string("' abc'.trimStart()"), nxt_string("abc") }, { nxt_string("' abc '.trim()"), nxt_string("abc") }, - { nxt_string("'??? '.trim()"), + { nxt_string("'??? '.trimEnd()"), nxt_string("???") }, - { nxt_string("' ???'.trim()"), + { nxt_string("' ???'.trimStart()"), nxt_string("???") }, - { nxt_string("' ??? '.trim()"), + { nxt_string("' ??? '.trimStart().trimEnd()"), nxt_string("???") }, { nxt_string("'\\u2029abc\\uFEFF\\u2028'.trim()"), diff -r ac39f4c902b5 -r 258b1e34ca0f nxt/nxt_string.h --- a/nxt/nxt_string.h Sun Jul 28 13:17:13 2019 +0300 +++ b/nxt/nxt_string.h Sun Jul 28 13:19:03 2019 +0300 @@ -41,6 +41,25 @@ nxt_upper_case(u_char c) } +nxt_inline nxt_bool_t +nxt_is_whitespace(u_char c) +{ + switch (c) { + case 0x09: /* */ + case 0x0A: /* */ + case 0x0B: /* */ + case 0x0C: /* */ + case 0x0D: /* */ + case 0x20: /* */ + case 0xA0: /* */ + return 1; + + default: + return 0; + } +} + + nxt_inline u_char * nxt_strlchr(u_char *p, u_char *last, u_char c) { diff -r ac39f4c902b5 -r 258b1e34ca0f nxt/nxt_utf8.h --- a/nxt/nxt_utf8.h Sun Jul 28 13:17:13 2019 +0300 +++ b/nxt/nxt_utf8.h Sun Jul 28 13:19:03 2019 +0300 @@ -122,4 +122,41 @@ nxt_utf8_copy(u_char *dst, const u_char ((u < 0x80) ? 1 : ((u < 0x0800) ? 2 : 3)) +nxt_inline nxt_bool_t +nxt_utf8_is_whitespace(uint32_t c) +{ + switch (c) { + case 0x0009: /* */ + case 0x000A: /* */ + case 0x000B: /* */ + case 0x000C: /* */ + case 0x000D: /* */ + case 0x0020: /* */ + case 0x00A0: /* */ + case 0x1680: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200A: + case 0x2028: /* */ + case 0x2029: /* */ + case 0x202F: + case 0x205F: + case 0x3000: + case 0xFEFF: /* */ + return 1; + + default: + return 0; + } +} + + #endif /* _NXT_UTF8_H_INCLUDED_ */ From vbart at nginx.com Sun Jul 28 12:56:49 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sun, 28 Jul 2019 12:56:49 +0000 Subject: [njs] Slight improvements to njs_vmcode_interpreter(). Message-ID: details: https://hg.nginx.org/njs/rev/07989e97b198 branches: changeset: 1080:07989e97b198 user: Valentin Bartenev date: Sun Jul 28 15:00:40 2019 +0300 description: Slight improvements to njs_vmcode_interpreter(). No functional changes. diffstat: njs/njs_vmcode.c | 26 +++++++++----------------- 1 files changed, 9 insertions(+), 17 deletions(-) diffs (74 lines): diff -r 258b1e34ca0f -r 07989e97b198 njs/njs_vmcode.c --- a/njs/njs_vmcode.c Sun Jul 28 13:19:03 2019 +0300 +++ b/njs/njs_vmcode.c Sun Jul 28 15:00:40 2019 +0300 @@ -379,13 +379,7 @@ next: || (!isnan(exponent) && !isinf(exponent))); - if (valid) { - num = pow(num, exponent); - - } else { - num = NAN; - } - + num = valid ? pow(num, exponent) : NAN; break; case NJS_VMCODE_DIVISION: @@ -399,19 +393,19 @@ next: case NJS_VMCODE_BITWISE_AND: case NJS_VMCODE_BITWISE_OR: case NJS_VMCODE_BITWISE_XOR: - i32 = njs_number_to_int32(num); + i32 = njs_number_to_int32(njs_number(value2)); switch (op) { case NJS_VMCODE_BITWISE_AND: - i32 = i32 & njs_number_to_int32(njs_number(value2)); + i32 &= njs_number_to_int32(num); break; case NJS_VMCODE_BITWISE_OR: - i32 = i32 | njs_number_to_int32(njs_number(value2)); + i32 |= njs_number_to_int32(num); break; case NJS_VMCODE_BITWISE_XOR: - i32 = i32 ^ njs_number_to_int32(njs_number(value2)); + i32 ^= njs_number_to_int32(num); break; } @@ -419,7 +413,7 @@ next: goto next; default: - u32 = njs_number_to_uint32(njs_number(value2)); + u32 = njs_number_to_uint32(njs_number(value2)) & 0x1f; switch (op) { case NJS_VMCODE_LEFT_SHIFT: @@ -427,19 +421,17 @@ next: i32 = njs_number_to_int32(num); if (op == NJS_VMCODE_LEFT_SHIFT) { - i32 <<= u32 & 0x1f; + i32 <<= u32; } else { - i32 >>= u32 & 0x1f; + i32 >>= u32; } njs_set_int32(retval, i32); - break; default: /* NJS_VMCODE_UNSIGNED_RIGHT_SHIFT */ njs_set_uint32(retval, - njs_number_to_uint32(num) - >> (u32 & 0x1f)); + njs_number_to_uint32(num) >> u32); } goto next; From vbart at nginx.com Sun Jul 28 14:20:54 2019 From: vbart at nginx.com (Valentin Bartenev) Date: Sun, 28 Jul 2019 14:20:54 +0000 Subject: [njs] Fixed undefined behaviour in left shift of negative numbers. Message-ID: details: https://hg.nginx.org/njs/rev/6be62551e6d4 branches: changeset: 1081:6be62551e6d4 user: Valentin Bartenev date: Sun Jul 28 17:19:51 2019 +0300 description: Fixed undefined behaviour in left shift of negative numbers. Now it's implementation defined. diffstat: njs/njs_vmcode.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 07989e97b198 -r 6be62551e6d4 njs/njs_vmcode.c --- a/njs/njs_vmcode.c Sun Jul 28 15:00:40 2019 +0300 +++ b/njs/njs_vmcode.c Sun Jul 28 17:19:51 2019 +0300 @@ -421,7 +421,8 @@ next: i32 = njs_number_to_int32(num); if (op == NJS_VMCODE_LEFT_SHIFT) { - i32 <<= u32; + /* Shifting of negative numbers is undefined. */ + i32 = (uint32_t) i32 << u32; } else { i32 >>= u32; } From witekfl at gazeta.pl Sun Jul 28 14:32:18 2019 From: witekfl at gazeta.pl (Witold Filipczyk) Date: Sun, 28 Jul 2019 16:32:18 +0200 Subject: zero size buf in writer in 1.17.2 Message-ID: <20190728143218.GA15027@lenovo> Hi, There is error in log: 2019/07/28 09:46:10 [alert] 2471467#2471467: *407 zero size buf in writer t:1 r:1 f:0 00007F482A259000 00007F482A259000-00007F482A259000 0000000000000000 0-0 while sending response to client, client: 127.0.0.1, server: localhost, request: "GET /Skrypty-m.js HTTP/1.1", host: "localhost" Reproducible at least on two machines. #!/bin/bash set -x VER=1.17.2 rm -rf nginx-$VER tar zxvf nginx-$VER.tar.gz cd nginx-$VER ./configure \ --with-cc-opt="-march=native -mtune=native" \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --http-log-path=/var/log/nginx/access.log \ --http-client-body-temp-path=/var/lib/nginx/body \ --http-proxy-temp-path=/var/lib/nginx/proxy \ --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ --with-http_stub_status_module \ --without-http_geo_module \ --without-http_memcached_module \ --without-http_scgi_module \ --without-http_autoindex_module \ --without-http_ssi_module \ --without-http_browser_module \ --with-pcre-jit \ --with-http_ssl_module \ --with-http_sub_module \ --with-http_addition_module \ --with-http_auth_request_module \ --with-threads \ --with-http_v2_module \ --with-http_gzip_static_module nginx.conf: user nginx http; error_log /var/log/nginx/error.log debug; pid /var/run/nginx-standard.pid; events { worker_connections 48; use epoll; } http { include /etc/nginx/mime.types; include /etc/nginx/fastcgi_params; default_type text/plain; gzip on; gzip_http_version 1.1; gzip_vary on; gzip_comp_level 6; gzip_proxied any; gzip_min_length 1024; gzip_buffers 32 4k; gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/font-sfnt; server { listen 80; server_name localhost; access_log /var/log/nginx/nginx-standard_access.log main; location = /Skrypty-m.js { root /var/www; } } } Skrypty-m.js in the attachment. The error does not occur in 1.17.1 and earlier. -------------- next part -------------- A non-text attachment was scrubbed... Name: Skrypty-m.js Type: application/javascript Size: 14920 bytes Desc: not available URL: From xeioex at nginx.com Mon Jul 29 13:23:43 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 29 Jul 2019 13:23:43 +0000 Subject: [njs] Style. Message-ID: details: https://hg.nginx.org/njs/rev/57a50d1ad5cc branches: changeset: 1083:57a50d1ad5cc user: hongzhidao date: Fri Jul 26 23:01:38 2019 -0400 description: Style. diffstat: njs/njs_object_property.c | 2 +- njs/njs_vmcode.c | 6 +++--- njs/njs_vmcode.h | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diffs (54 lines): diff -r 19aec8a00867 -r 57a50d1ad5cc njs/njs_object_property.c --- a/njs/njs_object_property.c Mon Jul 29 16:22:39 2019 +0300 +++ b/njs/njs_object_property.c Fri Jul 26 23:01:38 2019 -0400 @@ -322,7 +322,7 @@ njs_string_property_query(njs_vm_t *vm, pq->lhq.value = prop; if (pq->query != NJS_PROPERTY_QUERY_GET) { - /* pq->lhq.key is used by njs_vmcode_property_set for TypeError */ + /* pq->lhq.key is used by NJS_VMCODE_PROPERTY_SET for TypeError */ njs_uint32_to_string(&pq->value, index); njs_string_get(&pq->value, &pq->lhq.key); } diff -r 19aec8a00867 -r 57a50d1ad5cc njs/njs_vmcode.c --- a/njs/njs_vmcode.c Mon Jul 29 16:22:39 2019 +0300 +++ b/njs/njs_vmcode.c Fri Jul 26 23:01:38 2019 -0400 @@ -14,7 +14,7 @@ struct njs_property_next_s { njs_array_t *array; }; -static njs_ret_t njs_vmcode_object(njs_vm_t *vm, u_char *pc); +static njs_ret_t njs_vmcode_object(njs_vm_t *vm); static njs_ret_t njs_vmcode_array(njs_vm_t *vm, u_char *pc); static njs_ret_t njs_vmcode_function(njs_vm_t *vm, u_char *pc); static njs_ret_t njs_vmcode_arguments(njs_vm_t *vm, u_char *pc); @@ -532,7 +532,7 @@ next: goto next; case NJS_VMCODE_OBJECT: - ret = njs_vmcode_object(vm, pc); + ret = njs_vmcode_object(vm); break; case NJS_VMCODE_ARRAY: @@ -871,7 +871,7 @@ done: static njs_ret_t -njs_vmcode_object(njs_vm_t *vm, u_char *pc) +njs_vmcode_object(njs_vm_t *vm) { njs_object_t *object; diff -r 19aec8a00867 -r 57a50d1ad5cc njs/njs_vmcode.h --- a/njs/njs_vmcode.h Mon Jul 29 16:22:39 2019 +0300 +++ b/njs/njs_vmcode.h Fri Jul 26 23:01:38 2019 -0400 @@ -374,6 +374,7 @@ typedef struct { } njs_vmcode_reference_error_t; -nxt_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *code); +nxt_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc); + #endif /* _NJS_VMCODE_H_INCLUDED_ */ From xeioex at nginx.com Mon Jul 29 13:23:42 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 29 Jul 2019 13:23:42 +0000 Subject: [njs] Removed dead store assignment in njs_vmcode_interpreter(). Message-ID: details: https://hg.nginx.org/njs/rev/19aec8a00867 branches: changeset: 1082:19aec8a00867 user: Dmitry Volyntsev date: Mon Jul 29 16:22:39 2019 +0300 description: Removed dead store assignment in njs_vmcode_interpreter(). diffstat: njs/njs_vmcode.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diffs (37 lines): diff -r 6be62551e6d4 -r 19aec8a00867 njs/njs_vmcode.c --- a/njs/njs_vmcode.c Sun Jul 28 17:19:51 2019 +0300 +++ b/njs/njs_vmcode.c Mon Jul 29 16:22:39 2019 +0300 @@ -54,7 +54,7 @@ static njs_ret_t njs_vmcode_try_end(njs_ njs_value_t *offset); static njs_ret_t njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval, u_char *pc); -static njs_ret_t njs_vmcode_reference_error(njs_vm_t *vm, u_char *pc); +static void njs_vmcode_reference_error(njs_vm_t *vm, u_char *pc); /* * These functions are forbidden to inline to minimize JavaScript VM @@ -806,7 +806,7 @@ next: break; case NJS_VMCODE_REFERENCE_ERROR: - ret = njs_vmcode_reference_error(vm, pc); + njs_vmcode_reference_error(vm, pc); goto error; default: @@ -2000,7 +2000,7 @@ njs_vmcode_finally(njs_vm_t *vm, njs_val } -static njs_ret_t +static void njs_vmcode_reference_error(njs_vm_t *vm, u_char *pc) { nxt_str_t *file; @@ -2018,6 +2018,4 @@ njs_vmcode_reference_error(njs_vm_t *vm, njs_reference_error(vm, "\"%V\" is not defined in %uD", &ref_err->name, ref_err->token_line); } - - return NJS_ERROR; } From xeioex at nginx.com Mon Jul 29 14:33:32 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 29 Jul 2019 14:33:32 +0000 Subject: [njs] Moving ctor from njs_vmcode_t to corresponding structure. Message-ID: details: https://hg.nginx.org/njs/rev/44d40e75aadf branches: changeset: 1084:44d40e75aadf user: hongzhidao date: Sun Jul 28 02:26:23 2019 -0400 description: Moving ctor from njs_vmcode_t to corresponding structure. diffstat: njs/njs_disassembler.c | 6 +++--- njs/njs_generator.c | 6 +++--- njs/njs_vmcode.c | 6 +++--- njs/njs_vmcode.h | 4 +++- 4 files changed, 12 insertions(+), 10 deletions(-) diffs (125 lines): diff -r 57a50d1ad5cc -r 44d40e75aadf njs/njs_disassembler.c --- a/njs/njs_disassembler.c Fri Jul 26 23:01:38 2019 -0400 +++ b/njs/njs_disassembler.c Sun Jul 28 02:26:23 2019 -0400 @@ -196,7 +196,7 @@ njs_disassemble(u_char *start, u_char *e nxt_printf("%05uz ARRAY %04Xz %uz%s\n", p - start, (size_t) array->retval, - (size_t) array->length, array->code.ctor ? " INIT" : ""); + (size_t) array->length, array->ctor ? " INIT" : ""); p += sizeof(njs_vmcode_array_t); @@ -282,7 +282,7 @@ njs_disassemble(u_char *start, u_char *e nxt_printf("%05uz FUNCTION FRAME %04Xz %uz%s\n", p - start, (size_t) function->name, function->nargs, - function->code.ctor ? " CTOR" : ""); + function->ctor ? " CTOR" : ""); p += sizeof(njs_vmcode_function_frame_t); @@ -295,7 +295,7 @@ njs_disassemble(u_char *start, u_char *e nxt_printf("%05uz METHOD FRAME %04Xz %04Xz %uz%s\n", p - start, (size_t) method->object, (size_t) method->method, method->nargs, - method->code.ctor ? " CTOR" : ""); + method->ctor ? " CTOR" : ""); p += sizeof(njs_vmcode_method_frame_t); continue; diff -r 57a50d1ad5cc -r 44d40e75aadf njs/njs_generator.c --- a/njs/njs_generator.c Fri Jul 26 23:01:38 2019 -0400 +++ b/njs/njs_generator.c Sun Jul 28 02:26:23 2019 -0400 @@ -1907,7 +1907,7 @@ njs_generate_array(njs_vm_t *vm, njs_gen njs_generate_code(generator, njs_vmcode_array_t, array, NJS_VMCODE_ARRAY, 1, 1); - array->code.ctor = node->ctor; + array->ctor = node->ctor; array->retval = node->index; array->length = node->u.length; @@ -2605,7 +2605,7 @@ njs_generate_function_call(njs_vm_t *vm, njs_generate_code(generator, njs_vmcode_function_frame_t, func, NJS_VMCODE_FUNCTION_FRAME, 2, 0); func_offset = njs_code_offset(generator, func); - func->code.ctor = node->ctor; + func->ctor = node->ctor; func->name = name->index; ret = njs_generate_call(vm, generator, node); @@ -2649,7 +2649,7 @@ njs_generate_method_call(njs_vm_t *vm, n njs_generate_code(generator, njs_vmcode_method_frame_t, method, NJS_VMCODE_METHOD_FRAME, 3, 0); method_offset = njs_code_offset(generator, method); - method->code.ctor = node->ctor; + method->ctor = node->ctor; method->object = prop->left->index; method->method = prop->right->index; diff -r 57a50d1ad5cc -r 44d40e75aadf njs/njs_vmcode.c --- a/njs/njs_vmcode.c Fri Jul 26 23:01:38 2019 -0400 +++ b/njs/njs_vmcode.c Sun Jul 28 02:26:23 2019 -0400 @@ -681,7 +681,7 @@ next: ret = njs_function_frame_create(vm, value1, &njs_value_undefined, (uintptr_t) value2, - function_frame->code.ctor); + function_frame->ctor); if (nxt_slow_path(ret != NXT_OK)) { goto error; @@ -901,7 +901,7 @@ njs_vmcode_array(njs_vm_t *vm, u_char *p if (nxt_fast_path(array != NULL)) { - if (code->code.ctor) { + if (code->ctor) { /* Array of the form [,,,], [1,,]. */ value = array->start; length = array->length; @@ -1808,7 +1808,7 @@ njs_vmcode_method_frame(njs_vm_t *vm, nj } ret = njs_function_frame_create(vm, value, object, method->nargs, - method->code.ctor); + method->ctor); if (nxt_fast_path(ret == NXT_OK)) { return sizeof(njs_vmcode_method_frame_t); diff -r 57a50d1ad5cc -r 44d40e75aadf njs/njs_vmcode.h --- a/njs/njs_vmcode.h Fri Jul 26 23:01:38 2019 -0400 +++ b/njs/njs_vmcode.h Sun Jul 28 02:26:23 2019 -0400 @@ -120,7 +120,6 @@ typedef struct { njs_vmcode_operation_t operation; uint8_t operands; /* 2 bits */ uint8_t retval; /* 1 bit */ - uint8_t ctor; /* 1 bit */ } njs_vmcode_t; @@ -182,6 +181,7 @@ typedef struct { njs_vmcode_t code; njs_index_t retval; uintptr_t length; + uint8_t ctor; /* 1 bit */ } njs_vmcode_array_t; @@ -286,6 +286,7 @@ typedef struct { njs_vmcode_t code; njs_index_t nargs; njs_index_t name; + uint8_t ctor; /* 1 bit */ } njs_vmcode_function_frame_t; @@ -294,6 +295,7 @@ typedef struct { njs_index_t nargs; njs_index_t object; njs_index_t method; + uint8_t ctor; /* 1 bit */ } njs_vmcode_method_frame_t; From xeioex at nginx.com Mon Jul 29 14:33:32 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 29 Jul 2019 14:33:32 +0000 Subject: [njs] Removed retval from njs_vmcode_t. Message-ID: details: https://hg.nginx.org/njs/rev/b685cc423391 branches: changeset: 1085:b685cc423391 user: hongzhidao date: Sun Jul 28 03:28:03 2019 -0400 description: Removed retval from njs_vmcode_t. diffstat: njs/njs_generator.c | 113 +++++++++++++++++++++++++-------------------------- njs/njs_vmcode.c | 3 +- njs/njs_vmcode.h | 3 +- 3 files changed, 60 insertions(+), 59 deletions(-) diffs (528 lines): diff -r 44d40e75aadf -r b685cc423391 njs/njs_generator.c --- a/njs/njs_generator.c Sun Jul 28 02:26:23 2019 -0400 +++ b/njs/njs_generator.c Sun Jul 28 03:28:03 2019 -0400 @@ -180,7 +180,7 @@ static nxt_int_t njs_generate_function_d njs_parser_node_t *node); -#define njs_generate_code(generator, type, _code, _operation, nargs, _retval) \ +#define njs_generate_code(generator, type, _code, _op, nargs) \ do { \ _code = (type *) njs_generate_reserve(vm, generator, sizeof(type)); \ if (nxt_slow_path(_code == NULL)) { \ @@ -189,16 +189,15 @@ static nxt_int_t njs_generate_function_d \ generator->code_end += sizeof(type); \ \ - _code->code.operation = _operation; \ + _code->code.operation = _op; \ _code->code.operands = 3 - nargs; \ - _code->code.retval = _retval; \ } while (0) #define njs_generate_code_jump(generator, _code, _offset) \ do { \ njs_generate_code(generator, njs_vmcode_jump_t, _code, \ - NJS_VMCODE_JUMP, 0, 0); \ + NJS_VMCODE_JUMP, 0); \ _code->offset = _offset; \ } while (0) @@ -206,7 +205,7 @@ static nxt_int_t njs_generate_function_d #define njs_generate_code_move(generator, _code, _dst, _src) \ do { \ njs_generate_code(generator, njs_vmcode_move_t, _code, \ - NJS_VMCODE_MOVE, 2, 1); \ + NJS_VMCODE_MOVE, 2); \ _code->dst = _dst; \ _code->src = _src; \ } while (0) @@ -562,7 +561,7 @@ njs_generate_name(njs_vm_t *vm, njs_gene } njs_generate_code(generator, njs_vmcode_object_copy_t, copy, - NJS_VMCODE_OBJECT_COPY, 2, 1); + NJS_VMCODE_OBJECT_COPY, 2); copy->retval = node->index; copy->object = var->index; @@ -591,7 +590,7 @@ njs_generate_builtin_object(njs_vm_t *vm } njs_generate_code(generator, njs_vmcode_object_copy_t, copy, - NJS_VMCODE_OBJECT_COPY, 2, 1); + NJS_VMCODE_OBJECT_COPY, 2); copy->retval = node->index; copy->object = index; @@ -680,7 +679,7 @@ njs_generate_if_statement(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - NJS_VMCODE_IF_FALSE_JUMP, 2, 0); + NJS_VMCODE_IF_FALSE_JUMP, 2); cond_jump->cond = node->left->index; ret = njs_generate_node_index_release(vm, generator, node->left); @@ -755,7 +754,7 @@ njs_generate_cond_expression(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - NJS_VMCODE_IF_FALSE_JUMP, 2, 0); + NJS_VMCODE_IF_FALSE_JUMP, 2); cond_jump_offset = njs_code_offset(generator, cond_jump); cond_jump->cond = node->left->index; @@ -875,7 +874,7 @@ njs_generate_switch_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_equal_jump_t, equal, - NJS_VMCODE_IF_EQUAL_JUMP, 3, 0); + NJS_VMCODE_IF_EQUAL_JUMP, 3); equal->offset = offsetof(njs_vmcode_equal_jump_t, offset); equal->value1 = index; equal->value2 = node->left->index; @@ -998,7 +997,7 @@ njs_generate_while_statement(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - NJS_VMCODE_IF_TRUE_JUMP, 2, 0); + NJS_VMCODE_IF_TRUE_JUMP, 2); cond_jump->offset = loop_offset - njs_code_offset(generator, cond_jump); cond_jump->cond = condition->index; @@ -1044,7 +1043,7 @@ njs_generate_do_while_statement(njs_vm_t } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - NJS_VMCODE_IF_TRUE_JUMP, 2, 0); + NJS_VMCODE_IF_TRUE_JUMP, 2); cond_jump->offset = loop_offset - njs_code_offset(generator, cond_jump); cond_jump->cond = condition->index; @@ -1138,7 +1137,7 @@ njs_generate_for_statement(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump, - NJS_VMCODE_IF_TRUE_JUMP, 2, 0); + NJS_VMCODE_IF_TRUE_JUMP, 2); cond_jump->offset = loop_offset - njs_code_offset(generator, cond_jump); cond_jump->cond = condition->index; @@ -1183,7 +1182,7 @@ njs_generate_for_in_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_prop_foreach_t, prop_foreach, - NJS_VMCODE_PROPERTY_FOREACH, 2, 1); + NJS_VMCODE_PROPERTY_FOREACH, 2); prop_offset = njs_code_offset(generator, prop_foreach); prop_foreach->object = foreach->right->index; @@ -1215,7 +1214,7 @@ njs_generate_for_in_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_prop_next_t, prop_next, - NJS_VMCODE_PROPERTY_NEXT, 3, 0); + NJS_VMCODE_PROPERTY_NEXT, 3); prop_offset = njs_code_offset(generator, prop_next); prop_next->retval = foreach->left->index; prop_next->object = foreach->right->index; @@ -1602,7 +1601,7 @@ njs_generate_stop_statement(njs_vm_t *vm if (nxt_fast_path(ret == NXT_OK)) { njs_generate_code(generator, njs_vmcode_stop_t, stop, - NJS_VMCODE_STOP, 1, 0); + NJS_VMCODE_STOP, 1); index = NJS_INDEX_NONE; node = node->right; @@ -1736,10 +1735,10 @@ njs_generate_assignment(njs_vm_t *vm, nj if (lvalue->token == NJS_TOKEN_PROPERTY_INIT) { njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - NJS_VMCODE_PROPERTY_INIT, 3, 0); + NJS_VMCODE_PROPERTY_INIT, 3); } else { njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - NJS_VMCODE_PROPERTY_SET, 3, 0); + NJS_VMCODE_PROPERTY_SET, 3); } prop_set->value = expr->index; @@ -1781,7 +1780,7 @@ njs_generate_operation_assignment(njs_vm /* Preserve variable value if it may be changed by expression. */ njs_generate_code(generator, njs_vmcode_move_t, move, - NJS_VMCODE_MOVE, 2, 1); + NJS_VMCODE_MOVE, 2); move->src = lvalue->index; index = njs_generate_temp_index_get(vm, generator, expr); @@ -1798,7 +1797,7 @@ njs_generate_operation_assignment(njs_vm } njs_generate_code(generator, njs_vmcode_3addr_t, code, - node->u.operation, 3, 1); + node->u.operation, 3); code->dst = lvalue->index; code->src1 = index; code->src2 = expr->index; @@ -1841,7 +1840,7 @@ njs_generate_operation_assignment(njs_vm } njs_generate_code(generator, njs_vmcode_prop_get_t, prop_get, - NJS_VMCODE_PROPERTY_GET, 3, 1); + NJS_VMCODE_PROPERTY_GET, 3); prop_get->value = index; prop_get->object = object->index; prop_get->property = property->index; @@ -1854,13 +1853,13 @@ njs_generate_operation_assignment(njs_vm } njs_generate_code(generator, njs_vmcode_3addr_t, code, - node->u.operation, 3, 1); + node->u.operation, 3); code->dst = node->index; code->src1 = node->index; code->src2 = expr->index; njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - NJS_VMCODE_PROPERTY_SET, 3, 0); + NJS_VMCODE_PROPERTY_SET, 3); prop_set->value = node->index; prop_set->object = object->index; prop_set->property = property->index; @@ -1886,7 +1885,7 @@ njs_generate_object(njs_vm_t *vm, njs_ge } njs_generate_code(generator, njs_vmcode_object_t, object, - NJS_VMCODE_OBJECT, 1, 1); + NJS_VMCODE_OBJECT, 1); object->retval = node->index; /* Initialize object. */ @@ -1906,7 +1905,7 @@ njs_generate_array(njs_vm_t *vm, njs_gen } njs_generate_code(generator, njs_vmcode_array_t, array, - NJS_VMCODE_ARRAY, 1, 1); + NJS_VMCODE_ARRAY, 1); array->ctor = node->ctor; array->retval = node->index; array->length = node->u.length; @@ -1946,7 +1945,7 @@ njs_generate_function(njs_vm_t *vm, njs_ } njs_generate_code(generator, njs_vmcode_function_t, function, - NJS_VMCODE_FUNCTION, 1, 1); + NJS_VMCODE_FUNCTION, 1); function->lambda = lambda; node->index = njs_generate_object_dest_index(vm, generator, node); @@ -1972,7 +1971,7 @@ njs_generate_regexp(njs_vm_t *vm, njs_ge } njs_generate_code(generator, njs_vmcode_regexp_t, regexp, - NJS_VMCODE_REGEXP, 1, 1); + NJS_VMCODE_REGEXP, 1); regexp->retval = node->index; regexp->pattern = node->u.value.data.u.data; @@ -1993,7 +1992,7 @@ njs_generate_template_literal(njs_vm_t * } njs_generate_code(generator, njs_vmcode_template_literal_t, code, - NJS_VMCODE_TEMPLATE_LITERAL, 1, 1); + NJS_VMCODE_TEMPLATE_LITERAL, 1); code->retval = node->left->index; node->index = node->left->index; @@ -2017,7 +2016,7 @@ njs_generate_test_jump_expression(njs_vm } njs_generate_code(generator, njs_vmcode_test_jump_t, test_jump, - node->u.operation, 2, 1); + node->u.operation, 2); jump_offset = njs_code_offset(generator, test_jump); test_jump->value = node->left->index; @@ -2073,7 +2072,7 @@ njs_generate_3addr_operation(njs_vm_t *v if (nxt_slow_path(njs_parser_has_side_effect(right))) { njs_generate_code(generator, njs_vmcode_move_t, move, - NJS_VMCODE_MOVE, 2, 1); + NJS_VMCODE_MOVE, 2); move->src = left->index; index = njs_generate_node_temp_index_get(vm, generator, left); @@ -2091,7 +2090,7 @@ njs_generate_3addr_operation(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_3addr_t, code, - node->u.operation, 3, 1); + node->u.operation, 3); if (!swap) { code->src1 = left->index; @@ -2133,7 +2132,7 @@ njs_generate_2addr_operation(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_2addr_t, code, - node->u.operation, 2, 1); + node->u.operation, 2); code->src = node->left->index; node->index = njs_generate_dest_index(vm, generator, node); @@ -2181,7 +2180,7 @@ njs_generate_typeof_operation(njs_vm_t * } njs_generate_code(generator, njs_vmcode_2addr_t, code, - node->u.operation, 2, 1); + node->u.operation, 2); code->src = node->left->index; node->index = njs_generate_dest_index(vm, generator, node); @@ -2225,7 +2224,7 @@ njs_generate_inc_dec_operation(njs_vm_t node->index = index; njs_generate_code(generator, njs_vmcode_3addr_t, code, - node->u.operation, 3, 1); + node->u.operation, 3); code->dst = index; code->src1 = lvalue->index; code->src2 = lvalue->index; @@ -2273,19 +2272,19 @@ found: } njs_generate_code(generator, njs_vmcode_prop_get_t, prop_get, - NJS_VMCODE_PROPERTY_GET, 3, 1); + NJS_VMCODE_PROPERTY_GET, 3); prop_get->value = index; prop_get->object = lvalue->left->index; prop_get->property = lvalue->right->index; njs_generate_code(generator, njs_vmcode_3addr_t, code, - node->u.operation, 3, 1); + node->u.operation, 3); code->dst = dest_index; code->src1 = index; code->src2 = index; njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - NJS_VMCODE_PROPERTY_SET, 3, 0); + NJS_VMCODE_PROPERTY_SET, 3); prop_set->value = index; prop_set->object = lvalue->left->index; prop_set->property = lvalue->right->index; @@ -2480,13 +2479,13 @@ njs_generate_lambda_variables(njs_vm_t * if (var->this_object) { njs_generate_code(generator, njs_vmcode_this_t, this, - NJS_VMCODE_THIS, 1, 0); + NJS_VMCODE_THIS, 1); this->dst = var->index; } if (var->arguments_object) { njs_generate_code(generator, njs_vmcode_arguments_t, arguments, - NJS_VMCODE_ARGUMENTS, 1, 0); + NJS_VMCODE_ARGUMENTS, 1); arguments->dst = var->index; } } @@ -2524,7 +2523,7 @@ njs_generate_return_statement(njs_vm_t * if (nxt_fast_path(immediate == NULL)) { njs_generate_code(generator, njs_vmcode_return_t, code, - NJS_VMCODE_RETURN, 1, 0); + NJS_VMCODE_RETURN, 1); code->retval = index; node->index = index; @@ -2554,7 +2553,7 @@ njs_generate_return_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_try_return_t, try_return, - NJS_VMCODE_TRY_RETURN, 2, 1); + NJS_VMCODE_TRY_RETURN, 2); try_return->retval = index; try_return->save = top->index; try_return->offset = offsetof(njs_vmcode_try_return_t, offset); @@ -2603,7 +2602,7 @@ njs_generate_function_call(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_function_frame_t, func, - NJS_VMCODE_FUNCTION_FRAME, 2, 0); + NJS_VMCODE_FUNCTION_FRAME, 2); func_offset = njs_code_offset(generator, func); func->ctor = node->ctor; func->name = name->index; @@ -2647,7 +2646,7 @@ njs_generate_method_call(njs_vm_t *vm, n } njs_generate_code(generator, njs_vmcode_method_frame_t, method, - NJS_VMCODE_METHOD_FRAME, 3, 0); + NJS_VMCODE_METHOD_FRAME, 3); method_offset = njs_code_offset(generator, method); method->ctor = node->ctor; method->object = prop->left->index; @@ -2706,7 +2705,7 @@ njs_generate_call(njs_vm_t *vm, njs_gene node->index = retval; njs_generate_code(generator, njs_vmcode_function_call_t, call, - NJS_VMCODE_FUNCTION_CALL, 1, 0); + NJS_VMCODE_FUNCTION_CALL, 1); call->retval = retval; return nargs; @@ -2716,7 +2715,7 @@ njs_generate_call(njs_vm_t *vm, njs_gene #define njs_generate_code_catch(generator, _code, _exception) \ do { \ njs_generate_code(generator, njs_vmcode_catch_t, _code, \ - NJS_VMCODE_CATCH, 2, 0); \ + NJS_VMCODE_CATCH, 2); \ _code->offset = sizeof(njs_vmcode_catch_t); \ _code->exception = _exception; \ } while (0) @@ -2725,7 +2724,7 @@ njs_generate_call(njs_vm_t *vm, njs_gene #define njs_generate_code_finally(generator, _code, _retval, _exit) \ do { \ njs_generate_code(generator, njs_vmcode_finally_t, _code, \ - NJS_VMCODE_FINALLY, 2, 0); \ + NJS_VMCODE_FINALLY, 2); \ _code->retval = _retval; \ _code->exit_value = _exit; \ _code->continue_offset = offsetof(njs_vmcode_finally_t, \ @@ -2755,7 +2754,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_vmcode_try_trampoline_t *try_break, *try_continue; njs_generate_code(generator, njs_vmcode_try_start_t, try_start, - NJS_VMCODE_TRY_START, 2, 0); + NJS_VMCODE_TRY_START, 2); try_offset = njs_code_offset(generator, try_start); exception_index = njs_generate_temp_index_get(vm, generator, node); @@ -2795,7 +2794,7 @@ njs_generate_try_statement(njs_vm_t *vm, try_cont_label = undef_label; njs_generate_code(generator, njs_vmcode_try_end_t, try_end, - NJS_VMCODE_TRY_END, 0, 0); + NJS_VMCODE_TRY_END, 0); try_end_offset = njs_code_offset(generator, try_end); if (try_block->exit != NULL) { @@ -2804,7 +2803,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_generate_patch_block(vm, generator, try_block->exit); njs_generate_code(generator, njs_vmcode_try_trampoline_t, try_break, - NJS_VMCODE_TRY_BREAK, 2, 0); + NJS_VMCODE_TRY_BREAK, 2); try_break->exit_value = exit_index; try_break->offset = -sizeof(njs_vmcode_try_end_t); @@ -2819,7 +2818,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_generate_patch_block(vm, generator, try_block->continuation); njs_generate_code(generator, njs_vmcode_try_trampoline_t, try_continue, - NJS_VMCODE_TRY_CONTINUE, 2, 0); + NJS_VMCODE_TRY_CONTINUE, 2); try_continue->exit_value = exit_index; try_continue->offset = -sizeof(njs_vmcode_try_end_t); @@ -2924,7 +2923,7 @@ njs_generate_try_statement(njs_vm_t *vm, } njs_generate_code(generator, njs_vmcode_try_end_t, catch_end, - NJS_VMCODE_TRY_END, 0, 0); + NJS_VMCODE_TRY_END, 0); catch_end_offset = njs_code_offset(generator, catch_end); if (catch_block->exit != NULL) { @@ -2933,7 +2932,7 @@ njs_generate_try_statement(njs_vm_t *vm, njs_generate_patch_block(vm, generator, catch_block->exit); njs_generate_code(generator, njs_vmcode_try_trampoline_t, - try_break, NJS_VMCODE_TRY_BREAK, 2, 0); + try_break, NJS_VMCODE_TRY_BREAK, 2); try_break->exit_value = exit_index; @@ -2950,7 +2949,7 @@ njs_generate_try_statement(njs_vm_t *vm, catch_block->continuation); njs_generate_code(generator, njs_vmcode_try_trampoline_t, - try_continue, NJS_VMCODE_TRY_CONTINUE, 2, 0); + try_continue, NJS_VMCODE_TRY_CONTINUE, 2); try_continue->exit_value = exit_index; @@ -3064,7 +3063,7 @@ njs_generate_throw_statement(njs_vm_t *v if (nxt_fast_path(ret == NXT_OK)) { njs_generate_code(generator, njs_vmcode_throw_t, throw, - NJS_VMCODE_THROW, 1, 0); + NJS_VMCODE_THROW, 1); node->index = node->right->index; throw->retval = node->index; @@ -3102,7 +3101,7 @@ njs_generate_import_statement(njs_vm_t * module = (njs_module_t *) expr->index; njs_generate_code(generator, njs_vmcode_object_copy_t, copy, - NJS_VMCODE_OBJECT_COPY, 2, 1); + NJS_VMCODE_OBJECT_COPY, 2); copy->retval = index; copy->object = module->index; @@ -3126,7 +3125,7 @@ njs_generate_export_statement(njs_vm_t * } njs_generate_code(generator, njs_vmcode_return_t, code, - NJS_VMCODE_RETURN, 1, 0); + NJS_VMCODE_RETURN, 1); code->retval = obj->index; node->index = obj->index; @@ -3297,7 +3296,7 @@ njs_generate_reference_error(njs_vm_t *v } njs_generate_code(generator, njs_vmcode_reference_error_t, ref_err, - NJS_VMCODE_REFERENCE_ERROR, 0, 0); + NJS_VMCODE_REFERENCE_ERROR, 0); ref_err->token_line = node->token_line; diff -r 44d40e75aadf -r b685cc423391 njs/njs_vmcode.c --- a/njs/njs_vmcode.c Sun Jul 28 02:26:23 2019 -0400 +++ b/njs/njs_vmcode.c Sun Jul 28 03:28:03 2019 -0400 @@ -158,7 +158,8 @@ next: * as a single unsigned comparision. */ - if (vmcode->code.retval) { + if (op > NJS_VMCODE_NORET) { + if (op == NJS_VMCODE_MOVE) { retval = njs_vmcode_operand(vm, vmcode->operand1); *retval = *value1; diff -r 44d40e75aadf -r b685cc423391 njs/njs_vmcode.h --- a/njs/njs_vmcode.h Sun Jul 28 02:26:23 2019 -0400 +++ b/njs/njs_vmcode.h Sun Jul 28 03:28:03 2019 -0400 @@ -60,6 +60,8 @@ typedef uint8_t #define NJS_VMCODE_FINALLY VMCODE0(39) #define NJS_VMCODE_REFERENCE_ERROR VMCODE0(40) +#define NJS_VMCODE_NORET 127 + #define NJS_VMCODE_MOVE VMCODE1(0) #define NJS_VMCODE_PROPERTY_GET VMCODE1(1) #define NJS_VMCODE_INCREMENT VMCODE1(2) @@ -119,7 +121,6 @@ typedef uint8_t typedef struct { njs_vmcode_operation_t operation; uint8_t operands; /* 2 bits */ - uint8_t retval; /* 1 bit */ } njs_vmcode_t; From mdounin at mdounin.ru Mon Jul 29 16:48:41 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 29 Jul 2019 19:48:41 +0300 Subject: zero size buf in writer in 1.17.2 In-Reply-To: <20190728143218.GA15027@lenovo> References: <20190728143218.GA15027@lenovo> Message-ID: <20190729164841.GC1877@mdounin.ru> Hello! On Sun, Jul 28, 2019 at 04:32:18PM +0200, Witold Filipczyk wrote: > Hi, > There is error in log: > 2019/07/28 09:46:10 [alert] 2471467#2471467: *407 zero size buf in writer t:1 r:1 f:0 00007F482A259000 00007F482A259000-00007F482A259000 0000000000000000 0-0 while sending response to client, client: 127.0.0.1, server: localhost, request: "GET /Skrypty-m.js HTTP/1.1", host: "localhost" > > Reproducible at least on two machines. [...] > Skrypty-m.js in the attachment. > The error does not occur in 1.17.1 and earlier. Thank you for the report, it seems to be a problem introduced in ac5a741d39cf. I'm able to reproduce it with the file and gzip configuration provided. The following patch should fix this: # HG changeset patch # User Maxim Dounin # Date 1564415524 -10800 # Mon Jul 29 18:52:04 2019 +0300 # Node ID aff4d33c72d8ee1a986d3e4c8e5c0f3d1b20962f # Parent e7181cfe9212de7f67df805bb746519c059b490b Gzip: fixed "zero size buf" alerts after ac5a741d39cf. After ac5a741d39cf it is now possible that after zstream.avail_out reaches 0 and we allocate additional buffer, there will be no more data to put into this buffer, triggering "zero size buf" alert. Fix is to avoid allocating additional buffer in this case, by checking if last deflate() call returned Z_STREAM_END. diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -778,7 +778,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re ctx->out_buf->last = ctx->zstream.next_out; - if (ctx->zstream.avail_out == 0) { + if (ctx->zstream.avail_out == 0 && rc != Z_STREAM_END) { /* zlib wants to output some more gzipped data */ -- Maxim Dounin http://mdounin.ru/ From witekfl at gazeta.pl Tue Jul 30 11:23:26 2019 From: witekfl at gazeta.pl (Witold Filipczyk) Date: Tue, 30 Jul 2019 13:23:26 +0200 Subject: zero size buf in writer in 1.17.2 In-Reply-To: <20190729164841.GC1877@mdounin.ru> References: <20190728143218.GA15027@lenovo> <20190729164841.GC1877@mdounin.ru> Message-ID: <20190730112326.GA7802@lenovo> On Mon, Jul 29, 2019 at 07:48:41PM +0300, Maxim Dounin wrote: > Hello! > > On Sun, Jul 28, 2019 at 04:32:18PM +0200, Witold Filipczyk wrote: > > > Hi, > > There is error in log: > > 2019/07/28 09:46:10 [alert] 2471467#2471467: *407 zero size buf in writer t:1 r:1 f:0 00007F482A259000 00007F482A259000-00007F482A259000 0000000000000000 0-0 while sending response to client, client: 127.0.0.1, server: localhost, request: "GET /Skrypty-m.js HTTP/1.1", host: "localhost" > > > > Reproducible at least on two machines. > > [...] > > > Skrypty-m.js in the attachment. > > The error does not occur in 1.17.1 and earlier. > > Thank you for the report, it seems to be a problem introduced in > ac5a741d39cf. I'm able to reproduce it with the file and gzip > configuration provided. > > The following patch should fix this: > > # HG changeset patch > # User Maxim Dounin > # Date 1564415524 -10800 > # Mon Jul 29 18:52:04 2019 +0300 > # Node ID aff4d33c72d8ee1a986d3e4c8e5c0f3d1b20962f > # Parent e7181cfe9212de7f67df805bb746519c059b490b > Gzip: fixed "zero size buf" alerts after ac5a741d39cf. > > After ac5a741d39cf it is now possible that after zstream.avail_out > reaches 0 and we allocate additional buffer, there will be no more data > to put into this buffer, triggering "zero size buf" alert. > > Fix is to avoid allocating additional buffer in this case, by checking > if last deflate() call returned Z_STREAM_END. > > diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c > --- a/src/http/modules/ngx_http_gzip_filter_module.c > +++ b/src/http/modules/ngx_http_gzip_filter_module.c > @@ -778,7 +778,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re > > ctx->out_buf->last = ctx->zstream.next_out; > > - if (ctx->zstream.avail_out == 0) { > + if (ctx->zstream.avail_out == 0 && rc != Z_STREAM_END) { > > /* zlib wants to output some more gzipped data */ > No error so far, thanks. From xeioex at nginx.com Tue Jul 30 18:12:26 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 30 Jul 2019 18:12:26 +0000 Subject: [njs] Refactored file hierarchy. Message-ID: details: https://hg.nginx.org/njs/rev/8b01e5bbbd16 branches: changeset: 1086:8b01e5bbbd16 user: Dmitry Volyntsev date: Tue Jul 30 20:11:46 2019 +0300 description: Refactored file hierarchy. 1) all source files are moved to src directory. 2) nxt files are renamed with "njs" prefix. 3) some files are renamed to avoid collisions: nxt_array.c -> njs_arr.c nxt_array.h -> njs_arr.h nxt_string.h -> njs_str.h nxt_time.c -> njs_time.c nxt_time.h -> njs_time.h njs_time.c -> njs_timer.c njs_time.h -> njs_timer.c njs_core.h -> njs_main.h 4) C tests are moved to src/test dir. 5) Other tests are moved to test dir. 6) Some structs are renamed to avoid collisions: nxt_array_t -> njs_arr_t nxt_string_t -> njs_str_t appropriate functions and macros are also renamed. 7) all macros, functions and other identifiers with "NXT_" and "nxt_" prefixes are renamed to corresponding "NJS_" or "njs_" prefix. NO functional changes. diffstat: auto/clang | 266 +- auto/define | 6 +- auto/deps | 20 +- auto/expect | 20 +- auto/explicit_bzero | 20 +- auto/feature | 86 +- auto/getrandom | 36 +- auto/make | 256 +- auto/memalign | 26 +- auto/os | 32 +- auto/pcre | 26 +- auto/readline | 54 +- auto/sources | 121 +- auto/time | 46 +- configure | 34 +- nginx/config | 4 +- nginx/ngx_http_js_module.c | 220 +- nginx/ngx_stream_js_module.c | 154 +- njs/njs.h | 307 - njs/njs_array.c | 2211 ---- njs/njs_array.h | 32 - njs/njs_boolean.c | 166 - njs/njs_boolean.h | 18 - njs/njs_builtin.c | 1355 -- njs/njs_builtin.h | 17 - njs/njs_core.h | 56 - njs/njs_crypto.c | 714 - njs/njs_crypto.h | 24 - njs/njs_date.c | 2336 ---- njs/njs_date.h | 22 - njs/njs_disassembler.c | 473 - njs/njs_error.c | 942 - njs/njs_error.h | 88 - njs/njs_event.c | 97 - njs/njs_event.h | 42 - njs/njs_extern.c | 412 - njs/njs_extern.h | 54 - njs/njs_fs.c | 1078 -- njs/njs_fs.h | 13 - njs/njs_function.c | 1264 -- njs/njs_function.h | 222 - njs/njs_generator.c | 3336 ------ njs/njs_generator.h | 34 - njs/njs_json.c | 2586 ----- njs/njs_json.h | 14 - njs/njs_lexer.c | 848 - njs/njs_lexer.h | 266 - njs/njs_lexer_keyword.c | 195 - njs/njs_math.c | 1167 -- njs/njs_math.h | 17 - njs/njs_module.c | 547 - njs/njs_module.h | 30 - njs/njs_number.c | 900 - njs/njs_number.h | 199 - njs/njs_object.c | 2293 ---- njs/njs_object.h | 148 - njs/njs_object_hash.h | 288 - njs/njs_object_property.c | 1405 -- njs/njs_parser.c | 2371 ---- njs/njs_parser.h | 277 - njs/njs_parser_expression.c | 1019 -- njs/njs_parser_terminal.c | 1316 -- njs/njs_regexp.c | 1239 -- njs/njs_regexp.h | 41 - njs/njs_regexp_pattern.h | 48 - njs/njs_shell.c | 1239 -- njs/njs_string.c | 4957 --------- njs/njs_string.h | 209 - njs/njs_time.c | 150 - njs/njs_time.h | 23 - njs/njs_value.c | 454 - njs/njs_value.h | 838 - njs/njs_variable.c | 673 - njs/njs_variable.h | 77 - njs/njs_vm.c | 1209 -- njs/njs_vm.h | 366 - njs/njs_vmcode.c | 2022 --- njs/njs_vmcode.h | 383 - njs/test/fs/ascii | 1 - njs/test/fs/non_utf8 | 1 - njs/test/fs/utf8 | 1 - njs/test/inputrc | 5 - njs/test/module/declaration_exception.js | 10 - njs/test/module/exception.js | 4 - njs/test/module/export.js | 4 - njs/test/module/export_expression.js | 10 - njs/test/module/export_expression2.js | 5 - njs/test/module/export_name.js | 6 - njs/test/module/export_non_default.js | 3 - njs/test/module/lib1.js | 19 - njs/test/module/lib2.js | 7 - njs/test/module/lib3.js | 11 - njs/test/module/libs/hash.js | 9 - njs/test/module/loading_exception.js | 3 - njs/test/module/normal.js | 41 - njs/test/module/recursive.js | 3 - njs/test/module/ref_exception.js | 1 - njs/test/module/return.js | 1 - njs/test/module/sub/sub1.js | 12 - njs/test/module/sub/sub2.js | 7 - njs/test/njs_benchmark.c | 173 - njs/test/njs_expect_test.exp | 777 - njs/test/njs_interactive_test.c | 359 - njs/test/njs_unit_test.c | 14690 ----------------------------- nxt/nxt_alignment.h | 49 - nxt/nxt_array.c | 168 - nxt/nxt_array.h | 68 - nxt/nxt_clang.h | 160 - nxt/nxt_diyfp.c | 150 - nxt/nxt_diyfp.h | 212 - nxt/nxt_djb_hash.c | 48 - nxt/nxt_djb_hash.h | 25 - nxt/nxt_dtoa.c | 376 - nxt/nxt_dtoa.h | 12 - nxt/nxt_file.c | 74 - nxt/nxt_file.h | 15 - nxt/nxt_lvlhsh.c | 859 - nxt/nxt_lvlhsh.h | 174 - nxt/nxt_malloc.c | 52 - nxt/nxt_malloc.h | 28 - nxt/nxt_md5.c | 271 - nxt/nxt_md5.h | 23 - nxt/nxt_mp.c | 818 - nxt/nxt_mp.h | 37 - nxt/nxt_murmur_hash.c | 89 - nxt/nxt_murmur_hash.h | 15 - nxt/nxt_pcre.c | 294 - nxt/nxt_pcre.h | 39 - nxt/nxt_queue.c | 87 - nxt/nxt_queue.h | 199 - nxt/nxt_random.c | 198 - nxt/nxt_random.h | 37 - nxt/nxt_rbtree.c | 535 - nxt/nxt_rbtree.h | 126 - nxt/nxt_regex.h | 45 - nxt/nxt_sha1.c | 299 - nxt/nxt_sha1.h | 24 - nxt/nxt_sha2.c | 321 - nxt/nxt_sha2.h | 24 - nxt/nxt_sprintf.c | 611 - nxt/nxt_sprintf.h | 27 - nxt/nxt_string.h | 137 - nxt/nxt_strtod.c | 404 - nxt/nxt_strtod.h | 12 - nxt/nxt_stub.h | 45 - nxt/nxt_time.c | 31 - nxt/nxt_time.h | 27 - nxt/nxt_trace.c | 57 - nxt/nxt_trace.h | 68 - nxt/nxt_types.h | 122 - nxt/nxt_unicode_lower_case.h | 1709 --- nxt/nxt_unicode_lower_case.pl | 95 - nxt/nxt_unicode_upper_case.h | 1867 --- nxt/nxt_unicode_upper_case.pl | 95 - nxt/nxt_unix.h | 23 - nxt/nxt_utf8.c | 421 - nxt/nxt_utf8.h | 162 - nxt/test/lvlhsh_unit_test.c | 276 - nxt/test/random_unit_test.c | 62 - nxt/test/rbtree_unit_test.c | 195 - nxt/test/utf8_unit_test.c | 208 - src/njs.h | 300 + src/njs_alignment.h | 49 + src/njs_arr.c | 168 + src/njs_arr.h | 67 + src/njs_array.c | 2211 ++++ src/njs_array.h | 32 + src/njs_boolean.c | 166 + src/njs_boolean.h | 18 + src/njs_builtin.c | 1355 ++ src/njs_builtin.h | 17 + src/njs_clang.h | 160 + src/njs_crypto.c | 714 + src/njs_crypto.h | 24 + src/njs_date.c | 2336 ++++ src/njs_date.h | 22 + src/njs_disassembler.c | 473 + src/njs_diyfp.c | 150 + src/njs_diyfp.h | 212 + src/njs_djb_hash.c | 48 + src/njs_djb_hash.h | 25 + src/njs_dtoa.c | 376 + src/njs_dtoa.h | 12 + src/njs_error.c | 942 + src/njs_error.h | 88 + src/njs_event.c | 97 + src/njs_event.h | 42 + src/njs_extern.c | 412 + src/njs_extern.h | 54 + src/njs_file.c | 74 + src/njs_file.h | 15 + src/njs_fs.c | 1078 ++ src/njs_fs.h | 13 + src/njs_function.c | 1264 ++ src/njs_function.h | 222 + src/njs_generator.c | 3336 ++++++ src/njs_generator.h | 34 + src/njs_json.c | 2586 +++++ src/njs_json.h | 14 + src/njs_lexer.c | 848 + src/njs_lexer.h | 266 + src/njs_lexer_keyword.c | 195 + src/njs_lvlhsh.c | 859 + src/njs_lvlhsh.h | 174 + src/njs_main.h | 56 + src/njs_malloc.c | 52 + src/njs_malloc.h | 28 + src/njs_math.c | 1167 ++ src/njs_math.h | 17 + src/njs_md5.c | 271 + src/njs_md5.h | 23 + src/njs_module.c | 547 + src/njs_module.h | 30 + src/njs_mp.c | 818 + src/njs_mp.h | 37 + src/njs_murmur_hash.c | 89 + src/njs_murmur_hash.h | 15 + src/njs_number.c | 900 + src/njs_number.h | 199 + src/njs_object.c | 2293 ++++ src/njs_object.h | 148 + src/njs_object_hash.h | 288 + src/njs_object_property.c | 1405 ++ src/njs_parser.c | 2371 ++++ src/njs_parser.h | 277 + src/njs_parser_expression.c | 1019 ++ src/njs_parser_terminal.c | 1316 ++ src/njs_pcre.c | 294 + src/njs_pcre.h | 39 + src/njs_queue.c | 87 + src/njs_queue.h | 199 + src/njs_random.c | 198 + src/njs_random.h | 37 + src/njs_rbtree.c | 535 + src/njs_rbtree.h | 126 + src/njs_regex.h | 45 + src/njs_regexp.c | 1239 ++ src/njs_regexp.h | 41 + src/njs_regexp_pattern.h | 48 + src/njs_sha1.c | 299 + src/njs_sha1.h | 24 + src/njs_sha2.c | 321 + src/njs_sha2.h | 24 + src/njs_shell.c | 1239 ++ src/njs_sprintf.c | 611 + src/njs_sprintf.h | 27 + src/njs_str.h | 137 + src/njs_string.c | 4957 +++++++++ src/njs_string.h | 209 + src/njs_strtod.c | 404 + src/njs_strtod.h | 12 + src/njs_stub.h | 45 + src/njs_time.c | 31 + src/njs_time.h | 27 + src/njs_timer.c | 150 + src/njs_timer.h | 23 + src/njs_trace.c | 57 + src/njs_trace.h | 68 + src/njs_types.h | 122 + src/njs_unicode_lower_case.h | 1709 +++ src/njs_unicode_lower_case.pl | 95 + src/njs_unicode_upper_case.h | 1867 +++ src/njs_unicode_upper_case.pl | 95 + src/njs_unix.h | 23 + src/njs_utf8.c | 421 + src/njs_utf8.h | 162 + src/njs_value.c | 454 + src/njs_value.h | 838 + src/njs_variable.c | 673 + src/njs_variable.h | 77 + src/njs_vm.c | 1209 ++ src/njs_vm.h | 366 + src/njs_vmcode.c | 2022 +++ src/njs_vmcode.h | 383 + src/test/lvlhsh_unit_test.c | 276 + src/test/njs_benchmark.c | 173 + src/test/njs_interactive_test.c | 359 + src/test/njs_unit_test.c | 14690 +++++++++++++++++++++++++++++ src/test/random_unit_test.c | 62 + src/test/rbtree_unit_test.c | 195 + src/test/utf8_unit_test.c | 208 + test/fs/ascii | 1 + test/fs/non_utf8 | 1 + test/fs/utf8 | 1 + test/inputrc | 5 + test/module/declaration_exception.js | 10 + test/module/exception.js | 4 + test/module/export.js | 4 + test/module/export_expression.js | 10 + test/module/export_expression2.js | 5 + test/module/export_name.js | 6 + test/module/export_non_default.js | 3 + test/module/lib1.js | 19 + test/module/lib2.js | 7 + test/module/lib3.js | 11 + test/module/libs/hash.js | 9 + test/module/loading_exception.js | 3 + test/module/normal.js | 41 + test/module/recursive.js | 3 + test/module/ref_exception.js | 1 + test/module/return.js | 1 + test/module/sub/sub1.js | 12 + test/module/sub/sub2.js | 7 + test/njs_expect_test.exp | 777 + 304 files changed, 74571 insertions(+), 74638 deletions(-) diffs (truncated from 151925 to 1000 lines): diff -r b685cc423391 -r 8b01e5bbbd16 auto/clang --- a/auto/clang Sun Jul 28 03:28:03 2019 -0400 +++ b/auto/clang Tue Jul 30 20:11:46 2019 +0300 @@ -4,7 +4,7 @@ $echo checking for C compiler: $CC -cat << END >> $NXT_AUTOCONF_ERR +cat << END >> $NJS_AUTOCONF_ERR ---------------------------------------- checking for C compiler: $CC END @@ -21,37 +21,37 @@ if [ -z `which $CC` ]; then fi -if `/bin/sh -c "($CC -v)" 2>&1 | grep "gcc version" >> $NXT_AUTOCONF_ERR 2>&1` +if `/bin/sh -c "($CC -v)" 2>&1 | grep "gcc version" >> $NJS_AUTOCONF_ERR 2>&1` then - NXT_CC_NAME=gcc + NJS_CC_NAME=gcc $echo " + using GNU C compiler" - NXT_CC_VERSION=`/bin/sh -c "($CC -v)" 2>&1 | grep "gcc version" 2>&1` - $echo " + $NXT_CC_VERSION" + NJS_CC_VERSION=`/bin/sh -c "($CC -v)" 2>&1 | grep "gcc version" 2>&1` + $echo " + $NJS_CC_VERSION" else -if `/bin/sh -c "($CC -v)" 2>&1 | grep "clang version" >> $NXT_AUTOCONF_ERR 2>&1` +if `/bin/sh -c "($CC -v)" 2>&1 | grep "clang version" >> $NJS_AUTOCONF_ERR 2>&1` then - NXT_CC_NAME=clang + NJS_CC_NAME=clang $echo " + using Clang C compiler" - NXT_CC_VERSION=`/bin/sh -c "($CC -v)" 2>&1 | grep "clang version" 2>&1` - $echo " + $NXT_CC_VERSION" + NJS_CC_VERSION=`/bin/sh -c "($CC -v)" 2>&1 | grep "clang version" 2>&1` + $echo " + $NJS_CC_VERSION" else if `/bin/sh -c "($CC -v)" 2>&1 \ - | grep "Apple LLVM version" >> $NXT_AUTOCONF_ERR 2>&1` + | grep "Apple LLVM version" >> $NJS_AUTOCONF_ERR 2>&1` then - NXT_CC_NAME=clang + NJS_CC_NAME=clang $echo " + using Clang C compiler" - NXT_CC_VERSION=`/bin/sh -c "($CC -v)" 2>&1 | grep "Apple LLVM version" 2>&1` - $echo " + $NXT_CC_VERSION" + NJS_CC_VERSION=`/bin/sh -c "($CC -v)" 2>&1 | grep "Apple LLVM version" 2>&1` + $echo " + $NJS_CC_VERSION" else -if `/bin/sh -c "($CC -V)" 2>&1 | grep "Sun C" >> $NXT_AUTOCONF_ERR 2>&1` +if `/bin/sh -c "($CC -V)" 2>&1 | grep "Sun C" >> $NJS_AUTOCONF_ERR 2>&1` then - NXT_CC_NAME=SunC + NJS_CC_NAME=SunC $echo " + using Sun C compiler" - NXT_CC_VERSION=`/bin/sh -c "($CC -V)" 2>&1 | grep "Sun C" 2>&1` - $echo " + $NXT_CC_VERSION" + NJS_CC_VERSION=`/bin/sh -c "($CC -V)" 2>&1 | grep "Sun C" 2>&1` + $echo " + $NJS_CC_VERSION" fi # SunC fi # Apple LLVM clang @@ -59,94 +59,94 @@ fi # clang fi # gcc -case $NXT_CC_NAME in +case $NJS_CC_NAME in gcc) - nxt_define=NXT_GCC . auto/define + njs_define=NJS_GCC . auto/define - NXT_CFLAGS="$NXT_CFLAGS -pipe" - NXT_CFLAGS="$NXT_CFLAGS -fPIC" + NJS_CFLAGS="$NJS_CFLAGS -pipe" + NJS_CFLAGS="$NJS_CFLAGS -fPIC" - # Do not export symbols except explicitly marked with NXT_EXPORT. - NXT_CFLAGS="$NXT_CFLAGS -fvisibility=hidden" + # Do not export symbols except explicitly marked with NJS_EXPORT. + NJS_CFLAGS="$NJS_CFLAGS -fvisibility=hidden" # c99/gnu99 conflict with Solaris XOPEN. - #NXT_CFLAGS="$NXT_CFLAGS -std=gnu99" + #NJS_CFLAGS="$NJS_CFLAGS -std=gnu99" - NXT_CFLAGS="$NXT_CFLAGS -O" - #NXT_CFLAGS="$NXT_CFLAGS -O0" - NXT_CFLAGS="$NXT_CFLAGS -W -Wall -Wextra" + NJS_CFLAGS="$NJS_CFLAGS -O" + #NJS_CFLAGS="$NJS_CFLAGS -O0" + NJS_CFLAGS="$NJS_CFLAGS -W -Wall -Wextra" - #NXT_CFLAGS="$NXT_CFLAGS -Wunused-result" - NXT_CFLAGS="$NXT_CFLAGS -Wno-unused-parameter" - #NXT_CFLAGS="$NXT_CFLAGS -Wshorten-64-to-32" - NXT_CFLAGS="$NXT_CFLAGS -Wwrite-strings" + #NJS_CFLAGS="$NJS_CFLAGS -Wunused-result" + NJS_CFLAGS="$NJS_CFLAGS -Wno-unused-parameter" + #NJS_CFLAGS="$NJS_CFLAGS -Wshorten-64-to-32" + NJS_CFLAGS="$NJS_CFLAGS -Wwrite-strings" # -O2 enables -fstrict-aliasing and -fstrict-overflow. - #NXT_CFLAGS="$NXT_CFLAGS -O2" - #NXT_CFLAGS="$NXT_CFLAGS -Wno-strict-aliasing" + #NJS_CFLAGS="$NJS_CFLAGS -O2" + #NJS_CFLAGS="$NJS_CFLAGS -Wno-strict-aliasing" - #NXT_CFLAGS="$NXT_CFLAGS -fomit-frame-pointer" - #NXT_CFLAGS="$NXT_CFLAGS -momit-leaf-frame-pointer" + #NJS_CFLAGS="$NJS_CFLAGS -fomit-frame-pointer" + #NJS_CFLAGS="$NJS_CFLAGS -momit-leaf-frame-pointer" # -Wstrict-overflow is supported by GCC 4.2+. - #NXT_CFLAGS="$NXT_CFLAGS -Wstrict-overflow=5" + #NJS_CFLAGS="$NJS_CFLAGS -Wstrict-overflow=5" - NXT_CFLAGS="$NXT_CFLAGS -Wmissing-prototypes" + NJS_CFLAGS="$NJS_CFLAGS -Wmissing-prototypes" # Stop on warning. - NXT_CFLAGS="$NXT_CFLAGS -Werror" + NJS_CFLAGS="$NJS_CFLAGS -Werror" # Debug. - NXT_CFLAGS="$NXT_CFLAGS -g" + NJS_CFLAGS="$NJS_CFLAGS -g" ;; clang) - nxt_define=NXT_CLANG . auto/define + njs_define=NJS_CLANG . auto/define - NXT_CFLAGS="$NXT_CFLAGS -pipe" - NXT_CFLAGS="$NXT_CFLAGS -fPIC" + NJS_CFLAGS="$NJS_CFLAGS -pipe" + NJS_CFLAGS="$NJS_CFLAGS -fPIC" - # Do not export symbols except explicitly marked with NXT_EXPORT. - NXT_CFLAGS="$NXT_CFLAGS -fvisibility=hidden" + # Do not export symbols except explicitly marked with NJS_EXPORT. + NJS_CFLAGS="$NJS_CFLAGS -fvisibility=hidden" - NXT_CFLAGS="$NXT_CFLAGS -O" - #NXT_CFLAGS="$NXT_CFLAGS -O0" - NXT_CFLAGS="$NXT_CFLAGS -W -Wall -Wextra" + NJS_CFLAGS="$NJS_CFLAGS -O" + #NJS_CFLAGS="$NJS_CFLAGS -O0" + NJS_CFLAGS="$NJS_CFLAGS -W -Wall -Wextra" - #NXT_CFLAGS="$NXT_CFLAGS -Wunused-result" - NXT_CFLAGS="$NXT_CFLAGS -Wno-unused-parameter" - #NXT_CFLAGS="$NXT_CFLAGS -Wshorten-64-to-32" - NXT_CFLAGS="$NXT_CFLAGS -Wwrite-strings" - #NXT_CFLAGS="$NXT_CFLAGS -O2" - #NXT_CFLAGS="$NXT_CFLAGS -fomit-frame-pointer" - NXT_CFLAGS="$NXT_CFLAGS -fstrict-aliasing" - NXT_CFLAGS="$NXT_CFLAGS -Wstrict-overflow=5" + #NJS_CFLAGS="$NJS_CFLAGS -Wunused-result" + NJS_CFLAGS="$NJS_CFLAGS -Wno-unused-parameter" + #NJS_CFLAGS="$NJS_CFLAGS -Wshorten-64-to-32" + NJS_CFLAGS="$NJS_CFLAGS -Wwrite-strings" + #NJS_CFLAGS="$NJS_CFLAGS -O2" + #NJS_CFLAGS="$NJS_CFLAGS -fomit-frame-pointer" + NJS_CFLAGS="$NJS_CFLAGS -fstrict-aliasing" + NJS_CFLAGS="$NJS_CFLAGS -Wstrict-overflow=5" - NXT_CFLAGS="$NXT_CFLAGS -Wmissing-prototypes" + NJS_CFLAGS="$NJS_CFLAGS -Wmissing-prototypes" # Stop on warning. - NXT_CFLAGS="$NXT_CFLAGS -Werror" + NJS_CFLAGS="$NJS_CFLAGS -Werror" # Debug. - if [ "$NXT_SYSTEM_PLATFORM" != "powerpc" ]; then + if [ "$NJS_SYSTEM_PLATFORM" != "powerpc" ]; then # "-g" flag causes the "unknown pseudo-op: `.cfi_sections'" # error on PowerPC Clang. - NXT_CFLAGS="$NXT_CFLAGS -g" + NJS_CFLAGS="$NJS_CFLAGS -g" fi ;; SunC) - nxt_define=NXT_SUNC . auto/define + njs_define=NJS_SUNC . auto/define - NXT_CFLAGS="$NXT_CFLAGS -fPIC" + NJS_CFLAGS="$NJS_CFLAGS -fPIC" # Optimization. - NXT_CFLAGS="$NXT_CFLAGS -O -fast" + NJS_CFLAGS="$NJS_CFLAGS -O -fast" # Stop on warning. - NXT_CFLAGS="$NXT_CFLAGS -errwarn=%all" + NJS_CFLAGS="$NJS_CFLAGS -errwarn=%all" # Debug. - NXT_CFLAGS="$NXT_CFLAGS -g" + NJS_CFLAGS="$NJS_CFLAGS -g" ;; *) @@ -157,33 +157,33 @@ esac # Stop on error exit status again. set -e -cat << END >> $NXT_MAKEFILE +cat << END >> $NJS_MAKEFILE -NXT_CC = ${CC} -NXT_CFLAGS = ${NXT_CFLAGS} ${CFLAGS} +NJS_CC = ${CC} +NJS_CFLAGS = ${NJS_CFLAGS} ${CFLAGS} END # C language features. -nxt_feature="GCC unsigned __int128" -nxt_feature_name=NXT_HAVE_UNSIGNED_INT128 -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="int main(void) { +njs_feature="GCC unsigned __int128" +njs_feature_name=NJS_HAVE_UNSIGNED_INT128 +njs_feature_run=no +njs_feature_incs= +njs_feature_libs= +njs_feature_test="int main(void) { unsigned __int128 p = 0; return (int) p; }" . auto/feature -nxt_feature="GCC __builtin_expect()" -nxt_feature_name=NXT_HAVE_BUILTIN_EXPECT -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="int main(int argc, char *const *argv) { +njs_feature="GCC __builtin_expect()" +njs_feature_name=NJS_HAVE_BUILTIN_EXPECT +njs_feature_run=no +njs_feature_incs= +njs_feature_libs= +njs_feature_test="int main(int argc, char *const *argv) { if ((__typeof__(argc == 0)) __builtin_expect((argc == 0), 0)) return 0; @@ -192,35 +192,35 @@ nxt_feature_test="int main(int argc, cha . auto/feature -nxt_feature="GCC __builtin_unreachable()" -nxt_feature_name=NXT_HAVE_BUILTIN_UNREACHABLE -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="int main(void) { +njs_feature="GCC __builtin_unreachable()" +njs_feature_name=NJS_HAVE_BUILTIN_UNREACHABLE +njs_feature_run=no +njs_feature_incs= +njs_feature_libs= +njs_feature_test="int main(void) { __builtin_unreachable(); }" . auto/feature -nxt_feature="GCC __builtin_prefetch()" -nxt_feature_name=NXT_HAVE_BUILTIN_PREFETCH -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="int main(void) { +njs_feature="GCC __builtin_prefetch()" +njs_feature_name=NJS_HAVE_BUILTIN_PREFETCH +njs_feature_run=no +njs_feature_incs= +njs_feature_libs= +njs_feature_test="int main(void) { __builtin_prefetch(0); return 0; }" . auto/feature -nxt_feature="GCC __builtin_clz()" -nxt_feature_name=NXT_HAVE_BUILTIN_CLZ -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="int main(void) { +njs_feature="GCC __builtin_clz()" +njs_feature_name=NJS_HAVE_BUILTIN_CLZ +njs_feature_run=no +njs_feature_incs= +njs_feature_libs= +njs_feature_test="int main(void) { if (__builtin_clz(1) != 31) { return 1; } @@ -229,12 +229,12 @@ nxt_feature_test="int main(void) { . auto/feature -nxt_feature="GCC __builtin_clzll()" -nxt_feature_name=NXT_HAVE_BUILTIN_CLZLL -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="int main(void) { +njs_feature="GCC __builtin_clzll()" +njs_feature_name=NJS_HAVE_BUILTIN_CLZLL +njs_feature_run=no +njs_feature_incs= +njs_feature_libs= +njs_feature_test="int main(void) { if (__builtin_clzll(1ULL) != 63) { return 1; } @@ -243,12 +243,12 @@ nxt_feature_test="int main(void) { . auto/feature -nxt_feature="GCC __attribute__ visibility" -nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY -nxt_feature_run=no -nxt_feature_path= -nxt_feature_libs= -nxt_feature_test="int n __attribute__ ((visibility(\"default\"))); +njs_feature="GCC __attribute__ visibility" +njs_feature_name=NJS_HAVE_GCC_ATTRIBUTE_VISIBILITY +njs_feature_run=no +njs_feature_path= +njs_feature_libs= +njs_feature_test="int n __attribute__ ((visibility(\"default\"))); int main(void) { return 0; @@ -256,12 +256,12 @@ nxt_feature_test="int n __attribute__ (( . auto/feature -nxt_feature="GCC __attribute__ malloc" -nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_MALLOC -nxt_feature_run=no -nxt_feature_path= -nxt_feature_libs= -nxt_feature_test="#include +njs_feature="GCC __attribute__ malloc" +njs_feature_name=NJS_HAVE_GCC_ATTRIBUTE_MALLOC +njs_feature_run=no +njs_feature_path= +njs_feature_libs= +njs_feature_test="#include void *f(void) __attribute__ ((__malloc__)); @@ -278,12 +278,12 @@ nxt_feature_test="#include . auto/feature -nxt_feature="GCC __attribute__ aligned" -nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_ALIGNED -nxt_feature_run=no -nxt_feature_path= -nxt_feature_libs= -nxt_feature_test="int n __attribute__ ((aligned(64))); +njs_feature="GCC __attribute__ aligned" +njs_feature_name=NJS_HAVE_GCC_ATTRIBUTE_ALIGNED +njs_feature_run=no +njs_feature_path= +njs_feature_libs= +njs_feature_test="int n __attribute__ ((aligned(64))); int main(void) { return 0; @@ -291,12 +291,12 @@ nxt_feature_test="int n __attribute__ (( . auto/feature -nxt_feature="Memory sanitizer" -nxt_feature_name=NXT_HAVE_MEMORY_SANITIZER -nxt_feature_run=yes -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="#include +njs_feature="Memory sanitizer" +njs_feature_name=NJS_HAVE_MEMORY_SANITIZER +njs_feature_run=yes +njs_feature_incs= +njs_feature_libs= +njs_feature_test="#include int main(int argc, char *argv[]) { __msan_unpoison(argv, sizeof(char *)); return 0; @@ -304,12 +304,12 @@ nxt_feature_test="#include $NXT_BUILD_DIR/$1" - $echo " && rm -f $NXT_BUILD_DIR/$1.tmp" + njs_gen_dep_post() { + $echo -n "@sed -e 's#^.*:#$NJS_BUILD_DIR/$2:#' " + $echo -n "$NJS_BUILD_DIR/$1.tmp > $NJS_BUILD_DIR/$1" + $echo " && rm -f $NJS_BUILD_DIR/$1.tmp" } ;; *) - nxt_gen_dep_flags() { - $echo "-MMD -MF $NXT_BUILD_DIR/$1 -MT $NXT_BUILD_DIR/$2" + njs_gen_dep_flags() { + $echo "-MMD -MF $NJS_BUILD_DIR/$1 -MT $NJS_BUILD_DIR/$2" } - nxt_gen_dep_post() { + njs_gen_dep_post() { $echo "" } ;; diff -r b685cc423391 -r 8b01e5bbbd16 auto/expect --- a/auto/expect Sun Jul 28 03:28:03 2019 -0400 +++ b/auto/expect Tue Jul 30 20:11:46 2019 +0300 @@ -2,14 +2,14 @@ # Copyright (C) Dmitry Volyntsev # Copyright (C) NGINX, Inc. -nxt_found=no +njs_found=no $echo -n "checking for expect ..." -if /bin/sh -c "(expect -v)" >> $NXT_AUTOCONF_ERR 2>&1; then - nxt_found=yes +if /bin/sh -c "(expect -v)" >> $NJS_AUTOCONF_ERR 2>&1; then + njs_found=yes fi -if [ $nxt_found = yes ]; then +if [ $njs_found = yes ]; then $echo " found" $echo " + Expect version: `expect -v`" @@ -17,18 +17,18 @@ else $echo " not found" fi -if [ $nxt_found = yes -a $NXT_HAVE_READLINE = YES ]; then - cat << END >> $NXT_MAKEFILE +if [ $njs_found = yes -a $NJS_HAVE_READLINE = YES ]; then + cat << END >> $NJS_MAKEFILE -expect_test: njs njs/test/njs_expect_test.exp - INPUTRC=njs/test/inputrc PATH=$NXT_BUILD_DIR:\$(PATH) \ - expect -f njs/test/njs_expect_test.exp +expect_test: njs test/njs_expect_test.exp + INPUTRC=test/inputrc PATH=$NJS_BUILD_DIR:\$(PATH) \ + expect -f test/njs_expect_test.exp END else $echo " - expect tests are disabled" - cat << END >> $NXT_MAKEFILE + cat << END >> $NJS_MAKEFILE expect_test: @echo "Skipping expect tests" diff -r b685cc423391 -r 8b01e5bbbd16 auto/explicit_bzero --- a/auto/explicit_bzero Sun Jul 28 03:28:03 2019 -0400 +++ b/auto/explicit_bzero Tue Jul 30 20:11:46 2019 +0300 @@ -5,12 +5,12 @@ # Linux (glibc and musl from 1.1.20), OpenBSD and FreeBSD. -nxt_feature="explicit_bzero()" -nxt_feature_name=NXT_HAVE_EXPLICIT_BZERO -nxt_feature_run=yes -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="#include +njs_feature="explicit_bzero()" +njs_feature_name=NJS_HAVE_EXPLICIT_BZERO +njs_feature_run=yes +njs_feature_incs= +njs_feature_libs= +njs_feature_test="#include #include int main(void) { @@ -22,13 +22,13 @@ nxt_feature_test="#include . auto/feature -if [ $nxt_found = no ]; then +if [ $njs_found = no ]; then # NetBSD has explicit_memset instead. - nxt_feature="explicit_memset()" - nxt_feature_name=NXT_HAVE_EXPLICIT_MEMSET - nxt_feature_test="#include + njs_feature="explicit_memset()" + njs_feature_name=NJS_HAVE_EXPLICIT_MEMSET + njs_feature_test="#include int main(void) { int r; diff -r b685cc423391 -r 8b01e5bbbd16 auto/feature --- a/auto/feature Sun Jul 28 03:28:03 2019 -0400 +++ b/auto/feature Tue Jul 30 20:11:46 2019 +0300 @@ -3,64 +3,64 @@ # Copyright (C) NGINX, Inc. -$echo -n "checking for $nxt_feature ..." +$echo -n "checking for $njs_feature ..." -cat << END >> $NXT_AUTOCONF_ERR +cat << END >> $NJS_AUTOCONF_ERR ---------------------------------------- -checking for $nxt_feature +checking for $njs_feature END -nxt_found=no -nxt_feature_value= -nxt_feature_inc_path= +njs_found=no +njs_feature_value= +njs_feature_inc_path= -if test -n "$nxt_feature_incs"; then - case "$nxt_feature_incs" in +if test -n "$njs_feature_incs"; then + case "$njs_feature_incs" in -*) - nxt_feature_inc_path="$nxt_feature_incs" + njs_feature_inc_path="$njs_feature_incs" ;; *) - for nxt_temp in $nxt_feature_incs; do - nxt_feature_inc_path="$nxt_feature_inc_path -I $nxt_temp" + for njs_temp in $njs_feature_incs; do + njs_feature_inc_path="$njs_feature_inc_path -I $njs_temp" done ;; esac fi -cat << END > $NXT_AUTOTEST.c -$nxt_feature_test +cat << END > $NJS_AUTOTEST.c +$njs_feature_test END -nxt_test="$CC $CFLAGS $NXT_CFLAGS $NXT_CC_OPT $NXT_TEST_CFLAGS \ - $nxt_feature_inc_path -o $NXT_AUTOTEST $NXT_AUTOTEST.c \ - $NXT_LD_OPT $NXT_TEST_LIBS $nxt_feature_libs" +njs_test="$CC $CFLAGS $NJS_CFLAGS $NJS_CC_OPT $NJS_TEST_CFLAGS \ + $njs_feature_inc_path -o $NJS_AUTOTEST $NJS_AUTOTEST.c \ + $NJS_LD_OPT $NJS_TEST_LIBS $njs_feature_libs" # /bin/sh -c "(...)" is to intercept "Killed", "Abort trap", # "Segmentation fault", or other shell messages. # "|| true" is to bypass "set -e" setting. -/bin/sh -c "($nxt_test || true)" >> $NXT_AUTOCONF_ERR 2>&1 +/bin/sh -c "($njs_test || true)" >> $NJS_AUTOCONF_ERR 2>&1 -if [ -x $NXT_AUTOTEST ]; then +if [ -x $NJS_AUTOTEST ]; then - case "$nxt_feature_run" in + case "$njs_feature_run" in value) - if /bin/sh -c "($NXT_AUTOTEST)" >> $NXT_AUTOCONF_ERR 2>&1; then - $echo >> $NXT_AUTOCONF_ERR - nxt_found=yes - nxt_feature_value=`$NXT_AUTOTEST` - $echo " $nxt_feature_value" - if [ -n "$nxt_feature_name" ]; then - cat << END >> $NXT_AUTO_CONFIG_H + if /bin/sh -c "($NJS_AUTOTEST)" >> $NJS_AUTOCONF_ERR 2>&1; then + $echo >> $NJS_AUTOCONF_ERR + njs_found=yes + njs_feature_value=`$NJS_AUTOTEST` + $echo " $njs_feature_value" + if [ -n "$njs_feature_name" ]; then + cat << END >> $NJS_AUTO_CONFIG_H -#ifndef $nxt_feature_name -#define $nxt_feature_name $nxt_feature_value +#ifndef $njs_feature_name +#define $njs_feature_name $njs_feature_value #endif END @@ -71,13 +71,13 @@ END ;; yes) - if /bin/sh -c "($NXT_AUTOTEST)" >> $NXT_AUTOCONF_ERR 2>&1; then + if /bin/sh -c "($NJS_AUTOTEST)" >> $NJS_AUTOCONF_ERR 2>&1; then $echo " found" - nxt_found=yes - cat << END >> $NXT_AUTO_CONFIG_H + njs_found=yes + cat << END >> $NJS_AUTO_CONFIG_H -#ifndef $nxt_feature_name -#define $nxt_feature_name 1 +#ifndef $njs_feature_name +#define $njs_feature_name 1 #endif END @@ -88,11 +88,11 @@ END *) $echo " found" - nxt_found=yes - cat << END >> $NXT_AUTO_CONFIG_H + njs_found=yes + cat << END >> $NJS_AUTO_CONFIG_H -#ifndef $nxt_feature_name -#define $nxt_feature_name 1 +#ifndef $njs_feature_name +#define $njs_feature_name 1 #endif END @@ -102,11 +102,11 @@ END else $echo " not found" - $echo "----------" >> $NXT_AUTOCONF_ERR - cat $NXT_AUTOTEST.c >> $NXT_AUTOCONF_ERR - $echo "----------" >> $NXT_AUTOCONF_ERR - $echo $nxt_test >> $NXT_AUTOCONF_ERR - $echo "----------" >> $NXT_AUTOCONF_ERR + $echo "----------" >> $NJS_AUTOCONF_ERR + cat $NJS_AUTOTEST.c >> $NJS_AUTOCONF_ERR + $echo "----------" >> $NJS_AUTOCONF_ERR + $echo $njs_test >> $NJS_AUTOCONF_ERR + $echo "----------" >> $NJS_AUTOCONF_ERR fi -rm -rf $NXT_AUTOTEST* +rm -rf $NJS_AUTOTEST* diff -r b685cc423391 -r 8b01e5bbbd16 auto/getrandom --- a/auto/getrandom Sun Jul 28 03:28:03 2019 -0400 +++ b/auto/getrandom Tue Jul 30 20:11:46 2019 +0300 @@ -5,12 +5,12 @@ # Linux 3.17 with glibc 2.25, FreeBSD 12, Solaris 11.3. -nxt_feature="getrandom()" -nxt_feature_name=NXT_HAVE_GETRANDOM -nxt_feature_run=yes -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="#include +njs_feature="getrandom()" +njs_feature_name=NJS_HAVE_GETRANDOM +njs_feature_run=yes +njs_feature_incs= +njs_feature_libs= +njs_feature_test="#include #include int main(void) { @@ -25,13 +25,13 @@ nxt_feature_test="#include . auto/feature -if [ $nxt_found = no ]; then +if [ $njs_found = no ]; then # Linux 3.17 SYS_getrandom. - nxt_feature="SYS_getrandom in Linux" - nxt_feature_name=NXT_HAVE_LINUX_SYS_GETRANDOM - nxt_feature_test="#include + njs_feature="SYS_getrandom in Linux" + njs_feature_name=NJS_HAVE_LINUX_SYS_GETRANDOM + njs_feature_test="#include #include #include @@ -48,13 +48,13 @@ if [ $nxt_found = no ]; then fi -if [ $nxt_found = no ]; then +if [ $njs_found = no ]; then # OpenBSD 5.6 lacks . - nxt_feature="getentropy()" - nxt_feature_name=NXT_HAVE_GETENTROPY - nxt_feature_test="#include + njs_feature="getentropy()" + njs_feature_name=NJS_HAVE_GETENTROPY + njs_feature_test="#include int main(void) { char buf[4]; @@ -69,13 +69,13 @@ if [ $nxt_found = no ]; then fi -if [ $nxt_found = no ]; then +if [ $njs_found = no ]; then # macOS 10.12. - nxt_feature="getentropy() in sys/random.h" - nxt_feature_name=NXT_HAVE_GETENTROPY_SYS_RANDOM - nxt_feature_test="#include + njs_feature="getentropy() in sys/random.h" + njs_feature_name=NJS_HAVE_GETENTROPY_SYS_RANDOM + njs_feature_test="#include #include int main(void) { diff -r b685cc423391 -r 8b01e5bbbd16 auto/make --- a/auto/make Sun Jul 28 03:28:03 2019 -0400 +++ b/auto/make Tue Jul 30 20:11:46 2019 +0300 @@ -4,141 +4,61 @@ . auto/deps -$echo "creating $NXT_MAKEFILE" +$echo "creating $NJS_MAKEFILE" -mkdir -p $NXT_BUILD_DIR/src -mkdir -p $NXT_BUILD_DIR/test +mkdir -p $NJS_BUILD_DIR/src +mkdir -p $NJS_BUILD_DIR/test -cat << END > $NXT_MAKEFILE +cat << END > $NJS_MAKEFILE # This file is auto-generated by configure -NXT_CC = ${CC} -NXT_AR = ${AR} -NXT_CFLAGS = ${NXT_CFLAGS} ${CFLAGS} +NJS_CC = ${CC} +NJS_AR = ${AR} +NJS_CFLAGS = ${NJS_CFLAGS} ${CFLAGS} -default: $NXT_DEFAULT_TARGET +default: $NJS_DEFAULT_TARGET END -# The nxt include paths list. - -$echo -n "NXT_LIB_INCS =" >> $NXT_MAKEFILE +# The include paths list. -for nxt_inc in nxt $NXT_BUILD_DIR -do - $echo -n " -I $nxt_inc" >> $NXT_MAKEFILE -done +$echo -n "NJS_LIB_INCS =" >> $NJS_MAKEFILE -$echo >> $NXT_MAKEFILE -$echo >> $NXT_MAKEFILE - - -# The nxt object files list. - -$echo "NXT_LIB_OBJS = \\" >> $NXT_MAKEFILE - -for nxt_src in $NXT_LIB_SRCS +for njs_inc in src $NJS_BUILD_DIR do - fname=$(basename $nxt_src) - nxt_obj="src/${fname%.c}.o" - $echo " $NXT_BUILD_DIR/$nxt_obj \\" >> $NXT_MAKEFILE + $echo -n " -I$njs_inc" >> $NJS_MAKEFILE done -$echo >> $NXT_MAKEFILE - - -# The nxt static library. - -cat << END >> $NXT_MAKEFILE - -libnxt: $NXT_BUILD_DIR/libnxt.a - -$NXT_BUILD_DIR/libnxt.a: \\ - $NXT_BUILD_DIR/nxt_auto_config.h \\ - \$(NXT_LIB_OBJS) - \$(NXT_AR) -r -c $NXT_BUILD_DIR/libnxt.a \\ - \$(NXT_LIB_OBJS) - -END - - -# The nxt object files. - -for nxt_src in $NXT_LIB_SRCS -do - fname=$(basename $nxt_src) - nxt_obj="src/${fname%.c}.o" - nxt_dep="src/${fname%.c}.dep" - nxt_dep_flags=`nxt_gen_dep_flags $nxt_dep $nxt_obj` - nxt_dep_post=`nxt_gen_dep_post $nxt_dep $nxt_obj` - cat << END >> $NXT_MAKEFILE +$echo >> $NJS_MAKEFILE +$echo >> $NJS_MAKEFILE -$NXT_BUILD_DIR/$nxt_obj: $nxt_src - \$(NXT_CC) -c \$(NXT_CFLAGS) $NXT_LIB_AUX_CFLAGS \\ - \$(NXT_LIB_INCS) -o $NXT_BUILD_DIR/$nxt_obj \\ - $nxt_dep_flags \\ - $nxt_src \\ - $nxt_dep_post - --include $NXT_BUILD_DIR/$nxt_dep - -END - -done - -# nxt tests. - -for nxt_src in $NXT_TEST_SRCS -do - fname=$(basename $nxt_src) - nxt_dep="test/${fname%.c}.dep" - nxt_bin="${fname%.c}" - nxt_dep_flags=`nxt_gen_dep_flags $nxt_dep $fname` - nxt_dep_post=`nxt_gen_dep_post $nxt_dep $fname` - cat << END >> $NXT_MAKEFILE - -$NXT_BUILD_DIR/$nxt_bin: $nxt_src \\ - $NXT_BUILD_DIR/libnxt.a - \$(NXT_CC) -o $NXT_BUILD_DIR/$nxt_bin \$(NXT_CFLAGS) \\ - \$(NXT_LIB_INCS) $nxt_dep_flags \\ - $nxt_src $NXT_BUILD_DIR/libnxt.a \\ - $nxt_dep_post -lm - --include $NXT_BUILD_DIR/$nxt_dep - -END - -done # The njs object files list. -$echo "NJS_LIB_OBJS = \\" >> $NXT_MAKEFILE +$echo "NJS_LIB_OBJS = \\" >> $NJS_MAKEFILE for njs_src in $NJS_LIB_SRCS do fname=$(basename $njs_src) njs_obj="src/${fname%.c}.o" - $echo " $NXT_BUILD_DIR/$njs_obj \\" >> $NXT_MAKEFILE + $echo " $NJS_BUILD_DIR/$njs_obj \\" >> $NJS_MAKEFILE done -$echo >> $NXT_MAKEFILE - +$echo >> $NJS_MAKEFILE # The njs static library. -cat << END >> $NXT_MAKEFILE - -libnjs: $NXT_BUILD_DIR/libnjs.a +cat << END >> $NJS_MAKEFILE -$NXT_BUILD_DIR/libnjs.a: \\ - $NXT_BUILD_DIR/nxt_auto_config.h \\ - \$(NXT_LIB_OBJS) \\ +libnjs: $NJS_BUILD_DIR/libnjs.a + +$NJS_BUILD_DIR/libnjs.a: \\ + $NJS_BUILD_DIR/njs_auto_config.h \\ \$(NJS_LIB_OBJS) - \$(NXT_AR) -r -c $NXT_BUILD_DIR/libnjs.a \\ - \$(NXT_LIB_OBJS) \\ + \$(NJS_AR) -r -c $NJS_BUILD_DIR/libnjs.a \\ \$(NJS_LIB_OBJS) END @@ -151,19 +71,19 @@ do fname=$(basename $njs_src) njs_obj="src/${fname%.c}.o" njs_dep="src/${fname%.c}.dep" - njs_dep_flags=`nxt_gen_dep_flags $njs_dep $njs_obj` - njs_dep_post=`nxt_gen_dep_post $njs_dep $njs_obj` - cat << END >> $NXT_MAKEFILE + njs_dep_flags=`njs_gen_dep_flags $njs_dep $njs_obj` + njs_dep_post=`njs_gen_dep_post $njs_dep $njs_obj` + cat << END >> $NJS_MAKEFILE -$NXT_BUILD_DIR/$njs_obj: $njs_src - \$(NXT_CC) -c \$(NXT_CFLAGS) $NXT_LIB_AUX_CFLAGS \\ - \$(NXT_LIB_INCS) -Injs \\ - -o $NXT_BUILD_DIR/$njs_obj \\ +$NJS_BUILD_DIR/$njs_obj: $njs_src + \$(NJS_CC) -c \$(NJS_CFLAGS) $NJS_LIB_AUX_CFLAGS \\ + \$(NJS_LIB_INCS) -Injs \\ + -o $NJS_BUILD_DIR/$njs_obj \\ $njs_dep_flags \\ $njs_src $njs_dep_post --include $NXT_BUILD_DIR/$njs_dep +-include $NJS_BUILD_DIR/$njs_dep END @@ -171,20 +91,45 @@ done # njs cli. -cat << END >> $NXT_MAKEFILE +cat << END >> $NJS_MAKEFILE -$NXT_BUILD_DIR/njs: \\ - $NXT_BUILD_DIR/libnxt.a \\ - $NXT_BUILD_DIR/libnjs.a \\ From xeioex at nginx.com Tue Jul 30 18:12:26 2019 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 30 Jul 2019 18:12:26 +0000 Subject: [njs] Refactored usage of njs_ret_t. Message-ID: details: https://hg.nginx.org/njs/rev/f4ac8168e856 branches: changeset: 1087:f4ac8168e856 user: Dmitry Volyntsev date: Tue Jul 30 21:12:08 2019 +0300 description: Refactored usage of njs_ret_t. Currently njs_ret_t is used in 2 different cases: as a jump offset for bytecode and as a return value for ordinary functions. The second case is quite similar with njs_int_t (and is often confused with). 1) Splitting this two cases into different types to avoid confusion with njs_int_t. 2) Renaming njs_ret_t to njs_jump_off_t to better reflect its purpose. NO functional changes. diffstat: nginx/ngx_http_js_module.c | 132 ++++++++++++++-------------- nginx/ngx_stream_js_module.c | 74 ++++++++-------- src/njs.h | 31 +++--- src/njs_array.c | 92 +++++++++--------- src/njs_array.h | 8 +- src/njs_boolean.c | 6 +- src/njs_boolean.h | 2 +- src/njs_builtin.c | 14 +- src/njs_crypto.c | 26 ++-- src/njs_crypto.h | 4 +- src/njs_date.c | 88 +++++++++--------- src/njs_date.h | 4 +- src/njs_error.c | 30 +++--- src/njs_error.h | 20 ++-- src/njs_extern.c | 2 +- src/njs_fs.c | 44 ++++---- src/njs_function.c | 46 ++++---- src/njs_function.h | 26 ++-- src/njs_generator.c | 52 +++++----- src/njs_json.c | 48 +++++----- src/njs_math.c | 76 ++++++++-------- src/njs_module.c | 3 +- src/njs_module.h | 2 +- src/njs_number.c | 26 ++-- src/njs_number.h | 12 +- src/njs_object.c | 84 +++++++++--------- src/njs_object.h | 24 ++-- src/njs_object_property.c | 50 +++++----- src/njs_parser.c | 28 +++--- src/njs_parser.h | 2 +- src/njs_parser_terminal.c | 12 +- src/njs_regexp.c | 42 ++++---- src/njs_regexp.h | 8 +- src/njs_shell.c | 22 ++-- src/njs_string.c | 198 +++++++++++++++++++++--------------------- src/njs_string.h | 32 +++--- src/njs_timer.c | 10 +- src/njs_timer.h | 6 +- src/njs_value.c | 4 +- src/njs_value.h | 16 +- src/njs_variable.c | 22 ++-- src/njs_variable.h | 8 +- src/njs_vm.c | 26 ++-- src/njs_vm.h | 2 +- src/njs_vmcode.c | 168 ++++++++++++++++++------------------ src/njs_vmcode.h | 27 +++-- src/test/njs_unit_test.c | 30 +++--- 47 files changed, 847 insertions(+), 842 deletions(-) diffs (truncated from 6313 to 1000 lines): diff -r 8b01e5bbbd16 -r f4ac8168e856 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Tue Jul 30 20:11:46 2019 +0300 +++ b/nginx/ngx_http_js_module.c Tue Jul 30 21:12:08 2019 +0300 @@ -60,76 +60,76 @@ static ngx_int_t ngx_http_js_init_vm(ngx static void ngx_http_js_cleanup_ctx(void *data); static void ngx_http_js_cleanup_vm(void *data); -static njs_ret_t ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj, void *next, uintptr_t data); -static njs_ret_t ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value, void *obj, void *next); static ngx_table_elt_t *ngx_http_js_get_header(ngx_list_part_t *part, u_char *data, size_t len); -static njs_ret_t ngx_http_js_ext_get_header_out(njs_vm_t *vm, +static njs_int_t ngx_http_js_ext_get_header_out(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_set_header_out(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_set_header_out(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); -static njs_ret_t ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj, uintptr_t data, njs_bool_t delete); -static njs_ret_t ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj, void *next); /*FIXME*/ -static njs_ret_t ngx_http_js_ext_get_status(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_get_status(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_set_status(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_set_status(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); -static njs_ret_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_internal_redirect(njs_vm_t *vm, +static njs_int_t ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_log(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_warn(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_warn(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_error(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_error(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_http_js_ext_log_core(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_log_core(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, ngx_uint_t level); -static njs_ret_t ngx_http_js_ext_get_http_version(njs_vm_t *vm, +static njs_int_t ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm, +static njs_int_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_get_request_body(njs_vm_t *vm, +static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj, void *next); /*FIXME*/ -static njs_ret_t ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj, void *next); -static njs_ret_t ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value, void *obj, void *next); -static njs_ret_t ngx_http_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_set_variable(njs_vm_t *vm, void *obj, +static njs_int_t ngx_http_js_ext_set_variable(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); -static njs_ret_t ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); static ngx_int_t ngx_http_js_subrequest(ngx_http_request_t *r, njs_str_t *uri_arg, njs_str_t *args_arg, njs_function_t *callback, ngx_http_request_t **sr); static ngx_int_t ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc); -static njs_ret_t ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_value_t *value, +static njs_int_t ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_http_js_ext_get_reply_body(njs_vm_t *vm, +static njs_int_t ngx_http_js_ext_get_reply_body(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); static njs_host_event_t ngx_http_js_set_timer(njs_external_ptr_t external, @@ -139,7 +139,7 @@ static void ngx_http_js_clear_timer(njs_ static void ngx_http_js_timer_handler(ngx_event_t *ev); static void ngx_http_js_handle_event(ngx_http_request_t *r, njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs); -static njs_ret_t ngx_http_js_string(njs_vm_t *vm, const njs_value_t *value, +static njs_int_t ngx_http_js_string(njs_vm_t *vm, const njs_value_t *value, njs_str_t *str); static char *ngx_http_js_include(ngx_conf_t *cf, ngx_command_t *cmd, @@ -807,7 +807,7 @@ ngx_http_js_cleanup_vm(void *data) } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -821,7 +821,7 @@ ngx_http_js_ext_get_string(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj, void *next, uintptr_t data) { @@ -850,7 +850,7 @@ ngx_http_js_ext_foreach_header(njs_vm_t } -static njs_ret_t +static njs_int_t ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value, void *obj, void *next) { @@ -918,7 +918,7 @@ ngx_http_js_get_header(ngx_list_part_t * } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_header_out(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -971,7 +971,7 @@ ngx_http_js_ext_get_header_out(njs_vm_t } -static njs_ret_t +static njs_int_t ngx_http_js_ext_set_header_out(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value) { @@ -1065,7 +1065,7 @@ ngx_http_js_ext_set_header_out(njs_vm_t } -static njs_ret_t +static njs_int_t ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj, uintptr_t data, njs_bool_t unused) { @@ -1077,7 +1077,7 @@ ngx_http_js_ext_delete_header_out(njs_vm } -static njs_ret_t +static njs_int_t ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj, void *next) { return ngx_http_js_ext_foreach_header(vm, obj, next, @@ -1085,7 +1085,7 @@ ngx_http_js_ext_foreach_header_out(njs_v } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_status(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1099,7 +1099,7 @@ ngx_http_js_ext_get_status(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t ngx_http_js_ext_set_status(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value) { @@ -1119,7 +1119,7 @@ ngx_http_js_ext_set_status(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1142,7 +1142,7 @@ ngx_http_js_ext_send_header(njs_vm_t *vm } -static njs_ret_t +static njs_int_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1216,7 +1216,7 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_v } -static njs_ret_t +static njs_int_t ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1240,7 +1240,7 @@ ngx_http_js_ext_finish(njs_vm_t *vm, njs } -static njs_ret_t +static njs_int_t ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1297,7 +1297,7 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs } -static njs_ret_t +static njs_int_t ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1331,7 +1331,7 @@ ngx_http_js_ext_internal_redirect(njs_vm } -static njs_ret_t +static njs_int_t ngx_http_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1339,7 +1339,7 @@ ngx_http_js_ext_log(njs_vm_t *vm, njs_va } -static njs_ret_t +static njs_int_t ngx_http_js_ext_warn(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1347,7 +1347,7 @@ ngx_http_js_ext_warn(njs_vm_t *vm, njs_v } -static njs_ret_t +static njs_int_t ngx_http_js_ext_error(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1355,7 +1355,7 @@ ngx_http_js_ext_error(njs_vm_t *vm, njs_ } -static njs_ret_t +static njs_int_t ngx_http_js_ext_log_core(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, ngx_uint_t level) { @@ -1388,7 +1388,7 @@ ngx_http_js_ext_log_core(njs_vm_t *vm, n } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1416,7 +1416,7 @@ ngx_http_js_ext_get_http_version(njs_vm_ } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1431,14 +1431,14 @@ ngx_http_js_ext_get_remote_address(njs_v } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { u_char *p, *body; size_t len; ngx_buf_t *buf; - njs_ret_t ret; + njs_int_t ret; njs_value_t *request_body; ngx_chain_t *cl; ngx_http_js_ctx_t *ctx; @@ -1510,7 +1510,7 @@ done: } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1532,14 +1532,14 @@ ngx_http_js_ext_get_header_in(njs_vm_t * } -static njs_ret_t +static njs_int_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj, void *next) { return ngx_http_js_ext_foreach_header(vm, obj, next, offsetof(ngx_http_request_t, headers_in.headers)); } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1560,7 +1560,7 @@ ngx_http_js_ext_get_arg(njs_vm_t *vm, nj } -static njs_ret_t +static njs_int_t ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj, void *next) { ngx_str_t *entry, **e; @@ -1582,7 +1582,7 @@ ngx_http_js_ext_foreach_arg(njs_vm_t *vm } -static njs_ret_t +static njs_int_t ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value, void *obj, void *next) { @@ -1625,7 +1625,7 @@ ngx_http_js_ext_next_arg(njs_vm_t *vm, n } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1653,7 +1653,7 @@ ngx_http_js_ext_get_variable(njs_vm_t *v } -static njs_ret_t +static njs_int_t ngx_http_js_ext_set_variable(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value) { @@ -1722,7 +1722,7 @@ ngx_http_js_ext_set_variable(njs_vm_t *v } -static njs_ret_t +static njs_int_t ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -2042,7 +2042,7 @@ ngx_http_js_subrequest_done(ngx_http_req } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -2065,7 +2065,7 @@ ngx_http_js_ext_get_parent(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t ngx_http_js_ext_get_reply_body(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -2161,7 +2161,7 @@ static void ngx_http_js_handle_event(ngx_http_request_t *r, njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs) { - njs_ret_t rc; + njs_int_t rc; njs_str_t exception; ngx_http_js_ctx_t *ctx; @@ -2186,7 +2186,7 @@ ngx_http_js_handle_event(ngx_http_reques } -static njs_ret_t +static njs_int_t ngx_http_js_string(njs_vm_t *vm, const njs_value_t *value, njs_str_t *str) { if (!njs_value_is_null_or_undefined(value)) { diff -r 8b01e5bbbd16 -r f4ac8168e856 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Tue Jul 30 20:11:46 2019 +0300 +++ b/nginx/ngx_stream_js_module.c Tue Jul 30 21:12:08 2019 +0300 @@ -64,43 +64,43 @@ static ngx_int_t ngx_stream_js_variable( static ngx_int_t ngx_stream_js_init_vm(ngx_stream_session_t *s); static void ngx_stream_js_cleanup_ctx(void *data); static void ngx_stream_js_cleanup_vm(void *data); -static njs_ret_t ngx_stream_js_buffer_arg(ngx_stream_session_t *s, +static njs_int_t ngx_stream_js_buffer_arg(ngx_stream_session_t *s, njs_value_t *buffer); -static njs_ret_t ngx_stream_js_flags_arg(ngx_stream_session_t *s, +static njs_int_t ngx_stream_js_flags_arg(ngx_stream_session_t *s, njs_value_t *flags); static njs_vm_event_t *ngx_stream_js_event(ngx_stream_session_t *s, njs_str_t *event); -static njs_ret_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm, +static njs_int_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_deny(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_deny(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_decline(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_decline(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_set_status(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_set_status(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, ngx_int_t status); -static njs_ret_t ngx_stream_js_ext_log(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_warn(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_warn(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_error(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_error(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_log_core(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_log_core(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, ngx_uint_t level); -static njs_ret_t ngx_stream_js_ext_on(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_off(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_off(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, +static njs_int_t ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); -static njs_ret_t ngx_stream_js_ext_get_variable(njs_vm_t *vm, +static njs_int_t ngx_stream_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_ret_t ngx_stream_js_ext_set_variable(njs_vm_t *vm, void *obj, +static njs_int_t ngx_stream_js_ext_set_variable(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); static njs_host_event_t ngx_stream_js_set_timer(njs_external_ptr_t external, @@ -110,7 +110,7 @@ static void ngx_stream_js_clear_timer(nj static void ngx_stream_js_timer_handler(ngx_event_t *ev); static void ngx_stream_js_handle_event(ngx_stream_session_t *s, njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs); -static njs_ret_t ngx_stream_js_string(njs_vm_t *vm, const njs_value_t *value, +static njs_int_t ngx_stream_js_string(njs_vm_t *vm, const njs_value_t *value, njs_str_t *str); static char *ngx_stream_js_include(ngx_conf_t *cf, ngx_command_t *cmd, @@ -406,7 +406,7 @@ static ngx_int_t ngx_stream_js_phase_handler(ngx_stream_session_t *s, ngx_str_t *name) { njs_str_t fname, exception; - njs_ret_t ret; + njs_int_t ret; ngx_int_t rc; njs_function_t *func; ngx_connection_t *c; @@ -507,7 +507,7 @@ ngx_stream_js_body_filter(ngx_stream_ses ngx_uint_t from_upstream) { njs_str_t name, exception; - njs_ret_t ret; + njs_int_t ret; ngx_int_t rc; ngx_chain_t *out, *cl; njs_function_t *func; @@ -790,7 +790,7 @@ ngx_stream_js_cleanup_vm(void *data) } -static njs_ret_t +static njs_int_t ngx_stream_js_buffer_arg(ngx_stream_session_t *s, njs_value_t *buffer) { size_t len; @@ -820,7 +820,7 @@ ngx_stream_js_buffer_arg(ngx_stream_sess -static njs_ret_t +static njs_int_t ngx_stream_js_flags_arg(ngx_stream_session_t *s, njs_value_t *flags) { ngx_buf_t *b; @@ -886,7 +886,7 @@ ngx_stream_js_event(ngx_stream_session_t } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -901,7 +901,7 @@ ngx_stream_js_ext_get_remote_address(njs } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -909,7 +909,7 @@ ngx_stream_js_ext_done(njs_vm_t *vm, njs } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_deny(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -918,7 +918,7 @@ ngx_stream_js_ext_deny(njs_vm_t *vm, njs } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_decline(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -927,7 +927,7 @@ ngx_stream_js_ext_decline(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_set_status(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, ngx_int_t status) { @@ -976,7 +976,7 @@ ngx_stream_js_ext_set_status(njs_vm_t *v } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -984,7 +984,7 @@ ngx_stream_js_ext_log(njs_vm_t *vm, njs_ } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_warn(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -992,7 +992,7 @@ ngx_stream_js_ext_warn(njs_vm_t *vm, njs } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_error(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1000,7 +1000,7 @@ ngx_stream_js_ext_error(njs_vm_t *vm, nj } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_log_core(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, ngx_uint_t level) { @@ -1033,7 +1033,7 @@ ngx_stream_js_ext_log_core(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1080,7 +1080,7 @@ ngx_stream_js_ext_on(njs_vm_t *vm, njs_v } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_off(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1113,7 +1113,7 @@ ngx_stream_js_ext_off(njs_vm_t *vm, njs_ } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1192,7 +1192,7 @@ ngx_stream_js_ext_send(njs_vm_t *vm, njs } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data) { @@ -1220,7 +1220,7 @@ ngx_stream_js_ext_get_variable(njs_vm_t } -static njs_ret_t +static njs_int_t ngx_stream_js_ext_set_variable(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value) { @@ -1351,7 +1351,7 @@ static void ngx_stream_js_handle_event(ngx_stream_session_t *s, njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs) { - njs_ret_t rc; + njs_int_t rc; njs_str_t exception; ngx_stream_js_ctx_t *ctx; @@ -1376,7 +1376,7 @@ ngx_stream_js_handle_event(ngx_stream_se } -static njs_ret_t +static njs_int_t ngx_stream_js_string(njs_vm_t *vm, const njs_value_t *value, njs_str_t *str) { if (!njs_value_is_null_or_undefined(value)) { diff -r 8b01e5bbbd16 -r f4ac8168e856 src/njs.h --- a/src/njs.h Tue Jul 30 20:11:46 2019 +0300 +++ b/src/njs.h Tue Jul 30 21:12:08 2019 +0300 @@ -22,7 +22,6 @@ #include -typedef intptr_t njs_ret_t; typedef uintptr_t njs_index_t; typedef struct njs_vm_s njs_vm_t; typedef union njs_value_s njs_value_t; @@ -60,16 +59,16 @@ extern const njs_value_t njs_ njs_vm_value_error_set(vm, njs_vm_retval(vm), fmt, ##__VA_ARGS__) -typedef njs_ret_t (*njs_extern_get_t)(njs_vm_t *vm, njs_value_t *value, +typedef njs_int_t (*njs_extern_get_t)(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -typedef njs_ret_t (*njs_extern_set_t)(njs_vm_t *vm, void *obj, uintptr_t data, +typedef njs_int_t (*njs_extern_set_t)(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); -typedef njs_ret_t (*njs_extern_find_t)(njs_vm_t *vm, void *obj, uintptr_t data, +typedef njs_int_t (*njs_extern_find_t)(njs_vm_t *vm, void *obj, uintptr_t data, njs_bool_t delete); -typedef njs_ret_t (*njs_extern_foreach_t)(njs_vm_t *vm, void *obj, void *next); -typedef njs_ret_t (*njs_extern_next_t)(njs_vm_t *vm, njs_value_t *value, +typedef njs_int_t (*njs_extern_foreach_t)(njs_vm_t *vm, void *obj, void *next); +typedef njs_int_t (*njs_extern_next_t)(njs_vm_t *vm, njs_value_t *value, void *obj, void *next); -typedef njs_ret_t (*njs_extern_method_t)(njs_vm_t *vm, njs_value_t *args, +typedef njs_int_t (*njs_extern_method_t)(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); @@ -236,7 +235,7 @@ NJS_EXPORT void njs_vm_retval_set(njs_vm * Sets a byte string value. * start data is not copied and should not be freed. */ -NJS_EXPORT njs_ret_t njs_vm_value_string_set(njs_vm_t *vm, njs_value_t *value, +NJS_EXPORT njs_int_t njs_vm_value_string_set(njs_vm_t *vm, njs_value_t *value, const u_char *start, uint32_t size); NJS_EXPORT u_char *njs_vm_value_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size); @@ -246,19 +245,19 @@ NJS_EXPORT njs_int_t njs_vm_value_string /* * Converts a value to string. */ -NJS_EXPORT njs_ret_t njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, +NJS_EXPORT njs_int_t njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, const njs_value_t *src); /* * Calls njs_vm_value_to_string(), if exception was thrown adds backtrace. */ -NJS_EXPORT njs_ret_t njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst, +NJS_EXPORT njs_int_t njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst, const njs_value_t *src); -NJS_EXPORT njs_ret_t njs_vm_retval_string(njs_vm_t *vm, njs_str_t *dst); +NJS_EXPORT njs_int_t njs_vm_retval_string(njs_vm_t *vm, njs_str_t *dst); -NJS_EXPORT njs_ret_t njs_vm_value_dump(njs_vm_t *vm, njs_str_t *dst, +NJS_EXPORT njs_int_t njs_vm_value_dump(njs_vm_t *vm, njs_str_t *dst, const njs_value_t *value, njs_uint_t console, njs_uint_t indent); -NJS_EXPORT njs_ret_t njs_vm_retval_dump(njs_vm_t *vm, njs_str_t *dst, +NJS_EXPORT njs_int_t njs_vm_retval_dump(njs_vm_t *vm, njs_str_t *dst, njs_uint_t indent); NJS_EXPORT void njs_vm_value_error_set(njs_vm_t *vm, njs_value_t *value, @@ -285,14 +284,14 @@ NJS_EXPORT njs_int_t njs_value_is_string NJS_EXPORT njs_int_t njs_value_is_object(const njs_value_t *value); NJS_EXPORT njs_int_t njs_value_is_function(const njs_value_t *value); -NJS_EXPORT njs_ret_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, +NJS_EXPORT njs_int_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...); NJS_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm, const njs_value_t *value, const njs_str_t *key); -NJS_EXPORT njs_ret_t njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, +NJS_EXPORT njs_int_t njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs); -NJS_EXPORT njs_ret_t njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, +NJS_EXPORT njs_int_t njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs); extern const njs_mem_proto_t njs_vm_mp_proto; diff -r 8b01e5bbbd16 -r f4ac8168e856 src/njs_array.c --- a/src/njs_array.c Tue Jul 30 20:11:46 2019 +0300 +++ b/src/njs_array.c Tue Jul 30 21:12:08 2019 +0300 @@ -9,7 +9,7 @@ #include -static njs_ret_t njs_array_prototype_slice_copy(njs_vm_t *vm, +static njs_int_t njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, int64_t start, int64_t length); static njs_value_t *njs_array_copy(njs_value_t *dst, njs_value_t *src); @@ -67,10 +67,10 @@ overflow: } -njs_ret_t +njs_int_t njs_array_add(njs_vm_t *vm, njs_array_t *array, njs_value_t *value) { - njs_ret_t ret; + njs_int_t ret; ret = njs_array_expand(vm, array, 0, 1); @@ -83,11 +83,11 @@ njs_array_add(njs_vm_t *vm, njs_array_t } -njs_ret_t +njs_int_t njs_array_string_add(njs_vm_t *vm, njs_array_t *array, const u_char *start, size_t size, size_t length) { - njs_ret_t ret; + njs_int_t ret; ret = njs_array_expand(vm, array, 0, 1); @@ -100,7 +100,7 @@ njs_array_string_add(njs_vm_t *vm, njs_a } -njs_ret_t +njs_int_t njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t append) { @@ -156,7 +156,7 @@ memory_error: } -njs_ret_t +njs_int_t njs_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -211,7 +211,7 @@ njs_array_constructor(njs_vm_t *vm, njs_ } -static njs_ret_t +static njs_int_t njs_array_is_array(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -230,7 +230,7 @@ njs_array_is_array(njs_vm_t *vm, njs_val } -static njs_ret_t +static njs_int_t njs_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -307,14 +307,14 @@ const njs_object_init_t njs_array_const }; -static njs_ret_t +static njs_int_t njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { double num; int64_t size; uint32_t length; - njs_ret_t ret; + njs_int_t ret; njs_value_t *val; njs_array_t *array; njs_object_t *proto; @@ -396,12 +396,12 @@ njs_array_length(njs_vm_t *vm, njs_value * JavaScript 1.2, ECMAScript 3. */ -static njs_ret_t +static njs_int_t njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { int64_t start, end, length; - njs_ret_t ret; + njs_int_t ret; njs_value_t prop_length; static const njs_value_t string_length = njs_string("length"); @@ -462,14 +462,14 @@ njs_array_prototype_slice(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, int64_t start, int64_t length) { size_t size; u_char *dst; uint32_t n; - njs_ret_t ret; + njs_int_t ret; njs_array_t *array; njs_value_t *value, name; const u_char *src, *end; @@ -566,11 +566,11 @@ njs_array_prototype_slice_copy(njs_vm_t } -static njs_ret_t +static njs_int_t njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { - njs_ret_t ret; + njs_int_t ret; njs_uint_t i; njs_array_t *array; @@ -596,7 +596,7 @@ njs_array_prototype_push(njs_vm_t *vm, n } -static njs_ret_t +static njs_int_t njs_array_prototype_pop(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -624,11 +624,11 @@ njs_array_prototype_pop(njs_vm_t *vm, nj } -static njs_ret_t +static njs_int_t njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { - njs_ret_t ret; + njs_int_t ret; njs_uint_t n; njs_array_t *array; @@ -660,7 +660,7 @@ njs_array_prototype_unshift(njs_vm_t *vm } -static njs_ret_t +static njs_int_t njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -690,11 +690,11 @@ njs_array_prototype_shift(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { - njs_ret_t ret; + njs_int_t ret; njs_int_t n, start, length, items, delta, delete; njs_uint_t i; njs_array_t *array, *deleted; @@ -790,7 +790,7 @@ njs_array_prototype_splice(njs_vm_t *vm, } -static njs_ret_t +static njs_int_t njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -821,7 +821,7 @@ njs_array_prototype_reverse(njs_vm_t *vm } -static njs_ret_t +static njs_int_t njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -844,14 +844,14 @@ njs_array_prototype_to_string(njs_vm_t * } -static njs_ret_t +static njs_int_t njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { u_char *p; uint32_t max; size_t size, length, mask; - njs_ret_t ret; + njs_int_t ret; njs_uint_t i, n; njs_array_t *array; njs_value_t *value, *values; @@ -989,7 +989,7 @@ njs_array_prototype_join(njs_vm_t *vm, n } -static njs_ret_t +static njs_int_t njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1048,7 +1048,7 @@ njs_array_copy(njs_value_t *dst, njs_val } -static njs_ret_t +static njs_int_t njs_array_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { @@ -1108,7 +1108,7 @@ done: From mdounin at mdounin.ru Wed Jul 31 14:48:35 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 31 Jul 2019 14:48:35 +0000 Subject: [nginx] Version bump. Message-ID: details: https://hg.nginx.org/nginx/rev/e1a3fa4c054f branches: changeset: 7544:e1a3fa4c054f user: Maxim Dounin date: Wed Jul 31 17:28:41 2019 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1017002 -#define NGINX_VERSION "1.17.2" +#define nginx_version 1017003 +#define NGINX_VERSION "1.17.3" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Wed Jul 31 14:48:37 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 31 Jul 2019 14:48:37 +0000 Subject: [nginx] Gzip: fixed "zero size buf" alerts after ac5a741d39cf. Message-ID: details: https://hg.nginx.org/nginx/rev/0ef2bc0ec9c9 branches: changeset: 7545:0ef2bc0ec9c9 user: Maxim Dounin date: Wed Jul 31 17:29:00 2019 +0300 description: Gzip: fixed "zero size buf" alerts after ac5a741d39cf. After ac5a741d39cf it is now possible that after zstream.avail_out reaches 0 and we allocate additional buffer, there will be no more data to put into this buffer, triggering "zero size buf" alert. Fix is to reset b->temporary flag in this case. Additionally, an optimization added to avoid allocating additional buffer in this case, by checking if last deflate() call returned Z_STREAM_END. Note that checking for Z_STREAM_END by itself is not enough to fix alerts, as deflate() can return Z_STREAM_END without producing any output if the buffer is smaller than gzip trailer. Reported by Witold Filipczyk, http://mailman.nginx.org/pipermail/nginx-devel/2019-July/012469.html. diffstat: src/http/modules/ngx_http_gzip_filter_module.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diffs (43 lines): diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -778,7 +778,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re ctx->out_buf->last = ctx->zstream.next_out; - if (ctx->zstream.avail_out == 0) { + if (ctx->zstream.avail_out == 0 && rc != Z_STREAM_END) { /* zlib wants to output some more gzipped data */ @@ -868,6 +868,7 @@ ngx_http_gzip_filter_deflate_end(ngx_htt ngx_http_gzip_ctx_t *ctx) { int rc; + ngx_buf_t *b; ngx_chain_t *cl; ctx->zin = ctx->zstream.total_in; @@ -888,13 +889,19 @@ ngx_http_gzip_filter_deflate_end(ngx_htt return NGX_ERROR; } - cl->buf = ctx->out_buf; + b = ctx->out_buf; + + if (ngx_buf_size(b) == 0) { + b->temporary = 0; + } + + b->last_buf = 1; + + cl->buf = b; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; - ctx->out_buf->last_buf = 1; - ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; From mdounin at mdounin.ru Wed Jul 31 14:50:44 2019 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 31 Jul 2019 17:50:44 +0300 Subject: zero size buf in writer in 1.17.2 In-Reply-To: <20190730112326.GA7802@lenovo> References: <20190728143218.GA15027@lenovo> <20190729164841.GC1877@mdounin.ru> <20190730112326.GA7802@lenovo> Message-ID: <20190731145043.GN1877@mdounin.ru> Hello! On Tue, Jul 30, 2019 at 01:23:26PM +0200, Witold Filipczyk wrote: > On Mon, Jul 29, 2019 at 07:48:41PM +0300, Maxim Dounin wrote: > > Hello! > > > > On Sun, Jul 28, 2019 at 04:32:18PM +0200, Witold Filipczyk wrote: > > > > > Hi, > > > There is error in log: > > > 2019/07/28 09:46:10 [alert] 2471467#2471467: *407 zero size buf in writer t:1 r:1 f:0 00007F482A259000 00007F482A259000-00007F482A259000 0000000000000000 0-0 while sending response to client, client: 127.0.0.1, server: localhost, request: "GET /Skrypty-m.js HTTP/1.1", host: "localhost" > > > > > > Reproducible at least on two machines. > > > > [...] > > > > > Skrypty-m.js in the attachment. > > > The error does not occur in 1.17.1 and earlier. > > > > Thank you for the report, it seems to be a problem introduced in > > ac5a741d39cf. I'm able to reproduce it with the file and gzip > > configuration provided. > > > > The following patch should fix this: > > > > # HG changeset patch > > # User Maxim Dounin > > # Date 1564415524 -10800 > > # Mon Jul 29 18:52:04 2019 +0300 > > # Node ID aff4d33c72d8ee1a986d3e4c8e5c0f3d1b20962f > > # Parent e7181cfe9212de7f67df805bb746519c059b490b > > Gzip: fixed "zero size buf" alerts after ac5a741d39cf. > > > > After ac5a741d39cf it is now possible that after zstream.avail_out > > reaches 0 and we allocate additional buffer, there will be no more data > > to put into this buffer, triggering "zero size buf" alert. > > > > Fix is to avoid allocating additional buffer in this case, by checking > > if last deflate() call returned Z_STREAM_END. > > > > diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c > > --- a/src/http/modules/ngx_http_gzip_filter_module.c > > +++ b/src/http/modules/ngx_http_gzip_filter_module.c > > @@ -778,7 +778,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re > > > > ctx->out_buf->last = ctx->zstream.next_out; > > > > - if (ctx->zstream.avail_out == 0) { > > + if (ctx->zstream.avail_out == 0 && rc != Z_STREAM_END) { > > > > /* zlib wants to output some more gzipped data */ > > > > No error so far, thanks. Committed an improved version of the patch, thanks for testing. http://hg.nginx.org/nginx/rev/0ef2bc0ec9c9 -- Maxim Dounin http://mdounin.ru/