return NULL;
}
+ code->start = NULL;
+ code->end = NULL;
code->lines = NULL;
if (vm->options.backtrace) {
}
+void
+njs_generator_cleanup(njs_vm_t *vm, njs_uint_t code_index)
+{
+ njs_vm_code_t *code;
+
+ if (vm->codes == NULL) {
+ return;
+ }
+
+ while (vm->codes->items > code_index) {
+ code = njs_arr_remove_last(vm->codes);
+
+ if (code->start != NULL) {
+ njs_mp_free(vm->mem_pool, code->start);
+ }
+
+ if (code->lines != NULL) {
+ njs_arr_destroy(code->lines);
+ }
+ }
+}
+
+
static njs_int_t
njs_generate_scope_end(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
njs_str_t *file, njs_int_t depth, njs_bool_t runtime);
njs_vm_code_t *njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_scope_t *scope, const njs_str_t *name);
+void njs_generator_cleanup(njs_vm_t *vm, njs_uint_t code_index);
njs_vm_code_t *njs_lookup_code(njs_vm_t *vm, u_char *pc);
uint32_t njs_lookup_line(njs_arr_t *lines, uint32_t offset);
}
+void
+njs_module_remove(njs_vm_t *vm, njs_mod_t *module)
+{
+ njs_flathsh_query_t fhq;
+
+ fhq.key = module->name;
+ fhq.key_hash = njs_djb_hash(module->name.start, module->name.length);
+ fhq.pool = vm->mem_pool;
+ fhq.proto = &njs_modules_hash_proto;
+
+ (void) njs_flathsh_delete(&vm->shared->modules_hash, &fhq);
+
+ njs_mp_free(vm->mem_pool, module->name.start);
+ njs_mp_free(vm->mem_pool, module);
+}
+
+
njs_int_t
njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused, njs_value_t *retval)
njs_mod_t *njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value);
+void njs_module_remove(njs_vm_t *vm, njs_mod_t *module);
njs_mod_t *njs_module_find(njs_vm_t *vm, njs_str_t *name,
njs_bool_t shared);
njs_int_t njs_module_require(njs_vm_t *vm, njs_value_t *args,
u_char *end)
{
njs_int_t ret;
+ njs_uint_t code_index;
njs_mod_t *module;
njs_parser_t parser;
njs_vm_code_t *code;
njs_parser_scope_t *scope;
njs_function_lambda_t *lambda;
+ parser.mem_pool = NULL;
+ lambda = NULL;
+ code_index = (vm->codes != NULL) ? vm->codes->items : 0;
+
module = njs_module_find(vm, name, 1);
if (module != NULL) {
return module;
ret = njs_parser_init(vm, &parser, NULL, 0, &module->name, *start, end);
if (njs_slow_path(ret != NJS_OK)) {
- return NULL;
+ goto failed;
}
parser.module = 1;
ret = njs_parser(vm, &parser);
if (njs_slow_path(ret != NJS_OK)) {
- njs_parser_destroy(&parser);
- return NULL;
+ goto failed;
}
*start = parser.lexer->start;
ret = njs_generator_init(&generator, parser.mem_pool, &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;
+ goto failed;
}
code = njs_generate_scope(vm, &generator, parser.scope, &njs_entry_module);
if (njs_slow_path(code == NULL)) {
njs_internal_error(vm, "njs_generate_scope() failed");
- njs_parser_destroy(&parser);
- return NULL;
+ goto failed;
}
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;
+ goto failed;
}
scope = parser.scope;
njs_parser_destroy(&parser);
return module;
+
+failed:
+
+ if (parser.mem_pool != NULL) {
+ njs_parser_destroy(&parser);
+ }
+
+ if (lambda != NULL) {
+ njs_mp_free(vm->mem_pool, lambda);
+ }
+
+ njs_generator_cleanup(vm, code_index);
+ njs_module_remove(vm, module);
+
+ return NULL;
}