// File: /workspace/github_c_makefile_star2_O2/BernardTatin[P]s7sh/s7.c
// Function: g_set_setter
static s7_pointer g_set_setter(s7_scheme *sc, s7_pointer args)
                {
                    s7_pointer p, setter;

                    p = car(args);
                    /* should we check that p != setter?
                     *   (set! (setter <) <) -> <
                     *   (set! (< 3 2) 3) -> #f
                     *   (set! (< 1) 2) -> #t
                     */

                    if (is_symbol(p))
                    {
                        s7_pointer sym, func, slot;
                        sym = p;
                        if (is_keyword(sym))
                            return(s7_wrong_type_arg_error(sc, "set! setter", 1, sym, "a normal symbol (a keyword can't be set)"));

                        if (is_pair(cddr(args)))
                        {
                            s7_pointer e, old_e;
                            e = cadr(args);
                            func = caddr(args);
                            if ((e == sc->rootlet) || (e == sc->nil))
                                slot = global_slot(sym);
                            else
                            {
                                if (!is_let(e))
                                    return(s7_wrong_type_arg_error(sc, "set! symbol-setter", 2, e, "a let"));
                                old_e = sc->envir;
                                sc->envir = e;
                                slot = symbol_to_slot(sc, sym);
                                sc->envir = old_e;
                            }
                        }
                        else
                        {
                            slot = symbol_to_slot(sc, sym);
                            func = cadr(args);
                        }
                        if ((!is_any_procedure(func)) && /* disallow continuation/goto here */
                                (func != sc->F))
                            return(s7_wrong_type_arg_error(sc, "set! setter", 3, func, "a function or #f"));

                        if (sym == sc->setter_symbol)
                            return(immutable_object_error(sc, set_elist_2(sc, wrap_string(sc, "can't set (setter setter) to ~S", 31), func)));

                        if (!is_slot(slot))
                            return(sc->F);

                        if (slot == global_slot(sym))
                        {
                            s7_set_setter(sc, sym, func); /* special GC protection for global vars */
                            return(func);
                        }

                        slot_set_setter(slot, func);
                        if (func != sc->F)
                        {
                            slot_set_has_setter(slot);
                            if (s7_is_aritable(sc, func, 3))
                                set_has_let_arg(func);
                            symbol_set_has_setter(sym);
                        }
                        return(func);
                    }

                    setter = cadr(args);
                    if ((setter != sc->F) &&
                            (!is_any_procedure(setter)))
                        return(s7_wrong_type_arg_error(sc, "set! setter", 2, setter, "a procedure or #f"));
                    if (p == sc->s7_let)
                        return(s7_wrong_type_arg_error(sc, "set! setter", 1, p, "something other than *s7*"));

                    switch (type(p))
                    {
                        case T_MACRO:   case T_MACRO_STAR:
                        case T_BACRO:   case T_BACRO_STAR:
                        case T_CLOSURE: case T_CLOSURE_STAR:
                            closure_set_setter(p, setter);
                            if (setter == sc->F)
                                closure_set_no_setter(p);
                            break;

                        case T_C_FUNCTION:
                        case T_C_ANY_ARGS_FUNCTION:
                        case T_C_OPT_ARGS_FUNCTION:
                        case T_C_RST_ARGS_FUNCTION:
                        case T_C_FUNCTION_STAR:
                            if (p == slot_value(global_slot(sc->setter_symbol)))
                                return(immutable_object_error(sc, set_elist_2(sc, wrap_string(sc, "can't set (setter setter) to ~S", 31), setter)));
                            c_function_set_setter(p, setter);
                            if ((is_any_closure(setter)) ||
                                    (is_any_macro(setter)))
                                add_setter(sc, p, setter);
                            break;

                        case T_C_MACRO:
                            c_macro_set_setter(p, setter);
                            if ((is_any_closure(setter)) ||
                                    (is_any_macro(setter)))
                                add_setter(sc, p, setter);
                            break;

                        case T_SLOT:
                            slot_set_setter(p, setter);
                            slot_set_has_setter(p);
                            break;
                    }
                    return(setter);
                }

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdi, %r14
movq 0x8(%rsi), %r15
movzbl (%r15), %eax
cmpl $0xa, %eax
jne 0x32bc5
testb $-0x80, 0x6(%r15)
jne 0x32c16
movq 0x10(%rsi), %rbx
movq 0x10(%rbx), %rax
cmpb $0x1, (%rax)
jne 0x32c57
movq 0x8(%rbx), %rcx
movq 0x8(%rax), %rbx
cmpq 0x150(%r14), %rcx
je 0x32cbc
cmpq 0x110(%r14), %rcx
je 0x32cbc
cmpb $0x1c, (%rcx)
jne 0x32dba
movq 0x8(%r14), %r13
movq %rcx, 0x8(%r14)
movq %r14, %rdi
movq %r15, %rsi
callq 0xb00b
movq %rax, %r12
movq %r13, 0x8(%r14)
jmp 0x32cc0
movq 0x10(%rsi), %rcx
movq 0x8(%rcx), %rbx
cmpq 0x120(%r14), %rbx
je 0x32bdb
cmpb $0x27, (%rbx)
jbe 0x32c26
cmpq 0x2150(%r14), %r15
je 0x32c3b
addl $-0x20, %eax
cmpl $0x13, %eax
ja 0x32df3
leaq 0xa0a5d(%rip), %rcx     # 0xd3654
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, 0x20(%r15)
cmpq 0x120(%r14), %rbx
jne 0x32df3
jmp 0x32dee
leaq 0xb066a(%rip), %rsi     # 0xe3287
leaq 0xb066f(%rip), %r8      # 0xe3293
jmp 0x32c49
leaq 0xb065a(%rip), %rsi     # 0xe3287
leaq 0xb06d2(%rip), %r8      # 0xe3306
pushq $0x2
jmp 0x32cde
leaq 0xb0645(%rip), %rsi     # 0xe3287
leaq 0xb06cf(%rip), %r8      # 0xe3318
pushq $0x1
popq %rdx
movq %r14, %rdi
movq %r15, %rcx
jmp 0x32ce5
movq %r14, %rdi
movq %r15, %rsi
callq 0xb00b
movq %rax, %r12
movq 0x8(%rbx), %rbx
jmp 0x32cc0
movq 0x14a0(%r14), %rax
movq 0x10(%rax), %rax
cmpq 0x10(%rax), %r15
je 0x32d4e
movq 0x8(%r15), %rax
movq %rbx, 0x30(%rax)
movzbl (%rbx), %eax
leaq 0xeef4e(%rip), %rcx     # 0x121be0
cmpb $0x0, (%rax,%rcx)
jne 0x32ca9
leaq 0xe86d1(%rip), %rcx     # 0x11b370
cmpb $0x1, (%rax,%rcx)
jne 0x32df3
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x7b6cf
jmp 0x32df3
movq 0x10(%r15), %r12
cmpb $0x27, (%rbx)
ja 0x32cf3
cmpq 0x120(%r14), %rbx
je 0x32cf3
leaq 0xb05b2(%rip), %rsi     # 0xe3287
leaq 0xb05f9(%rip), %r8      # 0xe32d5
pushq $0x3
popq %rdx
movq %r14, %rdi
movq %rbx, %rcx
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0xc2b0
cmpq 0x14a0(%r14), %r15
je 0x32d4e
cmpb $0x20, (%r12)
jne 0x32db1
cmpq 0x10(%r15), %r12
je 0x32dd3
movq %r12, %rdi
movq %rbx, %rsi
callq 0x32b2e
cmpq 0x120(%r14), %rbx
je 0x32df3
orb $0x4, 0x2(%r12)
pushq $0x3
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x32378
testb %al, %al
je 0x32dee
orb $0x1, 0x6(%rbx)
jmp 0x32dee
movq 0x820(%r14), %rax
movslq 0x7dc(%r14), %rcx
movq (%rax,%rcx,8), %rax
incl %ecx
andl $0x7, %ecx
movl %ecx, 0x7dc(%r14)
leaq 0xb0573(%rip), %rcx     # 0xe32e6
movq %rcx, 0x10(%rax)
movq $0x1f, 0x8(%rax)
movq 0x6e0(%r14), %rcx
movq %rax, 0x8(%rcx)
movq 0x6e0(%r14), %rax
movq 0x10(%rax), %rax
movq %rbx, 0x8(%rax)
movq 0x6e0(%r14), %rsi
movq %r14, %rdi
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x972b
movq 0x120(%r14), %rbx
jmp 0x32df3
leaq 0xb04fb(%rip), %rsi     # 0xe32bc
leaq 0xb0507(%rip), %r8      # 0xe32cf
pushq $0x2
popq %rdx
movq %r14, %rdi
jmp 0x32ce5
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x328e3
jmp 0x32df3
movq %r15, %rdi
movq %rbx, %rsi
callq 0x32b2e
orb $0x4, 0x2(%r15)
movq %rbx, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq