[njs] Removed surplus condition from Base64 decoded length counting.
details: https://hg.nginx.org/njs/rev/264fb92817cd branches: changeset: 1730:264fb92817cd user: Valentin Bartenev date: Tue Oct 26 16:14:07 2021 +0300 description: Removed surplus condition from Base64 decoded length counting. diffstat: src/njs_string.c | 4 1 files changed, 0 insertions(+), 4 deletions(-) diffs (14 lines): diff -r b9bbb230fe4f -r 264fb92817cd src/njs_string.c --- a/src/njs_string.c Wed Oct 20 13:01:55 2021 + +++ b/src/njs_string.c Tue Oct 26 16:14:07 2021 +0300 @@ -1885,10 +1885,6 @@ njs_decode_base64_length_core(const njs_ size_t len; for (len = 0; len < src->length; len++) { -if (src->start[len] == '=') { -break; -} - if (basis[src->start[len]] == 77) { break; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Unicode case tables updated to version 14.0.0 (May 2021).
details: https://hg.nginx.org/njs/rev/36dd0370b121 branches: changeset: 1673:36dd0370b121 user: Valentin Bartenev date: Fri Jul 09 12:03:11 2021 +0300 description: Unicode case tables updated to version 14.0.0 (May 2021). diffstat: src/njs_unicode_lower_case.h | 60 ++- src/njs_unicode_upper_case.h | 36 +- src/njs_utf8.c | 2 +- 3 files changed, 82 insertions(+), 16 deletions(-) diffs (184 lines): diff -r 45c470a2d710 -r 36dd0370b121 src/njs_unicode_lower_case.h --- a/src/njs_unicode_lower_case.h Tue Jun 29 17:08:23 2021 +0300 +++ b/src/njs_unicode_lower_case.h Fri Jul 09 12:03:11 2021 +0300 @@ -1,7 +1,7 @@ /* - * 33 128-bytes blocks, 979 pointers. - * 20330 bytes on 32-bit platforms, 24242 bytes on 64-bit platforms. + * 35 128-bytes blocks, 979 pointers. + * 21354 bytes on 32-bit platforms, 25266 bytes on 64-bit platforms. */ #define NJS_UNICODE_MAX_LOWER_CASE 0x1e921 @@ -457,7 +457,7 @@ static const uint32_t njs_unicode_lower 0x02c40, 0x02c41, 0x02c42, 0x02c43, 0x02c44, 0x02c45, 0x02c46, 0x02c47, 0x02c48, 0x02c49, 0x02c4a, 0x02c4b, 0x02c4c, 0x02c4d, 0x02c4e, 0x02c4f, 0x02c50, 0x02c51, 0x02c52, 0x02c53, 0x02c54, 0x02c55, 0x02c56, 0x02c57, -0x02c58, 0x02c59, 0x02c5a, 0x02c5b, 0x02c5c, 0x02c5d, 0x02c5e, 0x02c2f, +0x02c58, 0x02c59, 0x02c5a, 0x02c5b, 0x02c5c, 0x02c5d, 0x02c5e, 0x02c5f, 0x02c30, 0x02c31, 0x02c32, 0x02c33, 0x02c34, 0x02c35, 0x02c36, 0x02c37, 0x02c38, 0x02c39, 0x02c3a, 0x02c3b, 0x02c3c, 0x02c3d, 0x02c3e, 0x02c3f, 0x02c40, 0x02c41, 0x02c42, 0x02c43, 0x02c44, 0x02c45, 0x02c46, 0x02c47, @@ -570,10 +570,10 @@ static const uint32_t njs_unicode_lower 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, 0x0a7c8, +0x0a7c1, 0x0a7c1, 0x0a7c3, 0x0a7c3, 0x0a794, 0x00282, 0x01d8e, 0x0a7c8, 0x0a7c8, 0x0a7ca, 0x0a7ca, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, -0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, -0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, +0x0a7d1, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d7, 0x0a7d7, +0x0a7d9, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, 0x0a7e0, 0x0a7e1, 0x0a7e2, 0x0a7e3, 0x0a7e4, 0x0a7e5, 0x0a7e6, 0x0a7e7, 0x0a7e8, 0x0a7e9, 0x0a7ea, 0x0a7eb, 0x0a7ec, 0x0a7ed, 0x0a7ee, 0x0a7ef, 0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f6, 0x0a7f6, 0x0a7f7, @@ -647,6 +647,50 @@ static const uint32_t njs_unicode_lower }; +static const uint32_t njs_unicode_lower_case_block_20a[128] +njs_aligned(64) = +{ +0x10500, 0x10501, 0x10502, 0x10503, 0x10504, 0x10505, 0x10506, 0x10507, +0x10508, 0x10509, 0x1050a, 0x1050b, 0x1050c, 0x1050d, 0x1050e, 0x1050f, +0x10510, 0x10511, 0x10512, 0x10513, 0x10514, 0x10515, 0x10516, 0x10517, +0x10518, 0x10519, 0x1051a, 0x1051b, 0x1051c, 0x1051d, 0x1051e, 0x1051f, +0x10520, 0x10521, 0x10522, 0x10523, 0x10524, 0x10525, 0x10526, 0x10527, +0x10528, 0x10529, 0x1052a, 0x1052b, 0x1052c, 0x1052d, 0x1052e, 0x1052f, +0x10530, 0x10531, 0x10532, 0x10533, 0x10534, 0x10535, 0x10536, 0x10537, +0x10538, 0x10539, 0x1053a, 0x1053b, 0x1053c, 0x1053d, 0x1053e, 0x1053f, +0x10540, 0x10541, 0x10542, 0x10543, 0x10544, 0x10545, 0x10546, 0x10547, +0x10548, 0x10549, 0x1054a, 0x1054b, 0x1054c, 0x1054d, 0x1054e, 0x1054f, +0x10550, 0x10551, 0x10552, 0x10553, 0x10554, 0x10555, 0x10556, 0x10557, +0x10558, 0x10559, 0x1055a, 0x1055b, 0x1055c, 0x1055d, 0x1055e, 0x1055f, +0x10560, 0x10561, 0x10562, 0x10563, 0x10564, 0x10565, 0x10566, 0x10567, +0x10568, 0x10569, 0x1056a, 0x1056b, 0x1056c, 0x1056d, 0x1056e, 0x1056f, +0x10597, 0x10598, 0x10599, 0x1059a, 0x1059b, 0x1059c, 0x1059d, 0x1059e, +0x1059f, 0x105a0, 0x105a1, 0x1057b, 0x105a3, 0x105a4, 0x105a5, 0x105a6, +}; + + +static const uint32_t njs_unicode_lower_case_block_20b[128] +njs_aligned(64) = +{ +0x105a7, 0x105a8, 0x105a9, 0x105aa, 0x105ab, 0x105ac, 0x105ad, 0x105ae, +0x105af, 0x105b0, 0x105b1, 0x1058b, 0x105b3, 0x105b4, 0x105b5, 0x105b6, +0x105b7, 0x105b8, 0x105b9, 0x10593, 0x105bb, 0x105bc, 0x10596, 0x10597, +0x10598, 0x10599, 0x1059a, 0x1059b, 0x1059c, 0x1059d, 0x1059e, 0x1059f, +0x105a0, 0x105a1, 0x105a2, 0x105a3, 0x105a4, 0x105a5, 0x105a6, 0x105a7, +0x105a8, 0x105a9, 0x105aa, 0x105ab, 0x105ac, 0x105ad, 0x105ae, 0x105af, +0x105b0, 0x105b1, 0x105b2, 0x105b3, 0x105b4, 0x105b5, 0x105b6, 0x105b7, +0x105b8, 0x105b9, 0x105ba, 0x105bb, 0x105bc, 0x105bd, 0x105be, 0x105bf, +0x105c0, 0x105c1, 0x105c2, 0x105c3, 0x105c4, 0x105c5, 0x105c6, 0x105c7, +0x105c8, 0x105c9, 0x105ca, 0x105cb, 0x105cc, 0x105cd, 0x105ce
[njs] Ignoring pcre_study() error.
details: https://hg.nginx.org/njs/rev/e51da8c71f26 branches: changeset: 1569:e51da8c71f26 user: Valentin Bartenev date: Fri Nov 20 12:29:30 2020 +0300 description: Ignoring pcre_study() error. It provides optional optimization that shouldn't be fatal for regex compilation. diffstat: src/njs_pcre.c | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diffs (15 lines): diff -r c947a300b96c -r e51da8c71f26 src/njs_pcre.c --- a/src/njs_pcre.cWed Nov 18 18:09:11 2020 + +++ b/src/njs_pcre.cFri Nov 20 12:29:30 2020 +0300 @@ -94,10 +94,8 @@ njs_regex_compile(njs_regex_t *regex, u_ regex->extra = pcre_study(regex->code, 0, ); if (njs_slow_path(errstr != NULL)) { -njs_alert(ctx->trace, NJS_LEVEL_ERROR, +njs_alert(ctx->trace, NJS_LEVEL_WARN, "pcre_study(\"%s\") failed: %s", pattern, errstr); - -goto done; } err = pcre_fullinfo(regex->code, NULL, PCRE_INFO_CAPTURECOUNT, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added support for numeric separators (ES12).
details: https://hg.nginx.org/njs/rev/4818a450f4e6 branches: changeset: 1495:4818a450f4e6 user: Valentin Bartenev date: Mon Aug 17 19:55:46 2020 +0300 description: Added support for numeric separators (ES12). diffstat: src/njs_json.c |2 +- src/njs_lexer.c | 10 +++- src/njs_number.c | 42 +- src/njs_number.h |6 +- src/njs_parser.c |4 +- src/njs_string.c |6 +- src/njs_strtod.c | 36 +++- src/njs_strtod.h |3 +- src/test/njs_unit_test.c | 101 ++ 9 files changed, 173 insertions(+), 37 deletions(-) diffs (518 lines): diff -r 10a2c35d53e7 -r 4818a450f4e6 src/njs_json.c --- a/src/njs_json.cMon Aug 17 14:44:29 2020 +0300 +++ b/src/njs_json.cMon Aug 17 19:55:46 2020 +0300 @@ -796,7 +796,7 @@ njs_json_parse_number(njs_json_parse_ctx } start = p; -num = njs_number_dec_parse(, ctx->end); +num = njs_number_dec_parse(, ctx->end, 0); if (p != start) { njs_set_number(value, sign * num); return p; diff -r 10a2c35d53e7 -r 4818a450f4e6 src/njs_lexer.c --- a/src/njs_lexer.c Mon Aug 17 14:44:29 2020 +0300 +++ b/src/njs_lexer.c Mon Aug 17 19:55:46 2020 +0300 @@ -787,7 +787,7 @@ njs_lexer_number(njs_lexer_t *lexer, njs goto illegal_token; } -token->number = njs_number_hex_parse(, lexer->end); +token->number = njs_number_hex_parse(, lexer->end, 1); goto done; } @@ -830,16 +830,20 @@ njs_lexer_number(njs_lexer_t *lexer, njs /* Legacy Octal literals are deprecated. */ -if (*p >= '0' && *p <= '9') { +if ((*p >= '0' && *p <= '9') || *p == '_') { goto illegal_trailer; } } p--; -token->number = njs_number_dec_parse(, lexer->end); +token->number = njs_number_dec_parse(, lexer->end, 1); done: +if (p[-1] == '_') { +p--; +} + lexer->start = (u_char *) p; token->text.length = p - token->text.start; diff -r 10a2c35d53e7 -r 4818a450f4e6 src/njs_number.c --- a/src/njs_number.c Mon Aug 17 14:44:29 2020 +0300 +++ b/src/njs_number.c Mon Aug 17 19:55:46 2020 +0300 @@ -54,9 +54,10 @@ njs_key_to_index(const njs_value_t *valu double -njs_number_dec_parse(const u_char **start, const u_char *end) +njs_number_dec_parse(const u_char **start, const u_char *end, +njs_bool_t literal) { -return njs_strtod(start, end); +return njs_strtod(start, end, literal); } @@ -65,22 +66,27 @@ njs_number_oct_parse(const u_char **star { u_charc; uint64_t num; -const u_char *p; +const u_char *p, *_; p = *start; num = 0; +_ = p - 1; -while (p < end) { +for (; p < end; p++) { /* Values less than '0' become >= 208. */ c = *p - '0'; if (njs_slow_path(c > 7)) { +if (*p == '_' && (p - _) > 1) { +_ = p; +continue; +} + break; } num = num * 8 + c; -p++; } *start = p; @@ -94,22 +100,27 @@ njs_number_bin_parse(const u_char **star { u_charc; uint64_t num; -const u_char *p; +const u_char *p, *_; p = *start; num = 0; +_ = p - 1; -while (p < end) { +for (; p < end; p++) { /* Values less than '0' become >= 208. */ c = *p - '0'; if (njs_slow_path(c > 1)) { +if (*p == '_' && (p - _) > 1) { +_ = p; +continue; +} + break; } num = num * 2 + c; -p++; } *start = p; @@ -119,24 +130,31 @@ njs_number_bin_parse(const u_char **star uint64_t -njs_number_hex_parse(const u_char **start, const u_char *end) +njs_number_hex_parse(const u_char **start, const u_char *end, +njs_bool_t literal) { uint64_t num; njs_int_t n; -const u_char *p; +const u_char *p, *_; p = *start; num = 0; +_ = p - 1; -while (p < end) { +for (; p < end; p++) { n = njs_char_to_hex(*p); + if (njs_slow_path(n < 0)) { +if (literal && *p == '_' && (p - _) > 1) { +_ = p; +continue; +} + break; } num = num * 16 + n; -p++; } *start = p; diff -r 10a2c35d53e7 -r 4818a450f4e6 src/njs_number.h --- a/src/njs_number.h Mon Aug 17 14:44:29 2020 +0300 +++ b/src/njs_number.h Mon Aug 17 19:55:46 2020 +0300 @@ -12,10 +12,12 @@ double njs_key_to_index(const njs_value_t *value); -double njs_number_dec_parse(const u_char **start, const u_char *end); +double njs_number_dec_pa
[njs] Unicode case tables updated to version 13.0.0 (March 2020).
details: https://hg.nginx.org/njs/rev/10a2c35d53e7 branches: changeset: 1494:10a2c35d53e7 user: Valentin Bartenev date: Mon Aug 17 14:44:29 2020 +0300 description: Unicode case tables updated to version 13.0.0 (March 2020). diffstat: src/njs_unicode_lower_case.h | 6 +++--- src/njs_unicode_upper_case.h | 4 ++-- src/njs_utf8.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diffs (50 lines): diff -r eebf9e525358 -r 10a2c35d53e7 src/njs_unicode_lower_case.h --- a/src/njs_unicode_lower_case.h Mon Aug 17 11:22:35 2020 + +++ b/src/njs_unicode_lower_case.h Mon Aug 17 14:44:29 2020 +0300 @@ -570,13 +570,13 @@ static const uint32_t njs_unicode_lower 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, +0x0a7c0, 0x0a7c1, 0x0a7c3, 0x0a7c3, 0x0a794, 0x00282, 0x01d8e, 0x0a7c8, +0x0a7c8, 0x0a7ca, 0x0a7ca, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, 0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, 0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, 0x0a7e0, 0x0a7e1, 0x0a7e2, 0x0a7e3, 0x0a7e4, 0x0a7e5, 0x0a7e6, 0x0a7e7, 0x0a7e8, 0x0a7e9, 0x0a7ea, 0x0a7eb, 0x0a7ec, 0x0a7ed, 0x0a7ee, 0x0a7ef, -0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f5, 0x0a7f6, 0x0a7f7, +0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f6, 0x0a7f6, 0x0a7f7, 0x0a7f8, 0x0a7f9, 0x0a7fa, 0x0a7fb, 0x0a7fc, 0x0a7fd, 0x0a7fe, 0x0a7ff, }; diff -r eebf9e525358 -r 10a2c35d53e7 src/njs_unicode_upper_case.h --- a/src/njs_unicode_upper_case.h Mon Aug 17 11:22:35 2020 + +++ b/src/njs_unicode_upper_case.h Mon Aug 17 14:44:29 2020 +0300 @@ -681,12 +681,12 @@ static const uint32_t njs_unicode_upper 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, +0x0a7c7, 0x0a7c9, 0x0a7c9, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, 0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, 0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, 0x0a7e0, 0x0a7e1, 0x0a7e2, 0x0a7e3, 0x0a7e4, 0x0a7e5, 0x0a7e6, 0x0a7e7, 0x0a7e8, 0x0a7e9, 0x0a7ea, 0x0a7eb, 0x0a7ec, 0x0a7ed, 0x0a7ee, 0x0a7ef, -0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f5, 0x0a7f6, 0x0a7f7, +0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f5, 0x0a7f5, 0x0a7f7, 0x0a7f8, 0x0a7f9, 0x0a7fa, 0x0a7fb, 0x0a7fc, 0x0a7fd, 0x0a7fe, 0x0a7ff, }; diff -r eebf9e525358 -r 10a2c35d53e7 src/njs_utf8.c --- a/src/njs_utf8.cMon Aug 17 11:22:35 2020 + +++ b/src/njs_utf8.cMon Aug 17 14:44:29 2020 +0300 @@ -9,7 +9,7 @@ /* * The njs_unicode_lower_case.h and njs_unicode_upper_case.h files are - * files auto-generated from the UnicodeData.txt file version 12.1.0 (May 2019) + * auto-generated from the UnicodeData.txt file version 13.0.0 (March 2020) * provided by Unicode, Inc.: * * ./njs_unicode_lower_case.pl UnicodeData.txt ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Introduced nullish coalescing operator.
details: https://hg.nginx.org/njs/rev/9c1ef5ab7a1f branches: changeset: 1284:9c1ef5ab7a1f user: Valentin Bartenev date: Thu Dec 12 18:50:27 2019 +0300 description: Introduced nullish coalescing operator. diffstat: src/njs_disassembler.c | 12 ++ src/njs_generator.c | 1 + src/njs_lexer.c | 11 ++ src/njs_lexer.h | 2 + src/njs_parser_expression.c | 81 +++- src/njs_vmcode.c| 9 +++- src/njs_vmcode.h| 26 +++-- src/test/njs_unit_test.c| 17 + 8 files changed, 142 insertions(+), 17 deletions(-) diffs (262 lines): diff -r 5bf71dfc052f -r 9c1ef5ab7a1f src/njs_disassembler.c --- a/src/njs_disassembler.cWed Dec 11 15:58:05 2019 +0300 +++ b/src/njs_disassembler.cThu Dec 12 18:50:27 2019 +0300 @@ -282,6 +282,18 @@ njs_disassemble(u_char *start, u_char *e continue; } +if (operation == NJS_VMCODE_COALESCE) { +test_jump = (njs_vmcode_test_jump_t *) p; + +njs_printf("%05uz COALESCE %04Xz %04Xz +%uz\n", + p - start, (size_t) test_jump->retval, + (size_t) test_jump->value, (size_t) test_jump->offset); + +p += sizeof(njs_vmcode_test_jump_t); + +continue; +} + if (operation == NJS_VMCODE_FUNCTION_FRAME) { function = (njs_vmcode_function_frame_t *) p; diff -r 5bf71dfc052f -r 9c1ef5ab7a1f src/njs_generator.c --- a/src/njs_generator.c Wed Dec 11 15:58:05 2019 +0300 +++ b/src/njs_generator.c Thu Dec 12 18:50:27 2019 +0300 @@ -361,6 +361,7 @@ njs_generate(njs_vm_t *vm, njs_generator case NJS_TOKEN_LOGICAL_AND: case NJS_TOKEN_LOGICAL_OR: +case NJS_TOKEN_COALESCE: return njs_generate_test_jump_expression(vm, generator, node); case NJS_TOKEN_DELETE: diff -r 5bf71dfc052f -r 9c1ef5ab7a1f src/njs_lexer.c --- a/src/njs_lexer.c Wed Dec 11 15:58:05 2019 +0300 +++ b/src/njs_lexer.c Thu Dec 12 18:50:27 2019 +0300 @@ -276,6 +276,11 @@ static const njs_lexer_multi_t njs_grea }; +static const njs_lexer_multi_t njs_conditional_token[] = { +{ '?', NJS_TOKEN_COALESCE, 0, NULL }, +}; + + static const njs_lexer_multi_t njs_assignment_token[] = { { '=', NJS_TOKEN_EQUAL, 1, njs_strict_equal_token }, { '>', NJS_TOKEN_ARROW, 0, NULL }, @@ -551,6 +556,12 @@ njs_lexer_next_token(njs_lexer_t *lexer, goto multi; +case NJS_TOKEN_CONDITIONAL: +n = njs_nitems(njs_conditional_token), +multi = njs_conditional_token; + +goto multi; + case NJS_TOKEN_LINE_END: lexer->line++; diff -r 5bf71dfc052f -r 9c1ef5ab7a1f src/njs_lexer.h --- a/src/njs_lexer.h Wed Dec 11 15:58:05 2019 +0300 +++ b/src/njs_lexer.h Thu Dec 12 18:50:27 2019 +0300 @@ -95,6 +95,8 @@ typedef enum { NJS_TOKEN_BITWISE_NOT, NJS_TOKEN_LOGICAL_NOT, +NJS_TOKEN_COALESCE, + NJS_TOKEN_IN, NJS_TOKEN_INSTANCEOF, NJS_TOKEN_TYPEOF, diff -r 5bf71dfc052f -r 9c1ef5ab7a1f src/njs_parser_expression.c --- a/src/njs_parser_expression.c Wed Dec 11 15:58:05 2019 +0300 +++ b/src/njs_parser_expression.c Thu Dec 12 18:50:27 2019 +0300 @@ -41,6 +41,8 @@ static njs_token_t njs_parser_any_expres njs_token_t token); static njs_token_t njs_parser_conditional_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); +static njs_token_t njs_parser_coalesce_expression(njs_vm_t *vm, +njs_parser_t *parser, njs_token_t token); static njs_token_t njs_parser_binary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); @@ -359,9 +361,7 @@ njs_parser_conditional_expression(njs_vm { njs_parser_node_t *node, *cond; -token = njs_parser_binary_expression(vm, parser, - _parser_logical_or_expression, - token); +token = njs_parser_coalesce_expression(vm, parser, token); if (njs_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -421,6 +421,81 @@ njs_parser_conditional_expression(njs_vm static njs_token_t +njs_parser_coalesce_expression(njs_vm_t *vm, njs_parser_t *parser, +njs_token_t token) +{ +njs_token_tprev_token, next_token; +njs_parser_node_t *node; + +token = njs_parser_binary_expression(vm, parser, + _parser_logical_or_expression, + token); +if (njs_slow_path(token <= NJS_TOKEN_ILLEGAL)) { +return token; +} + +for ( ;; ) { +if (token != NJS_TOKEN_COALESCE) { +return token; +} + +prev_token = parser->lexer->prev_token; + +node = njs_parser_node_new(vm, parser, NJS_TOKEN_COALESCE); +
[njs] Date.prototype.toUTCString() format was aligned to ES9.
details: https://hg.nginx.org/njs/rev/5c22e2f006fe branches: changeset: 1166:5c22e2f006fe user: Valentin Bartenev date: Fri Sep 27 22:21:55 2019 +0300 description: Date.prototype.toUTCString() format was aligned to ES9. This closes #224 issue on GitHub. diffstat: src/njs_date.c | 12 +++- src/test/njs_unit_test.c | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diffs (57 lines): diff -r f516c8332495 -r 5c22e2f006fe src/njs_date.c --- a/src/njs_date.cThu Sep 19 10:19:02 2019 +0300 +++ b/src/njs_date.cFri Sep 27 22:21:55 2019 +0300 @@ -14,7 +14,9 @@ * FreeBSD and MacOSX timegm() cannot handle years before 1900. */ -#define NJS_ISO_DATE_TIME_LEN sizeof("+001970-09-28T12:00:00.000Z") +#define NJS_ISO_DATE_TIME_LEN sizeof("+001970-09-28T12:00:00.000Z") + +#define NJS_HTTP_DATE_TIME_LEN sizeof("Mon, 28 Sep 1970 12:00:00 GMT") #define NJS_DATE_TIME_LEN \ sizeof("Mon Sep 28 1970 12:00:00 GMT+0600 (X)") @@ -1009,7 +1011,7 @@ njs_date_prototype_to_utc_string(njs_vm_ { double time; time_t clock; -u_char buf[NJS_DATE_TIME_LEN], *p; +u_char buf[NJS_HTTP_DATE_TIME_LEN], *p; struct tm tm; static const char *week[] = { "Sun", "Mon", "Tue", "Wed", @@ -1024,9 +1026,9 @@ njs_date_prototype_to_utc_string(njs_vm_ clock = time / 1000; gmtime_r(, ); -p = njs_sprintf(buf, buf + NJS_DATE_TIME_LEN, -"%s %s %02d %4d %02d:%02d:%02d GMT", -week[tm.tm_wday], month[tm.tm_mon], tm.tm_mday, +p = njs_sprintf(buf, buf + NJS_HTTP_DATE_TIME_LEN, +"%s, %02d %s %4d %02d:%02d:%02d GMT", +week[tm.tm_wday], tm.tm_mday, month[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec); return njs_string_new(vm, >retval, buf, p - buf, p - buf); diff -r f516c8332495 -r 5c22e2f006fe src/test/njs_unit_test.c --- a/src/test/njs_unit_test.c Thu Sep 19 10:19:02 2019 +0300 +++ b/src/test/njs_unit_test.c Fri Sep 27 22:21:55 2019 +0300 @@ -11323,7 +11323,7 @@ static njs_unit_test_t njs_test[] = njs_str("18:45:00 GMT+") }, { njs_str("var d = new Date(2011, 5, 24, 18, 45); d.toUTCString()"), - njs_str("Fri Jun 24 2011 18:45:00 GMT") }, + njs_str("Fri, 24 Jun 2011 18:45:00 GMT") }, { njs_str("var d = new Date(2011, 5, 24, 18, 45, 12, 625);" "d.toISOString()"), @@ -14074,7 +14074,7 @@ static njs_unit_test_t njs_tz_test[] = njs_str("18:45:00 GMT+1245") }, { njs_str("var d = new Date(2011, 5, 24, 18, 45); d.toUTCString()"), - njs_str("Fri Jun 24 2011 06:00:00 GMT") }, + njs_str("Fri, 24 Jun 2011 06:00:00 GMT") }, { njs_str("var d = new Date(2011, 5, 24, 18, 45, 12, 625);" "d.toISOString()"), ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed undefined behaviour in left shift of negative numbers.
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; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Slight improvements to njs_vmcode_interpreter().
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; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added String.prototype.trimStrart() and String.prototype.trimEnd().
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_END2 + + 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, [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, [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, [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(, [0]); - -p = string.start; +njs_string_prop(, 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(, 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: -
[njs] Updated the list of space separators in String.prototype.trim().
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") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed String.fromCodePoint(), broken after 0b82f1c9268c.
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([i])) { +ret = njs_value_to_numeric(vm, [i], [i]); +if (ret != NXT_OK) { +return ret; +} +} +} + +size = 0; + +for (i = 1; i < nargs; i++) { +num = njs_number([i]); +if (isnan(num)) { +goto range_error; +} + +code = num; + +if (code != num || code < 0 || code >= 0x11) { +goto range_error; +} + +size += nxt_utf8_size(code); +} + +p = njs_string_alloc(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([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("A") }, + { 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[] = "})()"
[njs] Fixed String.toLowerCase() and String.toUpperCase().
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(, [0]); -start = njs_string_alloc(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, >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(, end); +size += nxt_utf8_size(code); +length--; +} + +p = njs_string_alloc(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(, end)); +code = nxt_utf8_lower_case(, 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(, [0]); -start = njs_string_alloc(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, >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(, end); +size += nxt_utf8_size(code); +length--; +} + +p = njs_string_alloc(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(, end)); +code = nxt_utf8_upper_case(, 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") }, +
[njs] Fixed String.fromCharCode() for code points > 65535 and NaN.
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_tcode; 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([i]); -if (isnan(num)) { -goto range_error; -} - -code = num; - -if (code != num || code < 0 || code >= 0x11) { -goto range_error; -} - -size += nxt_utf8_size(code); +code = njs_number_to_uint16(njs_number([i])); +size += nxt_utf8_size_uint16(code); } p = njs_string_alloc(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([i])); +code = njs_number_to_uint16(njs_number([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" "})()"), -
[njs] Unicode case tables updated to version 12.1 (May 2019).
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 @@ -,7 +,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, +0x0
[njs] Style in nxt_unicode_upper_case.pl and nxt_unicode_upper_case.h.
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) { ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Optimized nxt_dec_count() using bisection.
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.cThu Jul 25 20:17:42 2019 +0300 +++ b/nxt/nxt_dtoa.cThu 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 < 1) return 4; -if (n < 10) return 5; -if (n < 100) return 6; -if (n < 1000) return 7; -if (n < 1) return 8; -if (n < 10) return 9; +if (n < 1) { +if (n < 100) { +return (n < 10) ? 1 : 2; + +} else { +return (n < 1000) ? 3 : 4; +} -return 10; +} else { +if (n < 100) { +return (n < 10) ? 5 : 6; + +} else { +if (n < 1) { +return (n < 1000) ? 7 : 8; + +} else { +return (n < 10) ? 9 : 10; +} +} +} } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed one byte overread in njs_string_to_c_string().
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_charstart[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; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Optimized inlining of njs_values_strict_equal().
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_tsize; +size_tsize, 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_tsize, 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
[njs] Reduced nesting level of branches in njs_string_replace_regexp().
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 + +++ 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(>parts, _array_mem_proto, +vm->mem_pool); +if (nxt_slow_path(r->part == NULL)) { +return NXT_ERROR; +} + +r->part = nxt_array_add(>parts, _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(>parts, _array_mem_proto, -vm->mem_pool); -if (nxt_slow_path(r->part == NULL)) { -return NXT_ERROR; -} - -r->part = nxt_array_add(>parts, _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(>part[2].value); - -if (r->function != NULL) { -return njs_string_replace_regexp_function(vm, args, r, - captures, ret); -} - -
[njs] Version bump.
details: https://hg.nginx.org/njs/rev/0119e834a202 branches: changeset: 1018:0119e834a202 user: Valentin Bartenev date: Thu Jun 27 18:54:21 2019 +0300 description: Version bump. diffstat: njs/njs.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 63cd8e6679ba -r 0119e834a202 njs/njs.h --- a/njs/njs.h Tue Jun 25 14:44:55 2019 +0300 +++ b/njs/njs.h Thu Jun 27 18:54:21 2019 +0300 @@ -11,7 +11,7 @@ #include -#define NJS_VERSION "0.3.3" +#define NJS_VERSION "0.3.4" #include ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Removed unused nxt_lvlhsh_ctx_t structure.
details: https://hg.nginx.org/njs/rev/40f26bb516a6 branches: changeset: 1020:40f26bb516a6 user: Valentin Bartenev date: Thu Jun 27 18:55:34 2019 +0300 description: Removed unused nxt_lvlhsh_ctx_t structure. diffstat: nxt/nxt_lvlhsh.h | 10 -- 1 files changed, 0 insertions(+), 10 deletions(-) diffs (20 lines): diff -r 9db5e400480c -r 40f26bb516a6 nxt/nxt_lvlhsh.h --- a/nxt/nxt_lvlhsh.h Thu Jun 27 18:55:34 2019 +0300 +++ b/nxt/nxt_lvlhsh.h Thu Jun 27 18:55:34 2019 +0300 @@ -79,16 +79,6 @@ typedef struct { typedef struct { -nxt_lvlhsh_test_t test; -nxt_lvlhsh_alloc_talloc; -nxt_lvlhsh_free_t free; - -/* The maximum allowed aligned shift. */ -uint32_t max_shift; -} nxt_lvlhsh_ctx_t; - - -typedef struct { void *slot; } nxt_lvlhsh_t; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Removed unused nalloc parameter from lvlhsh allocation functions.
details: https://hg.nginx.org/njs/rev/9db5e400480c branches: changeset: 1019:9db5e400480c user: Valentin Bartenev date: Thu Jun 27 18:55:34 2019 +0300 description: Removed unused nalloc parameter from lvlhsh allocation functions. diffstat: njs/njs_event.c | 1 - njs/njs_extern.c| 2 -- njs/njs_lexer_keyword.c | 1 - njs/njs_module.c| 1 - njs/njs_object.c| 1 - njs/njs_shell.c | 5 ++--- njs/njs_string.c| 1 - njs/njs_variable.c | 2 -- njs/njs_vm.c| 2 +- njs/njs_vm.h| 2 +- njs/test/njs_unit_test.c| 3 +-- nxt/nxt_lvlhsh.c| 5 ++--- nxt/nxt_lvlhsh.h| 6 +- nxt/test/lvlhsh_unit_test.c | 3 +-- 14 files changed, 9 insertions(+), 26 deletions(-) diffs (252 lines): diff -r 0119e834a202 -r 9db5e400480c njs/njs_event.c --- a/njs/njs_event.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_event.c Thu Jun 27 18:55:34 2019 +0300 @@ -15,7 +15,6 @@ const nxt_lvlhsh_proto_t njs_event_hash nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_event_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_extern.c --- a/njs/njs_extern.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_extern.c Thu Jun 27 18:55:34 2019 +0300 @@ -50,7 +50,6 @@ const nxt_lvlhsh_proto_t njs_extern_has nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -NXT_LVLHSH_BATCH_ALLOC, njs_extern_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, @@ -61,7 +60,6 @@ const nxt_lvlhsh_proto_t njs_extern_val nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -NXT_LVLHSH_BATCH_ALLOC, njs_extern_value_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_lexer_keyword.c Thu Jun 27 18:55:34 2019 +0300 @@ -138,7 +138,6 @@ const nxt_lvlhsh_proto_t njs_keyword_ha nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_keyword_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_module.c --- a/njs/njs_module.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_module.c Thu Jun 27 18:55:34 2019 +0300 @@ -415,7 +415,6 @@ const nxt_lvlhsh_proto_t njs_modules_ha nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_module_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_object.c --- a/njs/njs_object.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_object.c Thu Jun 27 18:55:34 2019 +0300 @@ -149,7 +149,6 @@ const nxt_lvlhsh_proto_t njs_object_has nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_object_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_shell.c --- a/njs/njs_shell.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_shell.c Thu Jun 27 18:55:34 2019 +0300 @@ -107,7 +107,7 @@ static void njs_console_clear_timer(njs_ njs_host_event_t event); static nxt_int_t lvlhsh_key_test(nxt_lvlhsh_query_t *lhq, void *data); -static void *lvlhsh_pool_alloc(void *pool, size_t size, nxt_uint_t nalloc); +static void *lvlhsh_pool_alloc(void *pool, size_t size); static void lvlhsh_pool_free(void *pool, void *p, size_t size); @@ -192,7 +192,6 @@ static njs_external_t njs_externals[] = static const nxt_lvlhsh_proto_t lvlhsh_proto nxt_aligned(64) = { NXT_LVLHSH_LARGE_SLAB, -0, lvlhsh_key_test, lvlhsh_pool_alloc, lvlhsh_pool_free, @@ -1227,7 +1226,7 @@ lvlhsh_key_test(nxt_lvlhsh_query_t *lhq, static void * -lvlhsh_pool_alloc(void *pool, size_t size, nxt_uint_t nalloc) +lvlhsh_pool_alloc(void *pool, size_t size) { return nxt_mp_align(pool, size, size); } diff -r 0119e834a202 -r 9db5e400480c njs/njs_string.c --- a/njs/njs_string.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_string.c Thu Jun 27 18:55:34 2019 +0300 @@ -4591,7 +4591,6 @@ static const nxt_lvlhsh_proto_t njs_val nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_values_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_variable.c --- a/njs/njs_variable.cThu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_variable.cThu Jun 27 18:55:34 2019 +0300 @@ -37,7 +37,6 @@ const nxt_lvlhsh_proto_t njs_variables_ nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_variables_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, @@ -232,7 +231,6 @@ const nxt_lvlhsh_proto_t njs_references nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, -0, njs_reference_hash_test, njs_lvlhsh_alloc, njs_lvlhsh_free, diff -r 0119e834a202 -r 9db5e400480c njs/njs_vm.c --- a/njs/njs_vm.c Thu Jun 27 18:54:21 2019 +0300 +++ b/njs/njs_vm.c Thu Jun 27 18:55:34 2019 +0300 @@ -3672,7
[njs] Added "name" property for built-in methods.
details: https://hg.nginx.org/njs/rev/5906cf108796 branches: changeset: 983:5906cf108796 user: Valentin Bartenev date: Thu May 23 16:21:55 2019 +0300 description: Added "name" property for built-in methods. diffstat: njs/njs_object.c | 28 ++-- njs/test/njs_unit_test.c | 33 - 2 files changed, 58 insertions(+), 3 deletions(-) diffs (95 lines): diff -r 4296c5b56e30 -r 5906cf108796 njs/njs_object.c --- a/njs/njs_object.c Thu May 23 15:05:52 2019 +0300 +++ b/njs/njs_object.c Thu May 23 16:21:55 2019 +0300 @@ -710,8 +710,12 @@ njs_external_property_delete(njs_vm_t *v njs_ret_t njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq) { -njs_function_t *function; -njs_object_prop_t *prop, *shared; +nxt_int_t ret; +njs_function_t *function; +njs_object_prop_t *prop, *shared, *name; +nxt_lvlhsh_query_t lhq; + +static const njs_value_t name_string = njs_string("name"); prop = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t), sizeof(njs_object_prop_t)); @@ -735,6 +739,26 @@ njs_method_private_copy(njs_vm_t *vm, nj function->object.shared_hash = vm->shared->arrow_instance_hash; } +name = njs_object_prop_alloc(vm, _string, >name, 0); +if (nxt_slow_path(name == NULL)) { +return NXT_ERROR; +} + +name->configurable = 1; + +lhq.key_hash = NJS_NAME_HASH; +lhq.key = nxt_string_value("name"); +lhq.replace = 0; +lhq.value = name; +lhq.proto = _object_hash_proto; +lhq.pool = vm->mem_pool; + +ret = nxt_lvlhsh_insert(>object.hash, ); +if (nxt_slow_path(ret != NXT_OK)) { +njs_internal_error(vm, "lvlhsh insert failed"); +return NXT_ERROR; +} + pq->lhq.replace = 0; pq->lhq.value = prop; pq->lhq.pool = vm->mem_pool; diff -r 4296c5b56e30 -r 5906cf108796 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu May 23 15:05:52 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu May 23 16:21:55 2019 +0300 @@ -9625,7 +9625,7 @@ static njs_unit_test_t njs_test[] = nxt_string("name,length,prototype,isArray,of") }, { nxt_string("Object.getOwnPropertyNames(Array.isArray)"), - nxt_string("length") }, + nxt_string("name,length") }, { nxt_string("Object.defineProperty(Object.freeze({}), 'b', {})"), nxt_string("TypeError: object is not extensible") }, @@ -12173,6 +12173,37 @@ static njs_unit_test_t njs_test[] = { nxt_string("njs.dump($r.header)"), nxt_string("{type:\"object\",props:[\"getter\",\"foreach\",\"next\"]}") }, +/* Built-in methods name. */ + +{ nxt_string( +"var fail;" +"function isMethodsHaveName(o) {" +"var except = [" +"'prototype'," +"'constructor'," +"];" +"return Object.getOwnPropertyNames(o)" +" .filter(v => !except.includes(v)" +" && typeof o[v] == 'function')" +" .every(v => o[v].name == v" +" || !(fail = `${o.name}.${v}: ${o[v].name}`));" +"}" +"[" +"Boolean, Boolean.prototype," +"Number, Number.prototype," +"String, String.prototype," +"Object, Object.prototype," +"Array, Array.prototype," +"Function, Function.prototype," +"RegExp, RegExp.prototype," +"Date, Date.prototype," +"Error, Error.prototype," +"Math," +"JSON," +"].every(obj => isMethodsHaveName(obj)) || fail"), + + nxt_string("true") }, + /* require(). */ { nxt_string("require('unknown_module')"), ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed overwriting "constructor" property of built-in prototypes.
details: https://hg.nginx.org/njs/rev/4296c5b56e30 branches: changeset: 982:4296c5b56e30 user: Valentin Bartenev date: Thu May 23 15:05:52 2019 +0300 description: Fixed overwriting "constructor" property of built-in prototypes. diffstat: njs/njs_object.c | 11 +++ njs/test/njs_unit_test.c | 9 + 2 files changed, 16 insertions(+), 4 deletions(-) diffs (54 lines): diff -r fd0918b6dd56 -r 4296c5b56e30 njs/njs_object.c --- a/njs/njs_object.c Thu May 23 15:05:51 2019 +0300 +++ b/njs/njs_object.c Thu May 23 15:05:52 2019 +0300 @@ -2909,8 +2909,11 @@ njs_object_prototype_create_constructor( found: -cons = njs_property_constructor_create(vm, >object.hash, - >scopes[NJS_SCOPE_GLOBAL][index]); +if (setval == NULL) { +setval = >scopes[NJS_SCOPE_GLOBAL][index]; +} + +cons = njs_property_constructor_create(vm, >object.hash, setval); if (nxt_fast_path(cons != NULL)) { *retval = *cons; return NXT_OK; @@ -2943,7 +2946,7 @@ njs_property_constructor_create(njs_vm_t lhq.value = prop; lhq.key_hash = NJS_CONSTRUCTOR_HASH; lhq.key = nxt_string_value("constructor"); -lhq.replace = 0; +lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = _object_hash_proto; @@ -2953,7 +2956,7 @@ njs_property_constructor_create(njs_vm_t return >value; } -njs_internal_error(vm, "lvlhsh insert failed"); +njs_internal_error(vm, "lvlhsh insert/replace failed"); return NULL; } diff -r fd0918b6dd56 -r 4296c5b56e30 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu May 23 15:05:51 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu May 23 15:05:52 2019 +0300 @@ -8480,6 +8480,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("Boolean.prototype.constructor === Boolean"), nxt_string("true") }, +{ nxt_string("Boolean.prototype.constructor = 1;" + "Boolean.prototype.constructor"), + nxt_string("1") }, + +{ nxt_string("var c = Boolean.prototype.constructor;" + "Boolean.prototype.constructor = 1;" + "[c(0), Boolean.prototype.constructor]"), + nxt_string("false,1") }, + { nxt_string("Boolean.prototype.hasOwnProperty('constructor')"), nxt_string("true") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Made writable most of built-in properties and methods.
details: https://hg.nginx.org/njs/rev/f7eedb8257eb branches: changeset: 980:f7eedb8257eb user: Valentin Bartenev date: Thu May 23 15:05:51 2019 +0300 description: Made writable most of built-in properties and methods. diffstat: njs/njs_array.c | 29 - njs/njs_boolean.c| 4 njs/njs_crypto.c | 8 njs/njs_date.c | 48 njs/njs_error.c | 19 +++ njs/njs_fs.c | 6 ++ njs/njs_function.c | 4 njs/njs_json.c | 2 ++ njs/njs_math.c | 36 njs/njs_number.c | 10 ++ njs/njs_object.c | 22 ++ njs/njs_regexp.c | 4 njs/njs_string.c | 32 njs/test/njs_unit_test.c | 46 -- 14 files changed, 255 insertions(+), 15 deletions(-) diffs (truncated from 1970 to 1000 lines): diff -r ff591ba3e780 -r f7eedb8257eb njs/njs_array.c --- a/njs/njs_array.c Thu May 23 15:05:50 2019 +0300 +++ b/njs/njs_array.c Thu May 23 15:05:51 2019 +0300 @@ -397,6 +397,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), +.writable = 1, .configurable = 1, }, @@ -406,6 +407,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), +.writable = 1, .configurable = 1, }, }; @@ -2252,13 +2254,14 @@ static const njs_object_prop_t njs_arra .type = NJS_PROPERTY_HANDLER, .name = njs_string("length"), .value = njs_prop_handler(njs_array_length), -.writable = 1 +.writable = 1, }, { .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.writable = 1, .configurable = 1, }, @@ -2268,6 +2271,7 @@ static const njs_object_prop_t njs_arra .value = njs_native_function(njs_array_prototype_slice, njs_continuation_size(njs_array_slice_t), NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG), +.writable = 1, .configurable = 1, }, @@ -2275,6 +2279,7 @@ static const njs_object_prop_t njs_arra .type = NJS_METHOD, .name = njs_string("push"), .value = njs_native_function(njs_array_prototype_push, 0, 0), +.writable = 1, .configurable = 1, }, @@ -2282,6 +2287,7 @@ static const njs_object_prop_t njs_arra .type = NJS_METHOD, .name = njs_string("pop"), .value = njs_native_function(njs_array_prototype_pop, 0, 0), +.writable = 1, .configurable = 1, }, @@ -2289,6 +2295,7 @@ static const njs_object_prop_t njs_arra .type = NJS_METHOD, .name = njs_string("unshift"), .value = njs_native_function(njs_array_prototype_unshift, 0, 0), +.writable = 1, .configurable = 1, }, @@ -2296,6 +2303,7 @@ static const njs_object_prop_t njs_arra .type = NJS_METHOD, .name = njs_string("shift"), .value = njs_native_function(njs_array_prototype_shift, 0, 0), +.writable = 1, .configurable = 1, }, @@ -2304,6 +2312,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("splice"), .value = njs_native_function(njs_array_prototype_splice, 0, NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG), +.writable = 1, .configurable = 1, }, @@ -2312,6 +2321,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("reverse"), .value = njs_native_function(njs_array_prototype_reverse, 0, NJS_OBJECT_ARG), +.writable = 1, .configurable = 1, }, @@ -2320,6 +2330,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("toString"), .value = njs_native_function(njs_array_prototype_to_string, NJS_CONTINUATION_SIZE, 0), +.writable = 1, .configurable = 1, }, @@ -2329,6 +2340,7 @@ static const njs_object_prop_t njs_arra .value = njs_native_function(njs_array_prototype_join, njs_continuation_size(njs_array_join_t), NJS_OBJECT_ARG, NJS_STRING_ARG), +.writable = 1, .configurable = 1, }, @@ -2336,6 +2348,7 @@ static const njs_object_prop_t njs_arra .type = NJS_METHOD,
[njs] Fixed array length property handler.
details: https://hg.nginx.org/njs/rev/fd0918b6dd56 branches: changeset: 981:fd0918b6dd56 user: Valentin Bartenev date: Thu May 23 15:05:51 2019 +0300 description: Fixed array length property handler. Previously it might change the length of prototype arrays. diffstat: njs/njs_array.c | 86 ++- njs/njs_vm.c | 12 +- njs/njs_vm.h | 5 ++ njs/test/njs_unit_test.c | 4 ++ 4 files changed, 65 insertions(+), 42 deletions(-) diffs (161 lines): diff -r f7eedb8257eb -r fd0918b6dd56 njs/njs_array.c --- a/njs/njs_array.c Thu May 23 15:05:51 2019 +0300 +++ b/njs/njs_array.c Thu May 23 15:05:51 2019 +0300 @@ -434,57 +434,65 @@ njs_array_length(njs_vm_t *vm, njs_value proto = value->data.u.object; -do { -if (nxt_fast_path(proto->type == NJS_ARRAY)) { -break; +if (setval == NULL) { +do { +if (nxt_fast_path(proto->type == NJS_ARRAY)) { +break; +} + +proto = proto->__proto__; +} while (proto != NULL); + +if (nxt_slow_path(proto == NULL)) { +njs_internal_error(vm, "no array in proto chain"); +return NJS_ERROR; } -proto = proto->__proto__; -} while (proto != NULL); - -if (nxt_slow_path(proto == NULL)) { -njs_internal_error(vm, "no array in proto chain"); +array = (njs_array_t *) proto; + +njs_value_number_set(retval, array->length); +return NJS_OK; +} + +if (proto->type != NJS_ARRAY) { +return NJS_DECLINED; +} + +if (!njs_is_number(setval)) { +njs_range_error(vm, "Invalid array length"); +return NJS_ERROR; +} + +num = setval->data.u.number; +length = (uint32_t) num; + +if ((double) length != num) { +njs_range_error(vm, "Invalid array length"); return NJS_ERROR; } array = (njs_array_t *) proto; -if (setval != NULL) { -if (!njs_is_number(setval)) { -njs_range_error(vm, "Invalid array length"); -return NJS_ERROR; -} - -num = setval->data.u.number; -length = (uint32_t) num; - -if ((double) length != num) { -njs_range_error(vm, "Invalid array length"); +size = (int64_t) length - array->length; + +if (size > 0) { +ret = njs_array_expand(vm, array, 0, size); +if (nxt_slow_path(ret != NXT_OK)) { return NJS_ERROR; } -size = (int64_t) length - array->length; - -if (size > 0) { -ret = njs_array_expand(vm, array, 0, size); -if (nxt_slow_path(ret != NXT_OK)) { -return NJS_ERROR; -} - -val = >start[array->length]; - -do { -njs_set_invalid(val); -val++; -size--; -} while (size != 0); -} - -array->length = length; +val = >start[array->length]; + +do { +njs_set_invalid(val); +val++; +size--; +} while (size != 0); } -njs_value_number_set(retval, array->length); - +array->length = length; + +njs_value_number_set(retval, length); return NJS_OK; } diff -r f7eedb8257eb -r fd0918b6dd56 njs/njs_vm.c --- a/njs/njs_vm.c Thu May 23 15:05:51 2019 +0300 +++ b/njs/njs_vm.c Thu May 23 15:05:51 2019 +0300 @@ -694,11 +694,17 @@ njs_vmcode_property_set(njs_vm_t *vm, nj if (prop->type == NJS_PROPERTY_HANDLER) { ret = prop->value.data.u.prop_handler(vm, object, value, >retval); -if (nxt_slow_path(ret != NXT_OK)) { + +switch (ret) { +case NXT_OK: +return sizeof(njs_vmcode_prop_set_t); + +case NXT_DECLINED: +break; + +default: return ret; } - -return sizeof(njs_vmcode_prop_set_t); } if (pq.own) { diff -r f7eedb8257eb -r fd0918b6dd56 njs/njs_vm.h --- a/njs/njs_vm.h Thu May 23 15:05:51 2019 +0300 +++ b/njs/njs_vm.h Thu May 23 15:05:51 2019 +0300 @@ -147,6 +147,11 @@ typedef struct njs_generator_snj * 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); di
[njs] Fixed setting of object properties.
details: https://hg.nginx.org/njs/rev/ff591ba3e780 branches: changeset: 979:ff591ba3e780 user: Valentin Bartenev date: Thu May 23 15:05:50 2019 +0300 description: Fixed setting of object properties. Now writability of prototype properties is properly taken into account. diffstat: njs/njs_disassembler.c|2 + njs/njs_generator.c | 12 +- njs/njs_lexer.h |1 + njs/njs_object.c | 48 ++--- njs/njs_object.h |2 + njs/njs_parser_terminal.c |2 +- njs/njs_vm.c | 240 +++-- njs/njs_vm.h |2 + njs/test/njs_unit_test.c | 70 +++-- 9 files changed, 269 insertions(+), 110 deletions(-) diffs (697 lines): diff -r 88c5787352b2 -r ff591ba3e780 njs/njs_disassembler.c --- a/njs/njs_disassembler.cWed May 22 21:01:39 2019 +0300 +++ b/njs/njs_disassembler.cThu May 23 15:05:50 2019 +0300 @@ -36,6 +36,8 @@ static njs_code_name_t code_names[] = { { njs_vmcode_property_get, sizeof(njs_vmcode_prop_get_t), nxt_string("PROPERTY GET") }, +{ njs_vmcode_property_init, sizeof(njs_vmcode_prop_set_t), + nxt_string("PROPERTY INIT ") }, { njs_vmcode_property_set, sizeof(njs_vmcode_prop_set_t), nxt_string("PROPERTY SET") }, { njs_vmcode_property_in, sizeof(njs_vmcode_3addr_t), diff -r 88c5787352b2 -r ff591ba3e780 njs/njs_generator.c --- a/njs/njs_generator.c Wed May 22 21:01:39 2019 +0300 +++ b/njs/njs_generator.c Thu May 23 15:05:50 2019 +0300 @@ -1682,7 +1682,7 @@ njs_generate_assignment(njs_vm_t *vm, nj return NXT_OK; } -/* lvalue->token == NJS_TOKEN_PROPERTY */ +/* lvalue->token == NJS_TOKEN_PROPERTY(_INIT) */ /* Object. */ @@ -1735,8 +1735,14 @@ njs_generate_assignment(njs_vm_t *vm, nj return ret; } -njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, - njs_vmcode_property_set, 3, 0); +if (lvalue->token == NJS_TOKEN_PROPERTY_INIT) { +njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, + njs_vmcode_property_init, 3, 0); +} else { +njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set, + njs_vmcode_property_set, 3, 0); +} + prop_set->value = expr->index; prop_set->object = object->index; prop_set->property = property->index; diff -r 88c5787352b2 -r ff591ba3e780 njs/njs_lexer.h --- a/njs/njs_lexer.h Wed May 22 21:01:39 2019 +0300 +++ b/njs/njs_lexer.h Thu May 23 15:05:50 2019 +0300 @@ -123,6 +123,7 @@ typedef enum { NJS_TOKEN_OBJECT, NJS_TOKEN_OBJECT_VALUE, NJS_TOKEN_PROPERTY, +NJS_TOKEN_PROPERTY_INIT, NJS_TOKEN_PROPERTY_DELETE, NJS_TOKEN_ARRAY, diff -r 88c5787352b2 -r ff591ba3e780 njs/njs_object.c --- a/njs/njs_object.c Wed May 22 21:01:39 2019 +0300 +++ b/njs/njs_object.c Thu May 23 15:05:50 2019 +0300 @@ -22,8 +22,6 @@ static njs_ret_t njs_external_property_s njs_value_t *setval, njs_value_t *retval); static njs_ret_t njs_external_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -static njs_ret_t njs_object_query_prop_handler(njs_property_query_t *pq, -njs_object_t *object); static njs_ret_t njs_define_property(njs_vm_t *vm, njs_value_t *object, const njs_value_t *name, const njs_object_t *descriptor); @@ -379,6 +377,7 @@ njs_property_query(njs_vm_t *vm, njs_pro pq->lhq.key_hash = hash(pq->lhq.key.start, pq->lhq.key.length); if (obj == NULL) { +pq->own = 1; return njs_external_property_query(vm, pq, object); } @@ -395,6 +394,7 @@ njs_object_property_query(njs_vm_t *vm, { uint32_tindex; njs_ret_t ret; +nxt_bool_t own; njs_array_t *array; njs_object_t*proto; njs_object_prop_t *prop; @@ -402,12 +402,8 @@ njs_object_property_query(njs_vm_t *vm, pq->lhq.proto = _object_hash_proto; -if (pq->query == NJS_PROPERTY_QUERY_SET) { -ret = njs_object_query_prop_handler(pq, object); -if (ret == NXT_OK) { -return ret; -} -} +own = pq->own; +pq->own = 1; proto = object; @@ -450,6 +446,10 @@ njs_object_property_query(njs_vm_t *vm, return ret; } +if (pq->own) { +pq->own_whiteout = prop; +} + } else { ret = nxt_lvlhsh_find(>shared_hash, >lhq); @@ -460,10 +460,11 @@ njs_object_property_query(njs_vm_t *vm, } } -if (pq->own || pq->query > NJS_PROPERTY_QUERY_GET) { +if (own) { return NXT_DECLINED; } +pq->own = 0; proto = proto->__proto__;
[njs] Uncommented a successful test of Object.create([1,2]).length.
details: https://hg.nginx.org/njs/rev/260d9d4f29ee branches: changeset: 977:260d9d4f29ee user: Valentin Bartenev date: Tue May 21 21:15:21 2019 +0300 description: Uncommented a successful test of Object.create([1,2]).length. It's actually passing after f5bdddca3252. diffstat: njs/test/njs_unit_test.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 96dc80e2ea1b -r 260d9d4f29ee njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue May 21 20:45:42 2019 +0300 +++ b/njs/test/njs_unit_test.c Tue May 21 21:15:21 2019 +0300 @@ -3399,10 +3399,8 @@ static njs_unit_test_t njs_test[] = { nxt_string("\n[\n1\n,\n2]\n[\n0]"), nxt_string("1") }, -#if 0 { nxt_string("Object.create([1,2]).length"), nxt_string("2") }, -#endif { nxt_string("Object.create(['α','β'])[1]"), nxt_string("β") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed arrays expansion.
details: https://hg.nginx.org/njs/rev/8fe38b9f8a94 branches: changeset: 960:8fe38b9f8a94 user: Valentin Bartenev date: Wed May 08 19:09:10 2019 +0300 description: Fixed arrays expansion. There were two problems with njs_array_expand(): 1. It checked that the requred size with the appended elements wasn't bigger then the array size and then did nothing. If there were elements removed from the beggining (by shift() operation), then "size <= array->size" can be true even if there wasn't enought free space after the array. 2. After allocating more space to prepend elements, it set array->size without counting those elements. Probably, the original idea was to decrement array->size while removing elements from the beginning, but it wasn't done right. Even if so, the new version of the function looks cleaner. This closes #152 and closes #153 issues on Github. diffstat: njs/njs_array.c | 22 -- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 15 insertions(+), 10 deletions(-) diffs (69 lines): diff -r cb9cbb358a8b -r 8fe38b9f8a94 njs/njs_array.c --- a/njs/njs_array.c Wed May 08 19:09:10 2019 +0300 +++ b/njs/njs_array.c Wed May 08 19:09:10 2019 +0300 @@ -214,15 +214,19 @@ njs_ret_t njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t append) { +uint32_t free_before, free_after; uint64_t size; njs_value_t *start, *old; -size = (uint64_t) append + array->length; - -if (nxt_fast_path(size <= array->size && prepend == 0)) { +free_before = array->start - array->data; +free_after = array->size - array->length - free_before; + +if (nxt_fast_path(free_before >= prepend && free_after >= append)) { return NXT_OK; } +size = (uint64_t) prepend + array->length + append; + if (size < 16) { size *= 2; @@ -230,12 +234,12 @@ njs_array_expand(njs_vm_t *vm, njs_array size += size / 2; } -if (nxt_slow_path((prepend + size) > NJS_ARRAY_MAX_LENGTH)) { +if (nxt_slow_path(size > NJS_ARRAY_MAX_LENGTH)) { goto memory_error; } start = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t), - (prepend + size) * sizeof(njs_value_t)); + size * sizeof(njs_value_t)); if (nxt_slow_path(start == NULL)) { goto memory_error; } @@ -728,11 +732,9 @@ njs_array_prototype_unshift(njs_vm_t *vm n = nargs - 1; if (n != 0) { -if ((intptr_t) n > (array->start - array->data)) { -ret = njs_array_expand(vm, array, n, 0); -if (nxt_slow_path(ret != NXT_OK)) { -return ret; -} +ret = njs_array_expand(vm, array, n, 0); +if (nxt_slow_path(ret != NXT_OK)) { +return ret; } array->length += n; diff -r cb9cbb358a8b -r 8fe38b9f8a94 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed May 08 19:09:10 2019 +0300 +++ b/njs/test/njs_unit_test.c Wed May 08 19:09:10 2019 +0300 @@ -3730,6 +3730,9 @@ static njs_unit_test_t njs_test[] = "len +' '+ a +' '+ a.shift()"), nxt_string("5 3,4,5,1,2 3") }, +{ nxt_string("var a=[0], n = 64; while(--n) {a.push(n); a.shift()}; a"), + nxt_string("1") }, + { nxt_string("var a = []; a.splice()"), nxt_string("") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Better name for append elements count in njs_array_expand().
details: https://hg.nginx.org/njs/rev/4ed09499a560 branches: changeset: 958:4ed09499a560 user: Valentin Bartenev date: Wed May 08 19:09:10 2019 +0300 description: Better name for append elements count in njs_array_expand(). No functional changes. diffstat: njs/njs_array.c | 4 ++-- njs/njs_array.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (30 lines): diff -r ff76f83fc49a -r 4ed09499a560 njs/njs_array.c --- a/njs/njs_array.c Tue May 07 20:41:07 2019 +0300 +++ b/njs/njs_array.c Wed May 08 19:09:10 2019 +0300 @@ -212,12 +212,12 @@ njs_array_string_add(njs_vm_t *vm, njs_a njs_ret_t njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, -uint32_t new_size) +uint32_t append) { uint64_t size; njs_value_t *start, *old; -size = (uint64_t) new_size + array->length; +size = (uint64_t) append + array->length; if (nxt_fast_path(size <= array->size && prepend == 0)) { return NXT_OK; diff -r ff76f83fc49a -r 4ed09499a560 njs/njs_array.h --- a/njs/njs_array.h Tue May 07 20:41:07 2019 +0300 +++ b/njs/njs_array.h Wed May 08 19:09:10 2019 +0300 @@ -20,7 +20,7 @@ njs_ret_t njs_array_add(njs_vm_t *vm, nj njs_ret_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 njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, -uint32_t size); +uint32_t append); njs_ret_t njs_array_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Simplified check for array length limit in njs_array_expand().
details: https://hg.nginx.org/njs/rev/cb9cbb358a8b branches: changeset: 959:cb9cbb358a8b user: Valentin Bartenev date: Wed May 08 19:09:10 2019 +0300 description: Simplified check for array length limit in njs_array_expand(). No functional changes. diffstat: njs/njs_array.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4ed09499a560 -r cb9cbb358a8b njs/njs_array.c --- a/njs/njs_array.c Wed May 08 19:09:10 2019 +0300 +++ b/njs/njs_array.c Wed May 08 19:09:10 2019 +0300 @@ -230,7 +230,7 @@ njs_array_expand(njs_vm_t *vm, njs_array size += size / 2; } -if (nxt_slow_path(((prepend + size) * sizeof(njs_value_t)) >= UINT32_MAX)) { +if (nxt_slow_path((prepend + size) > NJS_ARRAY_MAX_LENGTH)) { goto memory_error; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Made all constructor properties configurable.
details: https://hg.nginx.org/njs/rev/ff76f83fc49a branches: changeset: 957:ff76f83fc49a user: Valentin Bartenev date: Tue May 07 20:41:07 2019 +0300 description: Made all constructor properties configurable. Note that actual "constructor" property is created on demand in the prototypes' private hash with "configurable" option set. This change corrects its state before any access. diffstat: njs/njs_array.c | 1 + njs/njs_date.c | 1 + njs/njs_error.c | 6 ++ njs/njs_regexp.c | 1 + 4 files changed, 9 insertions(+), 0 deletions(-) diffs (84 lines): diff -r 1b95bc101b4c -r ff76f83fc49a njs/njs_array.c --- a/njs/njs_array.c Tue May 07 19:50:39 2019 +0300 +++ b/njs/njs_array.c Tue May 07 20:41:07 2019 +0300 @@ -2252,6 +2252,7 @@ static const njs_object_prop_t njs_arra .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, { diff -r 1b95bc101b4c -r ff76f83fc49a njs/njs_date.c --- a/njs/njs_date.cTue May 07 19:50:39 2019 +0300 +++ b/njs/njs_date.cTue May 07 20:41:07 2019 +0300 @@ -1951,6 +1951,7 @@ static const njs_object_prop_t njs_date .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, { diff -r 1b95bc101b4c -r ff76f83fc49a njs/njs_error.c --- a/njs/njs_error.c Tue May 07 19:50:39 2019 +0300 +++ b/njs/njs_error.c Tue May 07 20:41:07 2019 +0300 @@ -748,6 +748,7 @@ static const njs_object_prop_t njs_eval .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, }; @@ -818,6 +819,7 @@ static const njs_object_prop_t njs_rang .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, }; @@ -842,6 +844,7 @@ static const njs_object_prop_t njs_refe .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, }; @@ -866,6 +869,7 @@ static const njs_object_prop_t njs_synt .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, }; @@ -890,6 +894,7 @@ static const njs_object_prop_t njs_type .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, }; @@ -907,6 +912,7 @@ static const njs_object_prop_t njs_uri_ .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, { diff -r 1b95bc101b4c -r ff76f83fc49a njs/njs_regexp.c --- a/njs/njs_regexp.c Tue May 07 19:50:39 2019 +0300 +++ b/njs/njs_regexp.c Tue May 07 20:41:07 2019 +0300 @@ -1019,6 +1019,7 @@ static const njs_object_prop_t njs_rege .type = NJS_PROPERTY_HANDLER, .name = njs_string("constructor"), .value = njs_prop_handler(njs_object_prototype_create_constructor), +.configurable = 1, }, { ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Made configurable "length", "name", and most of built-in methods.
details: https://hg.nginx.org/njs/rev/a84f514e864d branches: changeset: 953:a84f514e864d user: Valentin Bartenev date: Mon May 06 05:40:03 2019 +0300 description: Made configurable "length", "name", and most of built-in methods. diffstat: njs/njs_array.c | 28 ++ njs/njs_boolean.c| 6 + njs/njs_builtin.c| 1 + njs/njs_crypto.c | 11 ++ njs/njs_date.c | 49 ++ njs/njs_error.c | 31 + njs/njs_fs.c | 7 ++ njs/njs_function.c | 12 +++ njs/njs_json.c | 2 + njs/njs_math.c | 36 + njs/njs_number.c | 20 ++ njs/njs_object.c | 27 +++- njs/njs_object.h | 1 + njs/njs_regexp.c | 9 njs/njs_string.c | 45 ++ njs/njs_vm.c | 51 +-- njs/test/njs_unit_test.c | 50 +++--- 17 files changed, 365 insertions(+), 21 deletions(-) diffs (truncated from 2439 to 1000 lines): diff -r 96c78f35a809 -r a84f514e864d njs/njs_array.c --- a/njs/njs_array.c Mon May 06 21:24:31 2019 +0300 +++ b/njs/njs_array.c Mon May 06 05:40:03 2019 +0300 @@ -370,6 +370,7 @@ static const njs_object_prop_t njs_arra .type = NJS_PROPERTY, .name = njs_string("name"), .value = njs_string("Array"), +.configurable = 1, }, /* Array.length == 1. */ @@ -377,6 +378,7 @@ static const njs_object_prop_t njs_arra .type = NJS_PROPERTY, .name = njs_string("length"), .value = njs_value(NJS_NUMBER, 1, 1.0), +.configurable = 1, }, /* Array.prototype. */ @@ -391,6 +393,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), +.configurable = 1, }, /* ES6. */ @@ -399,6 +402,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), +.configurable = 1, }, }; @@ -2256,30 +2260,35 @@ static const njs_object_prop_t njs_arra .value = njs_native_function(njs_array_prototype_slice, njs_continuation_size(njs_array_slice_t), NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG), +.configurable = 1, }, { .type = NJS_METHOD, .name = njs_string("push"), .value = njs_native_function(njs_array_prototype_push, 0, 0), +.configurable = 1, }, { .type = NJS_METHOD, .name = njs_string("pop"), .value = njs_native_function(njs_array_prototype_pop, 0, 0), +.configurable = 1, }, { .type = NJS_METHOD, .name = njs_string("unshift"), .value = njs_native_function(njs_array_prototype_unshift, 0, 0), +.configurable = 1, }, { .type = NJS_METHOD, .name = njs_string("shift"), .value = njs_native_function(njs_array_prototype_shift, 0, 0), +.configurable = 1, }, { @@ -2287,6 +2296,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("splice"), .value = njs_native_function(njs_array_prototype_splice, 0, NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG), +.configurable = 1, }, { @@ -2294,6 +2304,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("reverse"), .value = njs_native_function(njs_array_prototype_reverse, 0, NJS_OBJECT_ARG), +.configurable = 1, }, { @@ -2301,6 +2312,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("toString"), .value = njs_native_function(njs_array_prototype_to_string, NJS_CONTINUATION_SIZE, 0), +.configurable = 1, }, { @@ -2309,12 +2321,14 @@ static const njs_object_prop_t njs_arra .value = njs_native_function(njs_array_prototype_join, njs_continuation_size(njs_array_join_t), NJS_OBJECT_ARG, NJS_STRING_ARG), +.configurable = 1, }, { .type = NJS_METHOD, .name = njs_string("concat"), .value = njs_native_function(njs_array_prototype_concat, 0, 0), +.configurable = 1, }, { @@ -2322,6 +2336,7 @@ static const njs_object_prop_t njs_arra .name = njs_string("indexOf"),
[njs] Fixed return value on deleting non-existent property.
details: https://hg.nginx.org/njs/rev/96c78f35a809 branches: changeset: 952:96c78f35a809 user: Valentin Bartenev date: Mon May 06 21:24:31 2019 +0300 description: Fixed return value on deleting non-existent property. diffstat: njs/njs_vm.c | 9 + njs/test/njs_unit_test.c | 11 ++- 2 files changed, 11 insertions(+), 9 deletions(-) diffs (78 lines): diff -r f876e5d1be41 -r 96c78f35a809 njs/njs_vm.c --- a/njs/njs_vm.c Mon May 06 20:26:58 2019 +0300 +++ b/njs/njs_vm.c Mon May 06 21:24:31 2019 +0300 @@ -712,12 +712,9 @@ njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *property) { njs_ret_t ret; -const njs_value_t *retval; njs_object_prop_t *prop; njs_property_query_t pq; -retval = _value_false; - njs_property_query_init(, NJS_PROPERTY_QUERY_DELETE, 1); ret = njs_property_query(vm, , object, property); @@ -734,7 +731,6 @@ njs_vmcode_property_delete(njs_vm_t *vm, case NJS_PROPERTY_REF: njs_set_invalid(prop->value.data.u.value); -retval = _value_true; goto done; case NJS_PROPERTY_HANDLER: @@ -744,7 +740,6 @@ njs_vmcode_property_delete(njs_vm_t *vm, return ret; } -retval = _value_true; goto done; } @@ -768,8 +763,6 @@ njs_vmcode_property_delete(njs_vm_t *vm, prop->type = NJS_WHITEOUT; njs_set_invalid(>value); -retval = _value_true; - break; case NXT_DECLINED: @@ -784,7 +777,7 @@ njs_vmcode_property_delete(njs_vm_t *vm, done: -vm->retval = *retval; +vm->retval = njs_value_true; return sizeof(njs_vmcode_3addr_t); } diff -r f876e5d1be41 -r 96c78f35a809 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon May 06 20:26:58 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon May 06 21:24:31 2019 +0300 @@ -3128,6 +3128,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("delete 1"), nxt_string("true") }, +{ nxt_string("var a = []; delete a[1]"), + nxt_string("true") }, + +{ nxt_string("var o = {}; [delete o.m, delete o.m]"), + nxt_string("true,true") }, + +{ nxt_string("[delete Array.nonexistent, delete Array.Array]"), + nxt_string("true,true") }, + { nxt_string("var a; delete (a = 1); a"), nxt_string("1") }, @@ -3261,7 +3270,7 @@ static njs_unit_test_t njs_test[] = nxt_string("1,2,34") }, { nxt_string("delete[]['4e9']"), - nxt_string("false") }, + nxt_string("true") }, { nxt_string("var n = 1, a = [ n += 1 ]; a"), nxt_string("2") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added own constructors to prototypes of built-in objects.
details: https://hg.nginx.org/njs/rev/f876e5d1be41 branches: changeset: 951:f876e5d1be41 user: Valentin Bartenev date: Mon May 06 20:26:58 2019 +0300 description: Added own constructors to prototypes of built-in objects. diffstat: njs/njs_array.c | 6 ++ njs/njs_boolean.c| 6 ++ njs/njs_date.c | 6 ++ njs/njs_error.c | 42 ++ njs/njs_function.c | 6 ++ njs/njs_number.c | 6 ++ njs/njs_object.c | 2 +- njs/njs_object.h | 2 ++ njs/njs_regexp.c | 6 ++ njs/njs_string.c | 6 ++ njs/test/njs_unit_test.c | 45 + 11 files changed, 132 insertions(+), 1 deletions(-) diffs (348 lines): diff -r e9de8a5d423c -r f876e5d1be41 njs/njs_array.c --- a/njs/njs_array.c Mon May 06 19:42:06 2019 +0300 +++ b/njs/njs_array.c Mon May 06 20:26:58 2019 +0300 @@ -2245,6 +2245,12 @@ static const njs_object_prop_t njs_arra }, { +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, + +{ .type = NJS_METHOD, .name = njs_string("slice"), .value = njs_native_function(njs_array_prototype_slice, diff -r e9de8a5d423c -r f876e5d1be41 njs/njs_boolean.c --- a/njs/njs_boolean.c Mon May 06 19:42:06 2019 +0300 +++ b/njs/njs_boolean.c Mon May 06 20:26:58 2019 +0300 @@ -132,6 +132,12 @@ static const njs_object_prop_t njs_bool }, { +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, + +{ .type = NJS_METHOD, .name = njs_string("valueOf"), .value = njs_native_function(njs_boolean_prototype_value_of, 0, 0), diff -r e9de8a5d423c -r f876e5d1be41 njs/njs_date.c --- a/njs/njs_date.cMon May 06 19:42:06 2019 +0300 +++ b/njs/njs_date.cMon May 06 20:26:58 2019 +0300 @@ -1942,6 +1942,12 @@ static const njs_object_prop_t njs_date }, { +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, + +{ .type = NJS_METHOD, .name = njs_string("valueOf"), .value = njs_native_function(njs_date_prototype_value_of, 0, diff -r e9de8a5d423c -r f876e5d1be41 njs/njs_error.c --- a/njs/njs_error.c Mon May 06 19:42:06 2019 +0300 +++ b/njs/njs_error.c Mon May 06 20:26:58 2019 +0300 @@ -680,6 +680,12 @@ static const njs_object_prop_t njs_erro }, { +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, + +{ .type = NJS_PROPERTY, .name = njs_string("message"), .value = njs_string(""), @@ -713,6 +719,12 @@ static const njs_object_prop_t njs_eval .name = njs_string("name"), .value = njs_string("EvalError"), }, + +{ +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, }; @@ -774,6 +786,12 @@ static const njs_object_prop_t njs_rang .name = njs_string("name"), .value = njs_string("RangeError"), }, + +{ +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, }; @@ -791,6 +809,12 @@ static const njs_object_prop_t njs_refe .name = njs_string("name"), .value = njs_string("ReferenceError"), }, + +{ +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, }; @@ -808,6 +832,12 @@ static const njs_object_prop_t njs_synt .name = njs_string("name"), .value = njs_string("SyntaxError"), }, + +{ +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, }; @@ -825,6 +855,12 @@ static const njs_object_prop_t njs_type .name = njs_string("name"), .value = njs_string("TypeError"), }, + +{ +.type = NJS_PROPERTY_HANDLER, +.name = njs_string("constructor"), +.value = njs_prop_handler(njs_object_prototype_create_constructor), +}, }; @@ -838,6 +874,12 @@
[njs] Added support for RegExp "groups" object (ES9).
details: https://hg.nginx.org/njs/rev/e9de8a5d423c branches: changeset: 950:e9de8a5d423c user: Valentin Bartenev date: Mon May 06 19:42:06 2019 +0300 description: Added support for RegExp "groups" object (ES9). diffstat: njs/njs_object_hash.h| 10 +++ njs/njs_regexp.c | 121 ++ njs/njs_regexp_pattern.h | 18 +++--- njs/test/njs_unit_test.c | 12 nxt/nxt_pcre.c | 58 ++ nxt/nxt_pcre.h |3 + nxt/nxt_regex.h |2 + 7 files changed, 203 insertions(+), 21 deletions(-) diffs (368 lines): diff -r d94c836632c7 -r e9de8a5d423c njs/njs_object_hash.h --- a/njs/njs_object_hash.h Mon May 06 11:33:23 2019 +0300 +++ b/njs/njs_object_hash.h Mon May 06 19:42:06 2019 +0300 @@ -100,6 +100,16 @@ 'i'), 'n'), 'p'), 'u'), 't') +#define NJS_GROUPS_HASH \ +nxt_djb_hash_add( \ +nxt_djb_hash_add( \ +nxt_djb_hash_add( \ +nxt_djb_hash_add( \ +nxt_djb_hash_add( \ +nxt_djb_hash_add(NXT_DJB_HASH_INIT, \ +'g'), 'r'), 'o'), 'u'), 'p'), 's') + + #define NJS_JOIN_HASH \ nxt_djb_hash_add( \ nxt_djb_hash_add( \ diff -r d94c836632c7 -r e9de8a5d423c njs/njs_regexp.c --- a/njs/njs_regexp.c Mon May 06 11:33:23 2019 +0300 +++ b/njs/njs_regexp.c Mon May 06 19:42:06 2019 +0300 @@ -11,6 +11,13 @@ #include +struct njs_regexp_group_s { +nxt_str_t name; +uint32_t hash; +uint32_t capture; +}; + + static void *njs_regexp_malloc(size_t size, void *memory_data); static void njs_regexp_free(void *p, void *memory_data); static njs_regexp_flags_t njs_regexp_flags(u_char **start, u_char *end, @@ -327,6 +334,9 @@ njs_regexp_pattern_create(njs_vm_t *vm, int options, ret; u_char*p, *end; size_tsize; +nxt_uint_tn; +nxt_regex_t *regex; +njs_regexp_group_t*group; njs_regexp_pattern_t *pattern; size = 1; /* A trailing "/". */ @@ -405,14 +415,42 @@ njs_regexp_pattern_create(njs_vm_t *vm, goto fail; } -if (!nxt_regex_is_valid(>regex[0]) -&& !nxt_regex_is_valid(>regex[1])) -{ +if (nxt_regex_is_valid(>regex[0])) { +regex = >regex[0]; + +} else if (nxt_regex_is_valid(>regex[1])) { +regex = >regex[1]; + +} else { goto fail; } *end = '/'; +pattern->ngroups = nxt_regex_named_captures(regex, NULL, 0); + +if (pattern->ngroups != 0) { +size = sizeof(njs_regexp_group_t) * pattern->ngroups; + +pattern->groups = nxt_mp_alloc(vm->mem_pool, size); +if (nxt_slow_path(pattern->groups == NULL)) { +njs_memory_error(vm); +return NULL; +} + +n = 0; + +do { +group = >groups[n]; + +group->capture = nxt_regex_named_captures(regex, >name, n); +group->hash = nxt_djb_hash(group->name.start, group->name.length); + +n++; + +} while (n != pattern->ngroups); +} + return pattern; fail: @@ -777,11 +815,15 @@ njs_regexp_exec_result(njs_vm_t *vm, njs njs_ret_t ret; nxt_uint_t i, n; njs_array_t *array; +njs_value_t name; +njs_object_t*groups; njs_object_prop_t *prop; +njs_regexp_group_t *group; nxt_lvlhsh_query_t lhq; static const njs_value_t string_index = njs_string("index"); static const njs_value_t string_input = njs_string("input"); +static const njs_value_t string_groups = njs_string("groups"); array = njs_array_alloc(vm, regexp->pattern->ncaptures, 0); if (nxt_slow_path(array == NULL)) { @@ -832,8 +874,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs ret = nxt_lvlhsh_insert(>object.hash, ); if (nxt_slow_path(ret != NXT_OK)) { -njs_internal_error(vm, "lvlhsh insert failed"); -goto fail; +goto insert_fail; } prop = njs_object_prop_alloc(vm, _input, >string, 1); @@ -846,16 +887,74 @@ njs_regexp_exec_result(njs_vm_t *vm, njs lhq.value = prop; ret = nxt_lvlhsh_insert(>object.hash, ); +if (nxt_slow_path(ret != NXT_OK)) { +goto insert_fail; +} -if (nxt_fast_path(ret
[njs] Fixed own properties quering.
details: https://hg.nginx.org/njs/rev/d94c836632c7 branches: changeset: 949:d94c836632c7 user: Valentin Bartenev date: Mon May 06 11:33:23 2019 +0300 description: Fixed own properties quering. njs_property_query() and njs_object_property_query() were simplified. diffstat: njs/njs_object.c | 124 +- njs/test/njs_unit_test.c | 17 ++ 2 files changed, 63 insertions(+), 78 deletions(-) diffs (186 lines): diff -r 6ee0e7a44e79 -r d94c836632c7 njs/njs_object.c --- a/njs/njs_object.c Mon May 06 17:47:26 2019 +0300 +++ b/njs/njs_object.c Mon May 06 11:33:23 2019 +0300 @@ -322,39 +322,11 @@ njs_property_query(njs_vm_t *vm, njs_pro obj = >string_object; break; -case NJS_OBJECT_STRING: -if (nxt_fast_path(!njs_is_null_or_undefined_or_boolean(property))) { -index = njs_value_to_index(property); - -if (nxt_fast_path(index < NJS_STRING_MAX_LENGTH)) { -ret = njs_string_property_query(vm, pq, - >data.u.object_value->value, -index); - -if (nxt_fast_path(ret != NXT_DECLINED)) { -return ret; -} -} -} - -obj = object->data.u.object; -break; - +case NJS_OBJECT: case NJS_ARRAY: -if (nxt_fast_path(!njs_is_null_or_undefined_or_boolean(property))) { -index = njs_value_to_index(property); - -if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) { -return njs_array_property_query(vm, pq, object->data.u.array, -index); -} -} - -/* Fall through. */ - -case NJS_OBJECT: case NJS_OBJECT_BOOLEAN: case NJS_OBJECT_NUMBER: +case NJS_OBJECT_STRING: case NJS_REGEXP: case NJS_DATE: case NJS_OBJECT_ERROR: @@ -442,62 +414,58 @@ njs_object_property_query(njs_vm_t *vm, do { pq->prototype = proto; -if (nxt_fast_path(!pq->own || proto == object)) { -ret = nxt_lvlhsh_find(>hash, >lhq); +if (!njs_is_null_or_undefined_or_boolean(property)) { +switch (proto->type) { +case NJS_ARRAY: +index = njs_value_to_index(property); +if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) { +array = (njs_array_t *) proto; +return njs_array_property_query(vm, pq, array, index); +} + +break; + +case NJS_OBJECT_STRING: +index = njs_value_to_index(property); +if (nxt_fast_path(index < NJS_STRING_MAX_LENGTH)) { +ov = (njs_object_value_t *) proto; +ret = njs_string_property_query(vm, pq, >value, index); + +if (nxt_fast_path(ret != NXT_DECLINED)) { +return ret; +} +} + +default: +break; +} +} + +ret = nxt_lvlhsh_find(>hash, >lhq); + +if (ret == NXT_OK) { +prop = pq->lhq.value; + +if (prop->type != NJS_WHITEOUT) { +pq->shared = 0; + +return ret; +} + +} else { +ret = nxt_lvlhsh_find(>shared_hash, >lhq); if (ret == NXT_OK) { -prop = pq->lhq.value; - -if (prop->type != NJS_WHITEOUT) { -pq->shared = 0; - -return ret; -} - -goto next; -} - -if (proto != object -&& !njs_is_null_or_undefined_or_boolean(property)) -{ -switch (proto->type) { -case NJS_ARRAY: -index = njs_value_to_index(property); -if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) { -array = (njs_array_t *) proto; -return njs_array_property_query(vm, pq, array, index); -} - -break; - -case NJS_OBJECT_STRING: -index = njs_value_to_index(property); -if (nxt_fast_path(index < NJS_STRING_MAX_LENGTH)) { -ov = (njs_object_value_t *) proto; -return njs_string_property_query(vm, pq, >value, - index); -} - -default: -break; -} +pq->shared = 1; + +return ret; } } -ret = nxt_lvlhsh_find(>shared_hash, >lhq); - -if (ret == NXT_OK) { -
[njs] Fixed alignment of njs_object_prop_t in njs_method_private_copy().
details: https://hg.nginx.org/njs/rev/6ee0e7a44e79 branches: changeset: 948:6ee0e7a44e79 user: Valentin Bartenev date: Mon May 06 17:47:26 2019 +0300 description: Fixed alignment of njs_object_prop_t in njs_method_private_copy(). It must be aligned to njs_value_t. diffstat: njs/njs_object.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r f3b145f3ca34 -r 6ee0e7a44e79 njs/njs_object.c --- a/njs/njs_object.c Mon May 06 05:07:51 2019 +0300 +++ b/njs/njs_object.c Mon May 06 17:47:26 2019 +0300 @@ -773,7 +773,8 @@ njs_method_private_copy(njs_vm_t *vm, nj njs_function_t *function; njs_object_prop_t *prop, *shared; -prop = nxt_mp_alloc(vm->mem_pool, sizeof(njs_object_prop_t)); +prop = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t), +sizeof(njs_object_prop_t)); if (nxt_slow_path(prop == NULL)) { njs_memory_error(vm); return NXT_ERROR; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Uncommented a successful test of getOwnPropertyNames().
details: https://hg.nginx.org/njs/rev/274d33eeb57d branches: changeset: 946:274d33eeb57d user: Valentin Bartenev date: Mon May 06 00:27:22 2019 +0300 description: Uncommented a successful test of getOwnPropertyNames(). It's actully passing after 1213e0a2b485 and d7a0eb59a7e7 changes. diffstat: njs/njs_object.c | 2 -- njs/test/njs_unit_test.c | 2 -- 2 files changed, 0 insertions(+), 4 deletions(-) diffs (26 lines): diff -r 0c42e997371c -r 274d33eeb57d njs/njs_object.c --- a/njs/njs_object.c Sat May 04 17:12:35 2019 +0300 +++ b/njs/njs_object.c Mon May 06 00:27:22 2019 +0300 @@ -442,8 +442,6 @@ njs_object_property_query(njs_vm_t *vm, do { pq->prototype = proto; -/* TODO: length should be Own property */ - if (nxt_fast_path(!pq->own || proto == object)) { ret = nxt_lvlhsh_find(>hash, >lhq); diff -r 0c42e997371c -r 274d33eeb57d njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat May 04 17:12:35 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon May 06 00:27:22 2019 +0300 @@ -9310,10 +9310,8 @@ static njs_unit_test_t njs_test[] = { nxt_string("Object.getOwnPropertyNames(Array)"), nxt_string("name,length,prototype,isArray,of") }, -#if 0 { nxt_string("Object.getOwnPropertyNames(Array.isArray)"), nxt_string("length") }, -#endif { nxt_string("Object.defineProperty(Object.freeze({}), 'b', {})"), nxt_string("TypeError: object is not extensible") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added missing "static" to njs_object_property_query() declaration.
details: https://hg.nginx.org/njs/rev/f3b145f3ca34 branches: changeset: 947:f3b145f3ca34 user: Valentin Bartenev date: Mon May 06 05:07:51 2019 +0300 description: Added missing "static" to njs_object_property_query() declaration. diffstat: njs/njs_object.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 274d33eeb57d -r f3b145f3ca34 njs/njs_object.c --- a/njs/njs_object.c Mon May 06 00:27:22 2019 +0300 +++ b/njs/njs_object.c Mon May 06 05:07:51 2019 +0300 @@ -417,7 +417,7 @@ njs_property_query(njs_vm_t *vm, njs_pro } -njs_ret_t +static njs_ret_t njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_object_t *object, const njs_value_t *property) { ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added the "name" property to the Function prototype object.
details: https://hg.nginx.org/njs/rev/0c42e997371c branches: changeset: 945:0c42e997371c user: Valentin Bartenev date: Sat May 04 17:12:35 2019 +0300 description: Added the "name" property to the Function prototype object. Its value according to the ES6+ specification must be the empty String. diffstat: njs/njs_function.c | 6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff -r b7cdfafdc20b -r 0c42e997371c njs/njs_function.c --- a/njs/njs_function.cSat May 04 16:59:24 2019 +0300 +++ b/njs/njs_function.cSat May 04 17:12:35 2019 +0300 @@ -1175,6 +1175,12 @@ static const njs_object_prop_t njs_func { { .type = NJS_PROPERTY, +.name = njs_string("name"), +.value = njs_string(""), +}, + +{ +.type = NJS_PROPERTY, .name = njs_string("length"), .value = njs_value(NJS_NUMBER, 0, 0.0), }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Style.
details: https://hg.nginx.org/njs/rev/b7cdfafdc20b branches: changeset: 944:b7cdfafdc20b user: Valentin Bartenev date: Sat May 04 16:59:24 2019 +0300 description: Style. diffstat: njs/njs_disassembler.c | 2 -- njs/njs_function.c | 1 - njs/njs_json.c | 8 njs/njs_object.c | 10 +- njs/njs_parser.c | 7 +++ njs/njs_string.c | 1 - njs/test/njs_unit_test.c | 10 +- 7 files changed, 17 insertions(+), 22 deletions(-) diffs (123 lines): diff -r 551d173ab9ec -r b7cdfafdc20b njs/njs_disassembler.c --- a/njs/njs_disassembler.cSat May 04 05:52:15 2019 +0300 +++ b/njs/njs_disassembler.cSat May 04 16:59:24 2019 +0300 @@ -295,7 +295,6 @@ njs_disassemble(u_char *start, u_char *e (size_t) method->method, method->nargs, method->code.ctor ? " CTOR" : ""); - p += sizeof(njs_vmcode_method_frame_t); continue; } @@ -308,7 +307,6 @@ njs_disassemble(u_char *start, u_char *e (size_t) prop_foreach->object, (size_t) prop_foreach->offset); - p += sizeof(njs_vmcode_prop_foreach_t); continue; } diff -r 551d173ab9ec -r b7cdfafdc20b njs/njs_function.c --- a/njs/njs_function.cSat May 04 05:52:15 2019 +0300 +++ b/njs/njs_function.cSat May 04 16:59:24 2019 +0300 @@ -31,7 +31,6 @@ njs_function_alloc(njs_vm_t *vm, njs_fun goto fail; } - /* * nxt_mp_zalloc() does also: * nxt_lvlhsh_init(>object.hash); diff -r 551d173ab9ec -r b7cdfafdc20b njs/njs_json.c --- a/njs/njs_json.cSat May 04 05:52:15 2019 +0300 +++ b/njs/njs_json.cSat May 04 16:59:24 2019 +0300 @@ -1916,10 +1916,10 @@ njs_json_append_number(njs_json_stringif static njs_value_t * njs_json_wrap_value(njs_vm_t *vm, const njs_value_t *value) { -nxt_int_t ret; -njs_value_t *wrapper; -njs_object_prop_t *prop; -nxt_lvlhsh_query_tlhq; +nxt_int_t ret; +njs_value_t *wrapper; +njs_object_prop_t *prop; +nxt_lvlhsh_query_t lhq; wrapper = nxt_mp_alloc(vm->mem_pool, sizeof(njs_value_t)); if (nxt_slow_path(wrapper == NULL)) { diff -r 551d173ab9ec -r b7cdfafdc20b njs/njs_object.c --- a/njs/njs_object.c Sat May 04 05:52:15 2019 +0300 +++ b/njs/njs_object.c Sat May 04 16:59:24 2019 +0300 @@ -2619,11 +2619,11 @@ njs_value_t * njs_property_prototype_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, njs_object_t *prototype) { -nxt_int_t ret; -njs_object_prop_t *prop; -nxt_lvlhsh_query_t lhq; - -static const njs_value_t proto_string = njs_string("prototype"); +nxt_int_t ret; +njs_object_prop_t *prop; +nxt_lvlhsh_query_tlhq; + +static const njs_value_t proto_string = njs_string("prototype"); prop = njs_object_prop_alloc(vm, _string, _value_undefined, 0); if (nxt_slow_path(prop == NULL)) { diff -r 551d173ab9ec -r b7cdfafdc20b njs/njs_parser.c --- a/njs/njs_parser.c Sat May 04 05:52:15 2019 +0300 +++ b/njs/njs_parser.c Sat May 04 16:59:24 2019 +0300 @@ -1064,7 +1064,6 @@ njs_parser_var_statement(njs_vm_t *vm, n return NJS_TOKEN_ILLEGAL; } - name = njs_parser_variable_node(vm, parser, njs_parser_text(parser), njs_parser_key_hash(parser), @@ -2179,9 +2178,9 @@ njs_token_t njs_parser_arrow_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) { -njs_ret_t ret; -njs_index_t index; -njs_parser_node_t *node, *body, *parent; +njs_ret_t ret; +njs_index_tindex; +njs_parser_node_t *node, *body, *parent; njs_function_lambda_t *lambda; node = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_EXPRESSION); diff -r 551d173ab9ec -r b7cdfafdc20b njs/njs_string.c --- a/njs/njs_string.c Sat May 04 05:52:15 2019 +0300 +++ b/njs/njs_string.c Sat May 04 16:59:24 2019 +0300 @@ -598,7 +598,6 @@ static const njs_object_prop_t njs_stri NJS_SKIP_ARG, NJS_STRING_ARG), }, - /* String.fromCharCode(). */ { .type = NJS_METHOD, diff -r 551d173ab9ec -r b7cdfafdc20b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat May 04 05:52:15 2019 +0300 +++ b/njs/test/njs_unit_test.c Sat May 04 16:59:24 2019 +0300 @@ -13104,11 +13104,11 @@ done: static nxt_int_t njs_timezone_optional_test(nxt_bool_t disassemble, nxt_bool_t verbose) { -size_t size; -u_char buf[16]; -time_t clock; -struct tm tm; -nxt_int_t ret; +size_t size; +u_char buf[16]; +time_t clock; +struct tm tm; +
[njs] Simplified condition in njs_function_alloc().
details: https://hg.nginx.org/njs/rev/551d173ab9ec branches: changeset: 943:551d173ab9ec user: Valentin Bartenev date: Sat May 04 05:52:15 2019 +0300 description: Simplified condition in njs_function_alloc(). There's no reason to check both flags when one depends on another. See just a few lines above: function->ctor = !lambda->arrow. Now the condition is made similar to the one in njs_method_private_copy(). diffstat: njs/njs_function.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (18 lines): diff -r fe74f3c7863a -r 551d173ab9ec njs/njs_function.c --- a/njs/njs_function.cSat May 04 00:56:39 2019 +0300 +++ b/njs/njs_function.cSat May 04 05:52:15 2019 +0300 @@ -42,11 +42,11 @@ njs_function_alloc(njs_vm_t *vm, njs_fun function->args_offset = 1; function->u.lambda = lambda; -if (lambda->arrow || !function->ctor) { -function->object.shared_hash = vm->shared->arrow_instance_hash; +if (function->ctor) { +function->object.shared_hash = vm->shared->function_instance_hash; } else { -function->object.shared_hash = vm->shared->function_instance_hash; +function->object.shared_hash = vm->shared->arrow_instance_hash; } function->object.__proto__ = >prototypes[NJS_PROTOTYPE_FUNCTION].object; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added missed njs_internal_error() call in njs_regexp_exec_result().
details: https://hg.nginx.org/njs/rev/fe74f3c7863a branches: changeset: 942:fe74f3c7863a user: Valentin Bartenev date: Sat May 04 00:56:39 2019 +0300 description: Added missed njs_internal_error() call in njs_regexp_exec_result(). diffstat: njs/njs_regexp.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r a9a4ffdea79c -r fe74f3c7863a njs/njs_regexp.c --- a/njs/njs_regexp.c Thu May 02 21:21:16 2019 +0300 +++ b/njs/njs_regexp.c Sat May 04 00:56:39 2019 +0300 @@ -856,6 +856,8 @@ njs_regexp_exec_result(njs_vm_t *vm, njs goto done; } +njs_internal_error(vm, "lvlhsh insert failed"); + fail: ret = NXT_ERROR; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Rejection of multiple "var" declarations in the for-in statement.
details: https://hg.nginx.org/njs/rev/a9a4ffdea79c branches: changeset: 941:a9a4ffdea79c user: Valentin Bartenev date: Thu May 02 21:21:16 2019 +0300 description: Rejection of multiple "var" declarations in the for-in statement. diffstat: njs/njs_parser.c | 8 ++-- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diffs (31 lines): diff -r ae95d2637819 -r a9a4ffdea79c njs/njs_parser.c --- a/njs/njs_parser.c Thu May 02 11:08:44 2019 +0300 +++ b/njs/njs_parser.c Thu May 02 21:21:16 2019 +0300 @@ -1078,8 +1078,12 @@ njs_parser_var_statement(njs_vm_t *vm, n return token; } -if (var_in && token == NJS_TOKEN_IN) { -return njs_parser_var_in_statement(vm, parser, name); +if (var_in) { +if (token == NJS_TOKEN_IN) { +return njs_parser_var_in_statement(vm, parser, name); +} + +var_in = 0; } expr = NULL; diff -r ae95d2637819 -r a9a4ffdea79c njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu May 02 11:08:44 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu May 02 21:21:16 2019 +0300 @@ -2265,6 +2265,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("for (null in undefined);"), nxt_string("ReferenceError: Invalid left-hand side \"null\" in for-in statement in 1") }, +{ nxt_string("for (var a, b in []);"), + nxt_string("SyntaxError: Unexpected token \"in\" in 1") }, + { nxt_string("var s = ''; for (var p in [1,2]) {s += p}; s"), nxt_string("01") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Corrected error message when parsing "var" inside "for".
details: https://hg.nginx.org/njs/rev/ae95d2637819 branches: changeset: 940:ae95d2637819 user: Valentin Bartenev date: Thu May 02 11:08:44 2019 +0300 description: Corrected error message when parsing "var" inside "for". The "var_in" flag indicates parsing inside the "for" statement with expectation of the "in" token, but it doesn't define the loop as a for-in one. In fact, that's unknown at the moment when this particular error message is emitted. As a result, the following code: for (var eval = 10; eval; eval--); produces the error message about for-in loop: SyntaxError: Identifier "eval" is forbidden in for-in var declaration Actually, according to the specification "eval" isn't a keyword and shouldn't cause any errors here. But this bug is beyond the scope of the current fix. diffstat: njs/njs_parser.c | 5 ++--- njs/test/njs_unit_test.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diffs (27 lines): diff -r 601a52c421d1 -r ae95d2637819 njs/njs_parser.c --- a/njs/njs_parser.c Mon Apr 29 15:57:36 2019 +0300 +++ b/njs/njs_parser.c Thu May 02 11:08:44 2019 +0300 @@ -1057,9 +1057,8 @@ njs_parser_var_statement(njs_vm_t *vm, n if (token != NJS_TOKEN_NAME) { if (token == NJS_TOKEN_ARGUMENTS || token == NJS_TOKEN_EVAL) { njs_parser_syntax_error(vm, parser, "Identifier \"%V\" " -"is forbidden in %s declaration", -njs_parser_text(parser), -var_in ? "for-in var" : "var"); +"is forbidden in var declaration", +njs_parser_text(parser)); } return NJS_TOKEN_ILLEGAL; diff -r 601a52c421d1 -r ae95d2637819 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Apr 29 15:57:36 2019 +0300 +++ b/njs/test/njs_unit_test.c Thu May 02 11:08:44 2019 +0300 @@ -6737,7 +6737,7 @@ static njs_unit_test_t njs_test[] = nxt_string("SyntaxError: Identifier \"arguments\" is forbidden in var declaration in 1") }, { nxt_string("for (var arguments in []) {}"), - nxt_string("SyntaxError: Identifier \"arguments\" is forbidden in for-in var declaration in 1") }, + nxt_string("SyntaxError: Identifier \"arguments\" is forbidden in var declaration in 1") }, { nxt_string("function arguments(){}"), nxt_string("SyntaxError: Identifier \"arguments\" is forbidden in function declaration in 1") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Removed NXT_READLINE_CFLAGS.
details: https://hg.nginx.org/njs/rev/60e98e247a53 branches: changeset: 932:60e98e247a53 user: Valentin Bartenev date: Fri Apr 26 19:30:43 2019 +0300 description: Removed NXT_READLINE_CFLAGS. It's not needed after 61f2616e21c7. diffstat: auto/make | 3 +-- auto/readline | 4 2 files changed, 1 insertions(+), 6 deletions(-) diffs (38 lines): diff -r 760d38110fd9 -r 60e98e247a53 auto/make --- a/auto/make Fri Apr 26 17:59:42 2019 +0300 +++ b/auto/make Fri Apr 26 19:30:43 2019 +0300 @@ -177,8 +177,7 @@ cat << END >> $NXT_MAKEFILE $NXT_BUILD_DIR/libnjs.a \\ njs/njs_shell.c \$(NXT_CC) -o $NXT_BUILD_DIR/njs \$(NXT_CFLAGS) \\ - $NXT_LIB_AUX_CFLAGS \$(NXT_LIB_INCS) \\ - $NXT_READLINE_CFLAGS -Injs \\ + $NXT_LIB_AUX_CFLAGS \$(NXT_LIB_INCS) -Injs \\ njs/njs_shell.c \\ $NXT_BUILD_DIR/libnjs.a \\ -lm $NXT_LIBS $NXT_LIB_AUX_LIBS $NXT_READLINE_LIB diff -r 760d38110fd9 -r 60e98e247a53 auto/readline --- a/auto/readline Fri Apr 26 17:59:42 2019 +0300 +++ b/auto/readline Fri Apr 26 19:30:43 2019 +0300 @@ -2,7 +2,6 @@ # Copyright (C) NGINX, Inc. -NXT_READLINE_CFLAGS= NXT_READLINE_LIB= nxt_found=no @@ -69,13 +68,10 @@ if [ $nxt_found = no ]; then . auto/feature fi - - NXT_DEFAULT_TARGET=libnjs if [ $nxt_found = yes ]; then NXT_HAVE_READLINE=YES -NXT_READLINE_CFLAGS=$nxt_feature_incs NXT_READLINE_LIB=$nxt_feature_libs NXT_DEFAULT_TARGET="$NXT_DEFAULT_TARGET njs" ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Support for building with GNU Readline library.
details: https://hg.nginx.org/njs/rev/760d38110fd9 branches: changeset: 931:760d38110fd9 user: Valentin Bartenev date: Fri Apr 26 17:59:42 2019 +0300 description: Support for building with GNU Readline library. diffstat: auto/editline | 68 - auto/expect | 2 +- auto/make | 4 +- auto/readline | 85 + configure | 2 +- njs/njs_shell.c | 3 ++ 6 files changed, 92 insertions(+), 72 deletions(-) diffs (214 lines): diff -r 43dc900bc914 -r 760d38110fd9 auto/editline --- a/auto/editline Thu Apr 25 19:50:20 2019 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 + @@ -1,68 +0,0 @@ -# Copyright (C) Dmitry Volyntsev -# Copyright (C) NGINX, Inc. - - -NXT_EDITLINE_CFLAGS= -NXT_EDITLINE_LIB= - -nxt_found=no - -nxt_feature="editline library in editline/readline.h" -nxt_feature_name=NXT_HAVE_EDITLINE -nxt_feature_run=no -nxt_feature_incs= -nxt_feature_libs="-ledit" -nxt_feature_test="#include - #include - - int main(void) { - add_history(NULL); - return 0; - }" -. auto/feature - -if [ $nxt_found = no ]; then - -# FreeBSD port - -nxt_feature_name=NXT_HAVE_EDIT_READLINE -nxt_feature="editline in edit/readline/readline.h" -nxt_feature_test="#include - #include - - int main(void) { - add_history(NULL); - return 0; - }" - -. auto/feature -fi - -if [ $nxt_found = no ]; then - -# NetBSD - -nxt_feature_name=NXT_HAVE_READLINE -nxt_feature="editline in readline/readline.h" -nxt_feature_test="#include - #include - - int main(void) { - add_history(NULL); - return 0; - }" -. auto/feature -fi - -NXT_DEFAULT_TARGET=libnjs - -if [ $nxt_found = yes ]; then -NXT_HAVE_LIBEDIT=YES -NXT_EDITLINE_CFLAGS=$nxt_feature_incs -NXT_EDITLINE_LIB=$nxt_feature_libs -NXT_DEFAULT_TARGET="$NXT_DEFAULT_TARGET njs" - -else -NXT_HAVE_LIBEDIT=NO -$echo " - building interactive shell is not possible" -fi diff -r 43dc900bc914 -r 760d38110fd9 auto/expect --- a/auto/expect Thu Apr 25 19:50:20 2019 +0300 +++ b/auto/expect Fri Apr 26 17:59:42 2019 +0300 @@ -17,7 +17,7 @@ else $echo " not found" fi -if [ $nxt_found = yes -a $NXT_HAVE_LIBEDIT = YES ]; then +if [ $nxt_found = yes -a $NXT_HAVE_READLINE = YES ]; then cat << END >> $NXT_MAKEFILE njs_expect_test: njs njs/test/njs_expect_test.exp diff -r 43dc900bc914 -r 760d38110fd9 auto/make --- a/auto/make Thu Apr 25 19:50:20 2019 +0300 +++ b/auto/make Fri Apr 26 17:59:42 2019 +0300 @@ -178,10 +178,10 @@ cat << END >> $NXT_MAKEFILE njs/njs_shell.c \$(NXT_CC) -o $NXT_BUILD_DIR/njs \$(NXT_CFLAGS) \\ $NXT_LIB_AUX_CFLAGS \$(NXT_LIB_INCS) \\ - $NXT_EDITLINE_CFLAGS -Injs \\ + $NXT_READLINE_CFLAGS -Injs \\ njs/njs_shell.c \\ $NXT_BUILD_DIR/libnjs.a \\ - -lm $NXT_LIBS $NXT_LIB_AUX_LIBS $NXT_EDITLINE_LIB + -lm $NXT_LIBS $NXT_LIB_AUX_LIBS $NXT_READLINE_LIB END diff -r 43dc900bc914 -r 760d38110fd9 auto/readline --- /dev/null Thu Jan 01 00:00:00 1970 + +++ b/auto/readline Fri Apr 26 17:59:42 2019 +0300 @@ -0,0 +1,85 @@ +# Copyright (C) Dmitry Volyntsev +# Copyright (C) NGINX, Inc. + + +NXT_READLINE_CFLAGS= +NXT_READLINE_LIB= + +nxt_found=no + +nxt_feature="GNU readline library" +nxt_feature_name=NXT_HAVE_GNU_READLINE +nxt_feature_run=no +nxt_feature_incs= +nxt_feature_libs="-lreadline" +nxt_feature_test="#include + #include + #include + + int main(void) { + add_history(NULL); + return 0; + }" +. auto/feature + +if [ $nxt_found = no ]; then +nxt_feature="editline library in editline/readline.h" +nxt_feature_name=NXT_HAVE_EDITLINE +nxt_feature_libs="-ledit" +nxt_feature_test="#include + #include + + int main(void) { + add_history(NULL); + return 0; + }" +. auto/feature +fi + +if [ $nxt_found = no ]; then + +# FreeBSD port + +nxt_feature_name=NXT_HAVE_EDIT_READLINE +nxt_feature="editline in edit/readline/readline.h" +nxt_feature_test="#include + #include + + int main(void) { + add_history(NULL); +
[njs] Object.entries() method.
details: https://hg.nginx.org/njs/rev/ce3a943df9c4 branches: changeset: 683:ce3a943df9c4 user: Valentin Bartenev date: Mon Dec 03 19:23:27 2018 +0300 description: Object.entries() method. diffstat: njs/njs_object.c | 151 ++- njs/njs_object.h |1 + njs/test/njs_unit_test.c | 37 +++ 3 files changed, 188 insertions(+), 1 deletions(-) diffs (261 lines): diff -r 1af8f40573f2 -r ce3a943df9c4 njs/njs_object.c --- a/njs/njs_object.c Mon Dec 03 19:20:58 2018 +0300 +++ b/njs/njs_object.c Mon Dec 03 19:23:27 2018 +0300 @@ -914,6 +914,35 @@ njs_object_values(njs_vm_t *vm, njs_valu } +static njs_ret_t +njs_object_entries(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) + { +njs_array_t*array; +const njs_value_t *value; + +value = njs_arg(args, nargs, 1); + +if (njs_is_null_or_void(value)) { +njs_type_error(vm, "cannot convert %s argument to object", + njs_type_string(value->type)); + +return NXT_ERROR; +} + +array = njs_object_enumerate(vm, value, NJS_ENUM_BOTH); +if (array == NULL) { +return NXT_ERROR; +} + +vm->retval.data.u.array = array; +vm->retval.type = NJS_ARRAY; +vm->retval.data.truth = 1; + +return NXT_OK; +} + + njs_array_t * njs_object_enumerate(njs_vm_t *vm, const njs_value_t *value, njs_object_enum_t kind) @@ -921,7 +950,7 @@ njs_object_enumerate(njs_vm_t *vm, const u_char *dst; uint32_t i, length, size, items_length, properties; njs_value_t*string, *item; -njs_array_t*items, *array; +njs_array_t*items, *array, *entry; nxt_lvlhsh_t *hash; const u_char *src, *end; njs_object_prop_t *prop; @@ -1013,6 +1042,29 @@ njs_object_enumerate(njs_vm_t *vm, const } break; + +case NJS_ENUM_BOTH: +for (i = 0; i < length; i++) { +if (njs_is_valid(>start[i])) { +entry = njs_array_alloc(vm, 2, 0); +if (nxt_slow_path(entry == NULL)) { +return NULL; +} + +njs_uint32_to_string(>start[0], i); + +/* GC: retain. */ +entry->start[1] = array->start[i]; + +item->data.u.array = entry; +item->type = NJS_ARRAY; +item->data.truth = 1; + +item++; +} +} + +break; } } else if (length != 0) { @@ -1057,6 +1109,66 @@ njs_object_enumerate(njs_vm_t *vm, const } break; + +case NJS_ENUM_BOTH: +if (string_prop.size == (size_t) length) { +/* Byte or ASCII string. */ + +for (i = 0; i < length; i++) { +entry = njs_array_alloc(vm, 2, 0); +if (nxt_slow_path(entry == NULL)) { +return NULL; +} + +njs_uint32_to_string(>start[0], i); + +string = >start[1]; + +dst = njs_string_short_start(string); +dst[0] = string_prop.start[i]; + +njs_string_short_set(string, 1, 1); + +item->data.u.array = entry; +item->type = NJS_ARRAY; +item->data.truth = 1; + +item++; +} + +} else { +/* UTF-8 string. */ + +src = string_prop.start; +end = src + string_prop.size; +i = 0; + +do { +entry = njs_array_alloc(vm, 2, 0); +if (nxt_slow_path(entry == NULL)) { +return NULL; +} + +njs_uint32_to_string(>start[0], i++); + +string = >start[1]; + +dst = njs_string_short_start(string); +dst = nxt_utf8_copy(dst, , end); +size = dst - njs_string_short_start(value); + +njs_string_short_set(string, size, 1); + +item->data.u.array = entry; +item->type = NJS_ARRAY; +item->data.truth = 1; + +item++; + +} while (src != end); +} + +break; } } @@ -1095,6 +1207,35 @@ njs_object_enumerate(njs_vm_t *vm, const } break; + +case NJS_ENUM_BOTH: +for ( ;; ) { +prop = nxt_lvlhsh_each(hash, ); + +if (prop == NULL) { +break; +} + +if (prop->type != N
[njs] Object.values() method.
details: https://hg.nginx.org/njs/rev/1af8f40573f2 branches: changeset: 682:1af8f40573f2 user: Valentin Bartenev date: Mon Dec 03 19:20:58 2018 +0300 description: Object.values() method. diffstat: njs/njs_json.c |4 +- njs/njs_object.c | 169 +++--- njs/njs_object.h |9 ++- njs/test/njs_unit_test.c | 38 ++ 4 files changed, 191 insertions(+), 29 deletions(-) diffs (347 lines): diff -r 4a543ed58c95 -r 1af8f40573f2 njs/njs_json.c --- a/njs/njs_json.cSat Dec 01 22:32:33 2018 +0300 +++ b/njs/njs_json.cMon Dec 03 19:20:58 2018 +0300 @@ -1095,7 +1095,7 @@ njs_json_push_parse_state(njs_vm_t *vm, } else { state->type = NJS_JSON_OBJECT_START; state->prop_value = NULL; -state->keys = njs_object_keys_array(vm, value); +state->keys = njs_object_enumerate(vm, value, NJS_ENUM_KEYS); if (state->keys == NULL) { return NULL; } @@ -1659,7 +1659,7 @@ njs_json_push_stringify_state(njs_vm_t * state->keys = njs_extern_keys_array(vm, value->external.proto); } else { -state->keys = njs_object_keys_array(vm, value); +state->keys = njs_object_enumerate(vm, value, NJS_ENUM_KEYS); } if (state->keys == NULL) { diff -r 4a543ed58c95 -r 1af8f40573f2 njs/njs_object.c --- a/njs/njs_object.c Sat Dec 01 22:32:33 2018 +0300 +++ b/njs/njs_object.c Mon Dec 03 19:20:58 2018 +0300 @@ -872,7 +872,7 @@ njs_object_keys(njs_vm_t *vm, njs_value_ return NXT_ERROR; } -keys = njs_object_keys_array(vm, value); +keys = njs_object_enumerate(vm, value, NJS_ENUM_KEYS); if (keys == NULL) { return NXT_ERROR; } @@ -885,20 +885,52 @@ njs_object_keys(njs_vm_t *vm, njs_value_ } +static njs_ret_t +njs_object_values(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) + { +njs_array_t*array; +const njs_value_t *value; + +value = njs_arg(args, nargs, 1); + +if (njs_is_null_or_void(value)) { +njs_type_error(vm, "cannot convert %s argument to object", + njs_type_string(value->type)); + +return NXT_ERROR; +} + +array = njs_object_enumerate(vm, value, NJS_ENUM_VALUES); +if (array == NULL) { +return NXT_ERROR; +} + +vm->retval.data.u.array = array; +vm->retval.type = NJS_ARRAY; +vm->retval.data.truth = 1; + +return NXT_OK; +} + + njs_array_t * -njs_object_keys_array(njs_vm_t *vm, const njs_value_t *value) +njs_object_enumerate(njs_vm_t *vm, const njs_value_t *value, +njs_object_enum_t kind) { -uint32_t i, n, length, keys_length, properties; -njs_value_t*string; -njs_array_t*keys, *array; +u_char *dst; +uint32_t i, length, size, items_length, properties; +njs_value_t*string, *item; +njs_array_t*items, *array; nxt_lvlhsh_t *hash; +const u_char *src, *end; njs_object_prop_t *prop; njs_string_prop_t string_prop; nxt_lvlhsh_each_t lhe; array = NULL; length = 0; -keys_length = 0; +items_length = 0; switch (value->type) { case NJS_ARRAY: @@ -907,7 +939,7 @@ njs_object_keys_array(njs_vm_t *vm, cons for (i = 0; i < length; i++) { if (njs_is_valid(>start[i])) { -keys_length++; +items_length++; } } @@ -923,7 +955,7 @@ njs_object_keys_array(njs_vm_t *vm, cons } length = njs_string_prop(_prop, string); -keys_length += length; +items_length += length; break; default: @@ -950,46 +982,123 @@ njs_object_keys_array(njs_vm_t *vm, cons } } -keys_length += properties; +items_length += properties; } -keys = njs_array_alloc(vm, keys_length, NJS_ARRAY_SPARE); -if (nxt_slow_path(keys == NULL)) { +items = njs_array_alloc(vm, items_length, NJS_ARRAY_SPARE); +if (nxt_slow_path(items == NULL)) { return NULL; } -n = 0; +item = items->start; if (array != NULL) { -for (i = 0; i < length; i++) { -if (njs_is_valid(>start[i])) { -njs_uint32_to_string(>start[n++], i); + +switch (kind) { +case NJS_ENUM_KEYS: +for (i = 0; i < length; i++) { +if (njs_is_valid(>start[i])) { +njs_uint32_to_string(item++, i); +} } + +break; + +case NJS_ENUM_VALUES: +for (i = 0; i < length; i++) { +if (njs_is_valid(>start[i])) { +/* GC: retain. */ +*item++ = array->st
[njs] Slightly optimized njs_object_keys_array().
details: https://hg.nginx.org/njs/rev/4a543ed58c95 branches: changeset: 681:4a543ed58c95 user: Valentin Bartenev date: Sat Dec 01 22:32:33 2018 +0300 description: Slightly optimized njs_object_keys_array(). There is no need to iterate over the object properties second time if after the first attempt we know that it contains no enumerable properties. Also removed surplus conditions. diffstat: njs/njs_object.c | 19 ++- 1 files changed, 10 insertions(+), 9 deletions(-) diffs (61 lines): diff -r e713f648ef71 -r 4a543ed58c95 njs/njs_object.c --- a/njs/njs_object.c Fri Nov 30 17:52:02 2018 +0300 +++ b/njs/njs_object.c Sat Dec 01 22:32:33 2018 +0300 @@ -888,7 +888,7 @@ njs_object_keys(njs_vm_t *vm, njs_value_ njs_array_t * njs_object_keys_array(njs_vm_t *vm, const njs_value_t *value) { -uint32_t i, n, length, keys_length; +uint32_t i, n, length, keys_length, properties; njs_value_t*string; njs_array_t*keys, *array; nxt_lvlhsh_t *hash; @@ -930,15 +930,14 @@ njs_object_keys_array(njs_vm_t *vm, cons break; } +/* GCC 4 and Clang 3 complain about uninitialized hash. */ +hash = NULL; +properties = 0; + if (nxt_fast_path(njs_is_object(value))) { nxt_lvlhsh_each_init(, _object_hash_proto); hash = >data.u.object->hash; -} else { -hash = NULL; -} - -if (nxt_fast_path(hash != NULL)) { for ( ;; ) { prop = nxt_lvlhsh_each(hash, ); @@ -947,9 +946,11 @@ njs_object_keys_array(njs_vm_t *vm, cons } if (prop->type != NJS_WHITEOUT && prop->enumerable) { -keys_length++; +properties++; } } + +keys_length += properties; } keys = njs_array_alloc(vm, keys_length, NJS_ARRAY_SPARE); @@ -966,13 +967,13 @@ njs_object_keys_array(njs_vm_t *vm, cons } } -} else if (length != 0) { +} else { for (i = 0; i < length; i++) { njs_uint32_to_string(>start[n++], i); } } -if (nxt_fast_path(hash != NULL)) { +if (nxt_fast_path(properties != 0)) { nxt_lvlhsh_each_init(, _object_hash_proto); for ( ;; ) { ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] RegExp: fixed a case when lastIndex is greater than string size.
details: http://hg.nginx.org/njs/rev/f1da98bdd82f branches: changeset: 647:f1da98bdd82f user: Valentin Bartenev date: Mon Nov 12 17:22:14 2018 +0300 description: RegExp: fixed a case when lastIndex is greater than string size. Previously, it resulted in: "InternalError: pcre_exec() failed: -32" due to negative string size caused by subtraction of last_index. diffstat: njs/njs_regexp.c | 62 --- njs/test/njs_unit_test.c | 3 ++ 2 files changed, 35 insertions(+), 30 deletions(-) diffs (91 lines): diff -r 7d06ada396d7 -r f1da98bdd82f njs/njs_regexp.c --- a/njs/njs_regexp.c Fri Nov 09 18:22:01 2018 +0300 +++ b/njs/njs_regexp.c Mon Nov 12 17:22:14 2018 +0300 @@ -644,42 +644,44 @@ njs_regexp_prototype_exec(njs_vm_t *vm, (void) njs_string_prop(, value); -utf8 = NJS_STRING_BYTE; -type = NJS_REGEXP_BYTE; - -if (string.length != 0) { -utf8 = NJS_STRING_ASCII; -type = NJS_REGEXP_UTF8; - -if (string.length != string.size) { -utf8 = NJS_STRING_UTF8; -} -} +if (string.size >= regexp->last_index) { +utf8 = NJS_STRING_BYTE; +type = NJS_REGEXP_BYTE; -pattern = regexp->pattern; - -if (nxt_regex_is_valid(>regex[type])) { -string.start += regexp->last_index; -string.size -= regexp->last_index; +if (string.length != 0) { +utf8 = NJS_STRING_ASCII; +type = NJS_REGEXP_UTF8; -match_data = nxt_regex_match_data(>regex[type], - vm->regex_context); -if (nxt_slow_path(match_data == NULL)) { -njs_memory_error(vm); -return NXT_ERROR; +if (string.length != string.size) { +utf8 = NJS_STRING_UTF8; +} } -ret = njs_regexp_match(vm, >regex[type], string.start, - string.size, match_data); -if (ret >= 0) { -return njs_regexp_exec_result(vm, regexp, utf8, string.start, - match_data); -} +pattern = regexp->pattern; + +if (nxt_regex_is_valid(>regex[type])) { +string.start += regexp->last_index; +string.size -= regexp->last_index; + +match_data = nxt_regex_match_data(>regex[type], + vm->regex_context); +if (nxt_slow_path(match_data == NULL)) { +njs_memory_error(vm); +return NXT_ERROR; +} -if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) { -nxt_regex_match_data_free(match_data, vm->regex_context); +ret = njs_regexp_match(vm, >regex[type], string.start, + string.size, match_data); +if (ret >= 0) { +return njs_regexp_exec_result(vm, regexp, utf8, string.start, + match_data); +} -return NXT_ERROR; +if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) { +nxt_regex_match_data_free(match_data, vm->regex_context); + +return NXT_ERROR; +} } } diff -r 7d06ada396d7 -r f1da98bdd82f njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 09 18:22:01 2018 +0300 +++ b/njs/test/njs_unit_test.c Mon Nov 12 17:22:14 2018 +0300 @@ -5973,6 +5973,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = /^$/.exec(''); a.length +' '+ a"), nxt_string("1 ") }, +{ nxt_string("var r = /3/g; r.exec('123') +' '+ r.exec('3')"), + nxt_string("3 null") }, + { nxt_string("var r = /бв/ig;" "var a = r.exec('АБВ');" "r.lastIndex +' '+ a +' '+ " ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed equality operator with object and string.
details: http://hg.nginx.org/njs/rev/7d06ada396d7 branches: changeset: 646:7d06ada396d7 user: Valentin Bartenev date: Fri Nov 09 18:22:01 2018 +0300 description: Fixed equality operator with object and string. diffstat: njs/njs_vm.c | 25 ++--- njs/test/njs_unit_test.c | 19 +++ 2 files changed, 41 insertions(+), 3 deletions(-) diffs (81 lines): diff -r 025b22bf8c49 -r 7d06ada396d7 njs/njs_vm.c --- a/njs/njs_vm.c Thu Nov 08 20:32:45 2018 +0300 +++ b/njs/njs_vm.c Fri Nov 09 18:22:01 2018 +0300 @@ -1519,7 +1519,8 @@ njs_vmcode_not_equal(njs_vm_t *vm, njs_v static nxt_noinline njs_ret_t njs_values_equal(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2) { -nxt_bool_t nv1, nv2; +nxt_bool_t nv1, nv2; +const njs_value_t *hv, *lv; nv1 = njs_is_null_or_void(val1); nv2 = njs_is_null_or_void(val2); @@ -1543,11 +1544,29 @@ njs_values_equal(njs_vm_t *vm, const njs return (val1->data.u.object == val2->data.u.object); } -if (njs_is_object(val1) && njs_is_object(val2)) { +/* Sort values as: numeric < string < objects. */ + +if (val1->type > val2->type) { +hv = val1; +lv = val2; + +} else { +hv = val2; +lv = val1; +} + +/* If "lv" is an object then "hv" can only be another object. */ +if (njs_is_object(lv)) { return 0; } -return njs_trap(vm, NJS_TRAP_NUMBERS); +/* If "hv" is a string then "lv" can only be a numeric. */ +if (njs_is_string(hv)) { +return (lv->data.u.number == njs_string_to_number(hv, 0)); +} + +/* "hv" is an object and "lv" is either a string or a numeric. */ +return njs_trap(vm, NJS_TRAP_COMPARISON); } diff -r 025b22bf8c49 -r 7d06ada396d7 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Nov 08 20:32:45 2018 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 09 18:22:01 2018 +0300 @@ -1142,6 +1142,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = Object; a == Object"), nxt_string("true") }, +{ nxt_string("'1' == new Number(1)"), + nxt_string("true") }, + +{ nxt_string("new String('abc') == 'abc'"), + nxt_string("true") }, + +{ nxt_string("false == new String('0')"), + nxt_string("true") }, + { nxt_string("var a = { valueOf: function() { return 5 } }; a == 5"), nxt_string("true") }, @@ -1151,6 +1160,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = { valueOf: function() { return '5' } }; a == '5'"), nxt_string("true") }, +{ nxt_string("var a = { valueOf: function() { return 5 } }; a == '5'"), + nxt_string("true") }, + +{ nxt_string("var a = { toString: function() { return true } }; '1' == a"), + nxt_string("true") }, + +{ nxt_string("var a = { valueOf: function() { return 'b' }," + " toString: function() { return 'a' } }; a == 'a'"), + nxt_string("false") }, + /* Comparisions. */ { nxt_string("1 < 2"), ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed equality operator when both operands are objects.
details: http://hg.nginx.org/njs/rev/025b22bf8c49 branches: changeset: 645:025b22bf8c49 user: Valentin Bartenev date: Thu Nov 08 20:32:45 2018 +0300 description: Fixed equality operator when both operands are objects. diffstat: njs/njs_vm.c | 4 njs/test/njs_unit_test.c | 6 ++ 2 files changed, 10 insertions(+), 0 deletions(-) diffs (30 lines): diff -r abec5f8d55a1 -r 025b22bf8c49 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 09 18:05:39 2018 +0300 +++ b/njs/njs_vm.c Thu Nov 08 20:32:45 2018 +0300 @@ -1543,6 +1543,10 @@ njs_values_equal(njs_vm_t *vm, const njs return (val1->data.u.object == val2->data.u.object); } +if (njs_is_object(val1) && njs_is_object(val2)) { +return 0; +} + return njs_trap(vm, NJS_TRAP_NUMBERS); } diff -r abec5f8d55a1 -r 025b22bf8c49 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 09 18:05:39 2018 +0300 +++ b/njs/test/njs_unit_test.c Thu Nov 08 20:32:45 2018 +0300 @@ -1136,6 +1136,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("({}) == false"), nxt_string("false") }, +{ nxt_string("new Number(1) == new String('1')"), + nxt_string("false") }, + +{ nxt_string("var a = Object; a == Object"), + nxt_string("true") }, + { nxt_string("var a = { valueOf: function() { return 5 } }; a == 5"), nxt_string("true") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed equality operator with "null" value as right operand.
details: http://hg.nginx.org/njs/rev/abec5f8d55a1 branches: changeset: 644:abec5f8d55a1 user: Valentin Bartenev date: Fri Nov 09 18:05:39 2018 +0300 description: Fixed equality operator with "null" value as right operand. diffstat: njs/njs_vm.c | 9 +++-- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diffs (33 lines): diff -r c5a3ac902bc2 -r abec5f8d55a1 njs/njs_vm.c --- a/njs/njs_vm.c Thu Nov 08 16:45:54 2018 +0300 +++ b/njs/njs_vm.c Fri Nov 09 18:05:39 2018 +0300 @@ -1519,9 +1519,14 @@ njs_vmcode_not_equal(njs_vm_t *vm, njs_v static nxt_noinline njs_ret_t njs_values_equal(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2) { +nxt_bool_t nv1, nv2; + +nv1 = njs_is_null_or_void(val1); +nv2 = njs_is_null_or_void(val2); + /* Void and null are equal and not comparable with anything else. */ -if (njs_is_null_or_void(val1)) { -return (njs_is_null_or_void(val2)); +if (nv1 || nv2) { +return (nv1 && nv2); } if (njs_is_numeric(val1) && njs_is_numeric(val2)) { diff -r c5a3ac902bc2 -r abec5f8d55a1 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Nov 08 16:45:54 2018 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 09 18:05:39 2018 +0300 @@ -1025,6 +1025,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("null == false"), nxt_string("false") }, +{ nxt_string("0 == null"), + nxt_string("false") }, + { nxt_string("!null"), nxt_string("true") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed misplaced njs_internal_error().
details: http://hg.nginx.org/njs/rev/c5a3ac902bc2 branches: changeset: 643:c5a3ac902bc2 user: Valentin Bartenev date: Thu Nov 08 16:45:54 2018 +0300 description: Fixed misplaced njs_internal_error(). diffstat: njs/njs_variable.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 6ebf35347eee -r c5a3ac902bc2 njs/njs_variable.c --- a/njs/njs_variable.cWed Nov 07 18:41:29 2018 +0300 +++ b/njs/njs_variable.cThu Nov 08 16:45:54 2018 +0300 @@ -83,10 +83,11 @@ njs_builtin_add(njs_vm_t *vm, njs_parser ret = nxt_lvlhsh_insert(>variables, ); if (nxt_fast_path(ret == NXT_OK)) { -njs_internal_error(vm, "lvlhsh insert failed"); return var; } +njs_internal_error(vm, "lvlhsh insert failed"); + nxt_mem_cache_free(vm->mem_cache_pool, var->name.start); nxt_mem_cache_free(vm->mem_cache_pool, var); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed configure process with non-default locale.
details: http://hg.nginx.org/njs/rev/7ccf9c0a412a branches: changeset: 568:7ccf9c0a412a user: Valentin Bartenev date: Tue Jul 24 19:25:39 2018 +0300 description: Fixed configure process with non-default locale. Overriding LANG might not work, since it has less precedence than LC_* settings. LC_ALL has the highest precedence. diffstat: configure | 4 ++-- nxt/auto/configure | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diffs (28 lines): diff -r a4e5abdc345d -r 7ccf9c0a412a configure --- a/configure Tue Jul 24 18:29:25 2018 +0300 +++ b/configure Tue Jul 24 19:25:39 2018 +0300 @@ -5,8 +5,8 @@ # Disable localized program messages. -LANG=C -export LANG +LC_ALL=C +export LC_ALL # Stop on error exit status. set -e diff -r a4e5abdc345d -r 7ccf9c0a412a nxt/auto/configure --- a/nxt/auto/configureTue Jul 24 18:29:25 2018 +0300 +++ b/nxt/auto/configureTue Jul 24 19:25:39 2018 +0300 @@ -5,8 +5,8 @@ # Disable localized program messages. -LANG=C -export LANG +LC_ALL=C +export LC_ALL # Stop on error exit status. set -e ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] String.padStart() and String.padEnd() methods.
details: http://hg.nginx.org/njs/rev/31e0580b3c02 branches: changeset: 547:31e0580b3c02 user: Valentin Bartenev date: Fri Jun 29 22:36:41 2018 +0300 description: String.padStart() and String.padEnd() methods. diffstat: njs/njs_string.c | 125 +++ njs/test/njs_unit_test.c | 99 + 2 files changed, 224 insertions(+), 0 deletions(-) diffs (258 lines): diff -r f2a2c9674082 -r 31e0580b3c02 njs/njs_string.c --- a/njs/njs_string.c Mon Jul 02 16:10:52 2018 +0300 +++ b/njs/njs_string.c Fri Jun 29 22:36:41 2018 +0300 @@ -64,6 +64,8 @@ static njs_ret_t njs_string_from_char_co njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); 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_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, njs_regexp_pattern_t *pattern); static njs_ret_t njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array, @@ -2073,6 +2075,113 @@ njs_string_prototype_repeat(njs_vm_t *vm } +static njs_ret_t +njs_string_prototype_pad_start(njs_vm_t *vm, njs_value_t *args, +nxt_uint_t nargs, njs_index_t unused) +{ +return njs_string_prototype_pad(vm, args, nargs, 1); +} + + +static njs_ret_t +njs_string_prototype_pad_end(njs_vm_t *vm, njs_value_t *args, +nxt_uint_t nargs, njs_index_t unused) +{ +return njs_string_prototype_pad(vm, args, nargs, 0); +} + + +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) +{ +u_char *p, *start; +size_t padding, trunc, new_size; +int32_tlength, new_length; +uint32_t n, pad_length; +const u_char *end; +njs_string_prop_t string, pad_string; + +length = njs_string_prop(, [0]); +new_length = nargs > 1 ? args[1].data.u.number : 0; + +if (new_length <= length) { +vm->retval = args[0]; +return NJS_OK; +} + +if (nxt_slow_path(new_length >= NJS_STRING_MAX_LENGTH)) { +njs_range_error(vm, NULL); +return NJS_ERROR; +} + +padding = new_length - length; + +/* GCC and Clang complain about uninitialized n and trunc. */ +n = 0; +trunc = 0; + +if (nargs > 2) { +pad_length = njs_string_prop(_string, [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; +} +} +} + +new_size = string.size + padding; + +start = njs_string_alloc(vm, >retval, new_size, new_length); +if (nxt_slow_path(start == NULL)) { +return NJS_ERROR; +} + +p = start; + +if (pad_start) { +start += padding; + +} else { +p += string.size; +} + +memcpy(start, string.start, string.size); + +if (nargs == 2) { +memset(p, ' ', padding); + +} else if (pad_string.size == 1) { +memset(p, pad_string.start[0], padding); + +} else { +while (n != 0) { +memcpy(p, pad_string.start, pad_string.size); +p += pad_string.size; +n--; +} + +memcpy(p, pad_string.start, trunc); +} + +return NJS_OK; +} + + /* * String.search([regexp]) */ @@ -3490,6 +3599,22 @@ static const njs_object_prop_t njs_stri NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG), }, +/* ES8. */ +{ +.type = NJS_METHOD, +.name = njs_string("padStart"), +.value = njs_native_function(njs_string_prototype_pad_start, 0, + NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_STRING_ARG), +}, + +/* ES8. */ +{ +.type = NJS_METHOD, +.name = njs_string("padEnd"), +.value = njs_native_function(njs_string_prototype_pad_end, 0, + NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_STRING_ARG), +}, + { .type = NJS_METHOD, .name = njs_string("search"), diff -r f2a2c9674082 -r 31e0580b3c02 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Jul 02 16:10:52 2018 +0300 +++ b/njs/test/njs_unit_test.c Fri Jun 29 22:36:41 2018 +0300 @@ -4557,6 +4557,105 @@ static njs_unit_test_t njs_test[] = { nxt_string("''.repeat
[njs] Allowed uppercased O in octal literal values.
details: http://hg.nginx.org/njs/rev/1cdf9c1a377d branches: changeset: 544:1cdf9c1a377d user: Valentin Bartenev date: Sun Jul 01 09:59:45 2018 +0300 description: Allowed uppercased O in octal literal values. diffstat: njs/njs_lexer.c | 2 +- njs/test/njs_unit_test.c | 7 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diffs (39 lines): diff -r a361553ce219 -r 1cdf9c1a377d njs/njs_lexer.c --- a/njs/njs_lexer.c Sat Jun 30 20:39:22 2018 +0300 +++ b/njs/njs_lexer.c Sun Jul 01 09:59:45 2018 +0300 @@ -550,7 +550,7 @@ njs_lexer_number(njs_lexer_t *lexer) /* Octal literal values. */ -if (*p == 'o') { +if (*p == 'o' || *p == 'O') { p++; if (p == lexer->end) { diff -r a361553ce219 -r 1cdf9c1a377d njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Jun 30 20:39:22 2018 +0300 +++ b/njs/test/njs_unit_test.c Sun Jul 01 09:59:45 2018 +0300 @@ -118,10 +118,13 @@ static njs_unit_test_t njs_test[] = { nxt_string("0o0"), nxt_string("0") }, +{ nxt_string("0O10"), + nxt_string("8") }, + { nxt_string("0o011"), nxt_string("9") }, -{ nxt_string("-0o777"), +{ nxt_string("-0O777"), nxt_string("-511") }, /* Legacy Octal Numbers are deprecated. */ @@ -141,7 +144,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("0o"), nxt_string("SyntaxError: Unexpected token \"\" in 1") }, -{ nxt_string("0o778"), +{ nxt_string("0O778"), nxt_string("SyntaxError: Unexpected token \"\" in 1") }, /* Hex Numbers. */ ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Added support of binary literals.
details: http://hg.nginx.org/njs/rev/e210675daceb branches: changeset: 545:e210675daceb user: Valentin Bartenev date: Sun Jul 01 10:01:53 2018 +0300 description: Added support of binary literals. diffstat: njs/njs_lexer.c | 21 + njs/njs_number.c | 29 + njs/njs_number.h | 1 + njs/test/njs_unit_test.c | 20 4 files changed, 71 insertions(+), 0 deletions(-) diffs (111 lines): diff -r 1cdf9c1a377d -r e210675daceb njs/njs_lexer.c --- a/njs/njs_lexer.c Sun Jul 01 09:59:45 2018 +0300 +++ b/njs/njs_lexer.c Sun Jul 01 10:01:53 2018 +0300 @@ -569,6 +569,27 @@ njs_lexer_number(njs_lexer_t *lexer) return NJS_TOKEN_NUMBER; } +/* Binary literal values. */ + +if (*p == 'b' || *p == 'B') { +p++; + +if (p == lexer->end) { +return NJS_TOKEN_ILLEGAL; +} + +lexer->start = p; +lexer->number = njs_number_bin_parse((const u_char **) >start, + lexer->end); +p = lexer->start; + +if (p < lexer->end && (*p >= '2' && *p <= '9')) { +return NJS_TOKEN_ILLEGAL; +} + +return NJS_TOKEN_NUMBER; +} + /* Legacy Octal literals are deprecated. */ if (*p >= '0' && *p <= '9') { diff -r 1cdf9c1a377d -r e210675daceb njs/njs_number.c --- a/njs/njs_number.c Sun Jul 01 09:59:45 2018 +0300 +++ b/njs/njs_number.c Sun Jul 01 10:01:53 2018 +0300 @@ -184,6 +184,35 @@ njs_number_oct_parse(const u_char **star uint64_t +njs_number_bin_parse(const u_char **start, const u_char *end) +{ +u_charc; +uint64_t num; +const u_char *p; + +p = *start; + +num = 0; + +while (p < end) { +/* Values less than '0' become >= 208. */ +c = *p - '0'; + +if (nxt_slow_path(c > 1)) { +break; +} + +num = num * 2 + c; +p++; +} + +*start = p; + +return num; +} + + +uint64_t njs_number_hex_parse(const u_char **start, const u_char *end) { u_charc; diff -r 1cdf9c1a377d -r e210675daceb njs/njs_number.h --- a/njs/njs_number.h Sun Jul 01 09:59:45 2018 +0300 +++ b/njs/njs_number.h Sun Jul 01 10:01:53 2018 +0300 @@ -14,6 +14,7 @@ uint32_t njs_value_to_index(const njs_value_t *value); double njs_number_dec_parse(const u_char **start, const u_char *end); uint64_t njs_number_oct_parse(const u_char **start, const u_char *end); +uint64_t njs_number_bin_parse(const u_char **start, const u_char *end); uint64_t njs_number_hex_parse(const u_char **start, const u_char *end); int64_t njs_number_radix_parse(const u_char **start, const u_char *end, uint8_t radix); diff -r 1cdf9c1a377d -r e210675daceb njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sun Jul 01 09:59:45 2018 +0300 +++ b/njs/test/njs_unit_test.c Sun Jul 01 10:01:53 2018 +0300 @@ -147,6 +147,26 @@ static njs_unit_test_t njs_test[] = { nxt_string("0O778"), nxt_string("SyntaxError: Unexpected token \"\" in 1") }, +/* Binary Numbers. */ + +{ nxt_string("0b0"), + nxt_string("0") }, + +{ nxt_string("0B10"), + nxt_string("2") }, + +{ nxt_string("0b0101"), + nxt_string("5") }, + +{ nxt_string("-0B"), + nxt_string("-255") }, + +{ nxt_string("0b"), + nxt_string("SyntaxError: Unexpected token \"\" in 1") }, + +{ nxt_string("0B12"), + nxt_string("SyntaxError: Unexpected token \"\" in 1") }, + /* Hex Numbers. */ { nxt_string("0x0"), ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed error handling of setting non-numeric Array.length.
details: http://hg.nginx.org/njs/rev/a361553ce219 branches: changeset: 543:a361553ce219 user: Valentin Bartenev date: Sat Jun 30 20:39:22 2018 +0300 description: Fixed error handling of setting non-numeric Array.length. diffstat: njs/njs_array.c | 5 + 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 0307e2740df7 -r a361553ce219 njs/njs_array.c --- a/njs/njs_array.c Thu Jun 28 17:04:18 2018 +0300 +++ b/njs/njs_array.c Sat Jun 30 20:39:22 2018 +0300 @@ -375,6 +375,11 @@ njs_array_prototype_length(njs_vm_t *vm, array = value->data.u.array; if (setval != NULL) { +if (!njs_is_number(setval)) { +njs_range_error(vm, "Invalid array length"); +return NJS_ERROR; +} + num = setval->data.u.number; length = (uint32_t) num; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Introduced nxt_length() macro.
details: http://hg.nginx.org/njs/rev/255c79369f59 branches: changeset: 540:255c79369f59 user: Valentin Bartenev date: Tue Jun 26 18:25:22 2018 +0300 description: Introduced nxt_length() macro. diffstat: nginx/ngx_http_js_module.c | 4 ++-- njs/njs.c | 2 +- njs/njs_extern.c| 2 +- njs/njs_json.c | 10 +- njs/njs_parser.c| 2 +- njs/njs_string.c| 2 +- njs/njs_vm.h| 8 nxt/nxt_string.h| 3 ++- nxt/test/random_unit_test.c | 2 +- nxt/test/utf8_unit_test.c | 4 ++-- 10 files changed, 20 insertions(+), 19 deletions(-) diffs (157 lines): diff -r 711079f55d46 -r 255c79369f59 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.cTue Jun 19 14:07:22 2018 +0300 +++ b/nginx/ngx_http_js_module.cTue Jun 26 18:25:22 2018 +0300 @@ -1157,9 +1157,9 @@ ngx_http_js_ext_set_header_out(njs_vm_t h->value.data = p; h->value.len = value->length; -if (h->key.len == sizeof("Content-Length") - 1 +if (h->key.len == nxt_length("Content-Length") && ngx_strncasecmp(h->key.data, (u_char *) "Content-Length", - sizeof("Content-Length") - 1) == 0) + nxt_length("Content-Length")) == 0) { n = ngx_atoi(value->start, value->length); if (n == NGX_ERROR) { diff -r 711079f55d46 -r 255c79369f59 njs/njs.c --- a/njs/njs.c Tue Jun 19 14:07:22 2018 +0300 +++ b/njs/njs.c Tue Jun 26 18:25:22 2018 +0300 @@ -131,7 +131,7 @@ njs_vm_create(njs_vm_opt_t *options) nxt_lvlhsh_init(>shared->values_hash); pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", -sizeof("(?:)") - 1, 0); +nxt_length("(?:)"), 0); if (nxt_slow_path(pattern == NULL)) { return NULL; } diff -r 711079f55d46 -r 255c79369f59 njs/njs_extern.c --- a/njs/njs_extern.c Tue Jun 19 14:07:22 2018 +0300 +++ b/njs/njs_extern.c Tue Jun 26 18:25:22 2018 +0300 @@ -273,7 +273,7 @@ found: len = 0; for (pr = head; pr != NULL; pr = pr->next) { -len += pr->str.length + sizeof(".") - 1; +len += pr->str.length + nxt_length("."); } buf = nxt_mem_cache_zalloc(vm->mem_cache_pool, len); diff -r 711079f55d46 -r 255c79369f59 njs/njs_json.c --- a/njs/njs_json.cTue Jun 19 14:07:22 2018 +0300 +++ b/njs/njs_json.cTue Jun 26 18:25:22 2018 +0300 @@ -1400,19 +1400,19 @@ done: * The value to stringify is wrapped as '{"": value}'. * An empty object means empty result. */ -if (str.length <= sizeof("{\n\n}") - 1) { +if (str.length <= nxt_length("{\n\n}")) { vm->retval = njs_value_void; return NXT_OK; } /* Stripping the wrapper's data. */ -str.start += sizeof("{\"\":") - 1; -str.length -= sizeof("{\"\":}") - 1; +str.start += nxt_length("{\"\":"); +str.length -= nxt_length("{\"\":}"); if (stringify->space.length != 0) { -str.start += sizeof("\n ") - 1; -str.length -= sizeof("\n \n") - 1; +str.start += nxt_length("\n "); +str.length -= nxt_length("\n \n"); } length = nxt_utf8_length(str.start, str.length); diff -r 711079f55d46 -r 255c79369f59 njs/njs_parser.c --- a/njs/njs_parser.c Tue Jun 19 14:07:22 2018 +0300 +++ b/njs/njs_parser.c Tue Jun 26 18:25:22 2018 +0300 @@ -2589,7 +2589,7 @@ njs_parser_trace_handler(nxt_trace_t *tr size_tsize; njs_vm_t *vm; -size = sizeof("InternalError: ") - 1; +size = nxt_length("InternalError: "); memcpy(start, "InternalError: ", size); p = start + size; diff -r 711079f55d46 -r 255c79369f59 njs/njs_string.c --- a/njs/njs_string.c Tue Jun 19 14:07:22 2018 +0300 +++ b/njs/njs_string.c Tue Jun 26 18:25:22 2018 +0300 @@ -3165,7 +3165,7 @@ njs_string_to_number(const njs_value_t * nxt_bool_tminus; const u_char *p, *start, *end; -const size_t infinity = sizeof("Infinity") - 1; +const size_t infinity = nxt_length("Infinity"); size = value->short_string.size; diff -r 711079f55d46 -r 255c79369f59 njs/njs_vm.h --- a/njs/njs_vm.h Tue Jun 19 14:07:22 2018 +0300 +++ b/njs/njs_vm.h Tue Jun 26 18:25:22 2018 +0300 @@ -365,8 +365,8 @@ typedef struct { #define njs_string(s) { \ .short_string = {
[nginx] MIME: added font/woff2 type (ticket #1243).
details: http://hg.nginx.org/nginx/rev/118885f7a577 branches: changeset: 7303:118885f7a577 user: Valentin Bartenev date: Fri Jun 15 17:29:55 2018 +0300 description: MIME: added font/woff2 type (ticket #1243). diffstat: conf/mime.types | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r bf1a7b363598 -r 118885f7a577 conf/mime.types --- a/conf/mime.types Fri Jun 15 17:29:55 2018 +0300 +++ b/conf/mime.types Fri Jun 15 17:29:55 2018 +0300 @@ -25,6 +25,7 @@ types { image/x-ms-bmp bmp; font/woffwoff; +font/woff2 woff2; application/java-archive jar war ear; application/json json; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] MIME: changed type for woff to font/woff (ticket #1243).
details: http://hg.nginx.org/nginx/rev/bf1a7b363598 branches: changeset: 7302:bf1a7b363598 user: Valentin Bartenev date: Fri Jun 15 17:29:55 2018 +0300 description: MIME: changed type for woff to font/woff (ticket #1243). According to RFC 8081 the previously used application/font-woff type is deprecated. diffstat: conf/mime.types | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r f2396ecf608b -r bf1a7b363598 conf/mime.types --- a/conf/mime.types Fri Jun 15 11:46:14 2018 +0300 +++ b/conf/mime.types Fri Jun 15 17:29:55 2018 +0300 @@ -24,7 +24,8 @@ types { image/x-jng jng; image/x-ms-bmp bmp; -application/font-woffwoff; +font/woffwoff; + application/java-archive jar war ear; application/json json; application/mac-binhex40 hqx; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: enforce writing the sync request body buffer to file.
details: http://hg.nginx.org/nginx/rev/b6dc472299da branches: changeset: 7118:b6dc472299da user: Valentin Bartenev <vb...@nginx.com> date: Wed Oct 04 21:15:15 2017 +0300 description: HTTP/2: enforce writing the sync request body buffer to file. The sync flag of HTTP/2 request body buffer is used when the size of request body is unknown or bigger than configured "client_body_buffer_size". In this case the buffer points to body data inside the global receive buffer that is used for reading all HTTP/2 connections in the worker process. Thus, when the sync flag is set, the buffer must be flushed to a temporary file, otherwise the request body data can be overwritten. Previously, the sync buffer wasn't flushed to a temporary file if the whole body was received in one DATA frame with the END_STREAM flag and wasn't copied into the HTTP/2 body preread buffer. As a result, the request body might be corrupted (ticket #1384). Now, setting r->request_body_in_file_only enforces writing the sync buffer to a temporary file in all cases. diffstat: src/http/v2/ngx_http_v2.c | 7 ++- 1 files changed, 2 insertions(+), 5 deletions(-) diffs (24 lines): diff -r dbd77a638eb7 -r b6dc472299da src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Oct 03 18:19:27 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Wed Oct 04 21:15:15 2017 +0300 @@ -3589,11 +3589,6 @@ ngx_http_v2_read_request_body(ngx_http_r rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); } else { -if (stream->preread) { -/* enforce writing preread buffer to file */ -r->request_body_in_file_only = 1; -} - rb->buf = ngx_calloc_buf(r->pool); if (rb->buf != NULL) { @@ -3694,6 +3689,8 @@ ngx_http_v2_process_request_body(ngx_htt buf->pos = buf->start = pos; buf->last = buf->end = pos + size; +r->request_body_in_file_only = 1; + } else { if (size > (size_t) (buf->end - buf->last)) { ngx_log_error(NGX_LOG_INFO, fc->log, 0, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] Parenthesized ASCII-related calculations.
details: http://hg.nginx.org/nginx/rev/e3723f2a11b7 branches: changeset: 7067:e3723f2a11b7 user: Valentin Bartenev <vb...@nginx.com> date: Mon Jul 17 17:23:51 2017 +0300 description: Parenthesized ASCII-related calculations. This also fixes potential undefined behaviour in the range and slice filter modules, caused by local overflows of signed integers in expressions. diffstat: src/core/ngx_parse_time.c | 16 src/core/ngx_string.c | 8 src/event/ngx_event_openssl_stapling.c | 2 +- src/http/modules/ngx_http_range_filter_module.c | 4 ++-- src/http/modules/ngx_http_slice_filter_module.c | 8 src/http/ngx_http_parse.c | 14 +++--- src/http/ngx_http_upstream.c| 6 +++--- 7 files changed, 29 insertions(+), 29 deletions(-) diffs (282 lines): diff -r a27e0c7e198c -r e3723f2a11b7 src/core/ngx_parse_time.c --- a/src/core/ngx_parse_time.c Wed Jul 12 11:34:04 2017 +0300 +++ b/src/core/ngx_parse_time.c Mon Jul 17 17:23:51 2017 +0300 @@ -58,7 +58,7 @@ ngx_parse_http_time(u_char *value, size_ return NGX_ERROR; } -day = (*p - '0') * 10 + *(p + 1) - '0'; +day = (*p - '0') * 10 + (*(p + 1) - '0'); p += 2; if (*p == ' ') { @@ -132,7 +132,7 @@ ngx_parse_http_time(u_char *value, size_ } year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 - + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; + + (*(p + 2) - '0') * 10 + (*(p + 3) - '0'); p += 4; } else if (fmt == rfc850) { @@ -140,7 +140,7 @@ ngx_parse_http_time(u_char *value, size_ return NGX_ERROR; } -year = (*p - '0') * 10 + *(p + 1) - '0'; +year = (*p - '0') * 10 + (*(p + 1) - '0'); year += (year < 70) ? 2000 : 1900; p += 2; } @@ -161,7 +161,7 @@ ngx_parse_http_time(u_char *value, size_ return NGX_ERROR; } -day = day * 10 + *p++ - '0'; +day = day * 10 + (*p++ - '0'); } if (end - p < 14) { @@ -177,7 +177,7 @@ ngx_parse_http_time(u_char *value, size_ return NGX_ERROR; } -hour = (*p - '0') * 10 + *(p + 1) - '0'; +hour = (*p - '0') * 10 + (*(p + 1) - '0'); p += 2; if (*p++ != ':') { @@ -188,7 +188,7 @@ ngx_parse_http_time(u_char *value, size_ return NGX_ERROR; } -min = (*p - '0') * 10 + *(p + 1) - '0'; +min = (*p - '0') * 10 + (*(p + 1) - '0'); p += 2; if (*p++ != ':') { @@ -199,7 +199,7 @@ ngx_parse_http_time(u_char *value, size_ return NGX_ERROR; } -sec = (*p - '0') * 10 + *(p + 1) - '0'; +sec = (*p - '0') * 10 + (*(p + 1) - '0'); if (fmt == isoc) { p += 2; @@ -216,7 +216,7 @@ ngx_parse_http_time(u_char *value, size_ } year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 - + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; + + (*(p + 2) - '0') * 10 + (*(p + 3) - '0'); } if (hour > 23 || min > 59 || sec > 59) { diff -r a27e0c7e198c -r e3723f2a11b7 src/core/ngx_string.c --- a/src/core/ngx_string.c Wed Jul 12 11:34:04 2017 +0300 +++ b/src/core/ngx_string.c Mon Jul 17 17:23:51 2017 +0300 @@ -178,7 +178,7 @@ ngx_vslprintf(u_char *buf, u_char *last, slen = (size_t) -1; while (*fmt >= '0' && *fmt <= '9') { -width = width * 10 + *fmt++ - '0'; +width = width * 10 + (*fmt++ - '0'); } @@ -211,7 +211,7 @@ ngx_vslprintf(u_char *buf, u_char *last, fmt++; while (*fmt >= '0' && *fmt <= '9') { -frac_width = frac_width * 10 + *fmt++ - '0'; +frac_width = frac_width * 10 + (*fmt++ - '0'); } break; @@ -1655,7 +1655,7 @@ ngx_unescape_uri(u_char **dst, u_char ** state = sw_usual; if (ch >= '0' && ch <= '9') { -ch = (u_char) ((decoded << 4) + ch - '0'); +ch = (u_char) ((decoded << 4) + (ch - '0')); if (type & NGX_UNESCAPE_REDIRECT) { if (ch > '%' && ch < 0x7f) { @@ -1675,7 +1675,7 @@ ngx_unescape_uri(u_char **dst, u_char ** c = (u_char) (ch | 0x20); if (c >= 'a' && c <= 'f') { -ch = (u_char) ((decoded << 4) + c - 'a' + 10); +ch = (u_char) ((decoded << 4) + (c - 'a') + 10); if (type & NGX_UNESCAPE_URI) { if (ch == '?') { diff -r a27e0c7e198c -r e3723f2a11b7 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.cWed Jul 12 11:34:04 2017 +0300 +++ b/src/event/ng
[nginx] HTTP/2: reject HTTP/2 requests without ":scheme" pseudo-header.
details: http://hg.nginx.org/nginx/rev/3c55863e6887 branches: changeset: 7029:3c55863e6887 user: Piotr Sikoradate: Tue Jun 13 17:01:08 2017 +0300 description: HTTP/2: reject HTTP/2 requests without ":scheme" pseudo-header. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r e6f399a176e7 -r 3c55863e6887 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Wed Jun 07 18:46:36 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue Jun 13 17:01:08 2017 +0300 @@ -3332,6 +3332,7 @@ ngx_http_v2_construct_request_line(ngx_h static const u_char ending[] = " HTTP/2.0"; if (r->method_name.len == 0 +|| r->schema_start == NULL || r->unparsed_uri.len == 0) { ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: send SETTINGS ACK after applying all SETTINGS params.
details: http://hg.nginx.org/nginx/rev/859d80f57aab branches: changeset: 7023:859d80f57aab user: Piotr Sikoradate: Fri Jun 02 15:05:24 2017 +0300 description: HTTP/2: send SETTINGS ACK after applying all SETTINGS params. This avoids sending unnecessary SETTINGS ACK in case of PROTOCOL_ERROR. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 645ed7112a01 -r 859d80f57aab src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:20 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:24 2017 +0300 @@ -1959,8 +1959,6 @@ ngx_http_v2_state_settings(ngx_http_v2_c return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } -ngx_http_v2_send_settings(h2c, 1); - return ngx_http_v2_state_settings_params(h2c, pos, end); } @@ -2026,6 +2024,8 @@ ngx_http_v2_state_settings_params(ngx_ht pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE; } +ngx_http_v2_send_settings(h2c, 1); + if (window_delta) { if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { return ngx_http_v2_connection_error(h2c, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: don't send SETTINGS ACK before already queued DATA frames.
details: http://hg.nginx.org/nginx/rev/7206c3630310 branches: changeset: 7025:7206c3630310 user: Piotr Sikoradate: Fri Jun 02 15:05:32 2017 +0300 description: HTTP/2: don't send SETTINGS ACK before already queued DATA frames. Previously, SETTINGS ACK was sent immediately upon receipt of SETTINGS frame, before already queued DATA frames created using old SETTINGS. This incorrect behavior was source of interoperability issues, because peers rely on the fact that new SETTINGS are in effect after receiving SETTINGS ACK. Reported by Feng Li. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 2 +- src/http/v2/ngx_http_v2.h | 9 + 2 files changed, 10 insertions(+), 1 deletions(-) diffs (31 lines): diff -r 79de0d2aa432 -r 7206c3630310 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:28 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:32 2017 +0300 @@ -2032,7 +2032,7 @@ ngx_http_v2_state_settings_params(ngx_ht return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); } -ngx_http_v2_queue_blocked_frame(h2c, frame); +ngx_http_v2_queue_ordered_frame(h2c, frame); if (window_delta) { if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { diff -r 79de0d2aa432 -r 7206c3630310 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Fri Jun 02 15:05:28 2017 +0300 +++ b/src/http/v2/ngx_http_v2.h Fri Jun 02 15:05:32 2017 +0300 @@ -261,6 +261,15 @@ ngx_http_v2_queue_blocked_frame(ngx_http } +static ngx_inline void +ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c, +ngx_http_v2_out_frame_t *frame) +{ +frame->next = h2c->last_out; +h2c->last_out = frame; +} + + void ngx_http_v2_init(ngx_event_t *rev); void ngx_http_v2_request_headers_init(void); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: make SETTINGS ACK frame reusable.
details: http://hg.nginx.org/nginx/rev/79de0d2aa432 branches: changeset: 7024:79de0d2aa432 user: Piotr Sikoradate: Fri Jun 02 15:05:28 2017 +0300 description: HTTP/2: make SETTINGS ACK frame reusable. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 62 +- 1 files changed, 34 insertions(+), 28 deletions(-) diffs (132 lines): diff -r 859d80f57aab -r 79de0d2aa432 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:24 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:28 2017 +0300 @@ -28,6 +28,7 @@ #define NGX_HTTP_V2_HTTP_1_1_REQUIRED0xd /* frame sizes */ +#define NGX_HTTP_V2_SETTINGS_ACK_SIZE0 #define NGX_HTTP_V2_RST_STREAM_SIZE 4 #define NGX_HTTP_V2_PRIORITY_SIZE5 #define NGX_HTTP_V2_PING_SIZE8 @@ -128,8 +129,7 @@ static ngx_http_v2_node_t *ngx_http_v2_g #define ngx_http_v2_index_size(h2scf) (h2scf->streams_index_mask + 1) #define ngx_http_v2_index(h2scf, sid) ((sid >> 1) & h2scf->streams_index_mask) -static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c, -ngx_uint_t ack); +static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c); static ngx_int_t ngx_http_v2_settings_frame_handler( ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c, @@ -269,7 +269,7 @@ ngx_http_v2_init(ngx_event_t *rev) return; } -if (ngx_http_v2_send_settings(h2c, 0) == NGX_ERROR) { +if (ngx_http_v2_send_settings(h2c) == NGX_ERROR) { ngx_http_close_connection(c); return; } @@ -1967,8 +1967,9 @@ static u_char * ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { -ssize_t window_delta; -ngx_uint_t id, value; +ssize_t window_delta; +ngx_uint_tid, value; +ngx_http_v2_out_frame_t *frame; window_delta = 0; @@ -2024,7 +2025,14 @@ ngx_http_v2_state_settings_params(ngx_ht pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE; } -ngx_http_v2_send_settings(h2c, 1); +frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_SETTINGS_ACK_SIZE, + NGX_HTTP_V2_SETTINGS_FRAME, + NGX_HTTP_V2_ACK_FLAG, 0); +if (frame == NULL) { +return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); +} + +ngx_http_v2_queue_blocked_frame(h2c, frame); if (window_delta) { if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { @@ -2476,7 +2484,7 @@ ngx_http_v2_parse_int(ngx_http_v2_connec static ngx_int_t -ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c, ngx_uint_t ack) +ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c) { size_tlen; ngx_buf_t*buf; @@ -2484,8 +2492,8 @@ ngx_http_v2_send_settings(ngx_http_v2_co ngx_http_v2_srv_conf_t *h2scf; ngx_http_v2_out_frame_t *frame; -ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 send SETTINGS frame ack:%ui", ack); +ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send SETTINGS frame"); frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t)); if (frame == NULL) { @@ -2497,7 +2505,7 @@ ngx_http_v2_send_settings(ngx_http_v2_co return NGX_ERROR; } -len = ack ? 0 : (sizeof(uint16_t) + sizeof(uint32_t)) * 3; +len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3; buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len); if (buf == NULL) { @@ -2521,28 +2529,26 @@ ngx_http_v2_send_settings(ngx_http_v2_co buf->last = ngx_http_v2_write_len_and_type(buf->last, len, NGX_HTTP_V2_SETTINGS_FRAME); -*buf->last++ = ack ? NGX_HTTP_V2_ACK_FLAG : NGX_HTTP_V2_NO_FLAG; +*buf->last++ = NGX_HTTP_V2_NO_FLAG; buf->last = ngx_http_v2_write_sid(buf->last, 0); -if (!ack) { -h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, - ngx_http_v2_module); - -buf->last = ngx_http_v2_write_uint16(buf->last, - NGX_HTTP_V2_MAX_STREAMS_SETTING); -buf->last = ngx_http_v2_write_uint32(buf->last, - h2scf->concurrent_streams); - -buf->last = ngx_http_v2_write_uint16(buf->last, +h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, + ngx_http_v2_module); + +buf->last = ngx_http_v2_write_uint16(buf->last, + NGX_HTTP_V2_MAX_STREAMS_SETTING); +
[nginx] HTTP/2: emit new frames only after applying all SETTINGS params.
details: http://hg.nginx.org/nginx/rev/645ed7112a01 branches: changeset: 7022:645ed7112a01 user: Piotr Sikoradate: Fri Jun 02 15:05:20 2017 +0300 description: HTTP/2: emit new frames only after applying all SETTINGS params. Previously, new frames could be emitted in the middle of applying new (and already acknowledged) SETTINGS params, which is illegal. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 17 +++-- 1 files changed, 11 insertions(+), 6 deletions(-) diffs (43 lines): diff -r 639e48c382a6 -r 645ed7112a01 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Jun 02 12:55:31 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Jun 02 15:05:20 2017 +0300 @@ -1969,8 +1969,11 @@ static u_char * ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { +ssize_t window_delta; ngx_uint_t id, value; +window_delta = 0; + while (h2c->state.length) { if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) { return ngx_http_v2_state_save(h2c, pos, end, @@ -1995,12 +1998,7 @@ ngx_http_v2_state_settings_params(ngx_ht NGX_HTTP_V2_FLOW_CTRL_ERROR); } -if (ngx_http_v2_adjust_windows(h2c, value - h2c->init_window) -!= NGX_OK) -{ -return ngx_http_v2_connection_error(h2c, - NGX_HTTP_V2_INTERNAL_ERROR); -} +window_delta = value - h2c->init_window; h2c->init_window = value; break; @@ -2028,6 +2026,13 @@ ngx_http_v2_state_settings_params(ngx_ht pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE; } +if (window_delta) { +if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { +return ngx_http_v2_connection_error(h2c, +NGX_HTTP_V2_INTERNAL_ERROR); +} +} + return ngx_http_v2_state_complete(h2c, pos, end); } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] Version bump.
details: http://hg.nginx.org/nginx/rev/dfed742c0183 branches: changeset: 7015:dfed742c0183 user: Valentin Bartenev <vb...@nginx.com> date: Tue May 30 19:29:45 2017 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r b4cb75066262 -r dfed742c0183 src/core/nginx.h --- a/src/core/nginx.h Tue May 30 17:55:23 2017 +0300 +++ b/src/core/nginx.h Tue May 30 19:29:45 2017 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1013001 -#define NGINX_VERSION "1.13.1" +#define nginx_version 1013002 +#define NGINX_VERSION "1.13.2" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: add debug logging of pseudo-headers and cookies.
details: http://hg.nginx.org/nginx/rev/ab6ef3037840 branches: changeset: 7016:ab6ef3037840 user: Piotr Sikoradate: Tue May 30 17:42:27 2017 +0300 description: HTTP/2: add debug logging of pseudo-headers and cookies. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 62 ++ 1 files changed, 35 insertions(+), 27 deletions(-) diffs (82 lines): diff -r dfed742c0183 -r ab6ef3037840 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue May 30 19:29:45 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue May 30 17:42:27 2017 +0300 @@ -1568,6 +1568,10 @@ ngx_http_v2_state_process_header(ngx_htt rc = ngx_http_v2_pseudo_header(r, header); if (rc == NGX_OK) { +ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http2 pseudo-header: \":%V: %V\"", + >name, >value); + return ngx_http_v2_state_header_complete(h2c, pos, end); } @@ -1609,36 +1613,40 @@ ngx_http_v2_state_process_header(ngx_htt NGX_HTTP_V2_INTERNAL_ERROR); } -return ngx_http_v2_state_header_complete(h2c, pos, end); -} - -h = ngx_list_push(>headers_in.headers); -if (h == NULL) { -return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); -} - -h->key.len = header->name.len; -h->key.data = header->name.data; - -/* TODO Optimization: precalculate hash and handler for indexed headers. */ -h->hash = ngx_hash_key(h->key.data, h->key.len); - -h->value.len = header->value.len; -h->value.data = header->value.data; - -h->lowcase_key = h->key.data; - -cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - -hh = ngx_hash_find(>headers_in_hash, h->hash, - h->lowcase_key, h->key.len); - -if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { -goto error; +} else { +h = ngx_list_push(>headers_in.headers); +if (h == NULL) { +return ngx_http_v2_connection_error(h2c, +NGX_HTTP_V2_INTERNAL_ERROR); +} + +h->key.len = header->name.len; +h->key.data = header->name.data; + +/* + * TODO Optimization: precalculate hash + * and handler for indexed headers. + */ +h->hash = ngx_hash_key(h->key.data, h->key.len); + +h->value.len = header->value.len; +h->value.data = header->value.data; + +h->lowcase_key = h->key.data; + +cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + +hh = ngx_hash_find(>headers_in_hash, h->hash, + h->lowcase_key, h->key.len); + +if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { +goto error; +} } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 http header: \"%V: %V\"", >key, >value); + "http2 http header: \"%V: %V\"", + >name, >value); return ngx_http_v2_state_header_complete(h2c, pos, end); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: fixed segfault when memory allocation failed.
details: http://hg.nginx.org/nginx/rev/b624fbf7bee2 branches: changeset: 7004:b624fbf7bee2 user: Valentin Bartenev <vb...@nginx.com> date: Tue May 23 20:19:39 2017 +0300 description: HTTP/2: fixed segfault when memory allocation failed. If allocation of cleanup handler in the HTTP/2 header filter failed, then a stream might be freed with a HEADERS frame left in the output queue. Now the HEADERS frame is accounted in the queue before trying to allocate the cleanup handler. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 7943298d4ac0 -r b624fbf7bee2 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Mon May 22 16:34:47 2017 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue May 23 20:19:39 2017 +0300 @@ -619,6 +619,8 @@ ngx_http_v2_header_filter(ngx_http_reque ngx_http_v2_queue_blocked_frame(r->stream->connection, frame); +r->stream->queued = 1; + cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { return NGX_ERROR; @@ -627,8 +629,6 @@ ngx_http_v2_header_filter(ngx_http_reque cln->handler = ngx_http_v2_filter_cleanup; cln->data = r->stream; -r->stream->queued = 1; - fc->send_chain = ngx_http_v2_send_chain; fc->need_last_buf = 1; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: reduced difference to HTTP/1.x in reading request body.
details: http://hg.nginx.org/nginx/rev/2c4dbcd6f2e4 branches: changeset: 6989:2c4dbcd6f2e4 user: Valentin Bartenev <vb...@nginx.com> date: Mon Apr 24 14:17:13 2017 +0300 description: HTTP/2: reduced difference to HTTP/1.x in reading request body. Particularly, this eliminates difference in behavior for requests without body and deduplicates code. Prodded by Piotr Sikora. diffstat: src/http/ngx_http_request_body.c | 20 src/http/v2/ngx_http_v2.c| 28 +--- src/http/v2/ngx_http_v2.h| 3 +-- 3 files changed, 18 insertions(+), 33 deletions(-) diffs (115 lines): diff -r cc823122d50d -r 2c4dbcd6f2e4 src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Mon Apr 24 14:16:57 2017 +0300 +++ b/src/http/ngx_http_request_body.c Mon Apr 24 14:17:13 2017 +0300 @@ -46,13 +46,6 @@ ngx_http_read_client_request_body(ngx_ht return NGX_OK; } -#if (NGX_HTTP_V2) -if (r->stream) { -rc = ngx_http_v2_read_request_body(r, post_handler); -goto done; -} -#endif - if (ngx_http_test_expect(r) != NGX_OK) { rc = NGX_HTTP_INTERNAL_SERVER_ERROR; goto done; @@ -85,6 +78,13 @@ ngx_http_read_client_request_body(ngx_ht return NGX_OK; } +#if (NGX_HTTP_V2) +if (r->stream) { +rc = ngx_http_v2_read_request_body(r); +goto done; +} +#endif + preread = r->header_in->last - r->header_in->pos; if (preread) { @@ -805,7 +805,11 @@ ngx_http_test_expect(ngx_http_request_t if (r->expect_tested || r->headers_in.expect == NULL -|| r->http_version < NGX_HTTP_VERSION_11) +|| r->http_version < NGX_HTTP_VERSION_11 +#if (NGX_HTTP_V2) +|| r->stream != NULL +#endif + ) { return NGX_OK; } diff -r cc823122d50d -r 2c4dbcd6f2e4 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Apr 24 14:16:57 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Apr 24 14:17:13 2017 +0300 @@ -3522,8 +3522,7 @@ ngx_http_v2_run_request(ngx_http_request ngx_int_t -ngx_http_v2_read_request_body(ngx_http_request_t *r, -ngx_http_client_body_handler_pt post_handler) +ngx_http_v2_read_request_body(ngx_http_request_t *r) { off_t len; size_t size; @@ -3536,33 +3535,14 @@ ngx_http_v2_read_request_body(ngx_http_r ngx_http_v2_connection_t *h2c; stream = r->stream; +rb = r->request_body; if (stream->skip_data) { r->request_body_no_buffering = 0; -post_handler(r); +rb->post_handler(r); return NGX_OK; } -rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); -if (rb == NULL) { -return NGX_HTTP_INTERNAL_SERVER_ERROR; -} - -/* - * set by ngx_pcalloc(): - * - * rb->bufs = NULL; - * rb->buf = NULL; - * rb->received = 0; - * rb->free = NULL; - * rb->busy = NULL; - */ - -rb->rest = 1; -rb->post_handler = post_handler; - -r->request_body = rb; - h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -3612,6 +3592,8 @@ ngx_http_v2_read_request_body(ngx_http_r return NGX_HTTP_INTERNAL_SERVER_ERROR; } +rb->rest = 1; + buf = stream->preread; if (stream->in_closed) { diff -r cc823122d50d -r 2c4dbcd6f2e4 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Mon Apr 24 14:16:57 2017 +0300 +++ b/src/http/v2/ngx_http_v2.h Mon Apr 24 14:17:13 2017 +0300 @@ -264,8 +264,7 @@ ngx_http_v2_queue_blocked_frame(ngx_http void ngx_http_v2_init(ngx_event_t *rev); void ngx_http_v2_request_headers_init(void); -ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r, -ngx_http_client_body_handler_pt post_handler); +ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r); ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r); void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] Core: improved JSON escaping.
details: http://hg.nginx.org/nginx/rev/289403abc84e branches: changeset: 6974:289403abc84e user: Valentin Bartenev <vb...@nginx.com> date: Wed Apr 12 22:47:57 2017 +0300 description: Core: improved JSON escaping. Two-character representations are now used for \b, \f, \n, \r, and \t. diffstat: src/core/ngx_string.c | 51 --- 1 files changed, 44 insertions(+), 7 deletions(-) diffs (68 lines): diff -r 99934aade555 -r 289403abc84e src/core/ngx_string.c --- a/src/core/ngx_string.c Wed Apr 12 22:21:04 2017 +0300 +++ b/src/core/ngx_string.c Wed Apr 12 22:47:57 2017 +0300 @@ -1808,7 +1808,19 @@ ngx_escape_json(u_char *dst, u_char *src len++; } else if (ch <= 0x1f) { -len += sizeof("\\u001F") - 2; + +switch (ch) { +case '\n': +case '\r': +case '\t': +case '\b': +case '\f': +len++; +break; + +default: +len += sizeof("\\u001F") - 2; +} } size--; @@ -1829,12 +1841,37 @@ ngx_escape_json(u_char *dst, u_char *src *dst++ = ch; } else { -*dst++ = '\\'; *dst++ = 'u'; *dst++ = '0'; *dst++ = '0'; -*dst++ = '0' + (ch >> 4); - -ch &= 0xf; - -*dst++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10); +*dst++ = '\\'; + +switch (ch) { +case '\n': +*dst++ = 'n'; +break; + +case '\r': +*dst++ = 'r'; +break; + +case '\t': +*dst++ = 't'; +break; + +case '\b': +*dst++ = 'b'; +break; + +case '\f': +*dst++ = 'f'; +break; + +default: +*dst++ = 'u'; *dst++ = '0'; *dst++ = '0'; +*dst++ = '0' + (ch >> 4); + +ch &= 0xf; + +*dst++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10); +} } size--; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: style and typos.
details: http://hg.nginx.org/nginx/rev/28dc369899ea branches: changeset: 6958:28dc369899ea user: Piotr Sikoradate: Sun Mar 26 01:25:01 2017 -0700 description: HTTP/2: style and typos. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 11 ++- src/http/v2/ngx_http_v2.h | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diffs (69 lines): diff -r 83bae3d354ab -r 28dc369899ea src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Wed Mar 29 20:21:01 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:01 2017 -0700 @@ -941,7 +941,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_ if (size >= h2c->state.length) { size = h2c->state.length; -stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; +stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; } r = stream->request; @@ -1905,7 +1905,7 @@ ngx_http_v2_state_rst_stream(ngx_http_v2 if (node == NULL || node->stream == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, -"unknown http2 stream"); + "unknown http2 stream"); return ngx_http_v2_state_complete(h2c, pos, end); } @@ -2019,6 +2019,7 @@ ngx_http_v2_state_settings_params(ngx_ht break; case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING: + if (value > NGX_HTTP_V2_MAX_FRAME_SIZE || value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE) { @@ -3076,7 +3077,7 @@ ngx_http_v2_pseudo_header(ngx_http_reque } ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent unknown pseudo header \"%V\"", + "client sent unknown pseudo-header \":%V\"", >name); return NGX_DECLINED; @@ -3223,14 +3224,14 @@ ngx_http_v2_parse_scheme(ngx_http_reques { if (r->schema_start) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent duplicate :schema header"); + "client sent duplicate :scheme header"); return NGX_DECLINED; } if (header->value.len == 0) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent empty :schema header"); + "client sent empty :scheme header"); return NGX_DECLINED; } diff -r 83bae3d354ab -r 28dc369899ea src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Wed Mar 29 20:21:01 2017 +0300 +++ b/src/http/v2/ngx_http_v2.h Sun Mar 26 01:25:01 2017 -0700 @@ -249,8 +249,8 @@ ngx_http_v2_queue_blocked_frame(ngx_http { ngx_http_v2_out_frame_t **out; -for (out = >last_out; *out; out = &(*out)->next) -{ +for (out = >last_out; *out; out = &(*out)->next) { + if ((*out)->blocked || (*out)->stream == NULL) { break; } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: fixed stream finalization.
details: http://hg.nginx.org/nginx/rev/9b5f31fdb850 branches: changeset: 6956:9b5f31fdb850 user: Valentin Bartenev <vb...@nginx.com> date: Wed Mar 29 20:16:23 2017 +0300 description: HTTP/2: fixed stream finalization. In order to finalize stream the error flag is set on fake connection and either "write" or "read" event handler is called. The read events of fake connections are always ready, but it's not the case with the write events. When the ready flag isn't set, the error flag can be not checked in some cases and as a result stream isn't finalized. Now the ready flag is explicilty set on write events for proper finalization in all cases. diffstat: src/http/v2/ngx_http_v2.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (14 lines): diff -r d38161da62cd -r 9b5f31fdb850 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:05 2017 -0700 +++ b/src/http/v2/ngx_http_v2.c Wed Mar 29 20:16:23 2017 +0300 @@ -4266,7 +4266,10 @@ ngx_http_v2_finalize_connection(ngx_http if (stream->queued) { stream->queued = 0; + ev = fc->write; +ev->active = 0; +ev->ready = 1; } else { ev = fc->read; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: emit PROTOCOL_ERROR on padding errors.
details: http://hg.nginx.org/nginx/rev/d38161da62cd branches: changeset: 6955:d38161da62cd user: Piotr Sikoradate: Sun Mar 26 01:25:05 2017 -0700 description: HTTP/2: emit PROTOCOL_ERROR on padding errors. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (23 lines): diff -r 052305810ca4 -r d38161da62cd src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:04 2017 -0700 +++ b/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:05 2017 -0700 @@ -812,7 +812,8 @@ ngx_http_v2_state_data(ngx_http_v2_conne "with incorrect length: %uz, padding: %uz", size, h2c->state.padding); -return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); +return ngx_http_v2_connection_error(h2c, +NGX_HTTP_V2_PROTOCOL_ERROR); } h2c->state.length -= 1 + h2c->state.padding; @@ -1055,7 +1056,8 @@ ngx_http_v2_state_headers(ngx_http_v2_co "with incorrect length: %uz, padding: %uz", h2c->state.length, h2c->state.padding); -return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); +return ngx_http_v2_connection_error(h2c, +NGX_HTTP_V2_PROTOCOL_ERROR); } h2c->state.length -= h2c->state.padding; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: fix flow control with padded DATA frames.
details: http://hg.nginx.org/nginx/rev/052305810ca4 branches: changeset: 6954:052305810ca4 user: Piotr Sikoradate: Sun Mar 26 01:25:04 2017 -0700 description: HTTP/2: fix flow control with padded DATA frames. Previously, flow control didn't account for padding in DATA frames, which meant that its view of the world could drift from peer's view by up to 256 bytes per received padded DATA frame, which could lead to a deadlock. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 24 +--- 1 files changed, 13 insertions(+), 11 deletions(-) diffs (80 lines): diff -r 663e6a48bfcb -r 052305810ca4 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:03 2017 -0700 +++ b/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:04 2017 -0700 @@ -783,9 +783,12 @@ ngx_http_v2_state_head(ngx_http_v2_conne static u_char * ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { +size_t size; ngx_http_v2_node_t*node; ngx_http_v2_stream_t *stream; +size = h2c->state.length; + if (h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG) { if (h2c->state.length == 0) { @@ -802,33 +805,32 @@ ngx_http_v2_state_data(ngx_http_v2_conne } h2c->state.padding = *pos++; -h2c->state.length--; - -if (h2c->state.padding > h2c->state.length) { + +if (h2c->state.padding >= size) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client sent padded DATA frame " "with incorrect length: %uz, padding: %uz", - h2c->state.length, h2c->state.padding); + size, h2c->state.padding); return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } -h2c->state.length -= h2c->state.padding; +h2c->state.length -= 1 + h2c->state.padding; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, "http2 DATA frame"); -if (h2c->state.length > h2c->recv_window) { +if (size > h2c->recv_window) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client violated connection flow control: " "received DATA frame length %uz, available window %uz", - h2c->state.length, h2c->recv_window); + size, h2c->recv_window); return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR); } -h2c->recv_window -= h2c->state.length; +h2c->recv_window -= size; if (h2c->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) { @@ -854,11 +856,11 @@ ngx_http_v2_state_data(ngx_http_v2_conne stream = node->stream; -if (h2c->state.length > stream->recv_window) { +if (size > stream->recv_window) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client violated flow control for stream %ui: " "received DATA frame length %uz, available window %uz", - node->id, h2c->state.length, stream->recv_window); + node->id, size, stream->recv_window); if (ngx_http_v2_terminate_stream(h2c, stream, NGX_HTTP_V2_FLOW_CTRL_ERROR) @@ -871,7 +873,7 @@ ngx_http_v2_state_data(ngx_http_v2_conne return ngx_http_v2_state_skip_padded(h2c, pos, end); } -stream->recv_window -= h2c->state.length; +stream->recv_window -= size; if (stream->no_flow_control && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: fix $body_bytes_sent variable.
details: http://hg.nginx.org/nginx/rev/663e6a48bfcb branches: changeset: 6953:663e6a48bfcb user: Piotr Sikoradate: Sun Mar 26 01:25:03 2017 -0700 description: HTTP/2: fix $body_bytes_sent variable. Previously, its value included payloads and frame headers of HEADERS and CONTINUATION frames. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2_filter_module.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r afc60bd9008f -r 663e6a48bfcb src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Sun Mar 26 01:25:02 2017 -0700 +++ b/src/http/v2/ngx_http_v2_filter_module.c Sun Mar 26 01:25:03 2017 -0700 @@ -1211,6 +1211,9 @@ ngx_http_v2_headers_frame_handler(ngx_ht "http2:%ui HEADERS frame %p was sent", stream->node->id, frame); +stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE ++ frame->length; + ngx_http_v2_handle_frame(stream, frame); ngx_http_v2_handle_stream(h2c, stream); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: fix $bytes_sent variable.
details: http://hg.nginx.org/nginx/rev/afc60bd9008f branches: changeset: 6952:afc60bd9008f user: Piotr Sikoradate: Sun Mar 26 01:25:02 2017 -0700 description: HTTP/2: fix $bytes_sent variable. Previously, its value accounted for payloads of HEADERS, CONTINUATION and DATA frames, as well as frame headers of HEADERS and DATA frames, but it didn't account for frame headers of CONTINUATION frames. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2_filter_module.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r ce37362a7a70 -r afc60bd9008f src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Tue Mar 28 18:15:42 2017 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Sun Mar 26 01:25:02 2017 -0700 @@ -769,6 +769,8 @@ ngx_http_v2_create_headers_frame(ngx_htt rest -= frame_size; if (rest) { +frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE; + type = NGX_HTTP_V2_CONTINUATION_FRAME; flags = NGX_HTTP_V2_NO_FLAG; continue; ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Test for right-associativity of exponential operator.
details: http://hg.nginx.org/njs/rev/58342f302de3 branches: changeset: 289:58342f302de3 user: Valentin Bartenev <vb...@nginx.com> date: Fri Dec 23 19:42:15 2016 +0300 description: Test for right-associativity of exponential operator. diffstat: njs/test/njs_unit_test.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r f5225d9cc97b -r 58342f302de3 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Dec 19 14:19:59 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Dec 23 19:42:15 2016 +0300 @@ -226,6 +226,9 @@ static njs_unit_test_t njs_test[] = /* Exponentiation. */ +{ nxt_string("2 ** 3 ** 2"), + nxt_string("512") }, + { nxt_string("2 ** (3 ** 2)"), nxt_string("512") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] The nxt_expect() macro.
details: http://hg.nginx.org/njs/rev/a76d7066a117 branches: changeset: 287:a76d7066a117 user: Valentin Bartenev <vb...@nginx.com> date: Mon Dec 19 14:19:43 2016 +0300 description: The nxt_expect() macro. diffstat: nxt/nxt_clang.h | 6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 631a3be91d22 -r a76d7066a117 nxt/nxt_clang.h --- a/nxt/nxt_clang.h Fri Dec 16 17:52:15 2016 +0300 +++ b/nxt/nxt_clang.h Mon Dec 19 14:19:43 2016 +0300 @@ -27,10 +27,12 @@ #if (NXT_HAVE_BUILTIN_EXPECT) -#define nxt_fast_path(x) __builtin_expect((long) (x), 1) -#define nxt_slow_path(x) __builtin_expect((long) (x), 0) +#define nxt_expect(c, x) __builtin_expect((long) (x), (c)) +#define nxt_fast_path(x) nxt_expect(1, x) +#define nxt_slow_path(x) nxt_expect(0, x) #else +#define nxt_expect(c, x) (x) #define nxt_fast_path(x) (x) #define nxt_slow_path(x) (x) #endif ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Exponentiation operators.
details: http://hg.nginx.org/njs/rev/f5225d9cc97b branches: changeset: 288:f5225d9cc97b user: Valentin Bartenev <vb...@nginx.com> date: Mon Dec 19 14:19:59 2016 +0300 description: Exponentiation operators. diffstat: njs/njs_disassembler.c |2 + njs/njs_generator.c |2 + njs/njs_lexer.c |6 + njs/njs_parser.h|3 + njs/njs_parser_expression.c | 76 +- njs/njs_vm.c| 34 + njs/njs_vm.h|2 + njs/test/njs_unit_test.c| 157 8 files changed, 281 insertions(+), 1 deletions(-) diffs (406 lines): diff -r a76d7066a117 -r f5225d9cc97b njs/njs_disassembler.c --- a/njs/njs_disassembler.cMon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_disassembler.cMon Dec 19 14:19:59 2016 +0300 @@ -87,6 +87,8 @@ static njs_code_name_t code_names[] = { nxt_string("SUBSTRACT ") }, { njs_vmcode_multiplication, sizeof(njs_vmcode_3addr_t), nxt_string("MULTIPLY") }, +{ njs_vmcode_exponentiation, sizeof(njs_vmcode_3addr_t), + nxt_string("POWER ") }, { njs_vmcode_division, sizeof(njs_vmcode_3addr_t), nxt_string("DIVIDE ") }, { njs_vmcode_remainder, sizeof(njs_vmcode_3addr_t), diff -r a76d7066a117 -r f5225d9cc97b njs/njs_generator.c --- a/njs/njs_generator.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_generator.c Mon Dec 19 14:19:59 2016 +0300 @@ -184,6 +184,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_ADDITION_ASSIGNMENT: case NJS_TOKEN_SUBSTRACTION_ASSIGNMENT: case NJS_TOKEN_MULTIPLICATION_ASSIGNMENT: +case NJS_TOKEN_EXPONENTIATION_ASSIGNMENT: case NJS_TOKEN_DIVISION_ASSIGNMENT: case NJS_TOKEN_REMAINDER_ASSIGNMENT: return njs_generate_operation_assignment(vm, parser, node); @@ -219,6 +220,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_ADDITION: case NJS_TOKEN_SUBSTRACTION: case NJS_TOKEN_MULTIPLICATION: +case NJS_TOKEN_EXPONENTIATION: case NJS_TOKEN_DIVISION: case NJS_TOKEN_REMAINDER: case NJS_TOKEN_PROPERTY_DELETE: diff -r a76d7066a117 -r f5225d9cc97b njs/njs_lexer.c --- a/njs/njs_lexer.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_lexer.c Mon Dec 19 14:19:59 2016 +0300 @@ -203,8 +203,14 @@ static const njs_lexer_multi_t njs_subs }; +static const njs_lexer_multi_t njs_exponentiation_token[] = { +{ '=', NJS_TOKEN_EXPONENTIATION_ASSIGNMENT, 0, NULL }, +}; + + static const njs_lexer_multi_t njs_multiplication_token[] = { { '=', NJS_TOKEN_MULTIPLICATION_ASSIGNMENT, 0, NULL }, +{ '*', NJS_TOKEN_EXPONENTIATION, 1, njs_exponentiation_token }, }; diff -r a76d7066a117 -r f5225d9cc97b njs/njs_parser.h --- a/njs/njs_parser.h Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_parser.h Mon Dec 19 14:19:59 2016 +0300 @@ -41,6 +41,7 @@ typedef enum { NJS_TOKEN_ADDITION_ASSIGNMENT, NJS_TOKEN_SUBSTRACTION_ASSIGNMENT, NJS_TOKEN_MULTIPLICATION_ASSIGNMENT, +NJS_TOKEN_EXPONENTIATION_ASSIGNMENT, NJS_TOKEN_DIVISION_ASSIGNMENT, NJS_TOKEN_REMAINDER_ASSIGNMENT, NJS_TOKEN_LEFT_SHIFT_ASSIGNMENT, @@ -69,6 +70,8 @@ typedef enum { NJS_TOKEN_MULTIPLICATION, +NJS_TOKEN_EXPONENTIATION, + NJS_TOKEN_DIVISION, NJS_TOKEN_REMAINDER, diff -r a76d7066a117 -r f5225d9cc97b njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Mon Dec 19 14:19:43 2016 +0300 +++ b/njs/njs_parser_expression.c Mon Dec 19 14:19:59 2016 +0300 @@ -63,6 +63,9 @@ static njs_token_t njs_parser_conditiona static njs_token_t njs_parser_binary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); +static njs_token_t njs_parser_exponential_expression(njs_vm_t *vm, +njs_parser_t *parser, const njs_parser_expression_t *expr, +njs_token_t token); static njs_token_t njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser, const njs_parser_expression_t *expr, njs_token_t token); @@ -83,7 +86,7 @@ static njs_token_t njs_parser_property_b static const njs_parser_expression_t njs_parser_factor_expression = { -njs_parser_unary_expression, +njs_parser_exponential_expression, NULL, 3, { { NJS_TOKEN_MULTIPLICATION, njs_vmcode_multiplication, @@ -391,6 +394,11 @@ njs_parser_assignment_expression(njs_vm_ operation = njs_vmcode_multiplication; break; +case NJS_TOKEN_EXPONENTIATION_ASSIGNMENT: +nxt_thread_log_debug("JS: **="); +operation = njs_vmcode_exponentiation; +break; + case NJS_TOKEN_DIVISION_ASSIGNMENT: nxt_thread_log_debug("JS: /="); operation = njs_vmcode_division; @@ -685,6 +693,64 @@ njs_parser_binary_expression(njs_vm_t *v
[nginx] Access log: support for json escaping.
details: http://hg.nginx.org/nginx/rev/0cf4e82e7c48 branches: changeset: 6840:0cf4e82e7c48 user: Valentin Bartenev <vb...@nginx.com> date: Thu Dec 15 16:25:42 2016 +0300 description: Access log: support for json escaping. diffstat: src/http/modules/ngx_http_log_module.c | 83 +++-- src/stream/ngx_stream_log_module.c | 83 +++-- 2 files changed, 154 insertions(+), 12 deletions(-) diffs (275 lines): diff -r 32714e608629 -r 0cf4e82e7c48 src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.cTue Dec 13 00:49:44 2016 +0100 +++ b/src/http/modules/ngx_http_log_module.cThu Dec 15 16:25:42 2016 +0300 @@ -126,12 +126,16 @@ static u_char *ngx_http_log_request_leng ngx_http_log_op_t *op); static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, -ngx_http_log_op_t *op, ngx_str_t *value); +ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t json); static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data); static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size); +static size_t ngx_http_log_json_variable_getlen(ngx_http_request_t *r, +uintptr_t data); +static u_char *ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf, +ngx_http_log_op_t *op); static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); @@ -909,7 +913,7 @@ ngx_http_log_request_length(ngx_http_req static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, -ngx_str_t *value) +ngx_str_t *value, ngx_uint_t json) { ngx_int_t index; @@ -919,8 +923,16 @@ ngx_http_log_variable_compile(ngx_conf_t } op->len = 0; -op->getlen = ngx_http_log_variable_getlen; -op->run = ngx_http_log_variable; + +if (json) { +op->getlen = ngx_http_log_json_variable_getlen; +op->run = ngx_http_log_json_variable; + +} else { +op->getlen = ngx_http_log_variable_getlen; +op->run = ngx_http_log_variable; +} + op->data = index; return NGX_OK; @@ -1028,6 +1040,47 @@ ngx_http_log_escape(u_char *dst, u_char } +static size_t +ngx_http_log_json_variable_getlen(ngx_http_request_t *r, uintptr_t data) +{ +uintptr_t len; +ngx_http_variable_value_t *value; + +value = ngx_http_get_indexed_variable(r, data); + +if (value == NULL || value->not_found) { +return 0; +} + +len = ngx_escape_json(NULL, value->data, value->len); + +value->escape = len ? 1 : 0; + +return value->len + len; +} + + +static u_char * +ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf, +ngx_http_log_op_t *op) +{ +ngx_http_variable_value_t *value; + +value = ngx_http_get_indexed_variable(r, op->data); + +if (value == NULL || value->not_found) { +return buf; +} + +if (value->escape == 0) { +return ngx_cpymem(buf, value->data, value->len); + +} else { +return (u_char *) ngx_escape_json(buf, value->data, value->len); +} +} + + static void * ngx_http_log_create_main_conf(ngx_conf_t *cf) { @@ -1491,12 +1544,28 @@ ngx_http_log_compile_format(ngx_conf_t * size_t i, len; ngx_str_t *value, var; ngx_int_t *flush; -ngx_uint_t bracket; +ngx_uint_t bracket, json; ngx_http_log_op_t *op; ngx_http_log_var_t *v; +json = 0; value = args->elts; +if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) { +data = value[s].data + 7; + +if (ngx_strcmp(data, "json") == 0) { +json = 1; + +} else if (ngx_strcmp(data, "default") != 0) { +ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown log format escaping \"%s\"", data); +return NGX_CONF_ERROR; +} + +s++; +} + for ( /* void */ ; s < args->nelts; s++) { i = 0; @@ -1575,7 +1644,9 @@ ngx_http_log_compile_format(ngx_conf_t * } } -if (ngx_http_log_variable_compile(cf, op, ) != NGX_OK) { +if (ngx_http_log_variable_compile(cf, op, , json) +!= NGX_OK) +{ return NGX_CONF_ERROR; } diff -r 32714e608629 -r 0cf4e82e7c48 src/stream/ngx_stream_log_module.c --- a/src/stream/ngx_stream_log_module.cTue Dec 13 00:49:44 2016 +0100 +++ b/src/stream/ngx_stream_log_module.cThu Dec 15 16:25:42 2016 +0300 @@ -106,12 +106,16 @@ static void ngx_stream_log_flush(ngx_ope static void ngx_stream_log_flush_handler(ngx_event_t *ev);
[njs] Math.pow() method fix.
details: http://hg.nginx.org/njs/rev/db0d8e2a4928 branches: changeset: 280:db0d8e2a4928 user: Valentin Bartenev <vb...@nginx.com> date: Thu Dec 08 01:52:41 2016 +0300 description: Math.pow() method fix. diffstat: njs/njs_math.c | 12 - njs/test/njs_unit_test.c | 60 2 files changed, 71 insertions(+), 1 deletions(-) diffs (92 lines): diff -r 6a60530c7b6b -r db0d8e2a4928 njs/njs_math.c --- a/njs/njs_math.cThu Dec 08 19:50:03 2016 +0300 +++ b/njs/njs_math.cThu Dec 08 01:52:41 2016 +0300 @@ -578,7 +578,17 @@ njs_object_math_pow(njs_vm_t *vm, njs_va base = args[1].data.u.number; exponent = args[2].data.u.number; -num = pow(base, exponent); +/* + * Accordig to ECMA-262 the result of Math.pow(+/-1, +/-Infinity) + * should be NaN. + */ + +if (fabs(base) != 1 || !isinf(exponent)) { +num = pow(base, exponent); + +} else { +num = NAN; +} } else { num = NAN; diff -r 6a60530c7b6b -r db0d8e2a4928 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Dec 08 19:50:03 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Dec 08 01:52:41 2016 +0300 @@ -6215,6 +6215,66 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, +{ nxt_string("Math.pow('a', -0)"), + nxt_string("1") }, + +{ nxt_string("Math.pow(1.1, Infinity)"), + nxt_string("Infinity") }, + +{ nxt_string("Math.pow(-1.1, -Infinity)"), + nxt_string("0") }, + +{ nxt_string("Math.pow(-1, Infinity)"), + nxt_string("NaN") }, + +{ nxt_string("Math.pow(1, -Infinity)"), + nxt_string("NaN") }, + +{ nxt_string("Math.pow(-0.9, Infinity)"), + nxt_string("0") }, + +{ nxt_string("Math.pow(0.9, -Infinity)"), + nxt_string("Infinity") }, + +{ nxt_string("Math.pow('Infinity', 0.1)"), + nxt_string("Infinity") }, + +{ nxt_string("Math.pow(Infinity, '-0.1')"), + nxt_string("0") }, + +{ nxt_string("Math.pow(-Infinity, 3)"), + nxt_string("-Infinity") }, + +{ nxt_string("Math.pow('-Infinity', '3.1')"), + nxt_string("Infinity") }, + +{ nxt_string("Math.pow(-Infinity, '-3')"), + nxt_string("-0") }, + +{ nxt_string("Math.pow('-Infinity', -2)"), + nxt_string("0") }, + +{ nxt_string("Math.pow('0', 0.1)"), + nxt_string("0") }, + +{ nxt_string("Math.pow(0, '-0.1')"), + nxt_string("Infinity") }, + +{ nxt_string("Math.pow(-0, 3)"), + nxt_string("-0") }, + +{ nxt_string("Math.pow('-0', '3.1')"), + nxt_string("0") }, + +{ nxt_string("Math.pow(-0, '-3')"), + nxt_string("-Infinity") }, + +{ nxt_string("Math.pow('-0', -2)"), + nxt_string("Infinity") }, + +{ nxt_string("Math.pow(-3, 0.1)"), + nxt_string("NaN") }, + { nxt_string("var a = Math.random(); a >= 0 && a < 1"), nxt_string("true") }, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] NXT_DEBUG_MEMORY macro.
details: http://hg.nginx.org/njs/rev/af66e460d7a0 branches: changeset: 278:af66e460d7a0 user: Valentin Bartenev <vb...@nginx.com> date: Thu Dec 08 19:29:40 2016 +0300 description: NXT_DEBUG_MEMORY macro. It allows to turn off accumulation of small pool allocations into a big preallocated chunk of memory. This is useful for debugging memory access with sanitizer, since such accumulation can cover buffer overruns from being detected. diffstat: nxt/nxt_mem_cache_pool.c | 14 ++ 1 files changed, 14 insertions(+), 0 deletions(-) diffs (69 lines): diff -r 0315d62a78c2 -r af66e460d7a0 nxt/nxt_mem_cache_pool.c --- a/nxt/nxt_mem_cache_pool.c Thu Dec 08 17:15:54 2016 +0300 +++ b/nxt/nxt_mem_cache_pool.c Thu Dec 08 19:29:40 2016 +0300 @@ -124,12 +124,14 @@ struct nxt_mem_cache_pool_s { static nxt_uint_t nxt_mem_cache_shift(nxt_uint_t n); +#if !(NXT_DEBUG_MEMORY) static void *nxt_mem_cache_alloc_small(nxt_mem_cache_pool_t *pool, size_t size); static nxt_uint_t nxt_mem_cache_alloc_chunk(u_char *map, nxt_uint_t size); static nxt_mem_cache_page_t * nxt_mem_cache_alloc_page(nxt_mem_cache_pool_t *pool); static nxt_mem_cache_block_t * nxt_mem_cache_alloc_cluster(nxt_mem_cache_pool_t *pool); +#endif static void *nxt_mem_cache_alloc_large(nxt_mem_cache_pool_t *pool, size_t alignment, size_t size); static intptr_t nxt_mem_cache_rbtree_compare(nxt_rbtree_node_t *node1, @@ -302,10 +304,14 @@ nxt_mem_cache_alloc(nxt_mem_cache_pool_t pool->proto->trace(pool->trace, "mem cache alloc: %zd", size); } +#if !(NXT_DEBUG_MEMORY) + if (size <= pool->page_size) { return nxt_mem_cache_alloc_small(pool, size); } +#endif + return nxt_mem_cache_alloc_large(pool, NXT_MAX_ALIGNMENT, size); } @@ -337,6 +343,8 @@ nxt_mem_cache_align(nxt_mem_cache_pool_t if (nxt_fast_path((alignment - 1) & alignment) == 0) { +#if !(NXT_DEBUG_MEMORY) + if (size <= pool->page_size && alignment <= pool->page_alignment) { size = nxt_max(size, alignment); @@ -345,6 +353,8 @@ nxt_mem_cache_align(nxt_mem_cache_pool_t } } +#endif + return nxt_mem_cache_alloc_large(pool, alignment, size); } @@ -367,6 +377,8 @@ nxt_mem_cache_zalign(nxt_mem_cache_pool_ } +#if !(NXT_DEBUG_MEMORY) + static void * nxt_mem_cache_alloc_small(nxt_mem_cache_pool_t *pool, size_t size) { @@ -549,6 +561,8 @@ nxt_mem_cache_alloc_cluster(nxt_mem_cach return cluster; } +#endif + static void * nxt_mem_cache_alloc_large(nxt_mem_cache_pool_t *pool, size_t alignment, ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Fixed a unit test for Math.acosh().
details: http://hg.nginx.org/njs/rev/7275165c3832 branches: changeset: 271:7275165c3832 user: Valentin Bartenev <vb...@nginx.com> date: Fri Dec 02 17:11:57 2016 +0300 description: Fixed a unit test for Math.acosh(). diffstat: njs/test/njs_unit_test.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (18 lines): diff -r f8f20b27724e -r 7275165c3832 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Dec 01 19:45:19 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Dec 02 17:11:57 2016 +0300 @@ -5568,11 +5568,11 @@ static njs_unit_test_t njs_test[] = nxt_string("Infinity") }, /* - * The difference is 2 * Number.EPSILON on FreeBSD + * The difference is Number.EPSILON on Linux/i686 * and zero on other platforms. */ -{ nxt_string("Math.abs(Math.cosh(1) - (1/Math.E + Math.E)/2)" - " <= 2 * Number.EPSILON"), +{ nxt_string("Math.abs(Math.acosh((1/Math.E + Math.E)/2) - 1)" + " <= Number.EPSILON"), nxt_string("true") }, { nxt_string("Math.asin()"), ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[nginx] HTTP/2: fixed saving preread buffer to temp file (ticket #1143).
details: http://hg.nginx.org/nginx/rev/52bd8cc17f34 branches: changeset: 6805:52bd8cc17f34 user: Valentin Bartenev <vb...@nginx.com> date: Mon Nov 28 19:19:21 2016 +0300 description: HTTP/2: fixed saving preread buffer to temp file (ticket #1143). Previously, a request body bigger than "client_body_buffer_size" wasn't written into a temporary file if it has been pre-read entirely. The preread buffer is freed after processing, thus subsequent use of it might result in sending corrupted body or cause a segfault. diffstat: src/http/v2/ngx_http_v2.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 2c7a2d75938a -r 52bd8cc17f34 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Nov 21 16:49:19 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Nov 28 19:19:21 2016 +0300 @@ -3575,6 +3575,9 @@ ngx_http_v2_read_request_body(ngx_http_r rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); } else { +/* enforce writing body to file */ +r->request_body_in_file_only = 1; + rb->buf = ngx_calloc_buf(r->pool); if (rb->buf != NULL) { ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Math.clz32 method.
details: http://hg.nginx.org/njs/rev/fd2a05f9eacf branches: changeset: 266:fd2a05f9eacf user: Valentin Bartenev <vb...@nginx.com> date: Tue Nov 22 00:06:46 2016 +0300 description: Math.clz32 method. diffstat: njs/njs_math.c | 29 + njs/test/njs_unit_test.c | 27 +++ nxt/auto/clang | 14 ++ nxt/nxt_clang.h | 32 4 files changed, 102 insertions(+), 0 deletions(-) diffs (149 lines): diff -r 9f0f13857c46 -r fd2a05f9eacf njs/njs_math.c --- a/njs/njs_math.cSat Nov 19 22:20:06 2016 +0300 +++ b/njs/njs_math.cTue Nov 22 00:06:46 2016 +0300 @@ -233,6 +233,27 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v static njs_ret_t +njs_object_math_clz32(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +doublenum; +uint32_t ui32; + +if (nargs > 1) { +ui32 = njs_number_to_integer(args[1].data.u.number); +num = nxt_leading_zeros(ui32); + +} else { +num = 32; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_cos(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -869,6 +890,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, +/* ES6. */ +{ +.type = NJS_METHOD, +.name = njs_string("clz32"), +.value = njs_native_function(njs_object_math_clz32, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), +}, + { .type = NJS_METHOD, .name = njs_string("cos"), diff -r 9f0f13857c46 -r fd2a05f9eacf njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Sat Nov 19 22:20:06 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Nov 22 00:06:46 2016 +0300 @@ -5799,6 +5799,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.ceil(3.1)"), nxt_string("4") }, +{ nxt_string("Math.clz32()"), + nxt_string("32") }, + +{ nxt_string("Math.clz32('abc')"), + nxt_string("32") }, + +{ nxt_string("Math.clz32(NaN)"), + nxt_string("32") }, + +{ nxt_string("Math.clz32(Infinity)"), + nxt_string("32") }, + +{ nxt_string("Math.clz32('1')"), + nxt_string("31") }, + +{ nxt_string("Math.clz32(0)"), + nxt_string("32") }, + +{ nxt_string("Math.clz32('65535')"), + nxt_string("16") }, + +{ nxt_string("Math.clz32(-1)"), + nxt_string("0") }, + +{ nxt_string("Math.clz32(4294967298)"), + nxt_string("30") }, + { nxt_string("Math.cos()"), nxt_string("NaN") }, diff -r 9f0f13857c46 -r fd2a05f9eacf nxt/auto/clang --- a/nxt/auto/clangSat Nov 19 22:20:06 2016 +0300 +++ b/nxt/auto/clangTue Nov 22 00:06:46 2016 +0300 @@ -203,6 +203,20 @@ nxt_feature_test="int main(void) { . ${NXT_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) { + if (__builtin_clz(1) != 31) { + return 1; + } + return 0; + }" +. ${NXT_AUTO}feature + + nxt_feature="GCC __attribute__ visibility" nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY nxt_feature_run=no diff -r 9f0f13857c46 -r fd2a05f9eacf nxt/nxt_clang.h --- a/nxt/nxt_clang.h Sat Nov 19 22:20:06 2016 +0300 +++ b/nxt/nxt_clang.h Tue Nov 22 00:06:46 2016 +0300 @@ -52,6 +52,38 @@ #endif +#if (NXT_HAVE_BUILTIN_CLZ) +#define nxt_leading_zeros(x) (((x) == 0) ? 32 : __builtin_clz(x)) + +#else + +nxt_inline uint32_t +nxt_leading_zeros(uint32_t x) +{ +uint32_t n; + +/* + * There is no sense to optimize this function, since almost + * all platforms nowadays support the built-in instruction. + */ + +if (x == 0) { +return 32; +} + +n = 0; + +while ((x & 0x8000) == 0) { +n++; +x <<= 1; +} + +return n; +} + +#endif + + #if (NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY) #define NXT_EXPORT __attribute__((visibility("default"))) ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Optimized conversion of negative numbers to integer.
details: http://hg.nginx.org/njs/rev/9f0f13857c46 branches: changeset: 265:9f0f13857c46 user: Valentin Bartenev <vb...@nginx.com> date: Sat Nov 19 22:20:06 2016 +0300 description: Optimized conversion of negative numbers to integer. There is no reason to use fmod() for all negative numbers. The numbers in range [-2^53, 2^53] can be converted directly to int64_t. diffstat: njs/njs_number.c | 15 --- 1 files changed, 8 insertions(+), 7 deletions(-) diffs (27 lines): diff -r 91dc07616b19 -r 9f0f13857c46 njs/njs_number.c --- a/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 +++ b/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 @@ -749,15 +749,16 @@ njs_number_to_integer(double num) int64_t i64; /* - * ECMAScript 5.1: integer must be modulo 2^32. - * 2^53 is the largest integer number which can be stored in the IEEE-754 - * format and numbers less than 2^53 can be just converted to int64_t - * eliding more expensive fmod() operation. Then the int64 integer is - * truncated to uint32_t. The NaN can be converted to 0x8000 - * and becomes 0 after truncation. fmod() of the infinity returns NaN. + * ES5.1: integer must be modulo 2^32. + * 2^53 is the largest integer number which can be stored safely + * in the IEEE-754 format and numbers less than 2^53 can be just + * converted to int64_t eliding more expensive fmod() operation. + * Then the int64 integer is truncated to uint32_t. The NaN is + * converted to 0x8000 and becomes 0 after truncation. + * fmod() of the Infinity returns NaN. */ -if (num < 0 || num > 9007199254740992.0) { +if (fabs(num) > 9007199254740992.0) { i64 = fmod(num, 4294967296.0); } else { ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Math.imul() method.
details: http://hg.nginx.org/njs/rev/91dc07616b19 branches: changeset: 264:91dc07616b19 user: Valentin Bartenev <vb...@nginx.com> date: Sat Nov 19 22:20:06 2016 +0300 description: Math.imul() method. diffstat: njs/njs_math.c | 31 ++ njs/njs_number.c | 25 + njs/njs_number.h | 1 + njs/njs_vm.c | 52 ++ njs/test/njs_unit_test.c | 57 5 files changed, 127 insertions(+), 39 deletions(-) diffs (276 lines): diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_math.c --- a/njs/njs_math.cFri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_math.cSat Nov 19 22:20:06 2016 +0300 @@ -378,6 +378,29 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_imul(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +doublenum; +uint32_t a, b; + +if (nargs > 2) { +a = njs_number_to_integer(args[1].data.u.number); +b = njs_number_to_integer(args[2].data.u.number); + +num = (int32_t) (a * b); + +} else { +num = 0; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_log(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -898,6 +921,14 @@ static const njs_object_prop_t njs_math .value = njs_native_function(njs_object_math_hypot, 0, 0), }, +/* ES6. */ +{ +.type = NJS_METHOD, +.name = njs_string("imul"), +.value = njs_native_function(njs_object_math_imul, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), +}, + { .type = NJS_METHOD, .name = njs_string("log"), diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_number.c --- a/njs/njs_number.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 @@ -741,3 +741,28 @@ njs_number_parse_float(njs_vm_t *vm, njs return NXT_OK; } + + +nxt_noinline uint32_t +njs_number_to_integer(double num) +{ +int64_t i64; + +/* + * ECMAScript 5.1: integer must be modulo 2^32. + * 2^53 is the largest integer number which can be stored in the IEEE-754 + * format and numbers less than 2^53 can be just converted to int64_t + * eliding more expensive fmod() operation. Then the int64 integer is + * truncated to uint32_t. The NaN can be converted to 0x8000 + * and becomes 0 after truncation. fmod() of the infinity returns NaN. + */ + +if (num < 0 || num > 9007199254740992.0) { +i64 = fmod(num, 4294967296.0); + +} else { +i64 = num; +} + +return (uint32_t) i64; +} diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_number.h --- a/njs/njs_number.h Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_number.h Sat Nov 19 22:20:06 2016 +0300 @@ -27,6 +27,7 @@ njs_ret_t njs_number_parse_int(njs_vm_t nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +nxt_noinline uint32_t njs_number_to_integer(double num); extern const njs_object_init_t njs_number_constructor_init; diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_vm.c Sat Nov 19 22:20:06 2016 +0300 @@ -78,7 +78,6 @@ static njs_ret_t njs_object_property_que njs_property_query_t *pq, njs_value_t *value, njs_object_t *object); static njs_ret_t njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq); -static nxt_noinline uint32_t njs_integer_value(double num); static nxt_noinline njs_ret_t njs_values_equal(const njs_value_t *val1, const njs_value_t *val2); static nxt_noinline njs_ret_t njs_values_compare(const njs_value_t *val1, @@ -1639,8 +1638,8 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { -num1 = njs_integer_value(val1->data.u.number); -num2 = njs_integer_value(val2->data.u.number); +num1 = njs_number_to_integer(val1->data.u.number); +num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(>retval, num1 << (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1658,8 +1657,8 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { -num1 = njs_integer_value(val1->data.u.number); -num2 = njs_integer_value(val2->data.u.number); +num1 = njs_number_to_integer(val1->data.u.number); +num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(>retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1678,8 +1677,8 @@ njs_v
[njs] More Math methods from ES6.
details: http://hg.nginx.org/njs/rev/4f4bda866d8e branches: changeset: 262:4f4bda866d8e user: Valentin Bartenev <vb...@nginx.com> date: Fri Nov 18 17:25:25 2016 +0300 description: More Math methods from ES6. diffstat: njs/njs_math.c | 333 +++ njs/test/njs_unit_test.c | 292 + 2 files changed, 625 insertions(+), 0 deletions(-) diffs (820 lines): diff -r f402a8c64d7a -r 4f4bda866d8e njs/njs_math.c --- a/njs/njs_math.cWed Nov 16 15:21:07 2016 +0300 +++ b/njs/njs_math.cFri Nov 18 17:25:25 2016 +0300 @@ -69,6 +69,25 @@ njs_object_math_acos(njs_vm_t *vm, njs_v static njs_ret_t +njs_object_math_acosh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = acosh(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_asin(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -97,6 +116,25 @@ njs_object_math_asin(njs_vm_t *vm, njs_v static njs_ret_t +njs_object_math_asinh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = asinh(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_atan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -138,6 +176,44 @@ njs_object_math_atan2(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_atanh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = atanh(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t +njs_object_math_cbrt(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = cbrt(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_ceil(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -176,6 +252,25 @@ njs_object_math_cos(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_cosh(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = cosh(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_exp(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -195,6 +290,25 @@ njs_object_math_exp(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_expm1(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = expm1(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_floor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -214,6 +328,25 @@ njs_object_math_floor(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_fround(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = (float) args[1].data.u.number; + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t njs_object_math_hypot(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -264,6 +397,72 @@ njs_object_math_log(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_log10(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = log10(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t +njs_object_math_log1p(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = log1p(args[1].data.u.number); + +} else { +num = NAN; +} + +njs_number_set(>retval, num); + +return NXT_OK; +} + + +static njs_ret_t +njs_object_math_log2(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, +njs_index_t unused) +{ +double num; + +if (nargs > 1) { +num = args[1].data.u.number; + +#if (NXT_SOLARIS) +/* On Solaris 10 log(-1) returns -Infinity. */ +if (num &
[njs] Improved unit test for Math.exp(1).
details: http://hg.nginx.org/njs/rev/f06c2b48ff78 branches: changeset: 263:f06c2b48ff78 user: Valentin Bartenev <vb...@nginx.com> date: Fri Nov 18 17:25:45 2016 +0300 description: Improved unit test for Math.exp(1). diffstat: njs/test/njs_unit_test.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4f4bda866d8e -r f06c2b48ff78 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 18 17:25:25 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Nov 18 17:25:45 2016 +0300 @@ -5868,7 +5868,7 @@ static njs_unit_test_t njs_test[] = * The difference is 2 * Number.EPSILON on FreeBSD * and zero on other platforms. */ -{ nxt_string("Math.exp(1) - Math.E <= 2 * Number.EPSILON"), +{ nxt_string("Math.abs(Math.exp(1) - Math.E) <= 2 * Number.EPSILON"), nxt_string("true") }, { nxt_string("Math.expm1()"), ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Removed checking for range errors in Math.hypot().
details: http://hg.nginx.org/njs/rev/8253ecba7ad6 branches: changeset: 259:8253ecba7ad6 user: Valentin Bartenev <vb...@nginx.com> date: Wed Nov 16 12:49:53 2016 +0300 description: Removed checking for range errors in Math.hypot(). It seems other interpreters do not return an exception in this case. diffstat: njs/njs_math.c | 10 +- 1 files changed, 1 insertions(+), 9 deletions(-) diffs (27 lines): diff -r 56bf74dccca1 -r 8253ecba7ad6 njs/njs_math.c --- a/njs/njs_math.cWed Nov 16 12:49:53 2016 +0300 +++ b/njs/njs_math.cWed Nov 16 12:49:53 2016 +0300 @@ -19,7 +19,6 @@ #include #include #include -#include static njs_ret_t @@ -216,14 +215,7 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ for (i = 2; i < nargs; i++) { num = hypot(num, args[i].data.u.number); -if (num == HUGE_VAL) { -/* HUGE_VAL is equal to INFINITY on IEEE-754 systems. */ - -if (nxt_slow_path(errno == ERANGE)) { -vm->exception = _exception_range_error; -return NXT_ERROR; -} - +if (num == INFINITY) { break; } } ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] Refactored Math methods.
details: http://hg.nginx.org/njs/rev/56bf74dccca1 branches: changeset: 258:56bf74dccca1 user: Valentin Bartenev <vb...@nginx.com> date: Wed Nov 16 12:49:53 2016 +0300 description: Refactored Math methods. diffstat: njs/njs_math.c | 94 - 1 files changed, 46 insertions(+), 48 deletions(-) diffs (287 lines): diff -r 87b49eec0c34 -r 56bf74dccca1 njs/njs_math.c --- a/njs/njs_math.cWed Nov 16 12:49:52 2016 +0300 +++ b/njs/njs_math.cWed Nov 16 12:49:53 2016 +0300 @@ -29,13 +29,13 @@ njs_object_math_abs(njs_vm_t *vm, njs_va double num; if (nargs > 1) { -num = args[1].data.u.number; +num = fabs(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, fabs(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -48,13 +48,13 @@ njs_object_math_acos(njs_vm_t *vm, njs_v double num; if (nargs > 1) { -num = args[1].data.u.number; +num = acos(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, acos(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -67,13 +67,13 @@ njs_object_math_asin(njs_vm_t *vm, njs_v double num; if (nargs > 1) { -num = args[1].data.u.number; +num = asin(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, asin(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -86,13 +86,13 @@ njs_object_math_atan(njs_vm_t *vm, njs_v double num; if (nargs > 1) { -num = args[1].data.u.number; +num = atan(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, atan(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -102,20 +102,19 @@ static njs_ret_t njs_object_math_atan2(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { -double y, x; +double num, y, x; -y = NAN; -x = NAN; +if (nargs > 2) { +y = args[1].data.u.number; +x = args[2].data.u.number; -if (nargs > 1) { -y = args[1].data.u.number; +num = atan2(y, x); + +} else { +num = NAN; } -if (nargs > 2) { -x = args[2].data.u.number; -} - -njs_number_set(>retval, atan2(y, x)); +njs_number_set(>retval, num); return NXT_OK; } @@ -128,13 +127,13 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v double num; if (nargs > 1) { -num = args[1].data.u.number; +num = ceil(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, ceil(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -147,13 +146,13 @@ njs_object_math_cos(njs_vm_t *vm, njs_va double num; if (nargs > 1) { -num = args[1].data.u.number; +num = cos(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, cos(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -166,13 +165,13 @@ njs_object_math_exp(njs_vm_t *vm, njs_va double num; if (nargs > 1) { -num = args[1].data.u.number; +num = exp(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, exp(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -185,13 +184,13 @@ njs_object_math_floor(njs_vm_t *vm, njs_ double num; if (nargs > 1) { -num = args[1].data.u.number; +num = floor(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, floor(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -242,13 +241,13 @@ njs_object_math_log(njs_vm_t *vm, njs_va double num; if (nargs > 1) { -num = args[1].data.u.number; +num = log(args[1].data.u.number); } else { num = NAN; } -njs_number_set(>retval, log(num)); +njs_number_set(>retval, num); return NXT_OK; } @@ -320,20 +319,19 @@ static njs_ret_t njs_object_math_pow(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { -double base, exponent; +double num, base, exponent; -base = NAN; -exponent = NAN; +if (nargs > 2) { +base = args[1].data.u.number; +exponent = args[2].data.u.number; -if (nargs > 1) { -base = args[1].data.u.number; +num = pow(base, exponent); + +} else { +num = NAN; } -if (nargs > 2) { -exponent = args[2].data.u.number; -} - -njs_number_set(>retval, pow(base, exponent)); +njs_number_set(>retval, num); return NXT_OK; } @@ -360,13 +358,13 @@ njs_object_math_round(njs_vm_t
[njs] Moved njs_string_offset_map_init() closer to its usage.
details: http://hg.nginx.org/njs/rev/0939df226d5c branches: changeset: 251:0939df226d5c user: Valentin Bartenev <vb...@nginx.com> date: Thu Nov 10 19:09:13 2016 +0300 description: Moved njs_string_offset_map_init() closer to its usage. No functional changes. diffstat: njs/njs_string.c | 58 njs/njs_string.h | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diffs (94 lines): diff -r adf61ca4267b -r 0939df226d5c njs/njs_string.c --- a/njs/njs_string.c Thu Nov 10 18:54:28 2016 +0300 +++ b/njs/njs_string.c Thu Nov 10 19:09:13 2016 +0300 @@ -466,35 +466,6 @@ njs_string_prototype_length(njs_vm_t *vm } -nxt_noinline void -njs_string_offset_map_init(const u_char *start, size_t size) -{ -size_toffset; -uint32_t *map; -nxt_uint_tn; -const u_char *p, *end; - -end = start + size; -map = njs_string_map_start(end); -p = start; -n = 0; -offset = NJS_STRING_MAP_STRIDE; - -do { -if (offset == 0) { -map[n++] = p - start; -offset = NJS_STRING_MAP_STRIDE; -} - -/* The UTF-8 string should be valid since its length is known. */ -p = nxt_utf8_next(p, end); - -offset--; - -} while (p < end); -} - - nxt_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2) { @@ -1588,6 +1559,35 @@ njs_string_index(njs_string_prop_t *stri } +nxt_noinline void +njs_string_offset_map_init(const u_char *start, size_t size) +{ +size_toffset; +uint32_t *map; +nxt_uint_tn; +const u_char *p, *end; + +end = start + size; +map = njs_string_map_start(end); +p = start; +n = 0; +offset = NJS_STRING_MAP_STRIDE; + +do { +if (offset == 0) { +map[n++] = p - start; +offset = NJS_STRING_MAP_STRIDE; +} + +/* The UTF-8 string should be valid since its length is known. */ +p = nxt_utf8_next(p, end); + +offset--; + +} while (p < end); +} + + /* * String.toLowerCase(). * The method supports only simple folding. For example, Turkish "İ" diff -r adf61ca4267b -r 0939df226d5c njs/njs_string.h --- a/njs/njs_string.h Thu Nov 10 18:54:28 2016 +0300 +++ b/njs/njs_string.h Thu Nov 10 19:09:13 2016 +0300 @@ -128,7 +128,6 @@ nxt_noinline size_t njs_string_prop(njs_ 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); -void njs_string_offset_map_init(const u_char *start, size_t size); 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); njs_ret_t njs_string_slice(njs_vm_t *vm, njs_value_t *dst, @@ -137,6 +136,7 @@ const u_char *njs_string_offset(const u_ size_t index); nxt_noinline 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_number(njs_value_t *value, nxt_bool_t exact); ___ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel
[njs] On-demand initialization of UTF-8 strings offset map.
details: http://hg.nginx.org/njs/rev/adf61ca4267b branches: changeset: 250:adf61ca4267b user: Valentin Bartenev <vb...@nginx.com> date: Thu Nov 10 18:54:28 2016 +0300 description: On-demand initialization of UTF-8 strings offset map. diffstat: njs/njs_string.c | 70 ++- njs/njs_string.h | 6 ++-- njs/njs_vm.c | 4 --- 3 files changed, 31 insertions(+), 49 deletions(-) diffs (229 lines): diff -r 187882f1895a -r adf61ca4267b njs/njs_string.c --- a/njs/njs_string.c Thu Nov 10 18:45:10 2016 +0300 +++ b/njs/njs_string.c Thu Nov 10 18:54:28 2016 +0300 @@ -178,11 +178,6 @@ njs_string_new(njs_vm_t *vm, njs_value_t if (nxt_fast_path(p != NULL)) { memcpy(p, start, size); - -if (size != length && length >= NJS_STRING_MAP_STRIDE) { -njs_string_offset_map_init(p, size); -} - return NXT_OK; } @@ -194,7 +189,7 @@ nxt_noinline u_char * njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size, uint32_t length) { -uint32_t total; +uint32_t total, map_offset, *map; njs_string_t *string; value->type = NJS_STRING; @@ -217,9 +212,11 @@ njs_string_alloc(njs_vm_t *vm, njs_value value->data.string_size = size; if (size != length && length > NJS_STRING_MAP_STRIDE) { -total = njs_string_map_offset(size) + njs_string_map_size(length); +map_offset = njs_string_map_offset(size); +total = map_offset + njs_string_map_size(length); } else { +map_offset = 0; total = size; } @@ -233,6 +230,11 @@ njs_string_alloc(njs_vm_t *vm, njs_value string->length = length; string->retain = 1; +if (map_offset != 0) { +map = (uint32_t *) (string->start + map_offset); +map[0] = 0; +} + return string->start; } @@ -251,15 +253,16 @@ njs_string_copy(njs_value_t *dst, njs_va /* * njs_string_validate() validates an UTF-8 string, evaluates its length, - * sets njs_string_prop_t struct, and initializes offset map if it is required. + * sets njs_string_prop_t struct. */ nxt_noinline njs_ret_t njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value) { -u_char *start; -size_t new_size; -ssize_t size, length; +u_char*start; +size_tnew_size, map_offset; +ssize_t size, length; +uint32_t *map; size = value->short_string.size; @@ -297,8 +300,8 @@ njs_string_validate(njs_vm_t *vm, njs_st * Reallocate the long string with offset map * after the string. */ -new_size = njs_string_map_offset(size) - + njs_string_map_size(length); +map_offset = njs_string_map_offset(size); +new_size = map_offset + njs_string_map_size(length); start = nxt_mem_cache_alloc(vm->mem_cache_pool, new_size); if (nxt_slow_path(start == NULL)) { @@ -309,7 +312,8 @@ njs_string_validate(njs_vm_t *vm, njs_st string->start = start; value->data.u.string->start = start; -njs_string_offset_map_init(start, size); +map = (uint32_t *) (start + map_offset); +map[0] = 0; } } @@ -649,10 +653,6 @@ njs_string_prototype_concat(njs_vm_t *vm p += string.size; } -if (length >= NJS_STRING_MAP_STRIDE && size != length) { -njs_string_offset_map_init(start, size); -} - return NXT_OK; } @@ -766,10 +766,6 @@ njs_string_prototype_from_bytes(njs_vm_t for (p = string.start; p < end; p++) { s = nxt_utf8_encode(s, *p); } - -if (slice.length >= NJS_STRING_MAP_STRIDE || size != slice.length) { -njs_string_offset_map_init(start, size); -} } return NXT_OK; @@ -1518,8 +1514,7 @@ done: /* - * njs_string_offset() assumes that index is correct - * and the optional offset map has been initialized. + * njs_string_offset() assumes that index is correct. */ nxt_noinline const u_char * @@ -1531,6 +1526,10 @@ njs_string_offset(const u_char *start, c if (index >= NJS_STRING_MAP_STRIDE) { map = njs_string_map_start(end); +if (map[0] == 0) { +njs_string_offset_map_init(start, end - start); +} + start += map[index / NJS_STRING_MAP_STRIDE - 1]; } @@ -1543,8 +1542,7 @@ njs_string_offset(const u_char *start, c /* - * njs_string_index() assumes that offset is correct - * and the optional offset map has been initialized. + * njs_string_index() assumes that offset is correct. */ nxt_noinline uint32_t @@ -1565,6