// File: /workspace/github_c_makefile_star2_O0/BernardTatin[P]s7sh/s7.c
// Function: optimize_lambda
static void optimize_lambda(s7_scheme *sc, bool unstarred_lambda, s7_pointer func, s7_pointer args, s7_pointer body)
                {
                    s7_int len;

                    len = s7_list_length(sc, body);
#if OPTIMIZE_PRINT
                    fprintf(stderr, "%s[%d]: %s %s %ld\n", __func__, __LINE__, DISPLAY(func), DISPLAY(args), len);
#endif

                    if (len < 0)                /* (define (hi) 1 . 2) */
                        s7_error(sc, sc->syntax_error_symbol,
                                set_elist_3(sc, wrap_string(sc, "~A: function body messed up, ~A", 31),
                                    (unstarred_lambda) ? sc->lambda_symbol : sc->lambda_star_symbol,
                                    sc->code));

                    if (len > 0)  /* i.e. not circular */
                    {
                        body_t result;
                        s7_pointer p, lst, cleared_args;

                        clear_symbol_list(sc);
                        for (p = args; is_pair(p); p = cdr(p))
                            add_symbol_to_list(sc, (is_symbol(car(p))) ? car(p) : caar(p));
                        if (!is_null(p))
                            add_symbol_to_list(sc, p);
                        sc->got_tc = false;
                        sc->got_rec = false;
                        result = body_is_safe(sc, func, body, true);
                        clear_symbol_list(sc);

                        /* if the body is safe, we can optimize the calling sequence */
                        if (!unstarred_lambda)
                        {
                            bool happy = true;
                            /* check default vals -- if none is an expression or symbol, set simple args */
                            for (p = args; is_pair(p); p = cdr(p))
                            {
                                s7_pointer arg;
                                arg = car(p);
                                if ((is_pair(arg)) &&                   /* has default value */
                                        (is_pair(cdr(arg))) &&              /*   is not a ridiculous improper list */
                                        ((is_symbol(cadr(arg))) ||          /*   if default value might involve eval in any way, it isn't simple */
                                         (is_unquoted_pair(cadr(arg)))))    /*   pair as default only ok if it is (quote ...) */
                                {
                                    happy = false;
                                    if ((result > UNSAFE_BODY) &&
                                            (tree_has_definers_or_binders(sc, cadr(arg)))) /* if the default has a definer, body is not safe (funclet is not stable) */
                                        result = UNSAFE_BODY;
                                    break;
                                }
                            }
                            if (happy)
                                lambda_set_simple_defaults(body);
                        }
                        if (result >= SAFE_BODY)
                        {
                            set_safe_closure_body(body);	  /* this bit is set on the function itself in make_closure and friends */
                            if (result == VERY_SAFE_BODY)
                                set_very_safe_closure_body(body);
                        }

                        if (is_symbol(func))
                        {
                            lst = cons(sc, add_symbol_to_list(sc, func), sc->nil);
                            sc->temp10 = lst;
                        }
                        else lst = sc->nil;

                        /* TODO: check cleared_args */
                        if (optimize(sc, body, 1, cleared_args = collect_parameters(sc, args, lst)) == OPT_OOPS)
                            clear_all_optimizations(sc, body);
                        else
                        {
                            if (result >= RECUR_BODY) /* (is_safe_closure_body(body)) */
                            {
                                int32_t nvars;
                                for (nvars = 0, p = args; is_pair(p); nvars++, p = cdr(p));

                                if (is_null(p))
                                {
                                    if (nvars > 0)
                                    {
                                        annotate_args(sc, body, cleared_args);
                                        fx_tree(sc, body,
                                                (is_pair(car(args))) ? caar(args) : car(args),
                                                (nvars > 1) ? ((is_pair(cadr(args))) ? caadr(args) : cadr(args)) : NULL);
                                    }
                                }
                                if ((unstarred_lambda) || (nvars == 1))
                                {
                                    if (is_null(cdr(body)))
                                    {
                                        if (sc->got_tc)
                                        {
                                            if (check_tc(sc, func, nvars, args, car(body)))
                                                set_safe_closure_body(body);
                                        }
                                        if ((sc->got_rec) &&
                                                (!is_tc_op(optimize_op(car(body)))) &&
                                                (result >= RECUR_BODY))
                                        {
                                            if (check_recur(sc, func, nvars, args, car(body)))
                                                set_safe_closure_body(body);
                                        }
#if 0
                                        if (((sc->got_tc) || (sc->got_rec)) &&
                                                (!is_rec_op(optimize_op(car(body)))) &&
                                                (!is_tc_op(optimize_op(car(body)))) &&
                                                (!is_symbol(cadar(body)))) /* and let as start */
                                            fprintf(stderr, "%s[%d]: %s %d %s\n", __func__, __LINE__, DISPLAY(func), nvars, DISPLAY(body));
#endif
                                    }
                                }
                            }
                        }
                        if (is_symbol(func))
                        {
                            sc->temp10 = sc->nil;
                            free_cell(sc, lst);
                        }
                        sc->got_tc = false;
                        sc->got_rec = false;
                    }
                }

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movb %sil, %al
movq %rdi, 0x100(%rsp)
andb $0x1, %al
movb %al, 0xff(%rsp)
movq %rdx, 0xf0(%rsp)
movq %rcx, 0xe8(%rsp)
movq %r8, 0xe0(%rsp)
movq 0x100(%rsp), %rdi
movq 0xe0(%rsp), %rsi
callq 0x31900
movq %rax, 0xd8(%rsp)
cmpq $0x0, 0xd8(%rsp)
jge 0x182e60
movq 0x100(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x100(%rsp), %rax
movq 0x1918(%rax), %rax
movq %rax, 0x68(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x100(%rsp), %rdi
leaq 0x6d14c(%rip), %rsi     # 0x1eff38
movl $0x1f, %edx
callq 0xb880
movq %rax, 0x78(%rsp)
testb $0x1, 0xff(%rsp)
je 0x182e1b
movq 0x100(%rsp), %rax
movq 0x1798(%rax), %rax
movq %rax, 0x58(%rsp)
jmp 0x182e2f
movq 0x100(%rsp), %rax
movq 0x17a0(%rax), %rax
movq %rax, 0x58(%rsp)
movq 0x78(%rsp), %rsi
movq 0x70(%rsp), %rdi
movq 0x58(%rsp), %rdx
movq 0x100(%rsp), %rax
movq (%rax), %rcx
callq 0xf240
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq %rax, %rdx
callq 0x2f940
cmpq $0x0, 0xd8(%rsp)
jle 0x1835d4
movq 0x100(%rsp), %rdi
callq 0xdd1b0
movq 0xe8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x182f0a
movq 0x100(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
cmpl $0xa, %eax
jne 0x182ed0
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x48(%rsp)
jmp 0x182ee5
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0xde160
movq 0xc8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0xc8(%rsp)
jmp 0x182e8c
movq 0xc8(%rsp), %rax
movq 0x100(%rsp), %rcx
cmpq 0x110(%rcx), %rax
je 0x182f38
movq 0x100(%rsp), %rdi
movq 0xc8(%rsp), %rsi
callq 0xde160
movq 0x100(%rsp), %rax
movb $0x0, 0x24e(%rax)
movq 0x100(%rsp), %rax
movb $0x0, 0x24f(%rax)
movq 0x100(%rsp), %rdi
movq 0xf0(%rsp), %rsi
movq 0xe0(%rsp), %rdx
movl $0x1, %ecx
callq 0x183880
movl %eax, 0xd4(%rsp)
movq 0x100(%rsp), %rdi
callq 0xdd1b0
testb $0x1, 0xff(%rsp)
jne 0x1830d9
movb $0x1, 0xb7(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x1830b8
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x18309d
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x18309d
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
cmpl $0xa, %eax
je 0x18305b
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x18309d
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movq 0x100(%rsp), %rcx
cmpq 0x17b0(%rcx), %rax
je 0x18309d
movb $0x0, 0xb7(%rsp)
cmpl $0x0, 0xd4(%rsp)
jbe 0x18309b
movq 0x100(%rsp), %rdi
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
callq 0x164670
testb $0x1, %al
jne 0x183090
jmp 0x18309b
movl $0x0, 0xd4(%rsp)
jmp 0x1830b8
jmp 0x18309f
movq 0xc8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0xc8(%rsp)
jmp 0x182fb2
testb $0x1, 0xb7(%rsp)
je 0x1830d7
movq 0xe0(%rsp), %rax
movq (%rax), %rcx
orq $0x400, %rcx            # imm = 0x400
movq %rcx, (%rax)
jmp 0x1830d9
cmpl $0x2, 0xd4(%rsp)
jb 0x183116
movq 0xe0(%rsp), %rax
movzwl (%rax), %ecx
orl $0x1000, %ecx           # imm = 0x1000
movw %cx, (%rax)
cmpl $0x3, 0xd4(%rsp)
jne 0x183114
movq 0xe0(%rsp), %rax
movzwl 0x6(%rax), %ecx
orl $0x10, %ecx
movw %cx, 0x6(%rax)
jmp 0x183116
movq 0xf0(%rsp), %rax
movzbl (%rax), %eax
cmpl $0xa, %eax
jne 0x183224
movq 0x100(%rsp), %rdi
movq 0xf0(%rsp), %rsi
callq 0xde160
movq %rax, 0x98(%rsp)
movq 0x100(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0x90(%rsp)
movq 0x100(%rsp), %rax
movq 0x90(%rax), %rax
movq 0x100(%rsp), %rcx
cmpq 0x98(%rcx), %rax
ja 0x18318b
movq 0x100(%rsp), %rdi
callq 0xc670
movq 0x100(%rsp), %rcx
movq 0x90(%rcx), %rax
movq %rax, %rdx
addq $-0x8, %rdx
movq %rdx, 0x90(%rcx)
movq -0x8(%rax), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
movq $0x200001, (%rax)       # imm = 0x200001
movq 0x98(%rsp), %rcx
movq 0xa0(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x90(%rsp), %rcx
movq 0xa0(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0xa0(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rcx
movq 0x100(%rsp), %rax
movq %rcx, 0x540(%rax)
jmp 0x18323b
movq 0x100(%rsp), %rax
movq 0x110(%rax), %rax
movq %rax, 0xc0(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x100(%rsp), %rdi
movq 0xe8(%rsp), %rsi
movq 0xc0(%rsp), %rdx
callq 0x17fc80
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq %rax, %rcx
movq %rcx, 0xb8(%rsp)
movl $0x1, %edx
callq 0x1835e0
cmpl $0x2, %eax
jne 0x1832b0
movq 0x100(%rsp), %rdi
movq 0xe0(%rsp), %rsi
callq 0x15a840
jmp 0x183573
cmpl $0x1, 0xd4(%rsp)
jb 0x183571
movl $0x0, 0x84(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x183312
jmp 0x1832eb
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
movq 0xc8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0xc8(%rsp)
jmp 0x1832d9
movq 0xc8(%rsp), %rax
movq 0x100(%rsp), %rcx
cmpq 0x110(%rcx), %rax
jne 0x18343c
cmpl $0x0, 0x84(%rsp)
jle 0x18343a
movq 0x100(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0xb8(%rsp), %rdx
callq 0x164800
movq 0x100(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x18339f
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x20(%rsp)
jmp 0x1833b0
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpl $0x1, 0x84(%rsp)
jle 0x183418
movq 0xe8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x1833f7
movq 0xe8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0x18340c
movq 0xe8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movq %rax, 0x8(%rsp)
jmp 0x183421
xorl %eax, %eax
movq %rax, 0x8(%rsp)
jmp 0x183421
movq 0x18(%rsp), %rdx
movq 0x30(%rsp), %rsi
movq 0x28(%rsp), %rdi
movq 0x8(%rsp), %rcx
callq 0x15d170
jmp 0x18343c
testb $0x1, 0xff(%rsp)
jne 0x183454
cmpl $0x1, 0x84(%rsp)
jne 0x18356f
movq 0xe0(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x100(%rsp), %rcx
cmpq 0x110(%rcx), %rax
jne 0x18356d
movq 0x100(%rsp), %rax
testb $0x1, 0x24e(%rax)
je 0x1834d2
movq 0x100(%rsp), %rdi
movq 0xf0(%rsp), %rsi
movl 0x84(%rsp), %edx
movq 0xe8(%rsp), %rcx
movq 0xe0(%rsp), %rax
movq 0x8(%rax), %r8
callq 0x183a00
testb $0x1, %al
jne 0x1834bc
jmp 0x1834d0
movq 0xe0(%rsp), %rax
movzwl (%rax), %ecx
orl $0x1000, %ecx           # imm = 0x1000
movw %cx, (%rax)
jmp 0x1834d2
movq 0x100(%rsp), %rax
testb $0x1, 0x24f(%rax)
je 0x18356b
movq 0xe0(%rsp), %rax
movq 0x8(%rax), %rax
movzwl 0x4(%rax), %eax
cmpl $0x32e, %eax            # imm = 0x32E
jl 0x183515
movq 0xe0(%rsp), %rax
movq 0x8(%rax), %rax
movzwl 0x4(%rax), %eax
cmpl $0x343, %eax            # imm = 0x343
jle 0x18356b
cmpl $0x1, 0xd4(%rsp)
jb 0x18356b
movq 0x100(%rsp), %rdi
movq 0xf0(%rsp), %rsi
movl 0x84(%rsp), %edx
movq 0xe8(%rsp), %rcx
movq 0xe0(%rsp), %rax
movq 0x8(%rax), %r8
callq 0x1866b0
testb $0x1, %al
jne 0x183555
jmp 0x183569
movq 0xe0(%rsp), %rax
movzwl (%rax), %ecx
orl $0x1000, %ecx           # imm = 0x1000
movw %cx, (%rax)
jmp 0x18356b
jmp 0x18356d
jmp 0x18356f
jmp 0x183571
jmp 0x183573
movq 0xf0(%rsp), %rax
movzbl (%rax), %eax
cmpl $0xa, %eax
jne 0x1835b6
movq 0x100(%rsp), %rax
movq 0x110(%rax), %rcx
movq 0x100(%rsp), %rax
movq %rcx, 0x540(%rax)
movq 0x100(%rsp), %rdi
movq 0xc0(%rsp), %rsi
callq 0x2bcd0
movq 0x100(%rsp), %rax
movb $0x0, 0x24e(%rax)
movq 0x100(%rsp), %rax
movb $0x0, 0x24f(%rax)
addq $0x108, %rsp            # imm = 0x108
retq
nopl (%rax)