// File: /workspace/github_c_makefile_star2_O0/BernardTatin[P]s7sh/s7.c
// Function: g_apply
static s7_pointer g_apply(s7_scheme *sc, s7_pointer args)
                {
#define H_apply "(apply func ...) applies func to the rest of the arguments"
#define Q_apply s7_make_circular_signature(sc, 2, 3, sc->values_symbol, s7_make_signature(sc, 2, sc->is_procedure_symbol, sc->is_sequence_symbol), sc->T)

                    /* can apply always be replaced with apply values?
                     *   (apply + '(1 2 3)) is the same as (+ (apply values '(1 2 3)))
                     * not if apply* in disguise, I think:
                     *   (apply + 1 2 ()) -> 3
                     *   (apply + 1 2 (apply values ())) -> error
                     */
                    sc->code = car(args);
                    if (is_null(cdr(args)))
                    {
                        sc->args = sc->nil;
                        push_stack(sc, OP_APPLY, sc->args, sc->code);
                        return(sc->nil);
                    }

                    if (is_safe_procedure(sc->code))
                    {
                        s7_pointer p, q;

                        for (q = args, p = cdr(args); is_not_null(cdr(p)); q = p, p = cdr(p));
                        /* the last arg is supposed to be a list, it will be spliced onto the end of the previous arg list (if any) below */

                        if (!s7_is_proper_list(sc, car(p)))        /* (apply + #f) etc */
                            return(apply_list_error(sc, args));
                        set_cdr(q, car(p));
                        /* this would work: if (is_c_function(sc->code)) return(c_function_call(sc->code)(sc, cdr(args)));
                         *   but it omits the arg number check, but if we copy the APPLY table here (returning sc->value)
                         *   the overhead from the now non-inline function calls is greater than the fewer-eval-jumps savings.
                         */
                        push_stack(sc, OP_APPLY, cdr(args), sc->code);
                        return(sc->nil);
                    }

                    /* here we may have to copy the arg list */
                    if (is_null(cddr(args)))
                        sc->args = cadr(args);
                    else sc->args = apply_list_star(sc, cdr(args));
                    if (!s7_is_proper_list(sc, sc->args))
                        return(apply_list_error(sc, args));

                    push_stack(sc, OP_APPLY, (needs_copied_args(sc->code)) ? copy_list(sc, sc->args) : sc->args, sc->code);
                    return(sc->nil);
                }

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x28(%rsp)
movq %rsi, 0x20(%rsp)
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x28(%rsp), %rax
movq %rcx, (%rax)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x28(%rsp), %rcx
cmpq 0x110(%rcx), %rax
jne 0x9e398
movq 0x28(%rsp), %rax
movq 0x110(%rax), %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rax
movq (%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, (%rax)
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, 0x8(%rax)
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movl $0x198, %ecx            # imm = 0x198
movq %rcx, 0x18(%rax)
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rcx
addq $0x20, %rcx
movq %rcx, 0x50(%rax)
movq 0x28(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0x9e5ec
movq 0x28(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
andq $0x200000, %rax         # imm = 0x200000
cmpq $0x0, %rax
je 0x9e4b9
movq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x28(%rsp), %rcx
cmpq 0x110(%rcx), %rax
je 0x9e3fe
jmp 0x9e3e4
movq 0x18(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x9e3cb
movq 0x28(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x31a40
testb $0x1, %al
jne 0x9e42e
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x15cad0
movq %rax, 0x30(%rsp)
jmp 0x9e5ec
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rax
movq (%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, (%rax)
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, 0x8(%rax)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movl $0x198, %ecx            # imm = 0x198
movq %rcx, 0x18(%rax)
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rcx
addq $0x20, %rcx
movq %rcx, 0x50(%rax)
movq 0x28(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0x9e5ec
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rax
movq 0x28(%rsp), %rcx
cmpq 0x110(%rcx), %rax
jne 0x9e4ec
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x10(%rax)
jmp 0x9e50b
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x1cfb60
movq %rax, %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rdi
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x31a40
testb $0x1, %al
jne 0x9e53b
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x15cad0
movq %rax, 0x30(%rsp)
jmp 0x9e5ec
jmp 0x9e53d
movq 0x28(%rsp), %rax
movq (%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, (%rax)
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, 0x8(%rax)
movq 0x28(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
andq $0x10000000, %rax       # imm = 0x10000000
cmpq $0x0, %rax
je 0x9e598
movq 0x28(%rsp), %rdi
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x44270
movq %rax, 0x8(%rsp)
jmp 0x9e5a6
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rcx
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movl $0x198, %ecx            # imm = 0x198
movq %rcx, 0x18(%rax)
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rcx
addq $0x20, %rcx
movq %rcx, 0x50(%rax)
movq 0x28(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
addq $0x38, %rsp
retq
nopw %cs:(%rax,%rax)