njs_generate_try_statement(njs_vm_t *vm, njs_generator_t *generator,
    njs_parser_node_t *node)
{
    njs_int_t                ret;
    njs_index_t              exception_index, exit_index;
    njs_vmcode_try_start_t   *try_start;
    njs_generator_try_ctx_t  ctx;

    njs_memzero(&ctx, sizeof(njs_generator_try_ctx_t));

    njs_generate_code(generator, njs_vmcode_try_start_t, try_start,
                      NJS_VMCODE_TRY_START, 2, node);
    ctx.try_offset = njs_code_offset(generator, try_start);

    exception_index = njs_generate_temp_index_get(vm, generator, node);
    if (njs_slow_path(exception_index == NJS_INDEX_ERROR)) {
        return NJS_ERROR;
    }

    try_start->exception_value = exception_index;

    /*
     * exit_value is used in njs_vmcode_finally to make a decision
     * which way to go after "break", "continue" and "return" instruction
     * inside "try" or "catch" blocks.
     */

    exit_index = njs_generate_temp_index_get(vm, generator, node);
    if (njs_slow_path(exit_index == NJS_INDEX_ERROR)) {
        return NJS_ERROR;
    }

    try_start->exit_value = exit_index;

    ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_TRY, &no_label);
    if (njs_slow_path(ret != NJS_OK)) {
        return ret;
    }

    ctx.try_block = generator->block;
    ctx.try_block->index = exit_index;
    ctx.exception_index = exception_index;

    ctx.catch_cont_label = undef_label;
    ctx.catch_exit_label = undef_label;
    ctx.try_cont_label = undef_label;
    ctx.try_exit_label = undef_label;

    njs_generator_next(generator, njs_generate, node->left);

    return njs_generator_after(vm, generator,
                               njs_queue_first(&generator->stack), node,
                               njs_generate_try_left,
                               &ctx, sizeof(njs_generator_try_ctx_t));
}
njs_generate_try_statement(njs_vm_t *vm, njs_generator_t *generator,
    njs_parser_node_t *node)
{
    njs_int_t                ret;
    njs_index_t              exception_index, exit_index;
    njs_vmcode_try_start_t   *try_start;
    njs_generator_try_ctx_t  ctx;

    njs_memzero(&ctx, sizeof(njs_generator_try_ctx_t));

    njs_generate_code(generator, njs_vmcode_try_start_t, try_start,
                      NJS_VMCODE_TRY_START, 2, node);
    ctx.try_offset = njs_code_offset(generator, try_start);

    exception_index = njs_generate_temp_index_get(vm, generator, node);
    if (njs_slow_path(exception_index == NJS_INDEX_ERROR)) {
        return NJS_ERROR;
    }

    try_start->exception_value = exception_index;

     

    exit_index = njs_generate_temp_index_get(vm, generator, node);
    if (njs_slow_path(exit_index == NJS_INDEX_ERROR)) {
        return NJS_ERROR;
    }

    try_start->exit_value = exit_index;

    ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_TRY, &no_label);
    if (njs_slow_path(ret != NJS_OK)) {
        return ret;
    }

    ctx.try_block = generator->block;
    ctx.try_block->index = exit_index;
    ctx.exception_index = exception_index;

    ctx.catch_cont_label = undef_label;
    ctx.catch_exit_label = undef_label;
    ctx.try_cont_label = undef_label;
    ctx.try_exit_label = undef_label;

    njs_generator_next(generator, njs_generate, node->left);

    return njs_generator_after(vm, generator,
                               njs_queue_first(&generator->stack), node,
                               njs_generate_try_left,
                               &ctx, sizeof(njs_generator_try_ctx_t));
}