"""Generate C code for a Python C extension module from Python source code."""

# FIXME: Basically nothing in this file operates on the level of a
#        single module and it should be renamed.

from __future__ import annotations

import json
import os
import sys
from collections.abc import Iterable
from typing import TypeVar

from mypy.build import (
    BuildResult,
    BuildSource,
    State,
    build,
    compute_hash,
    create_metastore,
    get_cache_names,
    sorted_components,
)
from mypy.errors import CompileError
from mypy.fscache import FileSystemCache
from mypy.nodes import MypyFile, TypeInfo
from mypy.options import Options
from mypy.plugin import Plugin, ReportConfigContext
from mypy.util import hash_digest, json_dumps
from mypyc.analysis.capsule_deps import find_class_dependencies, find_implicit_op_dependencies
from mypyc.codegen.cstring import c_string_initializer
from mypyc.codegen.emit import (
    Emitter,
    EmitterContext,
    HeaderDeclaration,
    c_array_initializer,
    native_function_doc_initializer,
)
from mypyc.codegen.emitclass import generate_class, generate_class_reuse, generate_class_type_decl
from mypyc.codegen.emitfunc import generate_native_function, native_function_header
from mypyc.codegen.emitwrapper import (
    generate_legacy_wrapper_function,
    generate_wrapper_function,
    legacy_wrapper_function_header,
    wrapper_function_header,
)
from mypyc.codegen.literals import Literals
from mypyc.common import (
    EXT_SUFFIX,
    GENERATOR_HELPER_NAME,
    IS_FREE_THREADED,
    MODULE_PREFIX,
    PREFIX,
    RUNTIME_C_FILES,
    TOP_LEVEL_NAME,
    TYPE_VAR_PREFIX,
    module_exec_name,
    module_import_state_name,
    module_init_name,
    module_init_only_name,
    module_lock_api_name,
    shared_lib_name,
    short_id_from_name,
)
from mypyc.crash import catch_errors
from mypyc.errors import Errors
from mypyc.ir.deps import (
    LIBRT_BASE64,
    LIBRT_RANDOM,
    LIBRT_STRINGS,
    LIBRT_THREADING,
    LIBRT_TIME,
    LIBRT_VECS,
    Capsule,
    HeaderDep,
    SourceDep,
)
from mypyc.ir.func_ir import FuncIR
from mypyc.ir.module_ir import ModuleIR, ModuleIRs, deserialize_modules
from mypyc.ir.ops import DeserMaps, LoadLiteral
from mypyc.ir.rtypes import RType
from mypyc.irbuild.main import build_ir
from mypyc.irbuild.mapper import Mapper
from mypyc.irbuild.prepare import load_type_map
from mypyc.namegen import NameGenerator, exported_name
from mypyc.options import CompilerOptions
from mypyc.transform.borrow_generator_attrs import borrow_generator_attrs
from mypyc.transform.copy_propagation import do_copy_propagation
from mypyc.transform.exceptions import insert_exception_handling
from mypyc.transform.flag_elimination import do_flag_elimination
from mypyc.transform.log_trace import insert_event_trace_logging
from mypyc.transform.lower import lower_ir
from mypyc.transform.refcount import insert_ref_count_opcodes
from mypyc.transform.spill import insert_spills
from mypyc.transform.uninit import insert_uninit_checks

# All the modules being compiled are divided into "groups". A group
# is a set of modules that are placed into the same shared library.
# Two common configurations are that every module is placed in a group
# by itself (fully separate compilation) and that every module is
# placed in the same group (fully whole-program compilation), but we
# support finer-grained control of the group as well.
#
# In fully whole-program compilation, we will generate N+1 extension
# modules: one shim per module and one shared library containing all
# the actual code.
# In fully separate compilation, we (unfortunately) will generate 2*N
# extension modules: one shim per module and also one library containing
# each module's actual code. (This might be fixable in the future,
# but allows a clean separation between setup of the export tables
# (see generate_export_table) and running module top levels.)
#
# A group is represented as a list of BuildSources containing all of
# its modules along with the name of the group. (Which can be None
# only if we are compiling only a single group with a single file in it
# and not using shared libraries).
Group = tuple[list[BuildSource], str | None]
Groups = list[Group]

# A list of (file name, file contents) pairs.
FileContents = list[tuple[str, str]]


class MarkedDeclaration:
    """Add a mark, useful for topological sort."""

    def __init__(self, declaration: HeaderDeclaration, mark: bool) -> None:
        self.declaration = declaration
        self.mark = False


class MypycPlugin(Plugin):
    """Plugin for making mypyc interoperate properly with mypy incremental mode.

    Basically the point of this plugin is to force mypy to recheck things
    based on the demands of mypyc in a couple situations:
      * Any modules in the same group must be compiled together, so we
        tell mypy that modules depend on all their groupmates.
      * If the IR metadata is missing or stale or any of the generated
        C source files associated missing or stale, then we need to
        recompile the module so we mark it as stale.
    """

    def __init__(
        self, options: Options, compiler_options: CompilerOptions, groups: Groups
    ) -> None:
        super().__init__(options)
        self.group_map: dict[str, tuple[str | None, list[str]]] = {}
        for sources, name in groups:
            modules = sorted(source.module for source in sources)
            for id in modules:
                self.group_map[id] = (name, modules)

        self.compiler_options = compiler_options
        self.metastore = create_metastore(options, parallel_worker=False)

    def report_config_data(self, ctx: ReportConfigContext) -> tuple[str | None, list[str]] | None:
        # The config data we report is the group map entry for the module.
        # If the data is being used to check validity, we do additional checks
        # that the IR cache exists and matches the metadata cache and all
        # output source files exist and are up to date.

        id, path, is_check = ctx.id, ctx.path, ctx.is_check

        if id not in self.group_map:
            return None

        # If we aren't doing validity checks, just return the cache data
        if not is_check:
            return self.group_map[id]

        # Load the metadata and IR cache
        meta_path, _, _ = get_cache_names(id, path, self.options)
        ir_path = get_ir_cache_name(id, path, self.options)
        try:
            meta_json = self.metastore.read(meta_path)
            ir_json = self.metastore.read(ir_path)
        except FileNotFoundError:
            # This could happen if mypyc failed after mypy succeeded
            # in the previous run or if some cache files got
            # deleted. No big deal, just fail to load the cache.
            return None

        ir_data = json.loads(ir_json)

        # Check that the IR cache matches the metadata cache
        if hash_digest(meta_json) != ir_data["meta_hash"]:
            return None

        # Check that all the source files are present and as
        # expected. The main situation where this would come up is the
        # user deleting the build directory without deleting
        # .mypy_cache, which we should handle gracefully.
        for path, hash in ir_data["src_hashes"].items():
            try:
                with open(os.path.join(self.compiler_options.target_dir, path), "rb") as f:
                    contents = f.read()
            except FileNotFoundError:
                return None
            real_hash = hash_digest(contents)
            if hash != real_hash:
                return None

        return self.group_map[id]

    def get_additional_deps(self, file: MypyFile) -> list[tuple[int, str, int]]:
        # Report dependency on modules in the module's group
        return [(10, id, -1) for id in self.group_map.get(file.fullname, (None, []))[1]]

    def get_additional_indirect_deps(self, file: MypyFile) -> set[str]:
        """Modules defining MRO ancestors of classes defined in this module.

        The generated C for a class (vtable arrays, getter/setter tables,
        object struct) references every inherited method/attribute of every
        ancestor, including ancestors defined in modules this module does
        not import directly. Recording them as indirect dependencies makes
        an ancestor's interface change re-trigger type checking (and hence
        C regeneration) of this module. Only top-level classes are scanned:
        mypyc rejects nested class definitions.
        """
        if file.fullname not in self.group_map:
            return set()

        mods: set[str] = set()
        for sym in file.names.values():
            node = sym.node
            if isinstance(node, TypeInfo) and node.module_name == file.fullname:
                for ancestor in node.mro[1:]:
                    mods.add(ancestor.module_name)
        return mods


def parse_and_typecheck(
    sources: list[BuildSource],
    options: Options,
    compiler_options: CompilerOptions,
    groups: Groups,
    fscache: FileSystemCache | None = None,
    alt_lib_path: str | None = None,
) -> BuildResult:
    assert options.strict_optional, "strict_optional must be turned on"
    mypyc_plugin = MypycPlugin(options, compiler_options, groups)
    try:
        result = build(
            sources=sources,
            options=options,
            alt_lib_path=alt_lib_path,
            fscache=fscache,
            extra_plugins=[mypyc_plugin],
        )
    finally:
        mypyc_plugin.metastore.close()
    if result.errors:
        result.manager.metastore.close()
        raise CompileError(result.errors)
    return result


def compile_scc_to_ir(
    scc: list[MypyFile],
    result: BuildResult,
    mapper: Mapper,
    compiler_options: CompilerOptions,
    errors: Errors,
) -> ModuleIRs:
    """Compile an SCC into ModuleIRs.

    Any modules that this SCC depends on must have either been compiled,
    type checked, or loaded from a cache into mapper.

    Arguments:
        scc: The list of MypyFiles to compile
        result: The BuildResult from the mypy front-end
        mapper: The Mapper object mapping mypy ASTs to class and func IRs
        compiler_options: The compilation options
        errors: Where to report any errors encountered

    Returns the IR of the modules.
    """

    if compiler_options.verbose:
        print("Compiling {}".format(", ".join(x.name for x in scc)))

    # Generate basic IR, with missing exception and refcount handling.
    modules = build_ir(scc, result.graph, result.types, mapper, compiler_options, errors)
    if errors.num_errors > 0:
        return modules

    generator_spill_owners = {}
    for module in modules.values():
        for cls in module.classes:
            if cls.env_user_function:
                generator_spill_owners[cls.env_user_function] = cls

    for module in modules.values():
        module_path = result.graph[module.fullname].xpath
        for fn in module.functions:
            with catch_errors(module_path, fn.line):
                # Insert checks for uninitialized values.
                insert_uninit_checks(fn, compiler_options.strict_traceback_checks)
                # Insert exception handling.
                insert_exception_handling(fn, compiler_options.strict_traceback_checks)
                if fn in generator_spill_owners:
                    borrow_generator_attrs(fn, generator_spill_owners[fn])
                # Insert reference count handling.
                insert_ref_count_opcodes(fn)

                if fn in generator_spill_owners:
                    insert_spills(fn, generator_spill_owners[fn])

                if compiler_options.log_trace:
                    insert_event_trace_logging(fn, compiler_options)

                # Switch to lower abstraction level IR.
                lower_ir(fn, compiler_options)
                # Calculate implicit module dependencies (needed for librt)
                deps = find_implicit_op_dependencies(fn)
                if deps is not None:
                    module.dependencies.update(deps)
                # Perform optimizations.
                do_copy_propagation(fn, compiler_options)
                do_flag_elimination(fn, compiler_options)

        # Calculate implicit dependencies from class attribute types
        for cl in module.classes:
            deps = find_class_dependencies(cl)
            if deps is not None:
                module.dependencies.update(deps)

    return modules


def compile_modules_to_ir(
    result: BuildResult, mapper: Mapper, compiler_options: CompilerOptions, errors: Errors
) -> ModuleIRs:
    """Compile a collection of modules into ModuleIRs.

    The modules to compile are specified as part of mapper's group_map.

    Returns the IR of the modules.
    """
    deser_ctx = DeserMaps({}, {})
    modules = {}

    # Process the graph by SCC in topological order, like we do in mypy.build
    for scc in sorted_components(result.graph):
        scc_states = [result.graph[id] for id in sorted(scc.mod_ids)]
        trees = [st.tree for st in scc_states if st.id in mapper.group_map and st.tree]

        if not trees:
            continue

        fresh = all(id not in result.manager.rechecked_modules for id in scc.mod_ids)
        if fresh:
            load_scc_from_cache(trees, result, mapper, deser_ctx)
        else:
            scc_ir = compile_scc_to_ir(trees, result, mapper, compiler_options, errors)
            modules.update(scc_ir)
            # A later SCC loaded from cache may reference classes/functions
            # defined in this freshly-built SCC; populate deser_ctx so the
            # cached IR deserializer can resolve those cross-SCC references.
            for module_ir in scc_ir.values():
                for cl in module_ir.classes:
                    deser_ctx.classes.setdefault(cl.fullname, cl)
                for fn in module_ir.functions:
                    deser_ctx.functions.setdefault(fn.decl.id, fn)

    return modules


def compile_ir_to_c(
    groups: Groups,
    modules: ModuleIRs,
    result: BuildResult,
    mapper: Mapper,
    compiler_options: CompilerOptions,
) -> dict[str | None, list[tuple[str, str]]]:
    """Compile a collection of ModuleIRs to C source text.

    Returns a dictionary mapping group names to a list of (file name,
    file text) pairs.
    """
    source_paths = {
        source.module: result.graph[source.module].xpath
        for sources, _ in groups
        for source in sources
    }

    names = NameGenerator(
        [[source.module for source in sources] for sources, _ in groups],
        separate=compiler_options.separate,
    )

    # Generate C code for each compilation group. Each group will be
    # compiled into a separate extension module.
    ctext: dict[str | None, list[tuple[str, str]]] = {}
    for group_sources, group_name in groups:
        group_modules = {
            source.module: modules[source.module]
            for source in group_sources
            if source.module in modules
        }
        if not group_modules:
            # Fully-cached group (e.g. pip's second setup.py invoke for
            # the wheel phase): no fresh IR was produced. Reuse the file
            # list recorded in any module's IR cache so the linker still
            # sees the previous run's outputs; empty content is a "do
            # not rewrite" sentinel for mypyc_build.
            ctext[group_name] = _load_cached_group_files(group_sources, result)
            continue
        generator = GroupGenerator(
            group_modules, source_paths, group_name, mapper.group_map, names, compiler_options
        )
        ctext[group_name] = generator.generate_c_for_modules()

    return ctext


def _load_cached_group_files(
    group_sources: list[BuildSource], result: BuildResult
) -> list[tuple[str, str]]:
    """Read the .c/.h paths recorded for this group on the previous run.

    All modules in a group share the same src_hashes map, so the first
    readable IR cache is sufficient. Returns paths paired with empty
    content so callers can distinguish "reuse on disk" from "newly
    generated".
    """
    for source in group_sources:
        state = result.graph.get(source.module)
        if state is None:
            continue
        try:
            ir_json = result.manager.metastore.read(get_state_ir_cache_name(state))
        except (FileNotFoundError, OSError):
            continue
        try:
            ir_data = json.loads(ir_json)
        except json.JSONDecodeError:
            continue
        return [(path, "") for path in ir_data.get("src_hashes", {})]
    return []


def get_ir_cache_name(id: str, path: str, options: Options) -> str:
    meta_path, _, _ = get_cache_names(id, path, options)
    # Mypyc uses JSON cache even with --fixed-format-cache (for now).
    return meta_path.replace(".meta.json", ".ir.json").replace(".meta.ff", ".ir.json")


def get_state_ir_cache_name(state: State) -> str:
    return get_ir_cache_name(state.id, state.xpath, state.options)


def write_cache(
    modules: ModuleIRs,
    result: BuildResult,
    group_map: dict[str, str | None],
    ctext: dict[str | None, list[tuple[str, str]]],
) -> None:
    """Write out the cache information for modules.

    Each module has the following cache information written (which is
    in addition to the cache information written by mypy itself):
      * A serialized version of its mypyc IR, minus the bodies of
        functions. This allows code that depends on it to use
        these serialized data structures when compiling against it
        instead of needing to recompile it. (Compiling against a
        module requires access to both its mypy and mypyc data
        structures.)
      * The hash of the mypy metadata cache file for the module.
        This is used to ensure that the mypyc cache and the mypy
        cache are in sync and refer to the same version of the code.
        This is particularly important if mypyc crashes/errors/is
        stopped after mypy has written its cache but before mypyc has.
      * The hashes of all the source file outputs for the group
        the module is in. This is so that the module will be
        recompiled if the source outputs are missing.
    """

    hashes = {}
    for name, files in ctext.items():
        hashes[name] = {file: compute_hash(data) for file, data in files}

    # Write out cache data
    for id, module in modules.items():
        st = result.graph[id]

        meta_path, _, _ = get_cache_names(id, st.xpath, result.manager.options)
        # If the metadata isn't there, skip writing the cache.
        try:
            meta_data = result.manager.metastore.read(meta_path)
        except OSError:
            continue

        newpath = get_state_ir_cache_name(st)
        ir_data = {
            "ir": module.serialize(),
            "meta_hash": hash_digest(meta_data),
            "src_hashes": hashes[group_map[id]],
        }

        result.manager.metastore.write(newpath, json_dumps(ir_data))

    result.manager.metastore.commit()


def load_scc_from_cache(
    scc: list[MypyFile], result: BuildResult, mapper: Mapper, ctx: DeserMaps
) -> ModuleIRs:
    """Load IR for an SCC of modules from the cache.

    Arguments and return are as compile_scc_to_ir.
    """
    cache_data = {
        k.fullname: json.loads(
            result.manager.metastore.read(get_state_ir_cache_name(result.graph[k.fullname]))
        )["ir"]
        for k in scc
    }
    modules = deserialize_modules(cache_data, ctx)
    load_type_map(mapper, scc, ctx)
    return modules


def collect_source_dependencies(modules: dict[str, ModuleIR]) -> set[SourceDep]:
    """Collect all SourceDep dependencies from all modules."""
    source_deps: set[SourceDep] = set()
    for module in modules.values():
        for dep in module.dependencies:
            if isinstance(dep, SourceDep):
                if dep.internal:
                    source_deps.add(dep)
            elif isinstance(dep, Capsule):
                source_deps.add(dep.internal_dep())
    return source_deps


def collect_header_dependencies(modules: dict[str, ModuleIR], *, internal: bool) -> set[str]:
    """Collect all header dependencies from all modules."""
    header_deps: set[str] = set()
    for module in modules.values():
        for dep in module.dependencies:
            if isinstance(dep, (SourceDep, HeaderDep)):
                if dep.internal == internal:
                    header_deps.add(dep.get_header())
            else:
                capsule_dep = dep.internal_dep() if internal else dep.external_dep()
                header_deps.add(capsule_dep.get_header())
    return header_deps


def compile_modules_to_c(
    result: BuildResult, compiler_options: CompilerOptions, errors: Errors, groups: Groups
) -> tuple[ModuleIRs, list[FileContents], Mapper]:
    """Compile Python module(s) to the source of Python C extension modules.

    This generates the source code for the "shared library" module
    for each group. The shim modules are generated in mypyc.build.
    Each shared library module provides, for each module in its group,
    a PyCapsule containing an initialization function.
    Additionally, it provides a capsule containing an export table of
    pointers to all the group's functions and static variables.

    Arguments:
        result: The BuildResult from the mypy front-end
        compiler_options: The compilation options
        errors: Where to report any errors encountered
        groups: The groups that we are compiling. See documentation of Groups type above.

    Returns the IR of the modules and a list containing the generated files for each group.
    """
    # Construct a map from modules to what group they belong to
    group_map = {source.module: lib_name for group, lib_name in groups for source in group}
    mapper = Mapper(group_map)

    # Sometimes when we call back into mypy, there might be errors.
    # We don't want to crash when that happens.
    result.manager.errors.set_file(
        "<mypyc>", module=None, scope=None, options=result.manager.options
    )

    modules = compile_modules_to_ir(result, mapper, compiler_options, errors)
    if errors.num_errors > 0:
        return {}, [], Mapper({})

    ctext = compile_ir_to_c(groups, modules, result, mapper, compiler_options)
    write_cache(modules, result, group_map, ctext)

    return modules, [ctext[name] for _, name in groups], mapper


def generate_function_declaration(fn: FuncIR, emitter: Emitter) -> None:
    emitter.context.declarations[emitter.native_function_name(fn.decl)] = HeaderDeclaration(
        f"{native_function_header(fn.decl, emitter)};", needs_export=True
    )
    if fn.name != TOP_LEVEL_NAME and not fn.internal:
        # needs_export=True so Python-wrapper (CPyPy_) symbols are reachable from
        # other groups via the export table — needed for cross-group inherited
        # __init__ / __new__ slot dispatch under `separate=True`.
        if is_fastcall_supported(fn, emitter.capi_version):
            emitter.context.declarations[PREFIX + fn.cname(emitter.names)] = HeaderDeclaration(
                f"{wrapper_function_header(fn, emitter.names)};", needs_export=True
            )
        else:
            emitter.context.declarations[PREFIX + fn.cname(emitter.names)] = HeaderDeclaration(
                f"{legacy_wrapper_function_header(fn, emitter.names)};", needs_export=True
            )


def pointerize(decl: str, name: str) -> str:
    """Given a C decl and its name, modify it to be a declaration to a pointer."""
    # This doesn't work in general but does work for all our types...
    if "(" in decl:
        # Function pointer. Stick an * in front of the name and wrap it in parens.
        return decl.replace(name, f"(*{name})")
    else:
        # Non-function pointer. Just stick an * in front of the name.
        return decl.replace(name, f"*{name}")


def group_dir(group_name: str) -> str:
    """Given a group name, return the relative directory path for it."""
    return os.sep.join(group_name.split(".")[:-1])


class GroupGenerator:
    def __init__(
        self,
        modules: dict[str, ModuleIR],
        source_paths: dict[str, str],
        group_name: str | None,
        group_map: dict[str, str | None],
        names: NameGenerator,
        compiler_options: CompilerOptions,
    ) -> None:
        """Generator for C source for a compilation group.

        The code for a compilation group contains an internal and an
        external .h file, and then one .c if not in multi_file mode or
        one .c file per module if in multi_file mode.

        Arguments:
            modules: (name, ir) pairs for each module in the group
            source_paths: Map from module names to source file paths
            group_name: The name of the group (or None if this is single-module compilation)
            group_map: A map of modules to their group names
            names: The name generator for the compilation
            compiler_options: Mypyc specific options, including multi_file mode
        """
        self.modules = modules
        self.source_paths = source_paths
        self.context = EmitterContext(
            names, compiler_options.strict_traceback_checks, group_name, group_map
        )
        self.names = names
        # Initializations of globals to simple values that we can't
        # do statically because the windows loader is bad.
        self.simple_inits: list[tuple[str, str]] = []
        self.group_name = group_name
        self.use_shared_lib = group_name is not None
        self.compiler_options = compiler_options
        self.multi_file = compiler_options.multi_file
        # Multi-phase init is needed to enable free-threading. In the future we'll
        # probably want to enable it always, but we'll wait until it's stable.
        self.multi_phase_init = IS_FREE_THREADED

    @property
    def group_suffix(self) -> str:
        return "_" + exported_name(self.group_name) if self.group_name else ""

    @property
    def short_group_suffix(self) -> str:
        return "_" + exported_name(self.group_name.split(".")[-1]) if self.group_name else ""

    def generate_c_for_modules(self) -> list[tuple[str, str]]:
        file_contents = []
        multi_file = self.use_shared_lib and self.multi_file

        # Collect all literal refs in IR.
        for module in self.modules.values():
            for fn in module.functions:
                collect_literals(fn, self.context.literals)

        base_emitter = Emitter(self.context)
        # Optionally just include the runtime library c files to
        # reduce the number of compiler invocations needed.
        # Use <> form (only -I paths) so a shim file with the same
        # basename as a runtime file can't shadow it. Triggered by
        # mypyc/lower/int_ops.py vs lib-rt/int_ops.c on mypy self-compile.
        if self.compiler_options.include_runtime_files:
            for name in RUNTIME_C_FILES:
                base_emitter.emit_line(f"#include <{name}>")
            # Include conditional source files
            source_deps = collect_source_dependencies(self.modules)
            for source_dep in sorted(source_deps, key=lambda d: d.path):
                base_emitter.emit_line(f"#include <{source_dep.path}>")
            if self.compiler_options.depends_on_librt_internal:
                base_emitter.emit_line("#include <internal/librt_internal_api.c>")
        base_emitter.emit_line(f'#include "__native{self.short_group_suffix}.h"')
        base_emitter.emit_line(f'#include "__native_internal{self.short_group_suffix}.h"')
        emitter = base_emitter

        if self.use_shared_lib:
            self.declare_module_lock_api()

        self.generate_literal_tables()

        for module_name, module in self.modules.items():
            if multi_file:
                emitter = Emitter(self.context, filepath=self.source_paths[module_name])
                emitter.emit_line(f'#include "__native{self.short_group_suffix}.h"')
                emitter.emit_line(f'#include "__native_internal{self.short_group_suffix}.h"')

            self.declare_module(module_name, emitter)
            self.declare_internal_globals(module_name, emitter)
            self.declare_imports(module.imports, emitter)

            for cl in module.classes:
                if cl.is_ext_class:
                    generate_class(cl, module_name, emitter)

            running_flag_classes = {cl.name: cl for cl in module.classes if cl.has_running_flag}

            # Generate Python extension module definitions and module initialization functions.
            self.generate_module_def(emitter, module_name, module)

            for fn in module.functions:
                emitter.emit_line()
                running_flag_class = None
                if fn.decl.name == GENERATOR_HELPER_NAME and fn.class_name is not None:
                    running_flag_class = running_flag_classes.get(fn.class_name)
                generate_native_function(
                    fn, emitter, self.source_paths[module_name], module_name, running_flag_class
                )
                if fn.name != TOP_LEVEL_NAME and not fn.internal:
                    emitter.emit_line()
                    if is_fastcall_supported(fn, emitter.capi_version):
                        generate_wrapper_function(
                            fn, emitter, self.source_paths[module_name], module_name
                        )
                    else:
                        generate_legacy_wrapper_function(
                            fn, emitter, self.source_paths[module_name], module_name
                        )
            if multi_file:
                name = f"__native_{exported_name(module_name)}.c"
                file_contents.append((name, "".join(emitter.fragments)))

        # The external header file contains type declarations while
        # the internal contains declarations of functions and objects
        # (which are shared between shared libraries via dynamic
        # exports tables and not accessed directly.)
        ext_declarations = Emitter(self.context)
        ext_declarations.emit_line(f"#ifndef MYPYC_NATIVE{self.group_suffix}_H")
        ext_declarations.emit_line(f"#define MYPYC_NATIVE{self.group_suffix}_H")
        ext_declarations.emit_line("#include <Python.h>")
        ext_declarations.emit_line("#include <CPy.h>")

        def emit_dep_headers(decls: Emitter, internal: bool) -> None:
            suffix = "_api" if internal else ""
            if self.compiler_options.depends_on_librt_internal:
                decls.emit_line(f'#include "internal/librt_internal{suffix}.h"')
            # Include headers for conditional source files
            header_deps = collect_header_dependencies(self.modules, internal=internal)
            for header_dep in sorted(header_deps):
                decls.emit_line(f'#include "{header_dep}"')

        emit_dep_headers(ext_declarations, False)

        declarations = Emitter(self.context)
        declarations.emit_line(f"#ifndef MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
        declarations.emit_line(f"#define MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
        declarations.emit_line("#include <Python.h>")
        declarations.emit_line("#include <CPy.h>")

        if not self.compiler_options.include_runtime_files:
            emit_dep_headers(declarations, True)

        declarations.emit_line(f'#include "__native{self.short_group_suffix}.h"')
        declarations.emit_line()
        declarations.emit_line("int CPyGlobalsInit(void);")
        declarations.emit_line()

        for module_name, module in self.modules.items():
            self.declare_finals(module_name, module.final_names, declarations)
            for cl in module.classes:
                generate_class_type_decl(cl, emitter, ext_declarations, declarations)
                if cl.reuse_freed_instance:
                    generate_class_reuse(cl, emitter, ext_declarations, declarations)
            self.declare_type_vars(module_name, module.type_var_names, declarations)
            for fn in module.functions:
                generate_function_declaration(fn, declarations)

        for lib in sorted(self.context.group_deps):
            elib = exported_name(lib)
            short_lib = exported_name(lib.split(".")[-1])
            declarations.emit_lines(
                "#include <{}>".format(os.path.join(group_dir(lib), f"__native_{short_lib}.h")),
                f"struct export_table_{elib} exports_{elib};",
            )

        sorted_decls = self.toposort_declarations()

        emitter = base_emitter
        self.generate_globals_init(emitter)

        emitter.emit_line()

        for declaration in sorted_decls:
            decls = ext_declarations if declaration.is_type else declarations
            if not declaration.is_type:
                decls.emit_lines(f"extern {declaration.decl[0]}", *declaration.decl[1:])
                # If there is a definition, emit it. Otherwise, repeat the declaration
                # (without an extern).
                if declaration.defn:
                    emitter.emit_lines(*declaration.defn)
                else:
                    emitter.emit_lines(*declaration.decl)
            else:
                decls.emit_lines(*declaration.decl)

        if self.group_name:
            if self.compiler_options.separate:
                self.generate_export_table(ext_declarations, emitter)

            self.generate_shared_lib_init(emitter)

        ext_declarations.emit_line("#endif")
        declarations.emit_line("#endif")

        output_dir = group_dir(self.group_name) if self.group_name else ""
        return file_contents + [
            (
                os.path.join(output_dir, f"__native{self.short_group_suffix}.c"),
                "".join(emitter.fragments),
            ),
            (
                os.path.join(output_dir, f"__native_internal{self.short_group_suffix}.h"),
                "".join(declarations.fragments),
            ),
            (
                os.path.join(output_dir, f"__native{self.short_group_suffix}.h"),
                "".join(ext_declarations.fragments),
            ),
        ]

    def generate_literal_tables(self) -> None:
        """Generate tables containing descriptions of Python literals to construct.

        We will store the constructed literals in a single array that contains
        literals of all types. This way we can refer to an arbitrary literal by
        its index.
        """
        literals = self.context.literals
        # During module initialization we store all the constructed objects here
        self.declare_global("PyObject *[%d]" % literals.num_literals(), "CPyStatics")
        # Descriptions of str literals
        init_str = c_string_array_initializer(literals.encoded_str_values())
        self.declare_global("const char * const []", "CPyLit_Str", initializer=init_str)
        # Descriptions of bytes literals
        init_bytes = c_string_array_initializer(literals.encoded_bytes_values())
        self.declare_global("const char * const []", "CPyLit_Bytes", initializer=init_bytes)
        # Descriptions of int literals
        init_int = c_string_array_initializer(literals.encoded_int_values())
        self.declare_global("const char * const []", "CPyLit_Int", initializer=init_int)
        # Descriptions of float literals
        init_floats = c_array_initializer(literals.encoded_float_values())
        self.declare_global("const double []", "CPyLit_Float", initializer=init_floats)
        # Descriptions of complex literals
        init_complex = c_array_initializer(literals.encoded_complex_values())
        self.declare_global("const double []", "CPyLit_Complex", initializer=init_complex)
        # Descriptions of tuple literals
        init_tuple = c_array_initializer(literals.encoded_tuple_values())
        self.declare_global("const int []", "CPyLit_Tuple", initializer=init_tuple)
        # Descriptions of frozenset literals
        init_frozenset = c_array_initializer(literals.encoded_frozenset_values())
        self.declare_global("const int []", "CPyLit_FrozenSet", initializer=init_frozenset)

    def generate_export_table(self, decl_emitter: Emitter, code_emitter: Emitter) -> None:
        """Generate the declaration and definition of the group's export struct.

        To avoid needing to deal with deeply platform specific issues
        involving dynamic library linking (and some possibly
        insurmountable issues involving cyclic dependencies), compiled
        code accesses functions and data in other compilation groups
        via an explicit "export struct".

        Each group declares a struct type that contains a pointer to
        every function and static variable it exports. It then
        populates this struct and stores a pointer to it in a capsule
        stored as an attribute named 'exports' on the group's shared
        library's python module.

        On load, a group's init function will import all of its
        dependencies' exports tables using the capsule mechanism and
        copy the contents into a local copy of the table (to eliminate
        the need for a pointer indirection when accessing it).

        Then, all calls to functions in another group and accesses to statics
        from another group are done indirectly via the export table.

        For example, a group containing a module b, where b contains a class B
        and a function bar, would declare an export table like:
            struct export_table_b {
                PyTypeObject **CPyType_B;
                PyObject *(*CPyDef_B)(CPyTagged cpy_r_x);
                CPyTagged (*CPyDef_B___foo)(PyObject *cpy_r_self, CPyTagged cpy_r_y);
                tuple_T2OI (*CPyDef_bar)(PyObject *cpy_r_x);
                char (*CPyDef___top_level__)(void);
            };
        that would be initialized with:
            static struct export_table_b exports = {
                &CPyType_B,
                &CPyDef_B,
                &CPyDef_B___foo,
                &CPyDef_bar,
                &CPyDef___top_level__,
            };
        To call `b.foo`, then, a function in another group would do
        `exports_b.CPyDef_bar(...)`.
        """

        decls = decl_emitter.context.declarations

        decl_emitter.emit_lines("", f"struct export_table{self.group_suffix} {{")
        for name, decl in decls.items():
            if decl.needs_export:
                decl_emitter.emit_line(pointerize("\n".join(decl.decl), name))

        decl_emitter.emit_line("};")

        code_emitter.emit_lines("", f"static struct export_table{self.group_suffix} exports = {{")
        for name, decl in decls.items():
            if decl.needs_export:
                code_emitter.emit_line(f"&{name},")

        code_emitter.emit_line("};")

    def generate_shared_lib_init(self, emitter: Emitter) -> None:
        """Generate the init function for a shared library.

        A shared library contains all the actual code for a
        compilation group.

        The init function is responsible for creating Capsules that
        wrap pointers to the initialization function of all the real
        init functions for modules in this shared library as well as
        the export table containing all the exported functions and
        values from all the modules.

        These capsules are stored in attributes of the shared library.
        """
        assert self.group_name is not None

        emitter.emit_line()

        short_name = shared_lib_name(self.group_name).split(".")[-1]

        emitter.emit_lines(
            f"static int exec_{short_name}(PyObject *module)",
            "{",
            "int res;",
            "PyObject *capsule;",
            "PyObject *tmp;",
            "",
        )

        lock_api = module_lock_api_name(self.group_name)
        emitter.emit_lines(
            f"if ({lock_api} == NULL) {{",
            f"{lock_api} = CPyModuleLockAPI_Alloc();",
            f"if ({lock_api} == NULL) goto fail;",
            "}",
            "if (intern_strings() < 0) goto fail;",
            "if (CPyGlobalsInit() < 0) goto fail;",
            "",
        )

        if self.compiler_options.separate:
            emitter.emit_lines(
                'capsule = PyCapsule_New(&exports, "{}.exports", NULL);'.format(
                    shared_lib_name(self.group_name)
                ),
                "if (!capsule) {",
                "goto fail;",
                "}",
                'res = PyObject_SetAttrString(module, "exports", capsule);',
                "Py_DECREF(capsule);",
                "if (res < 0) {",
                "goto fail;",
                "}",
                "",
                # Expose ensure_deps_<short> as a capsule so the shim can call
                # it before invoking the per-module init.
                f"extern int ensure_deps_{short_name}(void);",
                'capsule = PyCapsule_New((void *)ensure_deps_{sh}, "{lib}.ensure_deps", NULL);'.format(
                    sh=short_name, lib=shared_lib_name(self.group_name)
                ),
                "if (!capsule) {",
                "goto fail;",
                "}",
                'res = PyObject_SetAttrString(module, "ensure_deps", capsule);',
                "Py_DECREF(capsule);",
                "if (res < 0) {",
                "goto fail;",
                "}",
                "",
            )

        for mod in self.modules:
            name = exported_name(mod)
            if self.multi_phase_init:
                capsule_func_name = module_exec_name(mod)
                capsule_name_prefix = "exec_"
                emitter.emit_line(f"extern int {capsule_func_name}(PyObject *);")
            else:
                capsule_func_name = module_init_name(mod)
                capsule_name_prefix = "init_"
                emitter.emit_line(f"extern PyObject *{capsule_func_name}(void);")
            emitter.emit_lines(
                'capsule = PyCapsule_New((void *){}, "{}.{}{}", NULL);'.format(
                    capsule_func_name, shared_lib_name(self.group_name), capsule_name_prefix, name
                ),
                "if (!capsule) {",
                "goto fail;",
                "}",
                f'res = PyObject_SetAttrString(module, "{capsule_name_prefix}{name}", capsule);',
                "Py_DECREF(capsule);",
                "if (res < 0) {",
                "goto fail;",
                "}",
                "",
            )

        # End of exec_<short_name>: only sets up capsules/module attributes.
        # Cross-group imports (populating `exports_<dep>` tables) are split
        # out into ensure_deps_<short_name>() below and run later, from the
        # shim's PyInit. See generate_shared_lib_init for details.
        emitter.emit_lines("return 0;", "fail:", "return -1;", "}")

        if self.compiler_options.separate:
            # ensure_deps_<short>(): populates cross-group exports tables. Run
            # once, lazily, from the shim's PyInit just before invoking the
            # per-module init capsule. This defers cross-group imports out of
            # the shared-lib PyInit so they can't transitively trigger a
            # sibling package's __init__.py while another package __init__.py
            # is still mid-flight.
            emitter.emit_lines(
                "",
                f"int ensure_deps_{short_name}(void)",
                "{",
                "static int done = 0;",
                "if (done) return 0;",
            )
            if self.context.group_deps:
                emitter.emit_lines(
                    "static PyObject *_mypyc_fromlist = NULL;",
                    "if (!_mypyc_fromlist) {",
                    '_mypyc_fromlist = Py_BuildValue("(s)", "*");',
                    "if (!_mypyc_fromlist) return -1;",
                    "}",
                    "PyObject *tmp;",
                    "PyObject *caps;",
                )
            for group in sorted(self.context.group_deps):
                egroup = exported_name(group)
                # ImportModuleLevel with fromlist returns the leaf via
                # sys.modules (no dotted getattr walk), and fetching the
                # `exports` capsule directly off that module bypasses
                # PyCapsule_Import (which would redo the attribute walk).
                emitter.emit_lines(
                    'tmp = PyImport_ImportModuleLevel("{}", NULL, NULL, _mypyc_fromlist, 0);'.format(
                        shared_lib_name(group)
                    ),
                    "if (!tmp) return -1;",
                    'caps = PyObject_GetAttrString(tmp, "exports");',
                    "Py_DECREF(tmp);",
                    "if (!caps) return -1;",
                    "struct export_table_{g} *pexports_{g} = "
                    '(struct export_table_{g} *)PyCapsule_GetPointer(caps, "{lib}.exports");'.format(
                        g=egroup, lib=shared_lib_name(group)
                    ),
                    "Py_DECREF(caps);",
                    f"if (!pexports_{egroup}) return -1;",
                    "memcpy(&exports_{g}, pexports_{g}, sizeof(exports_{g}));".format(g=egroup),
                )
            emitter.emit_lines("done = 1;", "return 0;", "}")

        if self.multi_phase_init:
            emitter.emit_lines(
                f"static PyModuleDef_Slot slots_{short_name}[] = {{",
                f"{{Py_mod_exec, exec_{short_name}}},",
                "{Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},",
                "{Py_mod_gil, Py_MOD_GIL_NOT_USED},",
                "{0, NULL},",
                "};",
            )

        size = 0 if self.multi_phase_init else -1
        emitter.emit_lines(
            f"static PyModuleDef module_def_{short_name} = {{",
            "PyModuleDef_HEAD_INIT,",
            f'.m_name = "{shared_lib_name(self.group_name)}",',
            ".m_doc = NULL,",
            f".m_size = {size},",
            ".m_methods = NULL,",
        )
        if self.multi_phase_init:
            emitter.emit_line(f".m_slots = slots_{short_name},")
        emitter.emit_line("};")

        if self.multi_phase_init:
            emitter.emit_lines(
                f"PyMODINIT_FUNC PyInit_{short_name}(void) {{",
                f"return PyModuleDef_Init(&module_def_{short_name});",
                "}",
            )
        else:
            emitter.emit_lines(
                f"PyMODINIT_FUNC PyInit_{short_name}(void) {{",
                "static PyObject *module = NULL;",
                "if (module) {",
                "Py_INCREF(module);",
                "return module;",
                "}",
                f"module = PyModule_Create(&module_def_{short_name});",
                "if (!module) {",
                "return NULL;",
                "}",
                f"if (exec_{short_name}(module) < 0) {{",
                "Py_DECREF(module);",
                "module = NULL;",
                "return NULL;",
                "}",
                "return module;",
                "}",
            )

    def generate_globals_init(self, emitter: Emitter) -> None:
        emitter.emit_lines(
            "",
            "int CPyGlobalsInit(void)",
            "{",
            "static int is_initialized = 0;",
            "if (is_initialized) return 0;",
            "",
        )

        emitter.emit_line("CPy_Init();")
        for symbol, fixup in self.simple_inits:
            emitter.emit_line(f"{symbol} = {fixup};")

        values = "CPyLit_Str, CPyLit_Bytes, CPyLit_Int, CPyLit_Float, CPyLit_Complex, CPyLit_Tuple, CPyLit_FrozenSet"
        emitter.emit_lines(
            f"if (CPyStatics_Initialize(CPyStatics, {values}) < 0) {{", "return -1;", "}"
        )

        emitter.emit_lines("is_initialized = 1;", "return 0;", "}")

    def generate_module_def(self, emitter: Emitter, module_name: str, module: ModuleIR) -> None:
        """Emit the PyModuleDef struct for a module and the module init function."""
        module_prefix = emitter.names.private_name(module_name)
        self.emit_module_methods(emitter, module_name, module_prefix, module)
        self.emit_module_exec_func(emitter, module_name, module_prefix, module)

        # If using multi-phase init and a shared lib, parts of module definition
        # will happen in the shim modules, so we skip some steps here.
        if not (self.multi_phase_init and self.use_shared_lib):
            if self.multi_phase_init:
                self.emit_module_def_slots(emitter, module_prefix, module_name)
            self.emit_module_def_struct(emitter, module_name, module_prefix)
            self.emit_module_init_func(emitter, module_name, module_prefix)
        elif self.use_shared_lib:
            # Multi-phase init with shared lib: shims handle PyInit_*, but we
            # still need CPyInitOnly_* for same-group native imports, and the
            # PyModuleDef struct it depends on.
            self.emit_module_def_struct(emitter, module_name, module_prefix)
            self.emit_init_only_func(emitter, module_name, module_prefix)

    def emit_module_def_slots(
        self, emitter: Emitter, module_prefix: str, module_name: str
    ) -> None:
        name = f"{module_prefix}_slots"
        exec_name = module_exec_name(module_name)

        emitter.emit_line(f"static PyModuleDef_Slot {name}[] = {{")
        emitter.emit_line(f"{{Py_mod_exec, {exec_name}}},")
        if sys.version_info >= (3, 12):
            # Multiple interpreter support requires not using any C global state,
            # which we don't support yet.
            emitter.emit_line(
                "{Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},"
            )
        if sys.version_info >= (3, 13):
            # Declare support for free-threading to enable experimentation,
            # even if we don't properly support it.
            emitter.emit_line("{Py_mod_gil, Py_MOD_GIL_NOT_USED},")
        emitter.emit_line("{0, NULL},")
        emitter.emit_line("};")

    def emit_module_methods(
        self, emitter: Emitter, module_name: str, module_prefix: str, module: ModuleIR
    ) -> None:
        """Emit module methods (the static PyMethodDef table)."""
        emitter.emit_line(f"static PyMethodDef {module_prefix}module_methods[] = {{")
        for fn in module.functions:
            if fn.class_name is not None or fn.name == TOP_LEVEL_NAME:
                continue
            # Coroutines are added to the module dict when the module is initialized.
            if fn.decl.is_coroutine:
                continue
            name = short_id_from_name(fn.name, fn.decl.shortname, fn.line)
            if is_fastcall_supported(fn, emitter.capi_version):
                flag = "METH_FASTCALL"
            else:
                flag = "METH_VARARGS"
            doc = native_function_doc_initializer(fn)
            emitter.emit_line(
                (
                    '{{"{name}", (PyCFunction){prefix}{cname}, {flag} | METH_KEYWORDS, '
                    "PyDoc_STR({doc}) /* docstring */}},"
                ).format(
                    name=name, cname=fn.cname(emitter.names), prefix=PREFIX, flag=flag, doc=doc
                )
            )
        emitter.emit_line("{NULL, NULL, 0, NULL}")
        emitter.emit_line("};")
        emitter.emit_line()

    def emit_module_def_struct(
        self, emitter: Emitter, module_name: str, module_prefix: str
    ) -> None:
        """Emit the static module definition struct (PyModuleDef)."""
        emitter.emit_lines(
            f"static struct PyModuleDef {module_prefix}module = {{",
            "PyModuleDef_HEAD_INIT,",
            f'"{module_name}",',
            "NULL, /* docstring */",
            "0,       /* size of per-interpreter state of the module */",
        )
        if self.multi_phase_init:
            # Methods are added later via PyModule_AddFunctions in CPyExec_*.
            emitter.emit_line("NULL, /* m_methods */")
        else:
            emitter.emit_line(f"{module_prefix}module_methods,")
        if self.multi_phase_init and not self.use_shared_lib:
            slots_name = f"{module_prefix}_slots"
            emitter.emit_line(f"{slots_name}, /* m_slots */")
        else:
            emitter.emit_line("NULL,")
        emitter.emit_line("};")
        emitter.emit_line()

    def emit_coroutine_wrappers(self, emitter: Emitter, module: ModuleIR, globals: str) -> None:
        """Emit insertion of coroutines into the module dict when the module is initialized.
        Coroutines are wrapped in CPyFunction objects to enable introspection by functions like
        inspect.iscoroutinefunction(fn).
        """
        for fn in module.functions:
            if fn.class_name is not None or fn.name == TOP_LEVEL_NAME:
                continue
            if not fn.decl.is_coroutine:
                continue

            filepath = self.source_paths[module.fullname]
            error_stmt = "    goto fail;"
            name = short_id_from_name(fn.name, fn.decl.shortname, fn.line)
            wrapper_name = emitter.emit_cpyfunction_instance(fn, name, filepath, error_stmt)
            name_obj = f"name_{wrapper_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({globals}, {name_obj}, (PyObject *){wrapper_name}) < 0)"
            )
            emitter.emit_line(error_stmt)

    def emit_module_exec_func(
        self, emitter: Emitter, module_name: str, module_prefix: str, module: ModuleIR
    ) -> None:
        """Emit the module exec function.

        If we are compiling just one module, this will be the normal C API
        exec function. If we are compiling 2+ modules, we generate a shared
        library for the modules and shims that call into the shared
        library, and in this case the shared module defines an internal
        exec function for each module and these will be called by the shims
        via Capsules.
        """
        exec_name = module_exec_name(module_name)
        declaration = f"int {exec_name}(PyObject *module)"
        emitter.context.declarations[exec_name] = HeaderDeclaration(declaration + ";")
        impl_name = f"{exec_name}__impl"
        module_static = self.module_internal_static_name(module_name, emitter)
        state = module_import_state_name(module_name)
        module_cache = emitter.static_name(module_name, None, prefix=MODULE_PREFIX)
        emitter.emit_lines(f"static int {impl_name}(PyObject *module)", "{")
        if not self.use_shared_lib:
            emitter.emit_lines("if (intern_strings() < 0)", "    return -1;")
        if self.compiler_options.depends_on_librt_internal:
            emitter.emit_line("if (import_librt_internal() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        if LIBRT_BASE64 in module.dependencies:
            emitter.emit_line("if (import_librt_base64() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        if LIBRT_STRINGS in module.dependencies:
            emitter.emit_line("if (import_librt_strings() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        if LIBRT_TIME in module.dependencies:
            emitter.emit_line("if (import_librt_time() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        if LIBRT_THREADING in module.dependencies:
            emitter.emit_line("if (import_librt_threading() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        if LIBRT_VECS in module.dependencies:
            emitter.emit_line("if (import_librt_vecs() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        if LIBRT_RANDOM in module.dependencies:
            emitter.emit_line("if (import_librt_random() < 0) {")
            emitter.emit_line("return -1;")
            emitter.emit_line("}")
        emitter.emit_line("PyObject* modname = NULL;")
        if self.multi_phase_init:
            emitter.emit_line(f"{module_static} = module;")
        emitter.emit_line(
            f'modname = PyObject_GetAttrString((PyObject *){module_static}, "__name__");'
        )

        module_globals = emitter.static_name("globals", module_name)
        emitter.emit_lines(
            f"{module_globals} = PyModule_GetDict({module_static});",
            f"if (unlikely({module_globals} == NULL))",
            "    goto fail;",
        )

        if self.multi_phase_init:
            emitter.emit_lines(
                f"if (PyModule_AddFunctions(module, {module_prefix}module_methods) < 0)",
                "    goto fail;",
            )

        self.emit_coroutine_wrappers(emitter, module, module_globals)

        # HACK: Manually instantiate generated classes here
        type_structs: list[str] = []
        for cl in module.classes:
            type_struct = emitter.type_struct_name(cl)
            type_structs.append(type_struct)
            if cl.is_generated:
                error_stmt = "    goto fail;"
                emitter.emit_lines(
                    "{t} = (PyTypeObject *)CPyType_FromTemplate("
                    "(PyObject *){t}_template, NULL, modname);".format(t=type_struct)
                )
                emitter.emit_lines(f"if (unlikely(!{type_struct}))", error_stmt)
                name_prefix = cl.name_prefix(emitter.names)
                emitter.emit_line(f"CPyDef_{name_prefix}_trait_vtable_setup();")

        if not self.use_shared_lib:
            # With shared lib we initialize globals in its init function in case
            # modules are executed concurrently.
            emitter.emit_lines("if (CPyGlobalsInit() < 0)", "    goto fail;")

        self.generate_top_level_call(module, emitter)

        emitter.emit_lines("Py_DECREF(modname);")

        emitter.emit_line("return 0;")
        emitter.emit_lines("fail:")
        if self.multi_phase_init:
            emitter.emit_lines(f"{module_static} = NULL;", "Py_CLEAR(modname);")
        else:
            emitter.emit_lines(f"Py_CLEAR({module_static});", "Py_CLEAR(modname);")
        for name, typ in module.final_names:
            static_name = emitter.static_name(name, module_name)
            emitter.emit_dec_ref(static_name, typ, is_xdec=True)
            undef = emitter.c_undefined_value(typ)
            emitter.emit_line(f"{static_name} = {undef};")
        # the type objects returned from CPyType_FromTemplate are all new references
        # so we have to decref them
        for t in type_structs:
            emitter.emit_line(f"Py_CLEAR({t});")
        emitter.emit_line("return -1;")
        emitter.emit_line("}")

        emitter.emit_lines(
            declaration,
            "{",
            f"return CPyImport_Exec(module, {impl_name}, &{state}, &{module_cache});",
            "}",
        )

    def emit_init_only_func(self, emitter: Emitter, module_name: str, module_prefix: str) -> None:
        """Emit CPyInitOnly_* which creates the module object without executing the body.

        This allows the caller to set up attributes like __file__ and __package__
        before the module body runs. Used for same-group native imports.
        """
        init_only_name = module_init_only_name(module_name)
        init_only_decl = f"PyObject *{init_only_name}(void)"
        emitter.context.declarations[init_only_name] = HeaderDeclaration(init_only_decl + ";")
        module_static = self.module_internal_static_name(module_name, emitter)
        emitter.emit_lines(init_only_decl, "{")
        emitter.emit_lines(
            f"if ({module_static}) {{",
            f"Py_INCREF({module_static});",
            f"return {module_static};",
            "}",
        )
        emitter.emit_lines(
            f"{module_static} = PyModule_Create(&{module_prefix}module);",
            f"return {module_static};",
        )
        emitter.emit_lines("}")
        emitter.emit_line("")

    def emit_module_init_func(
        self, emitter: Emitter, module_name: str, module_prefix: str
    ) -> None:
        if not self.use_shared_lib:
            declaration = f"PyMODINIT_FUNC PyInit_{module_name}(void)"
        else:
            n = module_init_name(module_name)
            declaration = f"PyObject *{n}(void)"
            emitter.context.declarations[n] = HeaderDeclaration(declaration + ";")

        if self.multi_phase_init:
            emitter.emit_lines(declaration, "{")
            def_name = f"{module_prefix}module"
            emitter.emit_line(f"return PyModuleDef_Init(&{def_name});")
            emitter.emit_line("}")
            return

        exec_func = module_exec_name(module_name)

        if self.use_shared_lib:
            self.emit_init_only_func(emitter, module_name, module_prefix)

        # Emit CPyInit_* / PyInit_* which creates the module and executes the body.
        emitter.emit_lines(declaration, "{")
        module_static = self.module_internal_static_name(module_name, emitter)

        emitter.emit_line("PyObject* modname = NULL;")
        emitter.emit_line("PyObject *initializing_spec = NULL;")
        emitter.emit_lines(
            f"if ({module_static}) {{",
            f"Py_INCREF({module_static});",
            f"return {module_static};",
            "}",
        )

        emitter.emit_lines(
            f"{module_static} = PyModule_Create(&{module_prefix}module);",
            f"if (unlikely({module_static} == NULL))",
            "    goto fail;",
        )

        emitter.emit_line(f'modname = PyUnicode_FromString("{module_name}");')
        emitter.emit_line("if (modname == NULL) CPyError_OutOfMemory();")
        emitter.emit_line("int rv = 0;")
        if self.group_name:
            shared_lib_mod_name = shared_lib_name(self.group_name)
            emitter.emit_line("PyObject *mod_dict = PyImport_GetModuleDict();")
            emitter.emit_line("PyObject *shared_lib = NULL;")
            emitter.emit_line(
                f'rv = PyDict_GetItemStringRef(mod_dict, "{shared_lib_mod_name}", &shared_lib);'
            )
            emitter.emit_line("if (rv < 0) goto fail;")
            emitter.emit_line(
                'PyObject *shared_lib_file = PyObject_GetAttrString(shared_lib, "__file__");'
            )
            emitter.emit_line("if (shared_lib_file == NULL) goto fail;")
        else:
            emitter.emit_line(
                f'PyObject *shared_lib_file = PyUnicode_FromString("{module_name + EXT_SUFFIX}");'
            )
            emitter.emit_line("if (shared_lib_file == NULL) CPyError_OutOfMemory();")
        emitter.emit_line(f'PyObject *ext_suffix = PyUnicode_FromString("{EXT_SUFFIX}");')
        emitter.emit_line("if (ext_suffix == NULL) CPyError_OutOfMemory();")
        is_pkg = int(self.source_paths[module_name].endswith("__init__.py"))
        emitter.emit_line(f"Py_ssize_t is_pkg = {is_pkg};")

        emitter.emit_line(
            f"rv = CPyImport_SetDunderAttrs({module_static}, modname, shared_lib_file, ext_suffix, is_pkg);"
        )
        emitter.emit_line("Py_DECREF(ext_suffix);")
        emitter.emit_line("Py_DECREF(shared_lib_file);")
        emitter.emit_line("if (rv < 0) goto fail;")

        # Mark the module as initializing before publishing it so that CPython's
        # import fast path waits on the module lock. Publishing early also lets
        # CPyImport_ImportNative detect circular imports.
        emitter.emit_line(f"initializing_spec = CPyImport_BeginInitializing({module_static});")
        emitter.emit_line("if (initializing_spec == NULL)")
        emitter.emit_line("    goto fail;")
        emitter.emit_line(
            f"if (PyObject_SetItem(PyImport_GetModuleDict(), modname, {module_static}) < 0)"
        )
        emitter.emit_line("    goto fail;")
        emitter.emit_line("Py_CLEAR(modname);")
        emitter.emit_lines(f"if ({exec_func}({module_static}) != 0)", "    goto fail;")
        emitter.emit_line("rv = CPyImport_EndInitializing(initializing_spec);")
        emitter.emit_line("initializing_spec = NULL;")
        emitter.emit_line("if (rv < 0)")
        emitter.emit_line("    goto fail;")
        emitter.emit_line(f"return {module_static};")
        emitter.emit_lines("fail:")
        # Clean up on failure: remove from sys.modules and clear the static
        # so that a subsequent import attempt will retry initialization.
        emitter.emit_line("{")
        emitter.emit_line("    PyObject *exc_type, *exc_val, *exc_tb;")
        emitter.emit_line("    PyErr_Fetch(&exc_type, &exc_val, &exc_tb);")
        emitter.emit_line("    if (modname == NULL) {")
        emitter.emit_line(f'        modname = PyUnicode_FromString("{module_name}");')
        emitter.emit_line("        if (modname == NULL) CPyError_OutOfMemory();")
        emitter.emit_line("    }")
        emitter.emit_line("    PyObject_DelItem(PyImport_GetModuleDict(), modname);")
        emitter.emit_line("    PyErr_Clear();")
        emitter.emit_line("    Py_DECREF(modname);")
        emitter.emit_line("    if (initializing_spec != NULL) {")
        emitter.emit_line("        CPyImport_EndInitializing(initializing_spec);")
        emitter.emit_line("        PyErr_Clear();")
        emitter.emit_line("    }")
        emitter.emit_line(f"    Py_CLEAR({module_static});")
        emitter.emit_line("    PyErr_Restore(exc_type, exc_val, exc_tb);")
        emitter.emit_line("}")
        emitter.emit_line("return NULL;")
        emitter.emit_lines("}")

    def generate_top_level_call(self, module: ModuleIR, emitter: Emitter) -> None:
        """Generate call to function representing module top level."""
        # Optimization: we tend to put the top level last, so reverse iterate
        for fn in reversed(module.functions):
            if fn.name == TOP_LEVEL_NAME:
                emitter.emit_lines(
                    f"char result = {emitter.native_function_name(fn.decl)}();",
                    "if (result == 2)",
                    "    goto fail;",
                )
                break

    def toposort_declarations(self) -> list[HeaderDeclaration]:
        """Topologically sort the declaration dict by dependencies.

        Declarations can require other declarations to come prior in C (such as declaring structs).
        In order to guarantee that the C output will compile the declarations will thus need to
        be properly ordered. This simple DFS guarantees that we have a proper ordering.

        This runs in O(V + E).
        """
        result = []
        marked_declarations: dict[str, MarkedDeclaration] = {}
        for k, v in self.context.declarations.items():
            marked_declarations[k] = MarkedDeclaration(v, False)

        def _toposort_visit(name: str) -> None:
            decl = marked_declarations[name]
            if decl.mark:
                return

            for child in sorted(decl.declaration.dependencies):
                _toposort_visit(child)

            result.append(decl.declaration)
            decl.mark = True

        for name in marked_declarations:
            _toposort_visit(name)

        return result

    def declare_global(
        self, type_spaced: str, name: str, *, initializer: str | None = None
    ) -> None:
        if "[" not in type_spaced:
            base = f"{type_spaced}{name}"
        else:
            a, b = type_spaced.split("[", 1)
            base = f"{a}{name}[{b}"

        if not initializer:
            defn = None
        else:
            defn = [f"{base} = {initializer};"]
        if name not in self.context.declarations:
            self.context.declarations[name] = HeaderDeclaration(f"{base};", defn=defn)

    def declare_internal_globals(self, module_name: str, emitter: Emitter) -> None:
        static_name = emitter.static_name("globals", module_name)
        if static_name not in self.context.declarations:
            self.context.declarations[static_name] = HeaderDeclaration(
                f"PyObject *{static_name};", needs_export=True
            )

    def module_internal_static_name(self, module_name: str, emitter: Emitter) -> str:
        return emitter.static_name(module_name + "__internal", None, prefix=MODULE_PREFIX)

    def declare_module(self, module_name: str, emitter: Emitter) -> None:
        # We declare two globals for each compiled module:
        # one used internally in the implementation of module init to cache results
        # and prevent infinite recursion in import cycles, and one used
        # by other modules to refer to it.
        if module_name in self.modules:
            internal_static_name = self.module_internal_static_name(module_name, emitter)
            self.declare_global("CPyModule *", internal_static_name, initializer="NULL")
            state_name = module_import_state_name(module_name)
            if state_name not in self.context.declarations:
                self.context.declarations[state_name] = HeaderDeclaration(
                    f"CPyImportState {state_name};", defn=[f"CPyImportState {state_name} = {{0}};"]
                )
        static_name = emitter.static_name(module_name, None, prefix=MODULE_PREFIX)
        self.declare_global("CPyModuleCache ", static_name)
        self.simple_inits.append((static_name, "(CPyModuleCache)Py_None"))

    def declare_module_lock_api(self) -> None:
        assert self.group_name is not None
        name = module_lock_api_name(self.group_name)
        if name not in self.context.declarations:
            self.context.declarations[name] = HeaderDeclaration(
                f"CPyModuleLockAPI *{name};", defn=[f"CPyModuleLockAPI *{name} = NULL;"]
            )

    def declare_imports(self, imps: Iterable[str], emitter: Emitter) -> None:
        for imp in imps:
            self.declare_module(imp, emitter)

    def declare_finals(
        self, module: str, final_names: Iterable[tuple[str, RType]], emitter: Emitter
    ) -> None:
        for name, typ in final_names:
            static_name = emitter.static_name(name, module)
            emitter.context.declarations[static_name] = HeaderDeclaration(
                f"{emitter.ctype_spaced(typ)}{static_name};",
                [self.final_definition(module, name, typ, emitter)],
                needs_export=True,
            )

    def final_definition(self, module: str, name: str, typ: RType, emitter: Emitter) -> str:
        static_name = emitter.static_name(name, module)
        # Here we rely on the fact that undefined value and error value are always the same
        undefined = emitter.c_initializer_undefined_value(typ)
        return f"{emitter.ctype_spaced(typ)}{static_name} = {undefined};"

    def declare_static_pyobject(self, identifier: str, emitter: Emitter) -> None:
        symbol = emitter.static_name(identifier, None)
        self.declare_global("PyObject *", symbol)

    def declare_type_vars(self, module: str, type_var_names: list[str], emitter: Emitter) -> None:
        for name in type_var_names:
            static_name = emitter.static_name(name, module, prefix=TYPE_VAR_PREFIX)
            emitter.context.declarations[static_name] = HeaderDeclaration(
                f"PyObject *{static_name};",
                [f"PyObject *{static_name} = NULL;"],
                needs_export=False,
            )


T = TypeVar("T")


def toposort(deps: dict[T, set[T]]) -> list[T]:
    """Topologically sort a dict from item to dependencies.

    This runs in O(V + E).
    """
    result = []
    visited: set[T] = set()

    def visit(item: T) -> None:
        if item in visited:
            return

        for child in deps[item]:
            visit(child)

        result.append(item)
        visited.add(item)

    for item in deps:
        visit(item)

    return result


def is_fastcall_supported(fn: FuncIR, capi_version: tuple[int, int]) -> bool:
    if fn.class_name is not None:
        if fn.name == "__call__":
            # We can use vectorcalls (PEP 590) when supported
            return True
        # TODO: Support fastcall for __init__ and __new__.
        return fn.name != "__init__" and fn.name != "__new__"
    return True


def collect_literals(fn: FuncIR, literals: Literals) -> None:
    """Store all Python literal object refs in fn.

    Collecting literals must happen only after we have the final IR.
    This way we won't include literals that have been optimized away.
    """
    for block in fn.blocks:
        for op in block.ops:
            if isinstance(op, LoadLiteral):
                literals.record_literal(op.value)


def c_string_array_initializer(components: list[bytes]) -> str:
    result = []
    result.append("{\n")
    for s in components:
        result.append("    " + c_string_initializer(s) + ",\n")
    result.append("}")
    return "".join(result)
