njs_function_lambda_t *lambda;
const njs_token_type_t *type;
+ njs_memzero(&chain, sizeof(njs_chb_t));
+ str.length = 0;
+ str.start = NULL;
+ parser.mem_pool = NULL;
+
static const njs_token_type_t safe_ast[] = {
NJS_TOKEN_END,
NJS_TOKEN_FUNCTION_EXPRESSION,
for (i = 1; i < nargs - 1; i++) {
ret = njs_value_to_chain(vm, &chain, njs_argument(args, i));
if (njs_slow_path(ret < NJS_OK)) {
- return ret;
+ goto done;
}
if (i != (nargs - 2)) {
if (nargs > 1) {
ret = njs_value_to_chain(vm, &chain, njs_argument(args, nargs - 1));
if (njs_slow_path(ret < NJS_OK)) {
- return ret;
+ goto done;
}
}
ret = njs_chb_join(&chain, &str);
if (njs_slow_path(ret != NJS_OK)) {
njs_memory_error(vm);
- return NJS_ERROR;
+ ret = NJS_ERROR;
+ goto done;
}
file = njs_str_value("runtime");
ret = njs_parser_init(vm, &parser, NULL, &file, str.start,
str.start + str.length);
if (njs_slow_path(ret != NJS_OK)) {
- return ret;
+ goto done;
}
ret = njs_parser(vm, &parser);
if (njs_slow_path(ret != NJS_OK)) {
- return ret;
+ goto done;
}
if (!vm->options.unsafe) {
ret = njs_generator_init(&generator, &file, 0, 1);
if (njs_slow_path(ret != NJS_OK)) {
njs_internal_error(vm, "njs_generator_init() failed");
- return NJS_ERROR;
+ ret = NJS_ERROR;
+ goto done;
}
code = njs_generate_scope(vm, &generator, parser.scope,
njs_internal_error(vm, "njs_generate_scope() failed");
}
- return NJS_ERROR;
+ ret = NJS_ERROR;
+ goto done;
}
- njs_chb_destroy(&chain);
-
if ((code->end - code->start)
!= (sizeof(njs_vmcode_function_t) + sizeof(njs_vmcode_return_t))
|| ((njs_vmcode_generic_t *) code->start)->code != NJS_VMCODE_FUNCTION)
{
njs_syntax_error(vm, "single function literal required");
- return NJS_ERROR;
+ ret = NJS_ERROR;
+ goto done;
}
lambda = ((njs_vmcode_function_t *) code->start)->lambda;
function = njs_function_alloc(vm, lambda, (njs_bool_t) async);
if (njs_slow_path(function == NULL)) {
- return NJS_ERROR;
+ ret = NJS_ERROR;
+ goto done;
}
function->global = 1;
ret = njs_function_name_set(vm, function, &name, NULL);
if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
+ goto done;
}
njs_set_function(retval, function);
- return NJS_OK;
+ ret = NJS_OK;
+ goto done;
fail:
njs_type_error(vm, "function constructor is disabled in \"safe\" mode");
- return NJS_ERROR;
+ ret = NJS_ERROR;
+
+done:
+
+ if (parser.mem_pool != NULL) {
+ njs_parser_destroy(&parser);
+ }
+
+ njs_chb_destroy(&chain);
+
+ if (str.start != NULL) {
+ njs_mp_free(vm->mem_pool, str.start);
+ }
+
+ return ret;
}
code->name = *name;
generator->code_size = generator->code_end - generator->code_start;
+ scope->top = NULL;
return code;
}
njs_int_t
-njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file,
- u_char *start, u_char *end)
+njs_lexer_init(njs_vm_t *vm, njs_mp_t *mem_pool, njs_lexer_t *lexer,
+ njs_str_t *file, u_char *start, u_char *end)
{
lexer->file = *file;
lexer->start = start;
lexer->end = end;
lexer->line = 1;
lexer->vm = vm;
+ lexer->mem_pool = mem_pool;
njs_queue_init(&lexer->preread);
njs_int_t ret;
njs_lexer_token_t *token;
- token = njs_mp_zalloc(lexer->vm->mem_pool, sizeof(njs_lexer_token_t));
+ token = njs_mp_zalloc(lexer->mem_pool, sizeof(njs_lexer_token_t));
if (njs_slow_path(token == NULL)) {
return NULL;
}
njs_queue_remove(lnk);
- njs_mp_free(lexer->vm->mem_pool, token);
+ njs_mp_free(lexer->mem_pool, token);
}
}
njs_str_t file;
njs_vm_t *vm;
+ njs_mp_t *mem_pool;
u_char *start;
u_char *end;
} njs_lexer_t;
-njs_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file,
- u_char *start, u_char *end);
+njs_int_t njs_lexer_init(njs_vm_t *vm, njs_mp_t *mem_pool,
+ njs_lexer_t *lexer, njs_str_t *file, u_char *start, u_char *end);
njs_lexer_token_t *njs_lexer_token(njs_lexer_t *lexer,
njs_bool_t with_end_line);
njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, njs_parser_scope_t *scope,
njs_str_t *file, u_char *start, u_char *end)
{
+ njs_int_t ret;
njs_lexer_t *lexer;
njs_memzero(parser, sizeof(njs_parser_t));
parser->scope = scope;
+ parser->mem_pool = njs_mp_fast_create(2 * njs_pagesize(), 128, 512, 16);
+ if (njs_slow_path(parser->mem_pool == NULL)) {
+ njs_memory_error(vm);
+ return NJS_ERROR;
+ }
+
lexer = &parser->lexer0;
parser->lexer = lexer;
njs_rbtree_init(&parser->labels, njs_parser_scope_rbtree_compare);
- return njs_lexer_init(vm, lexer, file, start, end);
+ ret = njs_lexer_init(vm, parser->mem_pool, lexer, file, start, end);
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_mp_destroy(parser->mem_pool);
+ parser->mem_pool = NULL;
+ }
+
+ return ret;
+}
+
+
+void
+njs_parser_destroy(njs_parser_t *parser)
+{
+ njs_parser_scope_t *scope;
+
+ for (scope = parser->scope; scope != NULL; scope = scope->parent) {
+ scope->top = NULL;
+ }
+
+ if (parser->mem_pool != NULL) {
+ njs_mp_destroy(parser->mem_pool);
+ parser->mem_pool = NULL;
+ }
}
items = array->u.array.items;
if (items == NULL) {
- items = njs_arr_create(parser->vm->mem_pool, 4,
+ items = njs_arr_create(parser->mem_pool, 4,
sizeof(njs_parser_array_item_t));
if (njs_slow_path(items == NULL)) {
return NJS_ERROR;
njs_lexer_t lexer0;
njs_lexer_t *lexer;
njs_vm_t *vm;
+ njs_mp_t *mem_pool;
njs_parser_node_t *node;
njs_parser_node_t *target;
njs_parser_scope_t *scope;
njs_rbtree_node_t *node2);
njs_int_t njs_parser_init(njs_vm_t *vm, njs_parser_t *parser,
njs_parser_scope_t *scope, njs_str_t *file, u_char *start, u_char *end);
+void njs_parser_destroy(njs_parser_t *parser);
njs_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser);
njs_bool_t njs_variable_closure_test(njs_parser_scope_t *root,
{
njs_parser_node_t *node;
- node = njs_mp_zalloc(parser->vm->mem_pool, sizeof(njs_parser_node_t));
+ node = njs_mp_zalloc(parser->mem_pool, sizeof(njs_parser_node_t));
if (njs_fast_path(node != NULL)) {
node->token_type = type;
njs_inline void
njs_parser_node_free(njs_parser_t *parser, njs_parser_node_t *node)
{
- njs_mp_free(parser->vm->mem_pool, node);
+ njs_mp_free(parser->mem_pool, node);
}
parser->allow_in = entry->allow_in;
parser->var_type = entry->var_type;
- njs_mp_free(parser->vm->mem_pool, entry);
+ njs_mp_free(parser->mem_pool, entry);
return NJS_OK;
}
{
njs_parser_stack_entry_t *entry;
- entry = njs_mp_alloc(parser->vm->mem_pool,
- sizeof(njs_parser_stack_entry_t));
+ entry = njs_mp_alloc(parser->mem_pool, sizeof(njs_parser_stack_entry_t));
if (njs_slow_path(entry == NULL)) {
return NJS_ERROR;
}
{
njs_parser_label_t *label;
- label = njs_mp_alloc(parser->vm->mem_pool, sizeof(njs_parser_label_t));
+ label = njs_mp_alloc(parser->mem_pool, sizeof(njs_parser_label_t));
if (njs_slow_path(label == NULL)) {
njs_memory_error(parser->vm);
return NJS_ERROR;
}
njs_rbtree_delete(&parser->labels, (njs_rbtree_part_t *) node);
- njs_mp_free(parser->vm->mem_pool, node);
+ njs_mp_free(parser->mem_pool, node);
return NJS_OK;
}
ret = njs_parser(vm, &parser);
if (njs_slow_path(ret != NJS_OK)) {
+ njs_parser_destroy(&parser);
return NJS_ERROR;
}
NJS_CHB_MP_INIT(&chain, njs_vm_memory_pool(vm));
ret = njs_parser_serialize_ast(parser.node, &chain);
if (njs_slow_path(ret == NJS_ERROR)) {
+ njs_parser_destroy(&parser);
return ret;
}
if (njs_slow_path(njs_chb_join(&chain, &ast) != NJS_OK)) {
+ njs_parser_destroy(&parser);
return NJS_ERROR;
}
ret = njs_generator_init(&generator, &vm->options.file, 0, 0);
if (njs_slow_path(ret != NJS_OK)) {
njs_internal_error(vm, "njs_generator_init() failed");
+ njs_parser_destroy(&parser);
return NJS_ERROR;
}
njs_internal_error(vm, "njs_generate_scope() failed");
}
+ njs_parser_destroy(&parser);
return NJS_ERROR;
}
+ njs_parser_destroy(&parser);
+
if (scope->items > global_items) {
global = vm->levels[NJS_LEVEL_GLOBAL];
ret = njs_parser(vm, &parser);
if (njs_slow_path(ret != NJS_OK)) {
+ njs_parser_destroy(&parser);
return NULL;
}
ret = njs_generator_init(&generator, &module->name, 0, 0);
if (njs_slow_path(ret != NJS_OK)) {
njs_internal_error(vm, "njs_generator_init() failed");
+ njs_parser_destroy(&parser);
return NULL;
}
if (njs_slow_path(code == NULL)) {
njs_internal_error(vm, "njs_generate_scope() failed");
+ njs_parser_destroy(&parser);
return NULL;
}
lambda = njs_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
if (njs_fast_path(lambda == NULL)) {
njs_memory_error(vm);
+ njs_parser_destroy(&parser);
return NULL;
}
module->function.u.lambda = lambda;
+ njs_parser_destroy(&parser);
+
return module;
}