njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator,
    njs_parser_scope_t *scope, const njs_str_t *name)
{
    u_char         *p;
    int64_t        nargs;
    njs_int_t      ret;
    njs_uint_t     index;
    njs_vm_code_t  *code;

    generator->code_size = 128;

    p = njs_mp_alloc(vm->mem_pool, generator->code_size);
    if (njs_slow_path(p == NULL)) {
        njs_memory_error(vm);
        return NULL;
    }

    generator->code_start = p;
    generator->code_end = p;

    nargs = njs_generate_lambda_variables(vm, generator, scope->top);
    if (njs_slow_path(nargs < NJS_OK)) {
        return NULL;
    }

    if (vm->codes == NULL) {
        vm->codes = njs_arr_create(vm->mem_pool, 4, sizeof(njs_vm_code_t));
        if (njs_slow_path(vm->codes == NULL)) {
            return NULL;
        }
    }

    index = vm->codes->items;
    code = njs_arr_add(vm->codes);
    if (njs_slow_path(code == NULL)) {
        njs_memory_error(vm);
        return NULL;
    }

    code->lines = NULL;

    if (vm->options.backtrace) {
        code->lines = njs_arr_create(vm->mem_pool, 4,
                                     sizeof(njs_vm_line_num_t));
        if (njs_slow_path(code->lines == NULL)) {
            njs_memory_error(vm);
            return NULL;
        }

        generator->lines = code->lines;
    }

    generator->closures = njs_arr_create(vm->mem_pool, 4, sizeof(njs_index_t));
    if (njs_slow_path(generator->closures == NULL)) {
        return NULL;
    }

    scope->closures = generator->closures;

    njs_queue_init(&generator->stack);

    njs_generator_next(generator, njs_generate, scope->top);

    ret = njs_generator_after(vm, generator,
                              njs_queue_first(&generator->stack), NULL,
                              njs_generate_scope_end, NULL, 0);
    if (njs_slow_path(ret != NJS_OK)) {
        return NULL;
    }

    do {
        ret = generator->state(vm, generator, generator->node);
        if (njs_slow_path(ret != NJS_OK)) {
            return NULL;
        }

    } while (generator->state != NULL);

    code = njs_arr_item(vm->codes, index);
    code->start = generator->code_start;
    code->end = generator->code_end;
    code->file = generator->file;
    code->name = *name;

    generator->code_size = generator->code_end - generator->code_start;

    return code;
}
njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator,
    njs_parser_scope_t *scope, const njs_str_t *name)
{
    u_char         *p;
    int64_t        nargs;
    njs_int_t      ret;
    njs_uint_t     index;
    njs_vm_code_t  *code;

    generator->code_size = 128;

    p = njs_mp_alloc(vm->mem_pool, generator->code_size);
    if (njs_slow_path(p == NULL)) {
        njs_memory_error(vm);
        return NULL;
    }

    generator->code_start = p;
    generator->code_end = p;

    nargs = njs_generate_lambda_variables(vm, generator, scope->top);
    if (njs_slow_path(nargs < NJS_OK)) {
        return NULL;
    }

    if (vm->codes == NULL) {
        vm->codes = njs_arr_create(vm->mem_pool, 4, sizeof(njs_vm_code_t));
        if (njs_slow_path(vm->codes == NULL)) {
            return NULL;
        }
    }

    index = vm->codes->items;
    code = njs_arr_add(vm->codes);
    if (njs_slow_path(code == NULL)) {
        njs_memory_error(vm);
        return NULL;
    }

    code->lines = NULL;

    if (vm->options.backtrace) {
        code->lines = njs_arr_create(vm->mem_pool, 4,
                                     sizeof(njs_vm_line_num_t));
        if (njs_slow_path(code->lines == NULL)) {
            njs_memory_error(vm);
            return NULL;
        }

        generator->lines = code->lines;
    }

    generator->closures = njs_arr_create(vm->mem_pool, 4, sizeof(njs_index_t));
    if (njs_slow_path(generator->closures == NULL)) {
        return NULL;
    }

    scope->closures = generator->closures;

    njs_queue_init(&generator->stack);

    njs_generator_next(generator, njs_generate, scope->top);

    ret = njs_generator_after(vm, generator,
                              njs_queue_first(&generator->stack), NULL,
                              njs_generate_scope_end, NULL, 0);
    if (njs_slow_path(ret != NJS_OK)) {
        return NULL;
    }

    do {
        ret = generator->state(vm, generator, generator->node);
        if (njs_slow_path(ret != NJS_OK)) {
            return NULL;
        }

    } while (generator->state != NULL);

    code = njs_arr_item(vm->codes, index);
    code->start = generator->code_start;
    code->end = generator->code_end;
    code->file = generator->file;
    code->name = *name;

    generator->code_size = generator->code_end - generator->code_start;

    return code;
}