[njs] nxt_trace interface. nxt_regex, RegExp, and parser use it ...
Igor Sysoev
igor at sysoev.ru
Thu Aug 4 13:06:21 UTC 2016
details: http://hg.nginx.org/njs/rev/23598cfcfd15
branches:
changeset: 140:23598cfcfd15
user: Igor Sysoev <igor at sysoev.ru>
date: Thu Aug 04 16:05:38 2016 +0300
description:
nxt_trace interface. nxt_regex, RegExp, and parser use it now.
diffstat:
Makefile | 2 +
njs/njs_generator.c | 41 ++---------
njs/njs_parser.c | 158 +++++++++++++++++++------------------------
njs/njs_parser.h | 14 +---
njs/njs_parser_expression.c | 37 +++------
njs/njs_regexp.c | 136 +++++++++++++++++++++++++++----------
njs/njs_regexp.h | 3 +-
njs/njs_string.c | 19 ++--
njs/njs_variable.c | 4 +-
njs/njs_vm.c | 19 ++---
njs/njs_vm.h | 7 +-
njs/njscript.c | 10 ++
njs/test/njs_unit_test.c | 3 +
nxt/Makefile | 15 ++++
nxt/nxt_clang.h | 1 +
nxt/nxt_pcre.c | 63 ++++-------------
nxt/nxt_regex.h | 2 +-
17 files changed, 263 insertions(+), 271 deletions(-)
diffs (truncated from 1095 to 1000 lines):
diff -r 016339472304 -r 23598cfcfd15 Makefile
--- a/Makefile Thu Aug 04 14:45:27 2016 +0300
+++ b/Makefile Thu Aug 04 16:05:38 2016 +0300
@@ -169,6 +169,7 @@ dist:
njs/njs_object_hash.h \
njs/njs_array.h \
njs/njs_function.h \
+ njs/njs_regexp.h \
njs/njs_parser.h \
njs/njs_string.c \
@@ -404,6 +405,7 @@ dist:
-I$(NXT_LIB) -Injs \
njs/test/njs_unit_test.c \
$(NXT_BUILDDIR)/libnjs.a \
+ $(NXT_BUILDDIR)/libnxt.a \
-lm $(NXT_PCRE_LIB)
include $(NXT_LIB)/Makefile
diff -r 016339472304 -r 23598cfcfd15 njs/njs_generator.c
--- a/njs/njs_generator.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_generator.c Thu Aug 04 16:05:38 2016 +0300
@@ -21,13 +21,6 @@
#include <njs_variable.h>
#include <njs_parser.h>
#include <string.h>
-#include <stdio.h>
-
-
-typedef enum {
- NJS_GENERATOR_ERROR_ILLEGAL_CONTINUE = 0,
- NJS_GENERATOR_ERROR_ILLEGAL_BREAK,
-} njs_generator_error_t;
static nxt_int_t njs_generator(njs_vm_t *vm, njs_parser_t *parser,
@@ -125,8 +118,6 @@ static nxt_noinline nxt_int_t njs_genera
static nxt_noinline nxt_int_t njs_generator_index_release(njs_vm_t *vm,
njs_parser_t *parser, njs_index_t index);
nxt_inline nxt_bool_t njs_generator_is_constant(njs_parser_node_t *node);
-static nxt_int_t njs_generator_error(njs_vm_t *vm, njs_parser_node_t *node,
- njs_generator_error_t err);
static const nxt_str_t no_label = { 0, NULL };
@@ -1085,7 +1076,10 @@ njs_generate_continue_statement(njs_vm_t
}
}
- return njs_generator_error(vm, node, NJS_GENERATOR_ERROR_ILLEGAL_CONTINUE);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Illegal continue statement");
+
+ return NXT_ERROR;
found:
@@ -1126,7 +1120,10 @@ njs_generate_break_statement(njs_vm_t *v
}
}
- return njs_generator_error(vm, node, NJS_GENERATOR_ERROR_ILLEGAL_BREAK);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Illegal break statement");
+
+ return NXT_ERROR;
found:
@@ -2476,25 +2473,3 @@ njs_generator_is_constant(njs_parser_nod
return (node->token >= NJS_TOKEN_FIRST_CONST
&& node->token <= NJS_TOKEN_LAST_CONST);
}
-
-
-static nxt_int_t
-njs_generator_error(njs_vm_t *vm, njs_parser_node_t *node,
- njs_generator_error_t err)
-{
- uint32_t size;
- const char *msg;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
- static const char *errors[] = {
- "SyntaxError: Illegal continue statement in %u",
- "SyntaxError: Illegal break statement in %u",
- };
-
- msg = errors[err];
-
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- msg, node->token_line);
-
- return njs_vm_throw_exception(vm, buf, size);
-}
diff -r 016339472304 -r 23598cfcfd15 njs/njs_parser.c
--- a/njs/njs_parser.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_parser.c Thu Aug 04 16:05:38 2016 +0300
@@ -54,8 +54,6 @@ static njs_token_t njs_parser_var_statem
static njs_token_t njs_parser_if_statement(njs_vm_t *vm, njs_parser_t *parser);
static njs_token_t njs_parser_switch_statement(njs_vm_t *vm,
njs_parser_t *parser);
-static njs_token_t njs_parser_duplicate_default_branch(njs_vm_t *vm,
- njs_parser_t *parser);
static njs_token_t njs_parser_while_statement(njs_vm_t *vm,
njs_parser_t *parser);
static njs_token_t njs_parser_do_while_statement(njs_vm_t *vm,
@@ -68,8 +66,6 @@ static njs_token_t njs_parser_continue_s
static njs_token_t njs_parser_break_statement(njs_vm_t *vm,
njs_parser_t *parser);
static njs_token_t njs_parser_try_statement(njs_vm_t *vm, njs_parser_t *parser);
-static njs_token_t njs_parser_missing_catch_or_finally(njs_vm_t *vm,
- njs_parser_t *parser);
static njs_token_t njs_parser_try_block(njs_vm_t *vm, njs_parser_t *parser);
static njs_token_t njs_parser_throw_statement(njs_vm_t *vm,
njs_parser_t *parser);
@@ -844,7 +840,11 @@ njs_parser_switch_statement(njs_vm_t *vm
} else {
if (dflt != NULL) {
- return njs_parser_duplicate_default_branch(vm, parser);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: More than one default clause "
+ "in switch statement");
+
+ return NJS_TOKEN_ILLEGAL;
}
branch = node;
@@ -890,22 +890,6 @@ njs_parser_switch_statement(njs_vm_t *vm
static njs_token_t
-njs_parser_duplicate_default_branch(njs_vm_t *vm, njs_parser_t *parser)
-{
- uint32_t size;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "SyntaxError: More than one default clause "
- "in switch statement in %u", parser->lexer->line);
-
- (void) njs_vm_throw_exception(vm, buf, size);
-
- return NJS_TOKEN_ILLEGAL;
-}
-
-
-static njs_token_t
njs_parser_while_statement(njs_vm_t *vm, njs_parser_t *parser)
{
njs_token_t token;
@@ -1099,19 +1083,14 @@ static njs_token_t
njs_parser_for_in_statement(njs_vm_t *vm, njs_parser_t *parser, nxt_str_t *name,
njs_token_t token)
{
- uint32_t size;
njs_parser_node_t *node;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
node = parser->node->left;
if (node->token != NJS_TOKEN_NAME) {
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "ReferenceError: Invalid left-hand side \"%.*s\" "
- "in for-in statement in %u",
- (int) name->length, name->start, parser->lexer->line);
-
- (void) njs_vm_throw_exception(vm, buf, size);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR, "ReferenceError: Invalid "
+ "left-hand side \"%.*s\" in for-in statement",
+ (int) name->length, name->start);
return NJS_TOKEN_ILLEGAL;
}
@@ -1326,29 +1305,15 @@ njs_parser_try_statement(njs_vm_t *vm, n
}
if (try->right == NULL) {
- return njs_parser_missing_catch_or_finally(vm, parser);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Missing catch or finally after try");
+
+ return NJS_TOKEN_ILLEGAL;
}
parser->node = try;
return token;
-
-}
-
-
-static njs_token_t
-njs_parser_missing_catch_or_finally(njs_vm_t *vm, njs_parser_t *parser)
-{
- uint32_t size;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "SyntaxError: Missing catch or finally after try in %u",
- parser->lexer->line);
-
- (void) njs_vm_throw_exception(vm, buf, size);
-
- return NJS_TOKEN_ILLEGAL;
}
@@ -1612,8 +1577,11 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
break;
case NJS_TOKEN_UNTERMINATED_STRING:
- return njs_parser_error(vm, parser,
- NJS_PARSER_ERROR_UNTERMINATED_STRING);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Unterminated string \"%.*s\"",
+ (int) parser->lexer->text.length, parser->lexer->text.start);
+
+ return NJS_TOKEN_ILLEGAL;
case NJS_TOKEN_NUMBER:
nxt_thread_log_debug("JS: %f", parser->lexer->number);
@@ -2042,8 +2010,7 @@ njs_parser_escape_string_create(njs_vm_t
}
if (hex_length == 0 || hex_length > 6) {
- return njs_parser_error(vm, parser,
- NJS_PARSER_ERROR_UNICODE);
+ goto invalid;
}
skip = 1;
@@ -2118,12 +2085,12 @@ njs_parser_escape_string_create(njs_vm_t
hex_end = src + hex_length;
if (hex_end > end) {
- return njs_parser_error(vm, parser, NJS_PARSER_ERROR_UNICODE);
+ goto invalid;
}
u = njs_number_radix_parse(src, hex_end, 16, 1);
if (nxt_slow_path(u < 0)) {
- return njs_parser_error(vm, parser, NJS_PARSER_ERROR_UNICODE);
+ goto invalid;
}
src = hex_end + skip;
@@ -2150,6 +2117,14 @@ njs_parser_escape_string_create(njs_vm_t
dst = start;
}
+
+invalid:
+
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Invalid Unicode code point \"%.*s\"",
+ (int) parser->lexer->text.length, parser->lexer->text.start);
+
+ return NJS_TOKEN_ILLEGAL;
}
@@ -2208,48 +2183,53 @@ static njs_token_t
njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token)
{
- uint32_t size;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
if (token != NJS_TOKEN_END) {
- return njs_parser_error(vm, parser, NJS_PARSER_ERROR_UNEXPECTED_TOKEN);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Unexpected token \"%.*s\"",
+ (int) parser->lexer->text.length, parser->lexer->text.start);
+
+ } else {
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Unexpected end of input");
}
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "SyntaxError: Unexpected end of input in %u",
- parser->lexer->line);
-
- (void) njs_vm_throw_exception(vm, buf, size);
-
return NJS_TOKEN_ILLEGAL;
}
-njs_token_t
-njs_parser_error(njs_vm_t *vm, njs_parser_t *parser, njs_parser_error_t err)
+u_char *
+njs_parser_trace_handler(nxt_trace_t *trace, nxt_trace_data_t *td,
+ u_char *start)
{
- uint32_t size;
- njs_lexer_t *lexer;
- const char *msg;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
- static const char *errors[] = {
- "SyntaxError: Unexpected token \"%.*s\" in %u",
- "SyntaxError: Unterminated string \"%.*s\" in %u",
- "SyntaxError: Invalid Unicode code point \"%.*s\" in %u",
- "SyntaxError: Unterminated RegExp \"%.*s\" in %u",
- "SyntaxError: Invalid RegExp flags \"%.*s\" in %u",
- "SyntaxError: Duplicate declaration \"%.*s\" in %u",
- };
-
- msg = errors[err];
- lexer = parser->lexer;
-
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- msg, (int) lexer->text.length, lexer->text.start,
- lexer->line);
-
- (void) njs_vm_throw_exception(vm, buf, size);
-
- return NJS_TOKEN_ILLEGAL;
+ int n;
+ u_char *p;
+ ssize_t size;
+ njs_vm_t *vm;
+
+ p = start;
+
+ if (td->level == NXT_LEVEL_CRIT) {
+ size = sizeof("InternalError: ") - 1;
+ memcpy(p, "InternalError: ", size);
+ p = start + size;
+ }
+
+ vm = trace->data;
+
+ trace = trace->next;
+ p = trace->handler(trace, td, p);
+
+ if (vm->parser != NULL) {
+ size = td->end - start;
+
+ n = snprintf((char *) p, size, " in %u", vm->parser->lexer->line);
+
+ if (n < size) {
+ p += n;
+ }
+ }
+
+ njs_vm_throw_exception(vm, start, p - start);
+
+ return p;
}
diff -r 016339472304 -r 23598cfcfd15 njs/njs_parser.h
--- a/njs/njs_parser.h Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_parser.h Thu Aug 04 16:05:38 2016 +0300
@@ -314,16 +314,6 @@ struct njs_parser_s {
};
-typedef enum {
- NJS_PARSER_ERROR_UNEXPECTED_TOKEN = 0,
- NJS_PARSER_ERROR_UNTERMINATED_STRING,
- NJS_PARSER_ERROR_UNICODE,
- NJS_PARSER_ERROR_UNTERMINATED_REGEXP,
- NJS_PARSER_ERROR_REGEXP_FLAGS,
- NJS_PARSER_ERROR_DUPLICATE_DECLARATION,
-} njs_parser_error_t;
-
-
njs_token_t njs_lexer_token(njs_lexer_t *lexer);
nxt_int_t njs_lexer_keywords_init(nxt_mem_cache_pool_t *mcp,
nxt_lvlhsh_t *hash);
@@ -350,8 +340,8 @@ njs_token_t njs_parser_token(njs_parser_
nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value);
njs_index_t njs_parser_index(njs_parser_t *parser, uint32_t scope);
nxt_bool_t njs_parser_has_side_effect(njs_parser_node_t *node);
-njs_token_t njs_parser_error(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_error_t err);
+u_char *njs_parser_trace_handler(nxt_trace_t *trace, nxt_trace_data_t *td,
+ u_char *start);
nxt_int_t njs_generate_scope(njs_vm_t *vm, njs_parser_t *parser,
njs_parser_node_t *node);
diff -r 016339472304 -r 23598cfcfd15 njs/njs_parser_expression.c
--- a/njs/njs_parser_expression.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_parser_expression.c Thu Aug 04 16:05:38 2016 +0300
@@ -24,7 +24,6 @@
#include <njs_variable.h>
#include <njs_parser.h>
#include <string.h>
-#include <stdio.h>
typedef struct {
@@ -75,8 +74,6 @@ static njs_token_t njs_parser_property_e
njs_parser_t *parser, njs_token_t token);
static njs_token_t njs_parser_property_brackets(njs_vm_t *vm,
njs_parser_t *parser, njs_token_t token);
-static njs_token_t njs_parser_invalid_lvalue(njs_vm_t *vm,
- njs_parser_t *parser, const char* operation);
static const njs_parser_expression_t
@@ -294,7 +291,9 @@ njs_parser_var_expression(njs_vm_t *vm,
node = parser->node;
if (parser->node->token != NJS_TOKEN_NAME) {
- return njs_parser_invalid_lvalue(vm, parser, "assignment");
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "ReferenceError: Invalid left-hand side in assignment");
+ return NJS_TOKEN_ILLEGAL;
}
pending = NULL;
@@ -439,7 +438,9 @@ njs_parser_assignment_expression(njs_vm_
node = parser->node;
if (!njs_parser_is_lvalue(parser->node)) {
- return njs_parser_invalid_lvalue(vm, parser, "assignment");
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "ReferenceError: Invalid left-hand side in assignment");
+ return NJS_TOKEN_ILLEGAL;
}
pending = NULL;
@@ -811,7 +812,9 @@ njs_parser_inc_dec_expression(njs_vm_t *
}
if (!njs_parser_is_lvalue(parser->node)) {
- return njs_parser_invalid_lvalue(vm, parser, "prefix operation");
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "ReferenceError: Invalid left-hand side in prefix operation");
+ return NJS_TOKEN_ILLEGAL;
}
node = njs_parser_node_alloc(vm);
@@ -863,7 +866,9 @@ njs_parser_post_inc_dec_expression(njs_v
}
if (!njs_parser_is_lvalue(parser->node)) {
- return njs_parser_invalid_lvalue(vm, parser, "postfix operation");
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "ReferenceError: Invalid left-hand side in postfix operation");
+ return NJS_TOKEN_ILLEGAL;
}
node = njs_parser_node_alloc(vm);
@@ -1143,21 +1148,3 @@ njs_parser_arguments(njs_vm_t *vm, njs_p
return token;
}
-
-
-static njs_token_t
-njs_parser_invalid_lvalue(njs_vm_t *vm, njs_parser_t *parser,
- const char *operation)
-{
- uint32_t size;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "ReferenceError: Invalid left-hand side in %s in %u",
- operation, parser->lexer->line);
-
- (void) njs_vm_throw_exception(vm, buf, size);
-
- return NJS_TOKEN_ILLEGAL;
-
-}
diff -r 016339472304 -r 23598cfcfd15 njs/njs_regexp.c
--- a/njs/njs_regexp.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_regexp.c Thu Aug 04 16:05:38 2016 +0300
@@ -39,6 +39,10 @@ static njs_regexp_flags_t njs_regexp_fla
nxt_bool_t bound);
static int njs_regexp_pattern_compile(njs_vm_t *vm, nxt_regex_t *regex,
u_char *source, int options);
+static u_char *njs_regexp_compile_trace_handler(nxt_trace_t *trace,
+ nxt_trace_data_t *td, u_char *start);
+static u_char *njs_regexp_match_trace_handler(nxt_trace_t *trace,
+ nxt_trace_data_t *td, u_char *start);
static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp,
u_char *string, nxt_regex_match_data_t *match_data, nxt_uint_t utf8);
static njs_ret_t njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value,
@@ -59,6 +63,8 @@ njs_regexp_init(njs_vm_t *vm)
return NXT_ERROR;
}
+ vm->regex_context->trace = &vm->trace;
+
return NXT_OK;
}
@@ -161,10 +167,11 @@ njs_regexp_literal(njs_vm_t *vm, njs_par
flags = njs_regexp_flags(&p, lexer->end, 0);
if (nxt_slow_path(flags < 0)) {
- lexer->text.start = lexer->start;
- lexer->text.length = p - lexer->text.start;
- return njs_parser_error(vm, parser,
- NJS_PARSER_ERROR_REGEXP_FLAGS);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Invalid RegExp flags \"%.*s\"",
+ p - lexer->start, lexer->start);
+
+ return NJS_TOKEN_ILLEGAL;
}
lexer->start = p;
@@ -181,10 +188,11 @@ njs_regexp_literal(njs_vm_t *vm, njs_par
}
}
- lexer->text.start = lexer->start - 1;
- lexer->text.length = p - lexer->text.start;
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Unterminated RegExp \"%.*s\"",
+ p - lexer->start - 1, lexer->start - 1);
- return njs_parser_error(vm, parser, NJS_PARSER_ERROR_UNTERMINATED_REGEXP);
+ return NJS_TOKEN_ILLEGAL;
}
@@ -345,28 +353,97 @@ static int
njs_regexp_pattern_compile(njs_vm_t *vm, nxt_regex_t *regex, u_char *source,
int options)
{
- uint32_t size;
- nxt_int_t ret;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
+ nxt_int_t ret;
+ nxt_trace_handler_t handler;
+
+ handler = vm->trace.handler;
+ vm->trace.handler = njs_regexp_compile_trace_handler;
/* Zero length means a zero-terminated string. */
ret = nxt_regex_compile(regex, source, 0, options, vm->regex_context);
+ vm->trace.handler = handler;
+
if (nxt_fast_path(ret == NXT_OK)) {
return regex->ncaptures;
}
+ return ret;
+}
+
+
+static u_char *
+njs_regexp_compile_trace_handler(nxt_trace_t *trace, nxt_trace_data_t *td,
+ u_char *start)
+{
+ int n;
+ u_char *p;
+ ssize_t size;
+ njs_vm_t *vm;
+
+ size = sizeof("SyntaxError: ") - 1;
+ memcpy(start, "SyntaxError: ", size);
+ p = start + size;
+
+ vm = trace->data;
+
+ trace = trace->next;
+ p = trace->handler(trace, td, p);
+
if (vm->parser != NULL) {
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "SyntaxError: %s in %u",
- vm->regex_context->error, vm->parser->lexer->line);
+ size = td->end - start;
- } else {
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "SyntaxError: %s", vm->regex_context->error);
+ n = snprintf((char *) p, size, " in %u", vm->parser->lexer->line);
+
+ if (n < size) {
+ p += n;
+ }
}
- return njs_vm_throw_exception(vm, buf, size);
+ njs_vm_throw_exception(vm, start, p - start);
+
+ return p;
+}
+
+
+nxt_int_t
+njs_regexp_match(njs_vm_t *vm, nxt_regex_t *regex, u_char *subject, size_t len,
+ nxt_regex_match_data_t *match_data)
+{
+ nxt_int_t ret;
+ nxt_trace_handler_t handler;
+
+ handler = vm->trace.handler;
+ vm->trace.handler = njs_regexp_match_trace_handler;
+
+ ret = nxt_regex_match(regex, subject, len, match_data, vm->regex_context);
+
+ vm->trace.handler = handler;
+
+ return ret;
+}
+
+
+static u_char *
+njs_regexp_match_trace_handler(nxt_trace_t *trace, nxt_trace_data_t *td,
+ u_char *start)
+{
+ u_char *p;
+ size_t size;
+ njs_vm_t *vm;
+
+ size = sizeof("RegExpError: ") - 1;
+ memcpy(start, "RegExpError: ", size);
+ p = start + size;
+
+ vm = trace->data;
+
+ trace = trace->next;
+ p = trace->handler(trace, td, p);
+
+ njs_vm_throw_exception(vm, start, p - start);
+
+ return p;
}
@@ -517,13 +594,13 @@ njs_regexp_prototype_test(njs_vm_t *vm,
pattern = args[0].data.u.regexp->pattern;
if (nxt_regex_is_valid(&pattern->regex[n])) {
- ret = nxt_regex_match(&pattern->regex[n], string.start, string.size,
- vm->single_match_data, vm->regex_context);
+ ret = njs_regexp_match(vm, &pattern->regex[n], string.start,
+ string.size, vm->single_match_data);
if (ret >= 0) {
retval = &njs_value_true;
} else if (ret != NGX_REGEX_NOMATCH) {
- return njs_regexp_match_error(vm);
+ return NXT_ERROR;
}
}
@@ -589,8 +666,8 @@ njs_regexp_prototype_exec(njs_vm_t *vm,
return NXT_ERROR;
}
- ret = nxt_regex_match(&pattern->regex[n], string.start, string.size,
- match_data, vm->regex_context);
+ ret = njs_regexp_match(vm, &pattern->regex[n], string.start,
+ string.size, match_data);
if (ret >= 0) {
return njs_regexp_exec_result(vm, regexp, string.start, match_data,
utf8);
@@ -599,7 +676,7 @@ njs_regexp_prototype_exec(njs_vm_t *vm,
if (nxt_slow_path(ret != NGX_REGEX_NOMATCH)) {
nxt_regex_match_data_free(match_data, vm->regex_context);
- return njs_regexp_match_error(vm);
+ return NXT_ERROR;
}
}
@@ -736,19 +813,6 @@ njs_regexp_string_create(njs_vm_t *vm, n
}
-njs_ret_t
-njs_regexp_match_error(njs_vm_t *vm)
-{
- uint32_t size;
- u_char buf[NJS_EXCEPTION_BUF_LENGTH];
-
- size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH,
- "RegExpError: %s", vm->regex_context->error);
-
- return njs_vm_throw_exception(vm, buf, size);
-}
-
-
static const njs_object_prop_t njs_regexp_constructor_properties[] =
{
/* RegExp.name == "RegExp". */
diff -r 016339472304 -r 23598cfcfd15 njs/njs_regexp.h
--- a/njs/njs_regexp.h Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_regexp.h Thu Aug 04 16:05:38 2016 +0300
@@ -39,10 +39,11 @@ njs_token_t njs_regexp_literal(njs_vm_t
njs_value_t *value);
njs_regexp_pattern_t *njs_regexp_pattern_create(njs_vm_t *vm,
u_char *string, size_t length, njs_regexp_flags_t flags);
+nxt_int_t njs_regexp_match(njs_vm_t *vm, nxt_regex_t *regex, u_char *subject,
+ size_t len, nxt_regex_match_data_t *match_data);
njs_regexp_t *njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern);
njs_ret_t njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused);
-njs_ret_t njs_regexp_match_error(njs_vm_t *vm);
extern const njs_object_init_t njs_regexp_constructor_init;
diff -r 016339472304 -r 23598cfcfd15 njs/njs_string.c
--- a/njs/njs_string.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_string.c Thu Aug 04 16:05:38 2016 +0300
@@ -31,7 +31,6 @@
#include <njs_regexp.h>
#include <njs_regexp_pattern.h>
#include <string.h>
-#include <stdio.h>
static nxt_noinline void njs_string_slice_prop(njs_string_prop_t *string,
@@ -1455,14 +1454,14 @@ njs_string_prototype_search(njs_vm_t *vm
n = (string.length != 0);
if (nxt_regex_is_valid(&pattern->regex[n])) {
- ret = nxt_regex_match(&pattern->regex[n], string.start, string.size,
- vm->single_match_data, vm->regex_context);
+ ret = njs_regexp_match(vm, &pattern->regex[n], string.start,
+ string.size, vm->single_match_data);
if (ret >= 0) {
captures = nxt_regex_captures(vm->single_match_data);
index = njs_string_index(&string, captures[0]);
} else if (ret != NGX_REGEX_NOMATCH) {
- return njs_regexp_match_error(vm);
+ return NXT_ERROR;
}
}
}
@@ -1555,8 +1554,8 @@ njs_string_prototype_match(njs_vm_t *vm,
array = NULL;
do {
- ret = nxt_regex_match(&pattern->regex[n], string.start, string.size,
- vm->single_match_data, vm->regex_context);
+ ret = njs_regexp_match(vm, &pattern->regex[n], string.start,
+ string.size, vm->single_match_data);
if (ret >= 0) {
if (array != NULL) {
if (array->length == array->size) {
@@ -1617,7 +1616,7 @@ njs_string_prototype_match(njs_vm_t *vm,
break;
} else {
- return njs_regexp_match_error(vm);
+ return NXT_ERROR;
}
} while (string.size > 0);
@@ -1756,8 +1755,8 @@ njs_string_prototype_split(njs_vm_t *vm,
end = string.start + string.size;
do {
- ret = nxt_regex_match(&pattern->regex[n], start, end - start,
- vm->single_match_data, vm->regex_context);
+ ret = njs_regexp_match(vm, &pattern->regex[n], start,
+ end - start, vm->single_match_data);
if (ret >= 0) {
captures = nxt_regex_captures(vm->single_match_data);
@@ -1769,7 +1768,7 @@ njs_string_prototype_split(njs_vm_t *vm,
next = (u_char *) end + 1;
} else {
- return njs_regexp_match_error(vm);
+ return NXT_ERROR;
}
/* Empty split regexp. */
diff -r 016339472304 -r 23598cfcfd15 njs/njs_variable.c
--- a/njs/njs_variable.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_variable.c Thu Aug 04 16:05:38 2016 +0300
@@ -79,7 +79,9 @@ njs_parser_name_alloc(njs_vm_t *vm, njs_
return var;
}
- (void) njs_parser_error(vm, parser, NJS_PARSER_ERROR_DUPLICATE_DECLARATION);
+ nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+ "SyntaxError: Duplicate declaration \"%.*s\"",
+ (int) parser->lexer->text.length, parser->lexer->text.start);
return NULL;
}
diff -r 016339472304 -r 23598cfcfd15 njs/njs_vm.c
--- a/njs/njs_vm.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_vm.c Thu Aug 04 16:05:38 2016 +0300
@@ -3316,24 +3316,21 @@ njs_value_string_copy(njs_vm_t *vm, nxt_
}
-njs_ret_t
+void
njs_vm_throw_exception(njs_vm_t *vm, u_char *buf, uint32_t size)
{
uint32_t length;
njs_value_t *value;
value = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_value_t));
- if (nxt_slow_path(value == NULL)) {
- return NJS_TOKEN_ERROR;
+
+ if (nxt_fast_path(value != NULL)) {
+ vm->exception = value;
+
+ length = nxt_utf8_length(buf, size);
+
+ (void) njs_string_new(vm, value, buf, size, length);
}
-
- vm->exception = value;
-
- length = nxt_utf8_length(buf, size);
-
- (void) njs_string_new(vm, value, buf, size, length);
-
- return NXT_ERROR;
}
diff -r 016339472304 -r 23598cfcfd15 njs/njs_vm.h
--- a/njs/njs_vm.h Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njs_vm.h Thu Aug 04 16:05:38 2016 +0300
@@ -8,6 +8,7 @@
#define _NJS_VM_H_INCLUDED_
+#include <nxt_trace.h>
#include <nxt_regex.h>
@@ -799,6 +800,7 @@ struct njs_vm_s {
nxt_array_t *code; /* of njs_vm_code_t */
+ nxt_trace_t trace;
nxt_random_t random;
};
@@ -827,9 +829,6 @@ struct njs_vm_shared_s {
};
-#define NJS_EXCEPTION_BUF_LENGTH 2048
-
-
nxt_int_t njs_vmcode_interpreter(njs_vm_t *vm);
void njs_value_retain(njs_value_t *value);
@@ -969,7 +968,7 @@ njs_ret_t njs_value_to_ext_string(njs_vm
const njs_value_t *src);
void njs_number_set(njs_value_t *value, double num);
-njs_ret_t njs_vm_throw_exception(njs_vm_t *vm, u_char *buf, uint32_t size);
+void njs_vm_throw_exception(njs_vm_t *vm, u_char *buf, uint32_t size);
nxt_int_t njs_builtin_objects_create(njs_vm_t *vm);
nxt_int_t njs_builtin_objects_clone(njs_vm_t *vm);
diff -r 016339472304 -r 23598cfcfd15 njs/njscript.c
--- a/njs/njscript.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/njscript.c Thu Aug 04 16:05:38 2016 +0300
@@ -155,6 +155,11 @@ njs_vm_create(nxt_mem_cache_pool_t *mcp,
if (externals != NULL) {
vm->externals_hash = *externals;
}
+
+ vm->trace.level = NXT_LEVEL_TRACE;
+ vm->trace.size = 2048;
+ vm->trace.handler = njs_parser_trace_handler;
+ vm->trace.data = vm;
}
return vm;
@@ -325,6 +330,11 @@ njs_vm_clone(njs_vm_t *vm, nxt_mem_cache
goto fail;
}
+ nvm->trace.level = NXT_LEVEL_TRACE;
+ nvm->trace.size = 2048;
+ nvm->trace.handler = njs_parser_trace_handler;
+ nvm->trace.data = nvm;
+
return nvm;
}
diff -r 016339472304 -r 23598cfcfd15 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Thu Aug 04 14:45:27 2016 +0300
+++ b/njs/test/njs_unit_test.c Thu Aug 04 16:05:38 2016 +0300
@@ -3511,6 +3511,9 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("/(/.test('')"),
nxt_string("SyntaxError: pcre_compile(\"(\") failed: missing ) in 1") },
+ { nxt_string("/+/.test('')"),
+ nxt_string("SyntaxError: pcre_compile(\"+\") failed: nothing to repeat at \"+\" in 1") },
+
{ nxt_string("/^$/.test('')"),
nxt_string("true") },
diff -r 016339472304 -r 23598cfcfd15 nxt/Makefile
--- a/nxt/Makefile Thu Aug 04 14:45:27 2016 +0300
+++ b/nxt/Makefile Thu Aug 04 16:05:38 2016 +0300
@@ -12,6 +12,7 @@ NXT_LIB = nxt
$(NXT_BUILDDIR)/nxt_random.o \
$(NXT_BUILDDIR)/nxt_pcre.o \
$(NXT_BUILDDIR)/nxt_malloc.o \
+ $(NXT_BUILDDIR)/nxt_trace.o \
$(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
ar -r -c $(NXT_BUILDDIR)/libnxt.a \
@@ -23,6 +24,7 @@ NXT_LIB = nxt
$(NXT_BUILDDIR)/nxt_random.o \
$(NXT_BUILDDIR)/nxt_pcre.o \
$(NXT_BUILDDIR)/nxt_malloc.o \
+ $(NXT_BUILDDIR)/nxt_trace.o \
$(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
$(NXT_BUILDDIR)/nxt_murmur_hash.o: \
@@ -111,6 +113,7 @@ NXT_LIB = nxt
$(NXT_BUILDDIR)/nxt_pcre.o: \
$(NXT_LIB)/nxt_types.h \
$(NXT_LIB)/nxt_clang.h \
+ $(NXT_LIB)/nxt_trace.h \
$(NXT_LIB)/nxt_regex.h \
$(NXT_LIB)/nxt_pcre.h \
$(NXT_LIB)/nxt_pcre.c \
@@ -130,6 +133,18 @@ NXT_LIB = nxt
-I$(NXT_LIB) \
$(NXT_LIB)/nxt_malloc.c
+$(NXT_BUILDDIR)/nxt_trace.o: \
+ $(NXT_LIB)/nxt_auto_config.h \
+ $(NXT_LIB)/nxt_types.h \
+ $(NXT_LIB)/nxt_clang.h \
+ $(NXT_LIB)/nxt_malloc.h \
+ $(NXT_LIB)/nxt_trace.h \
+ $(NXT_LIB)/nxt_trace.c \
+
+ $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_trace.o $(NXT_CFLAGS) \
+ -I$(NXT_LIB) \
+ $(NXT_LIB)/nxt_trace.c
+
$(NXT_BUILDDIR)/nxt_mem_cache_pool.o: \
$(NXT_LIB)/nxt_types.h \
$(NXT_LIB)/nxt_clang.h \
diff -r 016339472304 -r 23598cfcfd15 nxt/nxt_clang.h
--- a/nxt/nxt_clang.h Thu Aug 04 14:45:27 2016 +0300
+++ b/nxt/nxt_clang.h Thu Aug 04 16:05:38 2016 +0300
@@ -8,6 +8,7 @@
#define _NXT_CLANG_H_INCLUDED_
+#include <stdarg.h>
#include <stddef.h> /* offsetof(). */
#include <unistd.h> /* NULL. */
diff -r 016339472304 -r 23598cfcfd15 nxt/nxt_pcre.c
--- a/nxt/nxt_pcre.c Thu Aug 04 14:45:27 2016 +0300
+++ b/nxt/nxt_pcre.c Thu Aug 04 16:05:38 2016 +0300
@@ -7,9 +7,9 @@
#include <nxt_types.h>
#include <nxt_clang.h>
#include <nxt_stub.h>
+#include <nxt_trace.h>
#include <nxt_regex.h>
#include <nxt_pcre.h>
-#include <stdio.h>
#include <string.h>
@@ -53,7 +53,6 @@ nxt_regex_compile(nxt_regex_t *regex, u_
char *pattern, *error;
void *(*saved_malloc)(size_t size);
void (*saved_free)(void *p);
- size_t size;
const char *errstr;
ret = NXT_ERROR;
@@ -82,22 +81,14 @@ nxt_regex_compile(nxt_regex_t *regex, u_
if (nxt_slow_path(regex->code == NULL)) {
error = pattern + erroff;
- size = sizeof("pcre_compile(\"\") failed: at \"\"")
- + strlen(errstr) + strlen(error) * 2 + erroff;
-
- ctx->error = ctx->private_malloc(size, ctx->memory_data);
- if (nxt_slow_path(ctx->error == NULL)) {
- goto done;
- }
+ if (*error != '\0') {
+ nxt_alert(ctx->trace, NXT_LEVEL_ERROR,
+ "pcre_compile(\"%s\") failed: %s at \"%s\"",
+ pattern, errstr, error);
- if (*error != '\0') {
- (void) snprintf((char *) ctx->error, size,
- "pcre_compile(\"%s\") failed: %s at \"%s\"",
More information about the nginx-devel
mailing list