"""Code generation for native classes and related wrappers."""

from __future__ import annotations

from collections.abc import Callable, Mapping

from mypy.nodes import ARG_STAR, ARG_STAR2
from mypyc.codegen.cstring import c_string_initializer
from mypyc.codegen.emit import (
    Emitter,
    HeaderDeclaration,
    ReturnHandler,
    native_function_doc_initializer,
)
from mypyc.codegen.emitfunc import native_function_header
from mypyc.codegen.emitwrapper import (
    generate_bin_op_wrapper,
    generate_bool_wrapper,
    generate_contains_wrapper,
    generate_dunder_wrapper,
    generate_get_wrapper,
    generate_hash_wrapper,
    generate_ipow_wrapper,
    generate_len_wrapper,
    generate_richcompare_wrapper,
    generate_set_del_item_wrapper,
)
from mypyc.common import (
    BITMAP_BITS,
    BITMAP_TYPE,
    CPYFUNCTION_NAME,
    IS_FREE_THREADED,
    MYPYC_DEFAULTS_SETUP,
    NATIVE_PREFIX,
    PREFIX,
    REG_PREFIX,
    short_id_from_name,
)
from mypyc.ir.class_ir import ClassIR, VTableEntries
from mypyc.ir.func_ir import (
    FUNC_CLASSMETHOD,
    FUNC_STATICMETHOD,
    FuncDecl,
    FuncIR,
    get_text_signature,
)
from mypyc.ir.rtypes import RTuple, RType, is_simple_refcounted_pointer, object_rprimitive
from mypyc.namegen import NameGenerator
from mypyc.sametype import is_same_type


def native_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    return f"{NATIVE_PREFIX}{fn.cname(emitter.names)}"


def dunder_attr_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    wrapper_fn = cl.get_method(fn.name + "__wrapper")
    assert wrapper_fn
    return f"{NATIVE_PREFIX}{wrapper_fn.cname(emitter.names)}"


# We maintain a table from dunder function names to struct slots they
# correspond to and functions that generate a wrapper (if necessary)
# and return the function name to stick in the slot.
# TODO: Add remaining dunder methods
SlotGenerator = Callable[[ClassIR, FuncIR, Emitter], str]
SlotTable = Mapping[str, tuple[str, SlotGenerator]]

SLOT_DEFS: SlotTable = {
    "__init__": ("tp_init", lambda c, t, e: generate_init_for_class(c, t, e)),
    "__call__": ("tp_call", lambda c, t, e: generate_call_wrapper(c, t, e)),
    "__str__": ("tp_str", native_slot),
    "__repr__": ("tp_repr", native_slot),
    "__next__": ("tp_iternext", native_slot),
    "__iter__": ("tp_iter", native_slot),
    "__hash__": ("tp_hash", generate_hash_wrapper),
    "__get__": ("tp_descr_get", generate_get_wrapper),
    "__getattr__": ("tp_getattro", dunder_attr_slot),
    "__setattr__": ("tp_setattro", dunder_attr_slot),
}

AS_MAPPING_SLOT_DEFS: SlotTable = {
    "__getitem__": ("mp_subscript", generate_dunder_wrapper),
    "__setitem__": ("mp_ass_subscript", generate_set_del_item_wrapper),
    "__delitem__": ("mp_ass_subscript", generate_set_del_item_wrapper),
    "__len__": ("mp_length", generate_len_wrapper),
}

AS_SEQUENCE_SLOT_DEFS: SlotTable = {"__contains__": ("sq_contains", generate_contains_wrapper)}

AS_NUMBER_SLOT_DEFS: SlotTable = {
    # Unary operations.
    "__bool__": ("nb_bool", generate_bool_wrapper),
    "__int__": ("nb_int", generate_dunder_wrapper),
    "__float__": ("nb_float", generate_dunder_wrapper),
    "__neg__": ("nb_negative", generate_dunder_wrapper),
    "__pos__": ("nb_positive", generate_dunder_wrapper),
    "__abs__": ("nb_absolute", generate_dunder_wrapper),
    "__invert__": ("nb_invert", generate_dunder_wrapper),
    # Binary operations.
    "__add__": ("nb_add", generate_bin_op_wrapper),
    "__radd__": ("nb_add", generate_bin_op_wrapper),
    "__sub__": ("nb_subtract", generate_bin_op_wrapper),
    "__rsub__": ("nb_subtract", generate_bin_op_wrapper),
    "__mul__": ("nb_multiply", generate_bin_op_wrapper),
    "__rmul__": ("nb_multiply", generate_bin_op_wrapper),
    "__mod__": ("nb_remainder", generate_bin_op_wrapper),
    "__rmod__": ("nb_remainder", generate_bin_op_wrapper),
    "__truediv__": ("nb_true_divide", generate_bin_op_wrapper),
    "__rtruediv__": ("nb_true_divide", generate_bin_op_wrapper),
    "__floordiv__": ("nb_floor_divide", generate_bin_op_wrapper),
    "__rfloordiv__": ("nb_floor_divide", generate_bin_op_wrapper),
    "__divmod__": ("nb_divmod", generate_bin_op_wrapper),
    "__rdivmod__": ("nb_divmod", generate_bin_op_wrapper),
    "__lshift__": ("nb_lshift", generate_bin_op_wrapper),
    "__rlshift__": ("nb_lshift", generate_bin_op_wrapper),
    "__rshift__": ("nb_rshift", generate_bin_op_wrapper),
    "__rrshift__": ("nb_rshift", generate_bin_op_wrapper),
    "__and__": ("nb_and", generate_bin_op_wrapper),
    "__rand__": ("nb_and", generate_bin_op_wrapper),
    "__or__": ("nb_or", generate_bin_op_wrapper),
    "__ror__": ("nb_or", generate_bin_op_wrapper),
    "__xor__": ("nb_xor", generate_bin_op_wrapper),
    "__rxor__": ("nb_xor", generate_bin_op_wrapper),
    "__matmul__": ("nb_matrix_multiply", generate_bin_op_wrapper),
    "__rmatmul__": ("nb_matrix_multiply", generate_bin_op_wrapper),
    # In-place binary operations.
    "__iadd__": ("nb_inplace_add", generate_dunder_wrapper),
    "__isub__": ("nb_inplace_subtract", generate_dunder_wrapper),
    "__imul__": ("nb_inplace_multiply", generate_dunder_wrapper),
    "__imod__": ("nb_inplace_remainder", generate_dunder_wrapper),
    "__itruediv__": ("nb_inplace_true_divide", generate_dunder_wrapper),
    "__ifloordiv__": ("nb_inplace_floor_divide", generate_dunder_wrapper),
    "__ilshift__": ("nb_inplace_lshift", generate_dunder_wrapper),
    "__irshift__": ("nb_inplace_rshift", generate_dunder_wrapper),
    "__iand__": ("nb_inplace_and", generate_dunder_wrapper),
    "__ior__": ("nb_inplace_or", generate_dunder_wrapper),
    "__ixor__": ("nb_inplace_xor", generate_dunder_wrapper),
    "__imatmul__": ("nb_inplace_matrix_multiply", generate_dunder_wrapper),
    # Ternary operations. (yes, really)
    # These are special cased in generate_bin_op_wrapper().
    "__pow__": ("nb_power", generate_bin_op_wrapper),
    "__rpow__": ("nb_power", generate_bin_op_wrapper),
    "__ipow__": ("nb_inplace_power", generate_ipow_wrapper),
}

AS_ASYNC_SLOT_DEFS: SlotTable = {
    "__await__": ("am_await", native_slot),
    "__aiter__": ("am_aiter", native_slot),
    "__anext__": ("am_anext", native_slot),
}

SIDE_TABLES = [
    ("as_mapping", "PyMappingMethods", AS_MAPPING_SLOT_DEFS),
    ("as_sequence", "PySequenceMethods", AS_SEQUENCE_SLOT_DEFS),
    ("as_number", "PyNumberMethods", AS_NUMBER_SLOT_DEFS),
    ("as_async", "PyAsyncMethods", AS_ASYNC_SLOT_DEFS),
]

# Slots that need to always be filled in because they don't get
# inherited right.
ALWAYS_FILL = {"__hash__"}


def generate_call_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    return "PyVectorcall_Call"


def slot_key(attr: str) -> str:
    """Map dunder method name to sort key.

    Sort reverse operator methods and __delitem__ after others ('x' > '_').
    """
    if (attr.startswith("__r") and attr != "__rshift__") or attr == "__delitem__":
        return "x" + attr
    return attr


def generate_slots(cl: ClassIR, table: SlotTable, emitter: Emitter) -> dict[str, str]:
    fields: dict[str, str] = {}
    generated: dict[str, str] = {}
    # Sort for determinism on Python 3.5
    for name, (slot, generator) in sorted(table.items(), key=lambda x: slot_key(x[0])):
        method_cls = cl.get_method_and_class(name)
        if method_cls and (method_cls[1] == cl or name in ALWAYS_FILL):
            if slot in generated:
                # Reuse previously generated wrapper.
                fields[slot] = generated[slot]
            else:
                # Generate new wrapper.
                name = generator(cl, method_cls[0], emitter)
                fields[slot] = name
                generated[slot] = name

    return fields


def generate_class_type_decl(
    cl: ClassIR, c_emitter: Emitter, external_emitter: Emitter, emitter: Emitter
) -> None:
    context = c_emitter.context
    name = emitter.type_struct_name(cl)
    context.declarations[name] = HeaderDeclaration(
        f"PyTypeObject *{emitter.type_struct_name(cl)};", needs_export=True
    )

    # If this is a non-extension class, all we want is the type object decl.
    if not cl.is_ext_class:
        return

    generate_object_struct(cl, external_emitter)
    generate_full = not cl.is_trait and not cl.builtin_base
    if generate_full:
        context.declarations[emitter.native_function_name(cl.ctor)] = HeaderDeclaration(
            f"{native_function_header(cl.ctor, emitter)};", needs_export=True
        )


def generate_class_reuse(
    cl: ClassIR, c_emitter: Emitter, external_emitter: Emitter, emitter: Emitter
) -> None:
    """Generate a definition of a single-object per-class free "list".

    This speeds up object allocation and freeing when there are many short-lived
    objects.

    TODO: Generalize to support a free list with up to N objects.
    """
    assert cl.reuse_freed_instance
    context = c_emitter.context
    name = cl.name_prefix(c_emitter.names) + "_free_instance"
    struct_name = cl.struct_name(c_emitter.names)
    # Not exported: the free-instance slot is only read/written by the class's
    # own setup/dealloc code, which lives in the defining group. Exporting it
    # also trips a C diagnostic under `Py_GIL_DISABLED`, where `CPyThreadLocal`
    # expands to `__thread` and can't legally appear inside the exports struct.
    context.declarations[name] = HeaderDeclaration(f"CPyThreadLocal {struct_name} *{name};")


def generate_class(cl: ClassIR, module: str, emitter: Emitter) -> None:
    """Generate C code for a class.

    This is the main entry point to the module.
    """
    name = cl.name
    name_prefix = cl.name_prefix(emitter.names)

    setup_name = emitter.native_function_name(cl.setup)
    new_name = f"{name_prefix}_new"
    finalize_name = f"{name_prefix}_finalize"
    members_name = f"{name_prefix}_members"
    getseters_name = f"{name_prefix}_getseters"
    vtable_name = f"{name_prefix}_vtable"
    traverse_name = f"{name_prefix}_traverse"
    clear_name = emitter.native_function_name(cl.clear)
    dealloc_name = f"{name_prefix}_dealloc"
    methods_name = f"{name_prefix}_methods"
    vtable_setup_name = f"{name_prefix}_trait_vtable_setup"
    coroutine_setup_name = f"{name_prefix}_coroutine_setup"

    fields: dict[str, str] = {"tp_name": f'"{name}"'}

    generate_full = not cl.is_trait and not cl.builtin_base
    needs_getseters = cl.needs_getseters or not cl.is_generated or cl.has_dict

    if not cl.builtin_base:
        fields["tp_new"] = new_name

    managed_dict = has_managed_dict(cl, emitter)
    # On Python <3.12, subclasses of builtin types (Exception, dict) get an extra __dict__
    # slot that the inherited base dealloc knows nothing about. Emit our own so it gets freed.
    needs_builtin_dict_cleanup = (
        cl.builtin_base is not None
        and cl.has_dict
        and not managed_dict
        and emitter.capi_version < (3, 12)
    )
    generate_dealloc_slots = generate_full or managed_dict or needs_builtin_dict_cleanup
    if generate_dealloc_slots:
        fields["tp_dealloc"] = f"(destructor){name_prefix}_dealloc"
        if not cl.is_acyclic:
            fields["tp_traverse"] = f"(traverseproc){name_prefix}_traverse"
            fields["tp_clear"] = f"(inquiry){clear_name}"
    # Populate .tp_finalize and generate a finalize method only if __del__ is defined for this class.
    del_method = next((e.method for e in cl.vtable_entries if e.name == "__del__"), None)
    if del_method:
        fields["tp_finalize"] = f"(destructor){finalize_name}"
    if needs_getseters:
        fields["tp_getset"] = getseters_name
    fields["tp_methods"] = methods_name

    def emit_line() -> None:
        emitter.emit_line()

    emit_line()

    # If the class has a method to initialize default attribute
    # values, we need to call it during initialization.
    defaults_fn = cl.get_method(MYPYC_DEFAULTS_SETUP)

    # If there is a __init__ method, we'll use it in the native constructor.
    init_fn = cl.get_method("__init__")

    # Fill out slots in the type object from dunder methods.
    fields.update(generate_slots(cl, SLOT_DEFS, emitter))

    # Fill out dunder methods that live in tables hanging off the side.
    for table_name, type, slot_defs in SIDE_TABLES:
        slots = generate_slots(cl, slot_defs, emitter)
        if slots:
            table_struct_name = generate_side_table_for_class(cl, table_name, type, slots, emitter)
            fields[f"tp_{table_name}"] = f"&{table_struct_name}"

    richcompare_name = generate_richcompare_wrapper(cl, emitter)
    if richcompare_name:
        fields["tp_richcompare"] = richcompare_name

    # If the class inherits from python, make space for a __dict__
    struct_name = cl.struct_name(emitter.names)
    if cl.builtin_base:
        base_size = f"sizeof({cl.builtin_base})"
    elif cl.is_trait:
        base_size = "sizeof(PyObject)"
    else:
        base_size = f"sizeof({struct_name})"
    # Since our types aren't allocated using type() we need to
    # populate these fields ourselves if we want them to have correct
    # values. PyType_Ready will inherit the offsets from tp_base but
    # that isn't what we want.

    # XXX: there is no reason for the __weakref__ stuff to be mixed up with __dict__
    if cl.has_dict and not has_managed_dict(cl, emitter):
        # __dict__ lives right after the struct and __weakref__ lives right after that
        # TODO: They should get members in the struct instead of doing this nonsense.
        weak_offset = f"{base_size} + sizeof(PyObject *)"
        emitter.emit_lines(
            f"PyMemberDef {members_name}[] = {{",
            f'{{"__dict__", T_OBJECT_EX, {base_size}, 0, NULL}},',
            f'{{"__weakref__", T_OBJECT_EX, {weak_offset}, 0, NULL}},',
            "{0}",
            "};",
        )

        fields["tp_members"] = members_name
        fields["tp_basicsize"] = f"{base_size} + 2*sizeof(PyObject *)"
        if emitter.capi_version < (3, 12):
            fields["tp_dictoffset"] = base_size
            fields["tp_weaklistoffset"] = weak_offset
    else:
        fields["tp_basicsize"] = base_size

    if generate_dealloc_slots:
        if not cl.is_acyclic:
            generate_traverse_for_class(cl, traverse_name, emitter)
            emit_line()
        generate_clear_for_class(cl, cl.clear, emitter)
        emit_line()
        generate_clear_for_class(
            cl, cl.clear_on_completion, emitter, skip_attrs=cl.attrs_to_keep_alive_on_completion
        )
        emit_line()
        generate_dealloc_for_class(cl, dealloc_name, clear_name, bool(del_method), emitter)
        emit_line()
    if generate_full:
        assert cl.setup is not None
        emitter.emit_line(native_function_header(cl.setup, emitter) + ";")
        assert cl.ctor is not None
        emitter.emit_line(native_function_header(cl.ctor, emitter) + ";")

        emit_line()
        init_fn = cl.get_method("__init__")
        generate_new_for_class(cl, new_name, vtable_name, setup_name, init_fn, emitter)
        emit_line()

        if cl.allow_interpreted_subclasses:
            shadow_vtable_name: str | None = generate_vtables(
                cl, vtable_setup_name + "_shadow", vtable_name + "_shadow", emitter, shadow=True
            )
            emit_line()
        else:
            shadow_vtable_name = None
        vtable_name = generate_vtables(cl, vtable_setup_name, vtable_name, emitter, shadow=False)
        emit_line()
        generate_coroutine_setup(cl, coroutine_setup_name, module, emitter)
        emit_line()
    if del_method:
        generate_finalize_for_class(del_method, finalize_name, emitter)
        emit_line()
    if needs_getseters:
        generate_getseter_declarations(cl, emitter)
        emit_line()
        generate_getseters_table(cl, getseters_name, emitter)
        emit_line()

    if cl.is_trait:
        generate_new_for_trait(cl, new_name, emitter)

    generate_methods_table(cl, methods_name, setup_name if generate_full else None, emitter)
    emit_line()

    flags = ["Py_TPFLAGS_DEFAULT", "Py_TPFLAGS_HEAPTYPE", "Py_TPFLAGS_BASETYPE"]
    if generate_dealloc_slots and not cl.is_acyclic:
        # Set explicitly: PyType_Ready won't inherit HAVE_GC once we override tp_dealloc/traverse.
        flags.append("Py_TPFLAGS_HAVE_GC")
    if cl.has_method("__call__"):
        fields["tp_vectorcall_offset"] = "offsetof({}, vectorcall)".format(
            cl.struct_name(emitter.names)
        )
        flags.append("_Py_TPFLAGS_HAVE_VECTORCALL")
        if not fields.get("tp_vectorcall"):
            # This is just a placeholder to please CPython. It will be
            # overridden during setup.
            fields["tp_call"] = "PyVectorcall_Call"
    if managed_dict:
        flags.append("Py_TPFLAGS_MANAGED_DICT")
    fields["tp_flags"] = " | ".join(flags)

    fields["tp_doc"] = f"PyDoc_STR({native_class_doc_initializer(cl)})"

    emitter.emit_line(f"static PyTypeObject {emitter.type_struct_name(cl)}_template_ = {{")
    emitter.emit_line("PyVarObject_HEAD_INIT(NULL, 0)")
    for field, value in fields.items():
        emitter.emit_line(f".{field} = {value},")
    emitter.emit_line("};")
    emitter.emit_line(
        "static PyTypeObject *{t}_template = &{t}_template_;".format(
            t=emitter.type_struct_name(cl)
        )
    )

    if cl.coroutine_name:
        cpyfunction = emitter.static_name(cl.name + "_cpyfunction", module)
        emitter.emit_line(f"static PyObject *{cpyfunction} = NULL;")

    emitter.emit_line()
    if generate_full:
        generate_setup_for_class(cl, defaults_fn, vtable_name, shadow_vtable_name, emitter)
        emitter.emit_line()
        generate_constructor_for_class(cl, cl.ctor, init_fn, setup_name, vtable_name, emitter)
        emitter.emit_line()
    if needs_getseters:
        generate_getseters(cl, emitter)


def getter_name(cl: ClassIR, attribute: str, names: NameGenerator) -> str:
    return names.private_name(cl.module_name, f"{cl.name}_get_{attribute}")


def setter_name(cl: ClassIR, attribute: str, names: NameGenerator) -> str:
    return names.private_name(cl.module_name, f"{cl.name}_set_{attribute}")


def generate_object_struct(cl: ClassIR, emitter: Emitter) -> None:
    seen_attrs: set[str] = set()
    lines: list[str] = []
    lines += ["typedef struct {", "PyObject_HEAD", "CPyVTableItem *vtable;"]
    if cl.has_method("__call__"):
        lines.append("vectorcallfunc vectorcall;")
    bitmap_attrs = []
    for base in reversed(cl.base_mro):
        if not base.is_trait:
            if base.bitmap_attrs:
                # Do we need another attribute bitmap field?
                if emitter.bitmap_field(len(base.bitmap_attrs) - 1) not in bitmap_attrs:
                    for i in range(0, len(base.bitmap_attrs), BITMAP_BITS):
                        attr = emitter.bitmap_field(i)
                        if attr not in bitmap_attrs:
                            lines.append(f"{BITMAP_TYPE} {attr};")
                            bitmap_attrs.append(attr)
            for attr, rtype in base.attributes.items():
                # Generated class may redefine certain attributes with different
                # types in subclasses (this would be unsafe for user-defined classes).
                if attr not in seen_attrs:
                    lines.append(f"{emitter.ctype_spaced(rtype)}{emitter.attr(attr)};")
                    seen_attrs.add(attr)

                    if isinstance(rtype, RTuple):
                        emitter.declare_tuple_struct(rtype)

    lines.append(f"}} {cl.struct_name(emitter.names)};")
    lines.append("")
    emitter.context.declarations[cl.struct_name(emitter.names)] = HeaderDeclaration(
        lines, is_type=True
    )


def generate_vtables(
    base: ClassIR, vtable_setup_name: str, vtable_name: str, emitter: Emitter, shadow: bool
) -> str:
    """Emit the vtables and vtable setup functions for a class.

    This includes both the primary vtable and any trait implementation vtables.
    The trait vtables go before the main vtable, and have the following layout:
        {
            CPyType_T1,         // pointer to type object
            C_T1_trait_vtable,  // pointer to array of method pointers
            C_T1_offset_table,  // pointer to array of attribute offsets
            CPyType_T2,
            C_T2_trait_vtable,
            C_T2_offset_table,
            ...
        }
    The method implementations are calculated at the end of IR pass, attribute
    offsets are {offsetof(native__C, _x1), offsetof(native__C, _y1), ...}.

    To account for both dynamic loading and dynamic class creation,
    vtables are populated dynamically at class creation time, so we
    emit empty array definitions to store the vtables and a function to
    populate them.

    If shadow is True, generate "shadow vtables" that point to the
    shadow glue methods (which should dispatch via the Python C-API).

    Returns the expression to use to refer to the vtable, which might be
    different than the name, if there are trait vtables.
    """

    def trait_vtable_name(trait: ClassIR) -> str:
        return "{}_{}_trait_vtable{}".format(
            base.name_prefix(emitter.names),
            trait.name_prefix(emitter.names),
            "_shadow" if shadow else "",
        )

    def trait_offset_table_name(trait: ClassIR) -> str:
        return "{}_{}_offset_table".format(
            base.name_prefix(emitter.names), trait.name_prefix(emitter.names)
        )

    # Emit array definitions with enough space for all the entries
    emitter.emit_line(
        "static CPyVTableItem {}[{}];".format(
            vtable_name, max(1, len(base.vtable_entries) + 3 * len(base.trait_vtables))
        )
    )

    for trait, vtable in base.trait_vtables.items():
        # Trait methods entry (vtable index -> method implementation).
        emitter.emit_line(
            f"static CPyVTableItem {trait_vtable_name(trait)}[{max(1, len(vtable))}];"
        )
        # Trait attributes entry (attribute number in trait -> offset in actual struct).
        emitter.emit_line(
            "static size_t {}[{}];".format(
                trait_offset_table_name(trait), max(1, len(trait.attributes))
            )
        )

    # Emit vtable setup function
    emitter.emit_line("static bool")
    emitter.emit_line(f"{NATIVE_PREFIX}{vtable_setup_name}(void)")
    emitter.emit_line("{")

    if base.allow_interpreted_subclasses and not shadow:
        emitter.emit_line(f"{NATIVE_PREFIX}{vtable_setup_name}_shadow();")

    subtables = []
    for trait, vtable in base.trait_vtables.items():
        name = trait_vtable_name(trait)
        offset_name = trait_offset_table_name(trait)
        generate_vtable(vtable, name, emitter, [], shadow)
        generate_offset_table(offset_name, emitter, trait, base)
        subtables.append((trait, name, offset_name))

    generate_vtable(base.vtable_entries, vtable_name, emitter, subtables, shadow)

    emitter.emit_line("return 1;")
    emitter.emit_line("}")

    return vtable_name if not subtables else f"{vtable_name} + {len(subtables) * 3}"


def generate_offset_table(
    trait_offset_table_name: str, emitter: Emitter, trait: ClassIR, cl: ClassIR
) -> None:
    """Generate attribute offset row of a trait vtable."""
    emitter.emit_line(f"size_t {trait_offset_table_name}_scratch[] = {{")
    for attr in trait.attributes:
        emitter.emit_line(f"offsetof({cl.struct_name(emitter.names)}, {emitter.attr(attr)}),")
    if not trait.attributes:
        # This is for msvc.
        emitter.emit_line("0")
    emitter.emit_line("};")
    emitter.emit_line(
        "memcpy({name}, {name}_scratch, sizeof({name}));".format(name=trait_offset_table_name)
    )


def generate_vtable(
    entries: VTableEntries,
    vtable_name: str,
    emitter: Emitter,
    subtables: list[tuple[ClassIR, str, str]],
    shadow: bool,
) -> None:
    emitter.emit_line(f"CPyVTableItem {vtable_name}_scratch[] = {{")
    if subtables:
        emitter.emit_line("/* Array of trait vtables */")
        for trait, table, offset_table in subtables:
            emitter.emit_line(
                "(CPyVTableItem){}, (CPyVTableItem){}, (CPyVTableItem){},".format(
                    emitter.type_struct_name(trait), table, offset_table
                )
            )
        emitter.emit_line("/* Start of real vtable */")

    for entry in entries:
        method = entry.shadow_method if shadow and entry.shadow_method else entry.method
        emitter.emit_line(
            "(CPyVTableItem){}{}{},".format(
                emitter.get_group_prefix(method.decl), NATIVE_PREFIX, method.cname(emitter.names)
            )
        )

    # msvc doesn't allow empty arrays; maybe allowing them at all is an extension?
    if not entries:
        emitter.emit_line("NULL")
    emitter.emit_line("};")
    emitter.emit_line("memcpy({name}, {name}_scratch, sizeof({name}));".format(name=vtable_name))


def generate_setup_for_class(
    cl: ClassIR,
    defaults_fn: FuncIR | None,
    vtable_name: str,
    shadow_vtable_name: str | None,
    emitter: Emitter,
) -> None:
    """Generate a native function that allocates an instance of a class."""
    emitter.emit_line(native_function_header(cl.setup, emitter))
    emitter.emit_line("{")
    type_arg_name = REG_PREFIX + cl.setup.sig.args[0].name
    emitter.emit_line(f"PyTypeObject *type = (PyTypeObject*){type_arg_name};")
    struct_name = cl.struct_name(emitter.names)
    emitter.emit_line(f"{struct_name} *self;")

    prefix = cl.name_prefix(emitter.names)
    if cl.reuse_freed_instance:
        # Attempt to use a per-type free list first (a free "list" with up to one object only).
        emitter.emit_line(f"if ({prefix}_free_instance != NULL) {{")
        emitter.emit_line(f"self = {prefix}_free_instance;")
        emitter.emit_line(f"{prefix}_free_instance = NULL;")
        emitter.emit_line("Py_SET_REFCNT(self, 1);")
        if not cl.is_acyclic:
            emitter.emit_line("PyObject_GC_Track(self);")
        if defaults_fn is not None:
            emit_attr_defaults_func_call(defaults_fn, "self", emitter)
        emitter.emit_line("return (PyObject *)self;")
        emitter.emit_line("}")

    emitter.emit_line(f"self = ({cl.struct_name(emitter.names)} *)type->tp_alloc(type, 0);")
    emitter.emit_line("if (self == NULL)")
    emitter.emit_line("    return NULL;")

    if shadow_vtable_name:
        emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
        emitter.emit_line(f"self->vtable = {shadow_vtable_name};")
        emitter.emit_line("} else {")
        emitter.emit_line(f"self->vtable = {vtable_name};")
        emitter.emit_line("}")
    else:
        emitter.emit_line(f"self->vtable = {vtable_name};")

    emit_clear_bitmaps(cl, emitter)

    if cl.has_method("__call__"):
        name = cl.method_decl("__call__").cname(emitter.names)
        emitter.emit_line(f"self->vectorcall = {PREFIX}{name};")

    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            value = emitter.c_undefined_value(rtype)

            # We don't need to set this field to NULL since tp_alloc() already
            # zero-initializes `self`.
            if value != "NULL":
                emitter.set_undefined_value(f"self->{emitter.attr(attr)}", rtype)

    # Initialize attributes to default values, if necessary
    if defaults_fn is not None:
        emit_attr_defaults_func_call(defaults_fn, "self", emitter)

    emitter.emit_line("return (PyObject *)self;")
    emitter.emit_line("}")


def emit_clear_bitmaps(cl: ClassIR, emitter: Emitter) -> None:
    """Emit C code to clear bitmaps that track if attributes have an assigned value."""
    for i in range(0, len(cl.bitmap_attrs), BITMAP_BITS):
        field = emitter.bitmap_field(i)
        emitter.emit_line(f"self->{field} = 0;")


def emit_attr_defaults_func_call(defaults_fn: FuncIR, self_name: str, emitter: Emitter) -> None:
    """Emit C code to initialize attribute defaults by calling defaults_fn.

    The code returns NULL on a raised exception.
    """
    emitter.emit_lines(
        "if ({}((PyObject *){}) == 0) {{".format(
            emitter.native_function_call(defaults_fn.decl), self_name
        ),
        "Py_DECREF(self);",
        "return NULL;",
        "}",
    )


def emit_setup_or_dunder_new_call(
    cl: ClassIR,
    setup_name: str,
    type_arg: str,
    native_prefix: bool,
    new_args: str,
    emitter: Emitter,
) -> None:
    def emit_null_check() -> None:
        emitter.emit_line("if (self == NULL)")
        emitter.emit_line("    return NULL;")

    new_fn = cl.get_method("__new__")
    if not new_fn:
        emitter.emit_line(f"PyObject *self = {setup_name}({type_arg});")
        emit_null_check()
        return
    call = (
        emitter.native_function_call(new_fn.decl)
        if native_prefix
        else emitter.wrapper_function_call(new_fn.decl)
    )
    all_args = type_arg
    if new_args != "":
        all_args += ", " + new_args
    emitter.emit_line(f"PyObject *self = {call}({all_args});")
    emit_null_check()

    # skip __init__ if __new__ returns some other type
    emitter.emit_line(f"if (Py_TYPE(self) != {emitter.type_struct_name(cl)})")
    emitter.emit_line("    return self;")


def generate_constructor_for_class(
    cl: ClassIR,
    fn: FuncDecl,
    init_fn: FuncIR | None,
    setup_name: str,
    vtable_name: str,
    emitter: Emitter,
) -> None:
    """Generate a native function that allocates and initializes an instance of a class."""
    emitter.emit_line(f"{native_function_header(fn, emitter)}")
    emitter.emit_line("{")

    fn_args = [REG_PREFIX + arg.name for arg in fn.sig.args]
    type_arg = "(PyObject *)" + emitter.type_struct_name(cl)
    new_args = ", ".join(fn_args)

    use_wrapper = (
        cl.has_method("__new__")
        and len(fn.sig.args) == 2
        and fn.sig.args[0].kind == ARG_STAR
        and fn.sig.args[1].kind == ARG_STAR2
    )
    emit_setup_or_dunder_new_call(cl, setup_name, type_arg, not use_wrapper, new_args, emitter)

    args = ", ".join(["self"] + fn_args)
    if init_fn is not None:
        call = (
            emitter.wrapper_function_call(init_fn.decl)
            if use_wrapper
            else emitter.native_function_call(init_fn.decl)
        )
        cast = "!= NULL ? 0 : -1" if use_wrapper else ""
        emitter.emit_line(f"char res = {call}({args}){cast};")
        emitter.emit_line("if (res == 2) {")
        emitter.emit_line("Py_DECREF(self);")
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")

    # If there is a nontrivial ctor that we didn't define, invoke it via tp_init
    elif len(fn.sig.args) > 1:
        emitter.emit_line(f"int res = {emitter.type_struct_name(cl)}->tp_init({args});")

        emitter.emit_line("if (res < 0) {")
        emitter.emit_line("Py_DECREF(self);")
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")

    emitter.emit_line("return self;")
    emitter.emit_line("}")


def generate_init_for_class(cl: ClassIR, init_fn: FuncIR, emitter: Emitter) -> str:
    """Generate an init function suitable for use as tp_init.

    tp_init needs to be a function that returns an int, and our
    __init__ methods return a PyObject. Translate NULL to -1,
    everything else to 0.
    """
    func_name = f"{cl.name_prefix(emitter.names)}_init"

    emitter.emit_line("static int")
    emitter.emit_line(f"{func_name}(PyObject *self, PyObject *args, PyObject *kwds)")
    emitter.emit_line("{")
    if cl.allow_interpreted_subclasses or cl.builtin_base or cl.has_method("__new__"):
        emitter.emit_line(
            f"return {emitter.wrapper_function_call(init_fn.decl)}"
            "(self, args, kwds) != NULL ? 0 : -1;"
        )
    else:
        emitter.emit_line("return 0;")
    emitter.emit_line("}")

    return func_name


def generate_new_for_class(
    cl: ClassIR,
    func_name: str,
    vtable_name: str,
    setup_name: str,
    init_fn: FuncIR | None,
    emitter: Emitter,
) -> None:
    emitter.emit_line("static PyObject *")
    emitter.emit_line(f"{func_name}(PyTypeObject *type, PyObject *args, PyObject *kwds)")
    emitter.emit_line("{")
    # TODO: Check and unbox arguments
    if not cl.allow_interpreted_subclasses:
        emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
        emitter.emit_line(
            'PyErr_SetString(PyExc_TypeError, "interpreted classes cannot inherit from compiled");'
        )
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")

    type_arg = "(PyObject*)type"
    new_args = "args, kwds"
    emit_setup_or_dunder_new_call(cl, setup_name, type_arg, False, new_args, emitter)
    if (
        not init_fn
        or cl.allow_interpreted_subclasses
        or cl.builtin_base
        or cl.is_serializable()
        or cl.has_method("__new__")
    ):
        # Match Python semantics -- __new__ doesn't call __init__.
        emitter.emit_line("return self;")
    else:
        # __new__ of a native class implicitly calls __init__ so that we
        # can enforce that instances are always properly initialized. This
        # is needed to support always defined attributes.
        emitter.emit_line(
            f"PyObject *ret = {emitter.wrapper_function_call(init_fn.decl)}(self, args, kwds);"
        )
        emitter.emit_lines("if (ret == NULL) {", "    Py_DECREF(self);", "    return NULL;", "}")
        emitter.emit_line("Py_DECREF(ret);")
        emitter.emit_line("return self;")
    emitter.emit_line("}")


def generate_new_for_trait(cl: ClassIR, func_name: str, emitter: Emitter) -> None:
    emitter.emit_line("static PyObject *")
    emitter.emit_line(f"{func_name}(PyTypeObject *type, PyObject *args, PyObject *kwds)")
    emitter.emit_line("{")
    emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
    emitter.emit_line(
        "PyErr_SetString(PyExc_TypeError, "
        '"interpreted classes cannot inherit from compiled traits");'
    )
    emitter.emit_line("} else {")
    emitter.emit_line('PyErr_SetString(PyExc_TypeError, "traits may not be directly created");')
    emitter.emit_line("}")
    emitter.emit_line("return NULL;")
    emitter.emit_line("}")


def generate_traverse_for_class(cl: ClassIR, func_name: str, emitter: Emitter) -> None:
    """Emit function that performs cycle GC traversal of an instance."""
    emitter.emit_line("static int")
    emitter.emit_line(
        f"{func_name}({cl.struct_name(emitter.names)} *self, visitproc visit, void *arg)"
    )
    emitter.emit_line("{")
    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            emitter.emit_gc_visit(f"self->{emitter.attr(attr)}", rtype)
    base_args = "(PyObject *)self, visit, arg"
    emitter.emit_line("int rv = 0;")
    if cl.builtin_base:
        emitter.emit_base_tp_function_call(cl, "tp_traverse", base_args, prefix="rv = ")
        emitter.emit_line("if (rv != 0) return rv;")
    if has_managed_dict(cl, emitter):
        emitter.emit_line(f"rv = PyObject_VisitManagedDict({base_args});")
        emitter.emit_line("if (rv != 0) return rv;")
    elif cl.has_dict:
        # __dict__ lives at tp_dictoffset (== base_size), __weakref__ right after it.
        base_size = f"sizeof({cl.builtin_base or cl.struct_name(emitter.names)})"
        emitter.emit_gc_visit(f"*((PyObject **)((char *)self + {base_size}))", object_rprimitive)
        emitter.emit_gc_visit(
            f"*((PyObject **)((char *)self + sizeof(PyObject *) + {base_size}))", object_rprimitive
        )
    emitter.emit_line("return rv;")
    emitter.emit_line("}")


def generate_clear_for_class(
    cl: ClassIR, func_decl: FuncDecl, emitter: Emitter, skip_attrs: set[str] | None = None
) -> None:
    if skip_attrs is None:
        skip_attrs = set()
    emitter.emit_line("static " + native_function_header(func_decl, emitter))
    emitter.emit_line("{")
    emitter.emit_line(
        f"{cl.struct_name(emitter.names)} *self = "
        f"({cl.struct_name(emitter.names)} *)cpy_r_self;"
    )
    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            if attr in skip_attrs:
                continue
            emitter.emit_gc_clear(f"self->{emitter.attr(attr)}", rtype)
    base_args = "(PyObject *)self"
    if cl.builtin_base:
        emitter.emit_base_tp_function_call(cl, "tp_clear", base_args)
    if has_managed_dict(cl, emitter):
        emitter.emit_line(f"PyObject_ClearManagedDict({base_args});")
    elif cl.has_dict:
        # __dict__ lives at tp_dictoffset (== base_size), __weakref__ right after it.
        base_size = f"sizeof({cl.builtin_base or cl.struct_name(emitter.names)})"
        emitter.emit_gc_clear(f"*((PyObject **)((char *)self + {base_size}))", object_rprimitive)
        emitter.emit_gc_clear(
            f"*((PyObject **)((char *)self + sizeof(PyObject *) + {base_size}))", object_rprimitive
        )
    emitter.emit_line("return 0;")
    emitter.emit_line("}")


def generate_dealloc_for_class(
    cl: ClassIR,
    dealloc_func_name: str,
    clear_func_name: str,
    has_tp_finalize: bool,
    emitter: Emitter,
) -> None:
    emitter.emit_line("static void")
    emitter.emit_line(f"{dealloc_func_name}({cl.struct_name(emitter.names)} *self)")
    emitter.emit_line("{")
    # Always run the finalizer dance for builtin_base subclasses: we're bypassing
    # subtype_dealloc, so an inherited tp_finalize (e.g. from an interpreted base's
    # __del__) would otherwise be skipped. Runtime-gate on tp_finalize so we no-op
    # when nothing in the MRO defines a finalizer.
    if has_tp_finalize or cl.builtin_base:
        if not has_tp_finalize:
            emitter.emit_line("if (Py_TYPE(self)->tp_finalize) {")
        emitter.emit_line("PyObject *type, *value, *traceback;")
        emitter.emit_line("PyErr_Fetch(&type, &value, &traceback);")
        emitter.emit_line("int res = PyObject_CallFinalizerFromDealloc((PyObject *)self);")
        # CPython interpreter uses PyErr_WriteUnraisable: https://docs.python.org/3/c-api/exceptions.html#c.PyErr_WriteUnraisable
        # However, the message is slightly different due to the way mypyc compiles classes.
        # CPython interpreter prints: Exception ignored in: <function F.__del__ at 0x100aed940>
        # mypyc prints: Exception ignored in: <slot wrapper '__del__' of 'F' objects>
        emitter.emit_line("if (PyErr_Occurred() != NULL) {")
        # Don't untrack instance if error occurred
        emitter.emit_line("PyErr_WriteUnraisable((PyObject *)self);")
        emitter.emit_line("res = -1;")
        emitter.emit_line("}")
        emitter.emit_line("PyErr_Restore(type, value, traceback);")
        emitter.emit_line("if (res < 0) {")
        emitter.emit_line("goto done;")
        emitter.emit_line("}")
        if not has_tp_finalize:
            emitter.emit_line("}")
    if not cl.is_acyclic:
        emitter.emit_line("PyObject_GC_UnTrack(self);")
    if cl.builtin_base:
        emitter.emit_line(f"{clear_func_name}((PyObject *)self);")
        # For native subclasses of builtins such as dict, the base deallocator
        # is responsible for tearing down base-owned storage and freeing memory.
        # Re-track self if base is GC-aware to match cpython's subtype_dealloc.
        base = f"{emitter.type_struct_name(cl)}->tp_base"
        base_arg = "(PyObject *)self"
        emitter.emit_line(f"if (PyType_IS_GC({base})) PyObject_GC_Track({base_arg});")
        emitter.emit_base_tp_function_call(cl, "tp_dealloc", base_arg)
        emitter.emit_line("done: ;")
        emitter.emit_line("}")
        return
    if cl.reuse_freed_instance:
        emit_reuse_dealloc(cl, emitter)
    # The trashcan is needed to handle deep recursive deallocations
    emitter.emit_line(f"CPy_TRASHCAN_BEGIN(self, {dealloc_func_name})")
    emitter.emit_line(f"{clear_func_name}((PyObject *)self);")
    emitter.emit_line("Py_TYPE(self)->tp_free((PyObject *)self);")
    emitter.emit_line("CPy_TRASHCAN_END(self)")
    emitter.emit_line("done: ;")
    emitter.emit_line("}")


def emit_reuse_dealloc(cl: ClassIR, emitter: Emitter) -> None:
    """Emit code to deallocate object by putting it to per-type free list.

    The free "list" currently can have up to one object.
    """
    prefix = cl.name_prefix(emitter.names)
    emitter.emit_line(f"if ({prefix}_free_instance == NULL) {{")
    emitter.emit_line(f"{prefix}_free_instance = self;")

    # Clear attributes and free referenced objects.

    emit_clear_bitmaps(cl, emitter)

    for base in reversed(cl.base_mro):
        for attr, rtype in base.attributes.items():
            emitter.emit_reuse_clear(f"self->{emitter.attr(attr)}", rtype)

    emitter.emit_line("return;")
    emitter.emit_line("}")


def generate_finalize_for_class(
    del_method: FuncIR, finalize_func_name: str, emitter: Emitter
) -> None:
    emitter.emit_line("static void")
    emitter.emit_line(f"{finalize_func_name}(PyObject *self)")
    emitter.emit_line("{")
    emitter.emit_line(
        "{}{}{}(self);".format(
            emitter.get_group_prefix(del_method.decl),
            NATIVE_PREFIX,
            del_method.cname(emitter.names),
        )
    )
    emitter.emit_line("}")


def generate_methods_table(
    cl: ClassIR, name: str, setup_name: str | None, emitter: Emitter
) -> None:
    emitter.emit_line(f"static PyMethodDef {name}[] = {{")
    if setup_name:
        # Store pointer to the setup function so it can be resolved dynamically
        # in case of instance creation in __new__.
        # CPy_SetupObject expects this method to be the first one in tp_methods.
        emitter.emit_line(
            f'{{"__internal_mypyc_setup", (PyCFunction){setup_name}, METH_O, NULL}},'
        )
    for fn in cl.methods.values():
        if fn.decl.is_prop_setter or fn.decl.is_prop_getter or fn.internal:
            continue
        emitter.emit_line(f'{{"{fn.name}",')
        emitter.emit_line(f" (PyCFunction){PREFIX}{fn.cname(emitter.names)},")
        flags = ["METH_FASTCALL", "METH_KEYWORDS"]
        if fn.decl.kind == FUNC_STATICMETHOD:
            flags.append("METH_STATIC")
        elif fn.decl.kind == FUNC_CLASSMETHOD:
            flags.append("METH_CLASS")

        doc = native_function_doc_initializer(fn)
        emitter.emit_line(" {}, PyDoc_STR({})}},".format(" | ".join(flags), doc))

    # Provide a default __getstate__ and __setstate__
    if not cl.has_method("__setstate__") and not cl.has_method("__getstate__"):
        emitter.emit_lines(
            '{"__setstate__", (PyCFunction)CPyPickle_SetState, METH_O, NULL},',
            '{"__getstate__", (PyCFunction)CPyPickle_GetState, METH_NOARGS, NULL},',
        )

    emitter.emit_line("{NULL}  /* Sentinel */")
    emitter.emit_line("};")


def generate_side_table_for_class(
    cl: ClassIR, name: str, type: str, slots: dict[str, str], emitter: Emitter
) -> str | None:
    name = f"{cl.name_prefix(emitter.names)}_{name}"
    emitter.emit_line(f"static {type} {name} = {{")
    for field, value in slots.items():
        emitter.emit_line(f".{field} = {value},")
    emitter.emit_line("};")
    return name


def generate_getseter_declarations(cl: ClassIR, emitter: Emitter) -> None:
    if not cl.is_trait:
        for attr in cl.attributes:
            emitter.emit_line("static PyObject *")
            emitter.emit_line(
                "{}({} *self, void *closure);".format(
                    getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
                )
            )
            # Final attributes are read-only, so they have no setter.
            if attr not in cl.final_attributes:
                emitter.emit_line("static int")
                emitter.emit_line(
                    "{}({} *self, PyObject *value, void *closure);".format(
                        setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
                    )
                )

    for prop, (getter, setter) in cl.properties.items():
        if getter.decl.implicit:
            continue

        # Generate getter declaration
        emitter.emit_line("static PyObject *")
        emitter.emit_line(
            "{}({} *self, void *closure);".format(
                getter_name(cl, prop, emitter.names), cl.struct_name(emitter.names)
            )
        )

        # Generate property setter declaration if a setter exists
        if setter:
            emitter.emit_line("static int")
            emitter.emit_line(
                "{}({} *self, PyObject *value, void *closure);".format(
                    setter_name(cl, prop, emitter.names), cl.struct_name(emitter.names)
                )
            )


def generate_getseters_table(cl: ClassIR, name: str, emitter: Emitter) -> None:
    emitter.emit_line(f"static PyGetSetDef {name}[] = {{")
    if not cl.is_trait:
        for attr in cl.attributes:
            emitter.emit_line(f'{{"{attr}",')
            if attr in cl.final_attributes:
                # Final attributes are read-only, so emit a NULL setter.
                emitter.emit_line(f" (getter){getter_name(cl, attr, emitter.names)}, NULL,")
            else:
                emitter.emit_line(
                    " (getter){}, (setter){},".format(
                        getter_name(cl, attr, emitter.names), setter_name(cl, attr, emitter.names)
                    )
                )
            emitter.emit_line(" NULL, NULL},")
    for prop, (getter, setter) in cl.properties.items():
        if getter.decl.implicit:
            continue

        emitter.emit_line(f'{{"{prop}",')
        emitter.emit_line(f" (getter){getter_name(cl, prop, emitter.names)},")

        if setter:
            emitter.emit_line(f" (setter){setter_name(cl, prop, emitter.names)},")
            emitter.emit_line("NULL, NULL},")
        else:
            emitter.emit_line("NULL, NULL, NULL},")

    if cl.has_dict:
        emitter.emit_line('{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},')

    emitter.emit_line("{NULL}  /* Sentinel */")
    emitter.emit_line("};")


def generate_getseters(cl: ClassIR, emitter: Emitter) -> None:
    if not cl.is_trait:
        for i, (attr, rtype) in enumerate(cl.attributes.items()):
            generate_getter(cl, attr, rtype, emitter)
            # Final attributes are read-only, so they have no setter.
            if attr not in cl.final_attributes:
                emitter.emit_line("")
                generate_setter(cl, attr, rtype, emitter)
            if i < len(cl.attributes) - 1:
                emitter.emit_line("")
    for prop, (getter, setter) in cl.properties.items():
        if getter.decl.implicit:
            continue

        rtype = getter.sig.ret_type
        emitter.emit_line("")
        generate_readonly_getter(cl, prop, rtype, getter, emitter)
        if setter:
            arg_type = setter.sig.args[1].type
            emitter.emit_line("")
            generate_property_setter(cl, prop, arg_type, setter, emitter)


def generate_getter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None:
    attr_field = emitter.attr(attr)
    emitter.emit_line("static PyObject *")
    emitter.emit_line(
        "{}({} *self, void *closure)".format(
            getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")
    attr_expr = f"self->{attr_field}"

    if IS_FREE_THREADED and is_simple_refcounted_pointer(rtype):
        # In free-threaded builds, load the attribute and take a new reference with
        # an optimistic validated incref to avoid racing with a concurrent setter.
        # CPy_GetAttrRef returns NULL if the attribute is undefined (NULL field),
        # which is exactly the error/undefined value for a 'PyObject *' field.
        #
        # Final attributes are never rebound (no setter), so there is no concurrent
        # writer to race with: a plain load + incref is safe. Use the cheaper
        # CPy_GetAttrRefFinal, which skips the try-incref and _Py_NewRefWithLock
        # slow path entirely (an unconditional Py_INCREF needs no maybe-weakref).
        # This getter is generated per defining class, so a direct membership test
        # matches the read-only getset table above (no need to walk the MRO).
        if attr in cl.final_attributes:
            getattr_ref = f"CPy_GetAttrRefFinal((PyObject **)&{attr_expr})"
        else:
            getattr_ref = f"CPy_GetAttrRef((PyObject *)self, (PyObject **)&{attr_expr})"
        emitter.emit_line(f"PyObject *retval = {getattr_ref};")
        emitter.emit_line("if (unlikely(retval == NULL)) {")
        emitter.emit_line("PyErr_SetString(PyExc_AttributeError,")
        emitter.emit_line(f'    "attribute {repr(attr)} of {repr(cl.name)} undefined");')
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")
        emitter.emit_line("return retval;")
        emitter.emit_line("}")
        return

    # HACK: Don't consider refcounted values as always defined, since it's possible to
    #       access uninitialized values via 'gc.get_objects()'. Accessing non-refcounted
    #       values is benign.
    always_defined = cl.is_always_defined(attr) and not rtype.is_refcounted

    if not always_defined:
        emitter.emit_undefined_attr_check(rtype, attr_expr, "==", "self", attr, cl, unlikely=True)
        emitter.emit_line("PyErr_SetString(PyExc_AttributeError,")
        emitter.emit_line(f'    "attribute {repr(attr)} of {repr(cl.name)} undefined");')
        emitter.emit_line("return NULL;")
        emitter.emit_line("}")
    emitter.emit_inc_ref(f"self->{attr_field}", rtype)
    emitter.emit_box(f"self->{attr_field}", "retval", rtype, declare_dest=True)
    emitter.emit_line("return retval;")
    emitter.emit_line("}")


def generate_setter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None:
    attr_field = emitter.attr(attr)
    emitter.emit_line("static int")
    emitter.emit_line(
        "{}({} *self, PyObject *value, void *closure)".format(
            setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")

    deletable = cl.is_deletable(attr)
    if not deletable:
        emitter.emit_line("if (value == NULL) {")
        emitter.emit_line("PyErr_SetString(PyExc_AttributeError,")
        emitter.emit_line(
            f'    "{repr(cl.name)} object attribute {repr(attr)} cannot be deleted");'
        )
        emitter.emit_line("return -1;")
        emitter.emit_line("}")

    if IS_FREE_THREADED and is_simple_refcounted_pointer(rtype):
        # In free-threaded builds, publish the new value atomically via
        # CPy_SetAttrRef so a concurrent reader (see CPy_GetAttrRef) never sees a
        # torn pointer or a freed old value. CPy_SetAttrRef steals its value and
        # reclaims the old one, so we cast/type-check the incoming value, take a
        # new reference (the setter only borrows 'value'), then hand it over.
        # A NULL value deletes the attribute (reclaims the old value, stores NULL).
        if deletable:
            emitter.emit_line("if (value != NULL) {")
        if is_same_type(rtype, object_rprimitive):
            emitter.emit_line("PyObject *tmp = value;")
        else:
            emitter.emit_cast("value", "tmp", rtype, declare_dest=True)
            emitter.emit_lines("if (!tmp)", "    return -1;")
        emitter.emit_inc_ref("tmp", rtype)
        emitter.emit_line(
            f"CPy_SetAttrRef((PyObject *)self, (PyObject **)&self->{attr_field}, tmp);"
        )
        if deletable:
            emitter.emit_line("} else {")
            emitter.emit_line(
                f"CPy_SetAttrRef((PyObject *)self, (PyObject **)&self->{attr_field}, NULL);"
            )
            emitter.emit_line("}")
        emitter.emit_line("return 0;")
        emitter.emit_line("}")
        return

    # HACK: Don't consider refcounted values as always defined, since it's possible to
    #       access uninitialized values via 'gc.get_objects()'. Accessing non-refcounted
    #       values is benign.
    always_defined = cl.is_always_defined(attr) and not rtype.is_refcounted

    if rtype.is_refcounted:
        attr_expr = f"self->{attr_field}"
        if not always_defined:
            emitter.emit_undefined_attr_check(rtype, attr_expr, "!=", "self", attr, cl)
        emitter.emit_dec_ref(f"self->{attr_field}", rtype)
        if not always_defined:
            emitter.emit_line("}")

    if deletable:
        emitter.emit_line("if (value != NULL) {")

    if rtype.is_unboxed:
        # Borrow the unboxed value: emit_inc_ref below takes the single owned
        # reference, matching the borrowed-then-incref pattern of the other two
        # branches. Without borrow=True, emit_unbox already creates a new
        # reference for refcounted unboxed types (e.g. CPyTagged boxed ints,
        # tuples with refcounted fields), so the emit_inc_ref would double the
        # reference and leak the stored value on every set via this setter.
        emitter.emit_unbox(
            "value", "tmp", rtype, error=ReturnHandler("-1"), declare_dest=True, borrow=True
        )
    elif is_same_type(rtype, object_rprimitive):
        emitter.emit_line("PyObject *tmp = value;")
    else:
        emitter.emit_cast("value", "tmp", rtype, declare_dest=True)
        emitter.emit_lines("if (!tmp)", "    return -1;")
    emitter.emit_inc_ref("tmp", rtype)
    emitter.emit_line(f"self->{attr_field} = tmp;")
    if rtype.error_overlap and not always_defined:
        emitter.emit_attr_bitmap_set("tmp", "self", rtype, cl, attr)

    if deletable:
        emitter.emit_line("} else {")
        emitter.set_undefined_value(f"self->{attr_field}", rtype)
        if rtype.error_overlap:
            emitter.emit_attr_bitmap_clear("self", rtype, cl, attr)
        emitter.emit_line("}")
    emitter.emit_line("return 0;")
    emitter.emit_line("}")


def generate_readonly_getter(
    cl: ClassIR, attr: str, rtype: RType, func_ir: FuncIR, emitter: Emitter
) -> None:
    emitter.emit_line("static PyObject *")
    emitter.emit_line(
        "{}({} *self, void *closure)".format(
            getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")
    if rtype.is_unboxed:
        emitter.emit_line(
            "{}retval = {}{}((PyObject *) self);".format(
                emitter.ctype_spaced(rtype), NATIVE_PREFIX, func_ir.cname(emitter.names)
            )
        )
        emitter.emit_error_check("retval", rtype, "return NULL;")
        emitter.emit_box("retval", "retbox", rtype, declare_dest=True)
        emitter.emit_line("return retbox;")
    else:
        emitter.emit_line(
            f"return {NATIVE_PREFIX}{func_ir.cname(emitter.names)}((PyObject *) self);"
        )
    emitter.emit_line("}")


def generate_property_setter(
    cl: ClassIR, attr: str, arg_type: RType, func_ir: FuncIR, emitter: Emitter
) -> None:
    emitter.emit_line("static int")
    emitter.emit_line(
        "{}({} *self, PyObject *value, void *closure)".format(
            setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names)
        )
    )
    emitter.emit_line("{")
    ret_type = func_ir.ret_type
    emitter.emit_line(f"{emitter.ctype(ret_type)} retval = {emitter.c_undefined_value(ret_type)};")
    if arg_type.is_unboxed:
        emitter.emit_unbox("value", "tmp", arg_type, error=ReturnHandler("-1"), declare_dest=True)
        emitter.emit_line(
            f"retval = {NATIVE_PREFIX}{func_ir.cname(emitter.names)}((PyObject *) self, tmp);"
        )
    else:
        emitter.emit_line(
            f"retval = {NATIVE_PREFIX}{func_ir.cname(emitter.names)}((PyObject *) self, value);"
        )
    emitter.emit_error_check("retval", ret_type, "return -1;")
    emitter.emit_line("return 0;")
    emitter.emit_line("}")


def has_managed_dict(cl: ClassIR, emitter: Emitter) -> bool:
    """Should the class get the Py_TPFLAGS_MANAGED_DICT flag?"""
    # On 3.11 and earlier the flag doesn't exist and we use
    # tp_dictoffset instead.  If a class inherits from Exception, the
    # flag conflicts with tp_dictoffset set in the base class.
    return (
        emitter.capi_version >= (3, 12)
        and cl.has_dict
        and cl.builtin_base != "PyBaseExceptionObject"
    )


def native_class_doc_initializer(cl: ClassIR) -> str:
    init_fn = cl.get_method("__init__")
    if init_fn is not None:
        text_sig = get_text_signature(init_fn, bound=True)
        if text_sig is None:
            return "NULL"
        text_sig = text_sig.replace("__init__", cl.name, 1)
    else:
        text_sig = f"{cl.name}()"
    docstring = f"{text_sig}\n--\n\n"
    return c_string_initializer(docstring.encode("ascii", errors="backslashreplace"))


def generate_coroutine_setup(
    cl: ClassIR, coroutine_setup_name: str, module_name: str, emitter: Emitter
) -> None:
    emitter.emit_line("static bool")
    emitter.emit_line(f"{NATIVE_PREFIX}{coroutine_setup_name}(PyObject *type)")
    emitter.emit_line("{")

    error_stmt = "    return 2;"

    def emit_instance(fn: FuncIR, fn_name: str) -> str:
        filepath = emitter.filepath or ""
        return emitter.emit_cpyfunction_instance(fn, fn_name, filepath, error_stmt)

    def success() -> None:
        emitter.emit_line("return 1;")
        emitter.emit_line("}")

    if cl.coroutine_name:
        # Callable class generated for a coroutine. It stores its function wrapper as an attribute.
        wrapper_name = emit_instance(cl.methods["__call__"], cl.coroutine_name)
        struct_name = cl.struct_name(emitter.names)
        attr = emitter.attr(CPYFUNCTION_NAME)
        emitter.emit_line(f"(({struct_name} *)type)->{attr} = {wrapper_name};")
        return success()

    if not any(fn.decl.is_coroutine for fn in cl.methods.values()):
        return success()

    emitter.emit_line("PyTypeObject *tp = (PyTypeObject *)type;")

    for fn in cl.methods.values():
        if not fn.decl.is_coroutine:
            continue

        name = short_id_from_name(fn.name, fn.decl.shortname, fn.line)
        wrapper_name = emit_instance(fn, name)
        name_obj = f"{wrapper_name}_name"
        emitter.emit_line(f'PyObject *{name_obj} = PyUnicode_FromString("{fn.name}");')
        emitter.emit_line(f"if (unlikely(!{name_obj}))")
        emitter.emit_line(error_stmt)
        emitter.emit_line(f"if (PyDict_SetItem(tp->tp_dict, {name_obj}, {wrapper_name}) < 0)")
        emitter.emit_line(error_stmt)

    return success()
