// File: /workspace/github_c_makefile_star2_O0/BernardTatin[P]s7sh/s7.c
// Function: catch_1_function
static bool catch_1_function(s7_scheme *sc, s7_int i, s7_pointer type, s7_pointer info, bool *reset_hook)
                {
                    s7_pointer x;
                    x = stack_code(sc->stack, i);
                    if ((catch_tag(x) == sc->T) ||
                            (catch_tag(x) == type) ||
                            (type == sc->T))
                    {
                        uint64_t loc;
                        opcode_t op;
                        s7_pointer catcher, error_func, error_body, error_args;

                        op = stack_op(sc->stack, i);
                        sc->temp4 = stack_let(sc->stack, i); /* GC protect this, since we're moving the stack top below */
                        catcher = x;
                        loc = catch_goto_loc(catcher);
                        sc->op_stack_now = (s7_pointer *)(sc->op_stack + catch_op_loc(catcher));
                        sc->stack_end = (s7_pointer *)(sc->stack_start + loc);
                        error_func = catch_handler(catcher);

                        /* very often the error handler just returns either a constant ('error or #f), or
                         *   the args passed to it, so there's no need to laboriously make a closure,
                         *   and apply it -- just set sc->value to the closure body (or the args) and return.
                         * so first examine closure_body(error_func)
                         *   if it is a constant, or quoted symbol, return that,
                         *   if it is the args symbol, return (list type info)
                         */

                        /* if OP_CATCH_1, we deferred making the error handler until it is actually needed */
                        if (op == OP_CATCH_1)
                        {
                            error_body = cdr(error_func);
                            error_args = car(error_func);
                        }
                        else
                        {
                            if (is_closure(error_func))
                            {
                                error_body = closure_body(error_func);
                                error_args = closure_args(error_func);
                            }
                            else
                            {
                                error_body = NULL;
                                error_args = NULL;
                            }
                        }

                        if ((error_body) && (is_null(cdr(error_body))))
                        {
                            s7_pointer y = NULL;
                            error_body = car(error_body);
                            if (is_pair(error_body))
                            {
                                if (car(error_body) == sc->quote_symbol)
                                    y = cadr(error_body);
                                else
                                {
                                    if ((car(error_body) == sc->car_symbol) &&
                                            (cadr(error_body) == error_args))
                                        y = type;
                                }
                            }
                            else
                            {
                                if (is_symbol(error_body))
                                {
                                    if (error_body == error_args)
                                        y = list_2(sc, type, info);
                                    else
                                    {
                                        if (is_keyword(error_body))
                                            y = error_body;
                                        else
                                        {
                                            if ((is_pair(error_args)) &&
                                                    (error_body == car(error_args)))
                                                y = type;
                                        }
                                    }
                                }
                                else y = error_body; /* not pair or symbol */
                            }
                            if (y)
                            {
                                if (loc > 4)
                                    pop_stack(sc);
                                /* we're at OP_CATCH, normally we want to pop that away, but (handwaving...) if we're coming
                                 *   from s7_eval (indirectly perhaps through s7_eval_c_string), we might push the OP_EVAL_DONE
                                 *   to end that call, but it's pushed at the precatch stack end (far beyond the catch loc).
                                 *   If we catch an error, catch unwinds to its starting point, and the pop_stack above
                                 *   puts us at the bottom of the stack (i.e. stack_end == stack_start), OP_EVAL_DONE.
                                 *   Now we return true, ending up back in eval, because the error handler jumped out of eval,
                                 *   back to wherever we were in eval when we hit the error.  eval jumps back to the start
                                 *   of its loop, and pops the stack to see what to do next!  So the (loc > 4) at least
                                 *   protects against stack underflow, but ideally we'd know we came from OP_CATCH+s7_eval.
                                 *   We can't do anything fancy here because we have to unwind the C stack as well as s7's stack.
                                 *   s7_eval doesn't know anything about the catches on the stack.  We can't look back for
                                 *   OP_EVAL_DONE -- segfault in OP_BEGIN.  Hmmmm.  Perhaps catch should not unwind until the
                                 *   end?  But we want the error handler to run as a part of the calling expression, and
                                 *   in any case the OP_EVAL_DONE is not useful (it marks the end of the no-error case).
                                 */
                                sc->value = y;
                                sc->temp4 = sc->nil;
                                if (loc == 4)
                                    sc->code = cons(sc, sc->value, sc->nil); /* if we end up at op_begin, give it something it can handle */
                                return(true);
                            }
                        }
                        if (op == OP_CATCH_1)
                        {
                            s7_pointer p;
                            new_cell(sc, p, T_CLOSURE | T_COPY_ARGS); /* never a safe_closure, apparently */
                            closure_set_args(p, car(error_func));
                            closure_set_body(p, cdr(error_func));
                            closure_set_setter(p, sc->F);
                            closure_set_arity(p, CLOSURE_ARITY_NOT_SET);
                            closure_set_let(p, sc->temp4);
                            sc->code = p;
                        }
                        else sc->code = error_func;
                        sc->temp4 = sc->nil;

                        /* if user (i.e. yers truly!) copies/pastes the preceding lambda () into the
                         *   error handler portion of the catch, he gets the inexplicable message:
                         *       ;(): too many arguments: (a1 ())
                         *   when this apply tries to call the handler.  So, we need a special case error check here!
                         */

                        if (!s7_is_aritable(sc, sc->code, 2))
                            s7_wrong_number_of_args_error(sc, "catch error handler should accept 2 args: ~S", sc->code);

                        sc->args = list_2(sc, type, info); /* almost never able to skip this -- costs more to check! */
                        sc->cur_op = OP_APPLY;
                        /* explicit eval needed if s7_call called into scheme where a caught error occurred (ex6 in exs7.c)
                         *  but putting it here (via eval(sc, OP_APPLY)) means the C stack is not cleared correctly in non-s7-call cases,
                         *  so defer it until s7_call
                         */
                        return(true);
                    }
                    return(false);
                }

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xe8(%rsp)
movq %rsi, 0xe0(%rsp)
movq %rdx, 0xd8(%rsp)
movq %rcx, 0xd0(%rsp)
movq %r8, 0xc8(%rsp)
movq 0xe8(%rsp), %rax
movq 0x38(%rax), %rax
movq 0x10(%rax), %rax
movq 0xe0(%rsp), %rcx
subq $0x3, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
movq 0x18(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x118(%rcx), %rax
je 0x1b8c47
movq 0xc0(%rsp), %rax
movq 0x18(%rax), %rax
cmpq 0xd8(%rsp), %rax
je 0x1b8c47
movq 0xd8(%rsp), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x118(%rcx), %rax
jne 0x1b93eb
movq 0xe8(%rsp), %rax
movq 0x38(%rax), %rax
movq 0x10(%rax), %rax
movq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xb0(%rsp)
movq 0xe8(%rsp), %rax
movq 0x38(%rax), %rax
movq 0x10(%rax), %rax
movq 0xe0(%rsp), %rcx
subq $0x2, %rcx
movq (%rax,%rcx,8), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x510(%rax)
movq 0xc0(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xb8(%rsp)
movq 0xe8(%rsp), %rax
movq 0x60(%rax), %rcx
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rax
shlq $0x3, %rax
addq %rax, %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x68(%rax)
movq 0xe8(%rsp), %rax
movq 0x48(%rax), %rcx
movq 0xb8(%rsp), %rax
shlq $0x3, %rax
addq %rax, %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x50(%rax)
movq 0xa8(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x216, 0xb0(%rsp) # imm = 0x216
jne 0x1b8d5c
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x90(%rsp)
jmp 0x1b8db0
movq 0xa0(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x28, %eax
jne 0x1b8d96
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x90(%rsp)
jmp 0x1b8dae
movq $0x0, 0x98(%rsp)
movq $0x0, 0x90(%rsp)
jmp 0x1b8db0
cmpq $0x0, 0x98(%rsp)
je 0x1b9194
movq 0x98(%rsp), %rax
movq 0x10(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x110(%rcx), %rax
jne 0x1b9194
movq $0x0, 0x88(%rsp)
movq 0x98(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x1b8e99
movq 0x98(%rsp), %rax
movq 0x8(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x17b0(%rcx), %rax
jne 0x1b8e4b
movq 0x98(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x88(%rsp)
jmp 0x1b8e94
movq 0x98(%rsp), %rax
movq 0x8(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0xd20(%rcx), %rax
jne 0x1b8e92
movq 0x98(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
cmpq 0x90(%rsp), %rax
jne 0x1b8e92
movq 0xd8(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x1b8e94
jmp 0x1b9026
movq 0x98(%rsp), %rax
movzbl (%rax), %eax
cmpl $0xa, %eax
jne 0x1b9014
movq 0x98(%rsp), %rax
cmpq 0x90(%rsp), %rax
jne 0x1b8fb0
movq 0xe8(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0xe8(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x70(%rsp)
movq 0xe8(%rsp), %rax
movq 0x90(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x98(%rcx), %rax
ja 0x1b8f2b
movq 0xe8(%rsp), %rdi
callq 0xc670
movq 0xe8(%rsp), %rcx
movq 0x90(%rcx), %rax
movq %rax, %rdx
addq $-0x8, %rdx
movq %rdx, 0x90(%rcx)
movq -0x8(%rax), %rax
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rax
movq $0x200001, (%rax)       # imm = 0x200001
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdi
movq 0x78(%rsp), %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x70(%rsp), %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x80(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rdx
callq 0xd9f0
movq %rax, 0x88(%rsp)
jmp 0x1b9012
movq 0x98(%rsp), %rax
movzwl 0x6(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x1b8fd8
movq 0x98(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x1b9010
movq 0x90(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x1b900e
movq 0x98(%rsp), %rax
movq 0x90(%rsp), %rcx
cmpq 0x8(%rcx), %rax
jne 0x1b900e
movq 0xd8(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x1b9010
jmp 0x1b9012
jmp 0x1b9024
movq 0x98(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x1b9026
cmpq $0x0, 0x88(%rsp)
je 0x1b9192
cmpq $0x4, 0xb8(%rsp)
jbe 0x1b908a
jmp 0x1b9042
movq 0xe8(%rsp), %rax
movq 0x50(%rax), %rcx
addq $-0x20, %rcx
movq %rcx, 0x50(%rax)
movq 0xe8(%rsp), %rax
movq 0xe8(%rsp), %rcx
movq 0x50(%rcx), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rax)
jmp 0x1b908a
movq 0x88(%rsp), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0xe8(%rsp), %rax
movq 0x110(%rax), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x510(%rax)
cmpq $0x4, 0xb8(%rsp)
jne 0x1b9185
movq 0xe8(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x58(%rsp)
movq 0xe8(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x50(%rsp)
movq 0xe8(%rsp), %rax
movq 0x90(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x98(%rcx), %rax
ja 0x1b911d
movq 0xe8(%rsp), %rdi
callq 0xc670
movq 0xe8(%rsp), %rcx
movq 0x90(%rcx), %rax
movq %rax, %rdx
addq $-0x8, %rdx
movq %rdx, 0x90(%rcx)
movq -0x8(%rax), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq $0x200001, (%rax)       # imm = 0x200001
movq 0x58(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x50(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x60(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, (%rax)
movb $0x1, 0xf7(%rsp)
jmp 0x1b93f3
jmp 0x1b9194
cmpq $0x216, 0xb0(%rsp) # imm = 0x216
jne 0x1b927f
jmp 0x1b91a8
movq 0xe8(%rsp), %rax
movq 0x90(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x98(%rcx), %rax
ja 0x1b91d5
movq 0xe8(%rsp), %rdi
callq 0xc670
movq 0xe8(%rsp), %rcx
movq 0x90(%rcx), %rax
movq %rax, %rdx
addq $-0x8, %rdx
movq %rdx, 0x90(%rcx)
movq -0x8(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq $0x10000028, (%rax)     # imm = 0x10000028
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0xe8(%rsp), %rax
movq 0x120(%rax), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0x40(%rsp), %rax
movl $0x40000000, 0x28(%rax) # imm = 0x40000000
movq 0xe8(%rsp), %rax
movq 0x510(%rax), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x40(%rsp), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, (%rax)
jmp 0x1b9292
movq 0xa0(%rsp), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, (%rax)
movq 0xe8(%rsp), %rax
movq 0x110(%rax), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x510(%rax)
movq 0xe8(%rsp), %rdi
movq 0xe8(%rsp), %rax
movq (%rax), %rsi
movl $0x2, %edx
callq 0x3cbf0
testb $0x1, %al
jne 0x1b92f0
movq 0xe8(%rsp), %rdi
movq 0xe8(%rsp), %rax
movq (%rax), %rdx
leaq 0x39e0d(%rip), %rsi     # 0x1f30f8
callq 0x33290
movq 0xe8(%rsp), %rax
movq %rax, (%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xe8(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0xe8(%rsp), %rax
movq 0x90(%rax), %rax
movq 0xe8(%rsp), %rcx
cmpq 0x98(%rcx), %rax
ja 0x1b9357
movq 0xe8(%rsp), %rdi
callq 0xc670
movq 0xe8(%rsp), %rcx
movq 0x90(%rcx), %rax
movq %rax, %rdx
addq $-0x8, %rdx
movq %rdx, 0x90(%rcx)
movq -0x8(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq $0x200001, (%rax)       # imm = 0x200001
movq 0x8(%rsp), %rsi
movq (%rsp), %rdi
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x28(%rsp), %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x38(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdx
callq 0xd9f0
movq %rax, %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0xe8(%rsp), %rax
movq $0x198, 0x18(%rax)      # imm = 0x198
movb $0x1, 0xf7(%rsp)
jmp 0x1b93f3
movb $0x0, 0xf7(%rsp)
movb 0xf7(%rsp), %al
andb $0x1, %al
addq $0xf8, %rsp
retq
nopw %cs:(%rax,%rax)