# Portions copyright (c) Meta Platforms, Inc. and affiliates.

# pyre-strict

import sys
from opcode import (
    hascompare,
    hasconst,
    hasfree,
    hasjabs,
    hasjrel,
    haslocal,
    hasname,
    opmap,
    opname,
)

from .opcodebase import Opcode

STATIC_OPMAP: dict[str, int] = {}
STATIC_OPNAMES: list[str] = [f"<{i}>" for i in range(256)]
STATIC_CONST_OPCODES: list[int] = []

if sys.version_info >= (3, 12):
    # pyre-fixme[21]: Could not find name `_cache_format` in `opcode` (stubbed).
    # pyre-fixme[21]: Could not find name `_inline_cache_entries` in `opcode` (stubbed).
    # pyre-fixme[21]: Could not find name `_specializations` in `opcode` (stubbed).
    from opcode import _cache_format, _inline_cache_entries, _specializations, hasarg

    if sys.version_info >= (3, 15):
        opmap = dict(opmap)
        _cache_format = dict(_cache_format)
        _inline_cache_entries = dict(_inline_cache_entries)
        _specializations = dict(_specializations)

    from cinderx import opcode as cinderx_opcode

    cinderx_opcode.init(
        STATIC_OPNAMES if sys.version_info >= (3, 14) else opname,
        STATIC_OPMAP,
        hasname,
        hasjrel,
        hasjabs,
        STATIC_CONST_OPCODES if sys.version_info >= (3, 14) else hasconst,
        hasarg,
        # pyre-fixme[16]: Module `opcode` has no attribute `_cache_format`.
        _cache_format,
        # pyre-fixme[16]: Module `opcode` has no attribute `_specializations`.
        _specializations,
        # pyre-fixme[16]: Module `opcode` has no attribute `_inline_cache_entries`.
        _inline_cache_entries,
    )
    if sys.version_info >= (3, 14):
        opname[126] = "EXTENDED_OPCODE"
        opmap["EXTENDED_OPCODE"] = 126
        hasarg.append(126)

    opmap.update(STATIC_OPMAP)

    if "dis" in sys.modules:
        # Fix up dis module to use the CinderX opcodes
        import dis

        dis._all_opname = list(opname)
        dis._all_opmap = dict(opmap)
        dis._empty_slot = [
            slot
            # pyre-fixme[16]: Module `dis` has no attribute `_all_opname`.
            for slot, name in enumerate(dis._all_opname)
            if name.startswith("<")
        ]


opcode: Opcode = Opcode()
for opname, opnum in opmap.items():
    if opnum in hasname:
        opcode.name_op(opname, opnum)
    elif opnum in hasjrel:
        opcode.jrel_op(opname, opnum)
    elif opnum in hasjabs:
        opcode.jabs_op(opname, opnum)
    else:
        opcode.def_op(opname, opnum)
        if opnum in hasconst:
            opcode.hasconst.add(opname)
        elif opnum in hasfree:
            opcode.hasfree.add(opnum)
        elif opnum in haslocal:
            opcode.haslocal.add(opnum)
        elif opnum in hascompare:
            opcode.hascompare.add(opnum)


for opnum in STATIC_CONST_OPCODES:
    opcode.hasconst.add(STATIC_OPNAMES[opnum])


FVC_MASK = 0x3
FVC_NONE = 0x0
FVC_STR = 0x1
FVC_REPR = 0x2
FVC_ASCII = 0x3
FVS_MASK = 0x4
FVS_HAVE_SPEC = 0x4


opcode.stack_effects.update(
    NOP=0,
    RESUME=0,
    POP_TOP=-1,
    ROT_TWO=0,
    ROT_THREE=0,
    DUP_TOP=1,
    DUP_TOP_TWO=2,
    ROT_FOUR=0,
    UNARY_POSITIVE=0,
    UNARY_NEGATIVE=0,
    UNARY_NOT=0,
    UNARY_INVERT=0,
    BINARY_MATRIX_MULTIPLY=-1,
    INPLACE_MATRIX_MULTIPLY=-1,
    BINARY_POWER=-1,
    BINARY_MULTIPLY=-1,
    BINARY_MODULO=-1,
    BINARY_ADD=-1,
    BINARY_SUBTRACT=-1,
    BINARY_SUBSCR=-1,
    BINARY_FLOOR_DIVIDE=-1,
    BINARY_TRUE_DIVIDE=-1,
    INPLACE_FLOOR_DIVIDE=-1,
    INPLACE_TRUE_DIVIDE=-1,
    GET_LEN=1,
    MATCH_MAPPING=1,
    MATCH_SEQUENCE=1,
    MATCH_KEYS=2,
    COPY_DICT_WITHOUT_KEYS=0,
    WITH_EXCEPT_START=1,
    GET_AITER=0,
    GET_ANEXT=1,
    BEFORE_ASYNC_WITH=1,
    END_ASYNC_FOR=-7,
    INPLACE_ADD=-1,
    INPLACE_SUBTRACT=-1,
    INPLACE_MULTIPLY=-1,
    INPLACE_MODULO=-1,
    STORE_SUBSCR=-3,
    DELETE_SUBSCR=-2,
    BINARY_LSHIFT=-1,
    BINARY_RSHIFT=-1,
    BINARY_AND=-1,
    BINARY_XOR=-1,
    BINARY_OR=-1,
    INPLACE_POWER=-1,
    GET_ITER=0,
    GET_YIELD_FROM_ITER=0,
    PRINT_EXPR=-1,
    LOAD_BUILD_CLASS=1,
    YIELD_FROM=-1,
    GET_AWAITABLE=0,
    LOAD_ASSERTION_ERROR=1,
    INPLACE_LSHIFT=-1,
    INPLACE_RSHIFT=-1,
    INPLACE_AND=-1,
    INPLACE_XOR=-1,
    INPLACE_OR=-1,
    LIST_TO_TUPLE=0,
    RETURN_VALUE=-1,
    IMPORT_STAR=-1,
    SETUP_ANNOTATIONS=0,
    YIELD_VALUE=0,
    POP_BLOCK=0,
    POP_EXCEPT=-3,
    STORE_NAME=-1,
    DELETE_NAME=0,
    UNPACK_SEQUENCE=lambda oparg, jmp=0: oparg - 1,
    FOR_ITER=lambda oparg, jmp=0: -1 if jmp > 0 else 1,
    UNPACK_EX=lambda oparg, jmp=0: (oparg & 0xFF) + (oparg >> 8),
    STORE_ATTR=-2,
    DELETE_ATTR=-1,
    STORE_GLOBAL=-1,
    DELETE_GLOBAL=0,
    ROT_N=0,
    LOAD_CONST=1,
    LOAD_NAME=1,
    BUILD_TUPLE=lambda oparg, jmp=0: 1 - oparg,
    BUILD_LIST=lambda oparg, jmp=0: 1 - oparg,
    BUILD_SET=lambda oparg, jmp=0: 1 - oparg,
    BUILD_MAP=lambda oparg, jmp=0: 1 - 2 * oparg,
    LOAD_ATTR=0,
    COMPARE_OP=-1,
    IMPORT_NAME=-1,
    IMPORT_FROM=1,
    JUMP_FORWARD=0,
    JUMP_IF_FALSE_OR_POP=lambda oparg, jmp=0: 0 if jmp else -1,
    JUMP_IF_TRUE_OR_POP=lambda oparg, jmp=0: 0 if jmp else -1,
    JUMP_ABSOLUTE=0,
    POP_JUMP_IF_FALSE=-1,
    POP_JUMP_IF_TRUE=-1,
    LOAD_GLOBAL=1,
    IS_OP=-1,
    CONTAINS_OP=-1,
    RERAISE=-3,
    JUMP_IF_NOT_EXC_MATCH=-2,
    SETUP_FINALLY=lambda oparg, jmp: 6 if jmp else 0,
    LOAD_FAST=1,
    STORE_FAST=-1,
    DELETE_FAST=0,
    GEN_START=-1,
    RAISE_VARARGS=lambda oparg, jmp=0: -oparg,
    CALL_FUNCTION=lambda oparg, jmp=0: -oparg,
    MAKE_FUNCTION=lambda oparg, jmp=0: -1
    - ((oparg & 0x01) != 0)
    - ((oparg & 0x02) != 0)
    - ((oparg & 0x04) != 0)
    - ((oparg & 0x08) != 0),
    BUILD_SLICE=lambda oparg, jmp=0: -2 if oparg == 3 else -1,
    LOAD_CLOSURE=1,
    LOAD_DEREF=1,
    STORE_DEREF=-1,
    DELETE_DEREF=0,
    CALL_FUNCTION_KW=lambda oparg, jmp=0: -oparg - 1,
    CALL_FUNCTION_EX=lambda oparg, jmp=0: -1 - ((oparg & 0x01) != 0),
    SETUP_WITH=lambda oparg, jmp=0: 6 if jmp else 1,
    EXTENDED_ARG=0,
    LIST_APPEND=-1,
    SET_ADD=-1,
    MAP_ADD=-2,
    LOAD_CLASSDEREF=1,
    MATCH_CLASS=-1,
    SETUP_ASYNC_WITH=lambda oparg, jmp: (-1 + 6) if jmp else 0,
    # If there's a fmt_spec on the stack, we go from 2->1,
    # else 1->1.
    FORMAT_VALUE=lambda oparg, jmp=0: -1 if (oparg & FVS_MASK) == FVS_HAVE_SPEC else 0,
    BUILD_CONST_KEY_MAP=lambda oparg, jmp=0: -oparg,
    BUILD_STRING=lambda oparg, jmp=0: 1 - oparg,
    INVOKE_METHOD=lambda oparg, jmp=0: -(oparg[1] + 1),
    LOAD_METHOD=1,
    CALL_METHOD=lambda oparg, jmp=0: -oparg - 1,
    LIST_EXTEND=-1,
    SET_UPDATE=-1,
    DICT_MERGE=-1,
    DICT_UPDATE=-1,
)

if sys.version_info >= (3, 12):
    # pyre-fixme[21]: Could not find name `_intrinsic_1_descs` in `opcode` (stubbed).
    # pyre-fixme[21]: Could not find name `_intrinsic_2_descs` in `opcode` (stubbed).
    # pyre-fixme[21]: Could not find name `_nb_ops` in `opcode` (stubbed).
    from opcode import (
        _intrinsic_1_descs as INTRINSIC_1,
        _intrinsic_2_descs as INTRINSIC_2,
        _nb_ops as NB_OPS,
    )
else:
    NB_OPS: list[tuple[str, str]] = []
    INTRINSIC_1: list[str] = []
    INTRINSIC_2: list[str] = []


if sys.version_info >= (3, 14):
    opcode.popped.update(
        ANNOTATIONS_PLACEHOLDER=0,
        BINARY_OP=2,
        BINARY_OP_ADD_FLOAT=2,
        BINARY_OP_ADD_INT=2,
        BINARY_OP_ADD_UNICODE=2,
        BINARY_OP_EXTEND=2,
        BINARY_OP_INPLACE_ADD_UNICODE=2,
        BINARY_OP_MULTIPLY_FLOAT=2,
        BINARY_OP_MULTIPLY_INT=2,
        BINARY_OP_SUBSCR_DICT=2,
        BINARY_OP_SUBSCR_GETITEM=2,
        BINARY_OP_SUBSCR_LIST_INT=2,
        BINARY_OP_SUBSCR_LIST_SLICE=2,
        BINARY_OP_SUBSCR_STR_INT=2,
        BINARY_OP_SUBSCR_TUPLE_INT=2,
        BINARY_OP_SUBTRACT_FLOAT=2,
        BINARY_OP_SUBTRACT_INT=2,
        BINARY_SLICE=3,
        BUILD_INTERPOLATION=lambda oparg: 2 + (oparg & 1),
        BUILD_LIST=lambda oparg: oparg,
        BUILD_MAP=lambda oparg: oparg * 2,
        BUILD_SET=lambda oparg: oparg,
        BUILD_SLICE=lambda oparg: oparg,
        BUILD_STRING=lambda oparg: oparg,
        BUILD_TEMPLATE=2,
        BUILD_TUPLE=lambda oparg: oparg,
        CACHE=0,
        CALL=lambda oparg: 2 + oparg,
        CALL_ALLOC_AND_ENTER_INIT=lambda oparg: 2 + oparg,
        CALL_BOUND_METHOD_EXACT_ARGS=lambda oparg: 2 + oparg,
        CALL_BOUND_METHOD_GENERAL=lambda oparg: 2 + oparg,
        CALL_BUILTIN_CLASS=lambda oparg: 2 + oparg,
        CALL_BUILTIN_FAST=lambda oparg: 2 + oparg,
        CALL_BUILTIN_FAST_WITH_KEYWORDS=lambda oparg: 2 + oparg,
        CALL_BUILTIN_O=lambda oparg: 2 + oparg,
        CALL_FUNCTION_EX=4,
        CALL_INTRINSIC_1=1,
        CALL_INTRINSIC_2=2,
        CALL_ISINSTANCE=lambda oparg: 2 + oparg,
        CALL_KW=lambda oparg: 3 + oparg,
        CALL_KW_BOUND_METHOD=lambda oparg: 3 + oparg,
        CALL_KW_NON_PY=lambda oparg: 3 + oparg,
        CALL_KW_PY=lambda oparg: 3 + oparg,
        CALL_LEN=3,
        CALL_LIST_APPEND=3,
        CALL_METHOD_DESCRIPTOR_FAST=lambda oparg: 2 + oparg,
        CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS=lambda oparg: 2 + oparg,
        CALL_METHOD_DESCRIPTOR_NOARGS=lambda oparg: 2 + oparg,
        CALL_METHOD_DESCRIPTOR_O=lambda oparg: 2 + oparg,
        CALL_NON_PY_GENERAL=lambda oparg: 2 + oparg,
        CALL_PY_EXACT_ARGS=lambda oparg: 2 + oparg,
        CALL_PY_GENERAL=lambda oparg: 2 + oparg,
        CALL_STR_1=3,
        CALL_TUPLE_1=3,
        CALL_TYPE_1=3,
        CHECK_EG_MATCH=2,
        CHECK_EXC_MATCH=2,
        CLEANUP_THROW=3,
        COMPARE_OP=2,
        COMPARE_OP_FLOAT=2,
        COMPARE_OP_INT=2,
        COMPARE_OP_STR=2,
        CONTAINS_OP=2,
        CONTAINS_OP_DICT=2,
        CONTAINS_OP_SET=2,
        CONVERT_VALUE=1,
        COPY=lambda oparg: 1 + (oparg - 1),
        COPY_FREE_VARS=0,
        DELETE_ATTR=1,
        DELETE_DEREF=0,
        DELETE_FAST=0,
        DELETE_GLOBAL=0,
        DELETE_NAME=0,
        DELETE_SUBSCR=2,
        DICT_MERGE=lambda oparg: 5 + (oparg - 1),
        DICT_UPDATE=lambda oparg: 2 + (oparg - 1),
        EAGER_IMPORT_NAME=2,
        END_ASYNC_FOR=2,
        END_FOR=1,
        END_SEND=2,
        ENTER_EXECUTOR=0,
        EXIT_INIT_CHECK=1,
        EXTENDED_ARG=0,
        FORMAT_SIMPLE=1,
        FORMAT_WITH_SPEC=2,
        FOR_ITER=1,
        FOR_ITER_GEN=1,
        FOR_ITER_LIST=1,
        FOR_ITER_RANGE=1,
        FOR_ITER_TUPLE=1,
        GET_AITER=1,
        GET_ANEXT=1,
        GET_AWAITABLE=1,
        GET_ITER=1,
        GET_LEN=1,
        GET_YIELD_FROM_ITER=1,
        IMPORT_FROM=1,
        IMPORT_NAME=2,
        INSTRUMENTED_CALL=lambda oparg: 2 + oparg,
        INSTRUMENTED_CALL_FUNCTION_EX=4,
        INSTRUMENTED_CALL_KW=lambda oparg: 3 + oparg,
        INSTRUMENTED_END_ASYNC_FOR=2,
        INSTRUMENTED_END_FOR=2,
        INSTRUMENTED_END_SEND=2,
        INSTRUMENTED_FOR_ITER=1,
        INSTRUMENTED_INSTRUCTION=0,
        INSTRUMENTED_JUMP_BACKWARD=0,
        INSTRUMENTED_JUMP_FORWARD=0,
        INSTRUMENTED_LINE=0,
        INSTRUMENTED_LOAD_SUPER_ATTR=3,
        INSTRUMENTED_NOT_TAKEN=0,
        INSTRUMENTED_POP_ITER=1,
        INSTRUMENTED_POP_JUMP_IF_FALSE=1,
        INSTRUMENTED_POP_JUMP_IF_NONE=1,
        INSTRUMENTED_POP_JUMP_IF_NOT_NONE=1,
        INSTRUMENTED_POP_JUMP_IF_TRUE=1,
        INSTRUMENTED_RESUME=0,
        INSTRUMENTED_RETURN_VALUE=1,
        INSTRUMENTED_YIELD_VALUE=1,
        INTERPRETER_EXIT=1,
        IS_OP=2,
        JUMP=0,
        JUMP_BACKWARD=0,
        JUMP_BACKWARD_JIT=0,
        JUMP_BACKWARD_NO_INTERRUPT=0,
        JUMP_BACKWARD_NO_JIT=0,
        JUMP_FORWARD=0,
        JUMP_IF_FALSE=1,
        JUMP_IF_TRUE=1,
        JUMP_NO_INTERRUPT=0,
        LIST_APPEND=lambda oparg: 2 + (oparg - 1),
        LIST_EXTEND=lambda oparg: 2 + (oparg - 1),
        LOAD_ATTR=1,
        LOAD_ATTR_CLASS=1,
        LOAD_ATTR_CLASS_WITH_METACLASS_CHECK=1,
        LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN=1,
        LOAD_ATTR_INSTANCE_VALUE=1,
        LOAD_ATTR_METHOD_LAZY_DICT=1,
        LOAD_ATTR_METHOD_NO_DICT=1,
        LOAD_ATTR_METHOD_WITH_VALUES=1,
        LOAD_ATTR_MODULE=1,
        LOAD_ATTR_NONDESCRIPTOR_NO_DICT=1,
        LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES=1,
        LOAD_ATTR_PROPERTY=1,
        LOAD_ATTR_SLOT=1,
        LOAD_ATTR_WITH_HINT=1,
        LOAD_BUILD_CLASS=0,
        LOAD_CLOSURE=0,
        LOAD_COMMON_CONSTANT=0,
        LOAD_CONST=0,
        LOAD_CONST_IMMORTAL=0,
        LOAD_CONST_MORTAL=0,
        LOAD_DEREF=0,
        LOAD_FAST=0,
        LOAD_FAST_AND_CLEAR=0,
        LOAD_FAST_BORROW=0,
        LOAD_FAST_BORROW_LOAD_FAST_BORROW=0,
        LOAD_FAST_CHECK=0,
        LOAD_FAST_LOAD_FAST=0,
        LOAD_FROM_DICT_OR_DEREF=1,
        LOAD_FROM_DICT_OR_GLOBALS=1,
        LOAD_GLOBAL=0,
        LOAD_GLOBAL_BUILTIN=0,
        LOAD_GLOBAL_MODULE=0,
        LOAD_LOCALS=0,
        LOAD_NAME=0,
        LOAD_SMALL_INT=0,
        LOAD_SPECIAL=1,
        LOAD_SUPER_ATTR=3,
        LOAD_SUPER_ATTR_ATTR=3,
        LOAD_SUPER_ATTR_METHOD=3,
        MAKE_CELL=0,
        MAKE_FUNCTION=1,
        MAP_ADD=lambda oparg: 3 + (oparg - 1),
        MATCH_CLASS=3,
        MATCH_KEYS=2,
        MATCH_MAPPING=1,
        MATCH_SEQUENCE=1,
        NOP=0,
        NOT_TAKEN=0,
        POP_BLOCK=0,
        POP_EXCEPT=1,
        POP_ITER=1,
        POP_JUMP_IF_FALSE=1,
        POP_JUMP_IF_NONE=1,
        POP_JUMP_IF_NOT_NONE=1,
        POP_JUMP_IF_TRUE=1,
        POP_TOP=1,
        PUSH_EXC_INFO=1,
        PUSH_NULL=0,
        RAISE_VARARGS=lambda oparg: oparg,
        RERAISE=lambda oparg: 1 + oparg,
        RESERVED=0,
        RESUME=0,
        RESUME_CHECK=0,
        RETURN_GENERATOR=0,
        RETURN_VALUE=1,
        SEND=2,
        SEND_GEN=2,
        SETUP_ANNOTATIONS=0,
        SETUP_CLEANUP=0,
        SETUP_FINALLY=0,
        SETUP_WITH=0,
        SET_ADD=lambda oparg: 2 + (oparg - 1),
        SET_FUNCTION_ATTRIBUTE=2,
        SET_UPDATE=lambda oparg: 2 + (oparg - 1),
        STORE_ATTR=2,
        STORE_ATTR_INSTANCE_VALUE=2,
        STORE_ATTR_SLOT=2,
        STORE_ATTR_WITH_HINT=2,
        STORE_DEREF=1,
        STORE_FAST=1,
        STORE_FAST_LOAD_FAST=1,
        STORE_FAST_MAYBE_NULL=1,
        STORE_FAST_STORE_FAST=2,
        STORE_GLOBAL=1,
        STORE_NAME=1,
        STORE_SLICE=4,
        STORE_SUBSCR=3,
        STORE_SUBSCR_DICT=3,
        STORE_SUBSCR_LIST_INT=3,
        SWAP=lambda oparg: 2 + (oparg - 2),
        TO_BOOL=1,
        TO_BOOL_ALWAYS_TRUE=1,
        TO_BOOL_BOOL=1,
        TO_BOOL_INT=1,
        TO_BOOL_LIST=1,
        TO_BOOL_NONE=1,
        TO_BOOL_STR=1,
        UNARY_INVERT=1,
        UNARY_NEGATIVE=1,
        UNARY_NOT=1,
        UNPACK_EX=1,
        UNPACK_SEQUENCE=1,
        UNPACK_SEQUENCE_LIST=1,
        UNPACK_SEQUENCE_TUPLE=1,
        UNPACK_SEQUENCE_TWO_TUPLE=1,
        WITH_EXCEPT_START=5,
        YIELD_VALUE=1,
        # Static opcodes
        EXTENDED_OPCODE=0,
        LOAD_FIELD=1,
        STORE_FIELD=2,
        CAST=1,
        LOAD_LOCAL=0,
        STORE_LOCAL=1,
        PRIMITIVE_BOX=1,
        POP_JUMP_IF_ZERO=1,
        POP_JUMP_IF_NONZERO=1,
        PRIMITIVE_UNBOX=1,
        PRIMITIVE_BINARY_OP=2,
        PRIMITIVE_UNARY_OP=1,
        PRIMITIVE_COMPARE_OP=2,
        LOAD_ITERABLE_ARG=1,
        LOAD_MAPPING_ARG=lambda oparg, jmp=0: 3 if oparg == 3 else 2,
        INVOKE_METHOD=lambda oparg, jmp=0: (oparg[1] + 2),
        INVOKE_FUNCTION=lambda oparg, jmp=0: (oparg[1]),
        INVOKE_NATIVE=lambda oparg, jmp=0: (len(oparg[1]) - 1),
        JUMP_IF_ZERO_OR_POP=lambda oparg, jmp=0: 0 if jmp else -1,
        JUMP_IF_NONZERO_OR_POP=lambda oparg, jmp=0: 0 if jmp else -1,
        FAST_LEN=1,
        CONVERT_PRIMITIVE=1,
        LOAD_CLASS=0,
        BUILD_CHECKED_MAP=lambda oparg, jmp=0: 2 * oparg[1],
        SEQUENCE_GET=2,
        SEQUENCE_SET=3,
        LIST_DEL=2,
        REFINE_TYPE=1,
        PRIMITIVE_LOAD_CONST=0,
        RETURN_PRIMITIVE=1,
        TP_ALLOC=0,
        BUILD_CHECKED_LIST=lambda oparg, jmp=0: oparg[1],
        LOAD_TYPE=1,
        LOAD_METHOD_STATIC=1,
    )

    opcode.pushed.update(
        ANNOTATIONS_PLACEHOLDER=0,
        BINARY_OP=1,
        BINARY_OP_ADD_FLOAT=1,
        BINARY_OP_ADD_INT=1,
        BINARY_OP_ADD_UNICODE=1,
        BINARY_OP_EXTEND=1,
        BINARY_OP_INPLACE_ADD_UNICODE=0,
        BINARY_OP_MULTIPLY_FLOAT=1,
        BINARY_OP_MULTIPLY_INT=1,
        BINARY_OP_SUBSCR_DICT=1,
        BINARY_OP_SUBSCR_GETITEM=0,
        BINARY_OP_SUBSCR_LIST_INT=1,
        BINARY_OP_SUBSCR_LIST_SLICE=1,
        BINARY_OP_SUBSCR_STR_INT=1,
        BINARY_OP_SUBSCR_TUPLE_INT=1,
        BINARY_OP_SUBTRACT_FLOAT=1,
        BINARY_OP_SUBTRACT_INT=1,
        BINARY_SLICE=1,
        BUILD_INTERPOLATION=1,
        BUILD_LIST=1,
        BUILD_MAP=1,
        BUILD_SET=1,
        BUILD_SLICE=1,
        BUILD_STRING=1,
        BUILD_TEMPLATE=1,
        BUILD_TUPLE=1,
        CACHE=0,
        CALL=1,
        CALL_ALLOC_AND_ENTER_INIT=0,
        CALL_BOUND_METHOD_EXACT_ARGS=0,
        CALL_BOUND_METHOD_GENERAL=0,
        CALL_BUILTIN_CLASS=1,
        CALL_BUILTIN_FAST=1,
        CALL_BUILTIN_FAST_WITH_KEYWORDS=1,
        CALL_BUILTIN_O=1,
        CALL_FUNCTION_EX=1,
        CALL_INTRINSIC_1=1,
        CALL_INTRINSIC_2=1,
        CALL_ISINSTANCE=1,
        CALL_KW=1,
        CALL_KW_BOUND_METHOD=0,
        CALL_KW_NON_PY=1,
        CALL_KW_PY=0,
        CALL_LEN=1,
        CALL_LIST_APPEND=0,
        CALL_METHOD_DESCRIPTOR_FAST=1,
        CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS=1,
        CALL_METHOD_DESCRIPTOR_NOARGS=1,
        CALL_METHOD_DESCRIPTOR_O=1,
        CALL_NON_PY_GENERAL=1,
        CALL_PY_EXACT_ARGS=0,
        CALL_PY_GENERAL=0,
        CALL_STR_1=1,
        CALL_TUPLE_1=1,
        CALL_TYPE_1=1,
        CHECK_EG_MATCH=2,
        CHECK_EXC_MATCH=2,
        CLEANUP_THROW=2,
        COMPARE_OP=1,
        COMPARE_OP_FLOAT=1,
        COMPARE_OP_INT=1,
        COMPARE_OP_STR=1,
        CONTAINS_OP=1,
        CONTAINS_OP_DICT=1,
        CONTAINS_OP_SET=1,
        CONVERT_VALUE=1,
        COPY=lambda oparg: 2 + (oparg - 1),
        COPY_FREE_VARS=0,
        DELETE_ATTR=0,
        DELETE_DEREF=0,
        DELETE_FAST=0,
        DELETE_GLOBAL=0,
        DELETE_NAME=0,
        DELETE_SUBSCR=0,
        DICT_MERGE=lambda oparg: 4 + (oparg - 1),
        DICT_UPDATE=lambda oparg: 1 + (oparg - 1),
        EAGER_IMPORT_NAME=1,
        END_ASYNC_FOR=0,
        END_FOR=0,
        END_SEND=1,
        ENTER_EXECUTOR=0,
        EXIT_INIT_CHECK=0,
        EXTENDED_ARG=0,
        FORMAT_SIMPLE=1,
        FORMAT_WITH_SPEC=1,
        FOR_ITER=2,
        FOR_ITER_GEN=1,
        FOR_ITER_LIST=2,
        FOR_ITER_RANGE=2,
        FOR_ITER_TUPLE=2,
        GET_AITER=1,
        GET_ANEXT=2,
        GET_AWAITABLE=1,
        GET_ITER=1,
        GET_LEN=2,
        GET_YIELD_FROM_ITER=1,
        IMPORT_FROM=2,
        IMPORT_NAME=1,
        INSTRUMENTED_CALL=1,
        INSTRUMENTED_CALL_FUNCTION_EX=1,
        INSTRUMENTED_CALL_KW=1,
        INSTRUMENTED_END_ASYNC_FOR=0,
        INSTRUMENTED_END_FOR=1,
        INSTRUMENTED_END_SEND=1,
        INSTRUMENTED_FOR_ITER=2,
        INSTRUMENTED_INSTRUCTION=0,
        INSTRUMENTED_JUMP_BACKWARD=0,
        INSTRUMENTED_JUMP_FORWARD=0,
        INSTRUMENTED_LINE=0,
        INSTRUMENTED_LOAD_SUPER_ATTR=lambda oparg: 1 + (oparg & 1),
        INSTRUMENTED_NOT_TAKEN=0,
        INSTRUMENTED_POP_ITER=0,
        INSTRUMENTED_POP_JUMP_IF_FALSE=0,
        INSTRUMENTED_POP_JUMP_IF_NONE=0,
        INSTRUMENTED_POP_JUMP_IF_NOT_NONE=0,
        INSTRUMENTED_POP_JUMP_IF_TRUE=0,
        INSTRUMENTED_RESUME=0,
        INSTRUMENTED_RETURN_VALUE=1,
        INSTRUMENTED_YIELD_VALUE=1,
        INTERPRETER_EXIT=0,
        IS_OP=1,
        JUMP=0,
        JUMP_BACKWARD=0,
        JUMP_BACKWARD_JIT=0,
        JUMP_BACKWARD_NO_INTERRUPT=0,
        JUMP_BACKWARD_NO_JIT=0,
        JUMP_FORWARD=0,
        JUMP_IF_FALSE=1,
        JUMP_IF_TRUE=1,
        JUMP_NO_INTERRUPT=0,
        LIST_APPEND=lambda oparg: 1 + (oparg - 1),
        LIST_EXTEND=lambda oparg: 1 + (oparg - 1),
        LOAD_ATTR=lambda oparg: (2 if (isinstance(oparg, tuple) and oparg[1]) else 1),
        LOAD_ATTR_CLASS=lambda oparg: 1 + (oparg & 1),
        LOAD_ATTR_CLASS_WITH_METACLASS_CHECK=lambda oparg: 1 + (oparg & 1),
        LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN=1,
        LOAD_ATTR_INSTANCE_VALUE=lambda oparg: 1 + (oparg & 1),
        LOAD_ATTR_METHOD_LAZY_DICT=2,
        LOAD_ATTR_METHOD_NO_DICT=2,
        LOAD_ATTR_METHOD_WITH_VALUES=2,
        LOAD_ATTR_MODULE=lambda oparg: 1 + (oparg & 1),
        LOAD_ATTR_NONDESCRIPTOR_NO_DICT=1,
        LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES=1,
        LOAD_ATTR_PROPERTY=0,
        LOAD_ATTR_SLOT=lambda oparg: 1 + (oparg & 1),
        LOAD_ATTR_WITH_HINT=lambda oparg: 1 + (oparg & 1),
        LOAD_BUILD_CLASS=1,
        LOAD_CLOSURE=1,
        LOAD_COMMON_CONSTANT=1,
        LOAD_CONST=1,
        LOAD_CONST_IMMORTAL=1,
        LOAD_CONST_MORTAL=1,
        LOAD_DEREF=1,
        LOAD_FAST=1,
        LOAD_FAST_AND_CLEAR=1,
        LOAD_FAST_BORROW=1,
        LOAD_FAST_BORROW_LOAD_FAST_BORROW=2,
        LOAD_FAST_CHECK=1,
        LOAD_FAST_LOAD_FAST=2,
        LOAD_FROM_DICT_OR_DEREF=1,
        LOAD_FROM_DICT_OR_GLOBALS=1,
        LOAD_GLOBAL=lambda oparg: 2 if isinstance(oparg, tuple) else 1,
        LOAD_GLOBAL_BUILTIN=lambda oparg: 1 + (oparg & 1),
        LOAD_GLOBAL_MODULE=lambda oparg: 1 + (oparg & 1),
        LOAD_LOCALS=1,
        LOAD_NAME=1,
        LOAD_SMALL_INT=1,
        LOAD_SPECIAL=2,
        LOAD_SUPER_ATTR=lambda oparg: (
            2 if oparg[0] in ("LOAD_SUPER_METHOD", "LOAD_ZERO_SUPER_METHOD") else 1
        ),
        LOAD_SUPER_ATTR_ATTR=1,
        LOAD_SUPER_ATTR_METHOD=2,
        MAKE_CELL=0,
        MAKE_FUNCTION=1,
        MAP_ADD=lambda oparg: 1 + (oparg - 1),
        MATCH_CLASS=1,
        MATCH_KEYS=3,
        MATCH_MAPPING=2,
        MATCH_SEQUENCE=2,
        NOP=0,
        NOT_TAKEN=0,
        POP_BLOCK=0,
        POP_EXCEPT=0,
        POP_ITER=0,
        POP_JUMP_IF_FALSE=0,
        POP_JUMP_IF_NONE=0,
        POP_JUMP_IF_NOT_NONE=0,
        POP_JUMP_IF_TRUE=0,
        POP_TOP=0,
        PUSH_EXC_INFO=2,
        PUSH_NULL=1,
        RAISE_VARARGS=0,
        RERAISE=lambda oparg: oparg,
        RESERVED=0,
        RESUME=0,
        RESUME_CHECK=0,
        RETURN_GENERATOR=1,
        RETURN_VALUE=1,
        SEND=2,
        SEND_GEN=1,
        SETUP_ANNOTATIONS=0,
        SETUP_CLEANUP=2,
        SETUP_FINALLY=1,
        SETUP_WITH=1,
        SET_ADD=lambda oparg: 1 + (oparg - 1),
        SET_FUNCTION_ATTRIBUTE=1,
        SET_UPDATE=lambda oparg: 1 + (oparg - 1),
        STORE_ATTR=0,
        STORE_ATTR_INSTANCE_VALUE=0,
        STORE_ATTR_SLOT=0,
        STORE_ATTR_WITH_HINT=0,
        STORE_DEREF=0,
        STORE_FAST=0,
        STORE_FAST_LOAD_FAST=1,
        STORE_FAST_MAYBE_NULL=0,
        STORE_FAST_STORE_FAST=0,
        STORE_GLOBAL=0,
        STORE_NAME=0,
        STORE_SLICE=0,
        STORE_SUBSCR=0,
        STORE_SUBSCR_DICT=0,
        STORE_SUBSCR_LIST_INT=0,
        SWAP=lambda oparg: 2 + (oparg - 2),
        TO_BOOL=1,
        TO_BOOL_ALWAYS_TRUE=1,
        TO_BOOL_BOOL=1,
        TO_BOOL_INT=1,
        TO_BOOL_LIST=1,
        TO_BOOL_NONE=1,
        TO_BOOL_STR=1,
        UNARY_INVERT=1,
        UNARY_NEGATIVE=1,
        UNARY_NOT=1,
        UNPACK_EX=lambda oparg: 1 + (oparg & 0xFF) + (oparg >> 8),
        UNPACK_SEQUENCE=lambda oparg: oparg,
        UNPACK_SEQUENCE_LIST=lambda oparg: oparg,
        UNPACK_SEQUENCE_TUPLE=lambda oparg: oparg,
        UNPACK_SEQUENCE_TWO_TUPLE=2,
        WITH_EXCEPT_START=6,
        YIELD_VALUE=1,
        # Static opcodes
        EXTENDED_OPCODE=0,
        LOAD_FIELD=1,
        STORE_FIELD=0,
        CAST=1,
        LOAD_LOCAL=1,
        STORE_LOCAL=0,
        PRIMITIVE_BOX=1,
        POP_JUMP_IF_ZERO=0,
        POP_JUMP_IF_NONZERO=0,
        PRIMITIVE_UNBOX=1,
        PRIMITIVE_BINARY_OP=1,
        PRIMITIVE_UNARY_OP=1,
        PRIMITIVE_COMPARE_OP=1,
        LOAD_ITERABLE_ARG=2,
        LOAD_MAPPING_ARG=1,
        INVOKE_METHOD=1,
        INVOKE_FUNCTION=1,
        INVOKE_NATIVE=1,
        JUMP_IF_ZERO_OR_POP=0,
        JUMP_IF_NONZERO_OR_POP=0,
        FAST_LEN=1,
        CONVERT_PRIMITIVE=1,
        LOAD_CLASS=1,
        BUILD_CHECKED_MAP=1,
        SEQUENCE_GET=1,
        SEQUENCE_SET=0,
        LIST_DEL=0,
        REFINE_TYPE=1,
        PRIMITIVE_LOAD_CONST=1,
        RETURN_PRIMITIVE=0,
        TP_ALLOC=1,
        BUILD_CHECKED_LIST=1,
        LOAD_TYPE=1,
        LOAD_METHOD_STATIC=2,
    )

    if sys.version_info >= (3, 15):
        opcode.popped.update(
            FOR_ITER=2,
            POP_ITER=2,
        )
        opcode.pushed.update(
            FOR_ITER=3,
            GET_ITER=2,
        )
    for opname, popped in opcode.popped.items():
        pushed = opcode.pushed[opname]
        if isinstance(popped, int) and isinstance(pushed, int):
            opcode.stack_effects[opname] = pushed - popped
        elif isinstance(popped, int):

            def make_effect(pushed, popped):
                return lambda oparg, jmp=0: pushed(oparg) - popped

            opcode.stack_effects[opname] = make_effect(pushed, popped)
        elif isinstance(pushed, int):

            def make_effect(pushed, popped):
                return lambda oparg, jmp=0: pushed - popped(oparg)

            opcode.stack_effects[opname] = make_effect(pushed, popped)
        else:

            def make_effect(pushed, popped):
                return lambda oparg, jmp=0: pushed(oparg) - popped(oparg)

            opcode.stack_effects[opname] = make_effect(pushed, popped)

elif sys.version_info >= (3, 12):

    def _load_mapping_arg_effect(oparg: int, _jmp: int = 0) -> int:
        """The effect of this opcode depends on the number of items on the stack
        when it is invoked. The number of items on the stack for LOAD_MAPPING_ARG
        is based on the oparg. LOAD_MAPPING_ARG will push the resulting value and
        will consume either a default value, the mapping, and the argument name when
        oparg == 3 or just the mapping and argument name when there is no default
        value for the argument."""
        if oparg == 2:
            return -1
        elif oparg == 3:
            return -2
        raise ValueError("bad oparg")

    opcode.stack_effects.update(
        CALL=lambda oparg, jmp=0: -(oparg + 1),
        COPY_FREE_VARS=lambda oparg, jmp=0: 0,
        MAKE_CELL=lambda oparg, jmp=0: 0,
        JUMP=0,
        JUMP_BACKWARD=0,
        PUSH_NULL=1,
        RETURN_CONST=0,
        SWAP=0,
        COPY=1,
        CALL_INTRINSIC_1=0,
        CALL_INTRINSIC_2=-1,
        LOAD_FROM_DICT_OR_DEREF=0,
        LOAD_LOCALS=1,
        MAKE_FUNCTION=lambda oparg, jmp=0: -oparg.bit_count(),
        LOAD_FROM_DICT_OR_GLOBALS=0,
        LOAD_SUPER_ATTR=lambda oparg, jmp: (
            2 if oparg[0] in ("LOAD_SUPER_METHOD", "LOAD_ZERO_SUPER_METHOD") else 1
        )
        - 3,
        LOAD_ATTR=lambda oparg, jmp: (
            1 if (isinstance(oparg, tuple) and oparg[1]) else 0
        ),
        BINARY_OP=-1,
        RETURN_GENERATOR=0,
        SEND=0,
        JUMP_NO_INTERRUPT=0,
        JUMP_BACKWARD_NO_INTERRUPT=0,
        CLEANUP_THROW=-1,
        END_SEND=-1,
        END_FOR=-2,
        FOR_ITER=lambda oparg, jmp=0: 1,
        END_ASYNC_FOR=-2,
        SETUP_FINALLY=lambda oparg, jmp=0: 1 if jmp else 0,
        SETUP_CLEANUP=lambda oparg, jmp=0: 2 if jmp else 0,
        SETUP_WITH=lambda oparg, jmp=0: 1 if jmp else 0,
        PUSH_EXC_INFO=1,
        POP_EXCEPT=-1,
        LOAD_FAST_AND_CLEAR=1,
        STORE_FAST_MAYBE_NULL=-1,
        RERAISE=-1,
        LOAD_FAST_CHECK=1,
        LOAD_GLOBAL=lambda oparg, jmp=0: 2 if isinstance(oparg, tuple) else 1,
        BEFORE_WITH=1,
        CALL_FUNCTION_EX=lambda oparg, jmp=0: 1 - (4 if oparg & 0x01 else 3),
        CHECK_EXC_MATCH=0,
        CHECK_EG_MATCH=0,
        POP_JUMP_IF_NONE=-1,
        POP_JUMP_IF_NOT_NONE=-1,
        BINARY_SLICE=-2,
        STORE_SLICE=-4,
        KW_NAMES=0,
        MATCH_KEYS=1,
        MATCH_CLASS=-2,
        EAGER_IMPORT_NAME=-1,
        LOAD_FIELD=0,
        STORE_FIELD=-2,
        CAST=0,
        LOAD_LOCAL=1,
        STORE_LOCAL=-1,
        PRIMITIVE_BOX=0,
        POP_JUMP_IF_ZERO=-1,
        POP_JUMP_IF_NONZERO=-1,
        PRIMITIVE_UNBOX=0,
        PRIMITIVE_BINARY_OP=lambda oparg, jmp: -1,
        PRIMITIVE_UNARY_OP=lambda oparg, jmp: 0,
        PRIMITIVE_COMPARE_OP=lambda oparg, jmp: -1,
        LOAD_ITERABLE_ARG=1,
        LOAD_MAPPING_ARG=_load_mapping_arg_effect,
        INVOKE_FUNCTION=lambda oparg, jmp=0: (-oparg[1]) + 1,
        INVOKE_NATIVE=lambda oparg, jmp=0: (-len(oparg[1])) + 2,
        JUMP_IF_ZERO_OR_POP=lambda oparg, jmp=0: 0 if jmp else -1,
        JUMP_IF_NONZERO_OR_POP=lambda oparg, jmp=0: 0 if jmp else -1,
        FAST_LEN=0,
        CONVERT_PRIMITIVE=0,
        LOAD_CLASS=1,
        BUILD_CHECKED_MAP=lambda oparg, jmp: 1 - 2 * oparg[1],
        SEQUENCE_GET=-1,
        SEQUENCE_SET=-3,
        LIST_DEL=-2,
        REFINE_TYPE=0,
        PRIMITIVE_LOAD_CONST=1,
        RETURN_PRIMITIVE=-1,
        TP_ALLOC=1,
        BUILD_CHECKED_LIST=lambda oparg, jmp: 1 - oparg[1],
        LOAD_TYPE=0,
        LOAD_METHOD_STATIC=1,
    )


def find_op_idx(opname: str) -> int:
    # pyre-fixme[16]: Module `opcode` has no attribute `_nb_ops`.
    for i, (name, _symbol) in enumerate(NB_OPS):
        if name == opname:
            return i

    return -1


STATIC_OPCODES = {
    "LOAD_FIELD",
    "STORE_FIELD",
    "CAST",
    "LOAD_LOCAL",
    "STORE_LOCAL",
    "PRIMITIVE_BOX",
    "POP_JUMP_IF_ZERO",
    "POP_JUMP_IF_NONZERO",
    "PRIMITIVE_UNBOX",
    "PRIMITIVE_BINARY_OP",
    "PRIMITIVE_UNARY_OP",
    "PRIMITIVE_COMPARE_OP",
    "LOAD_ITERABLE_ARG",
    "LOAD_MAPPING_ARG",
    "INVOKE_FUNCTION",
    "INVOKE_METHOD",
    "INVOKE_NATIVE",
    "JUMP_IF_ZERO_OR_POP",
    "JUMP_IF_NONZERO_OR_POP",
    "FAST_LEN",
    "CONVERT_PRIMITIVE",
    "LOAD_CLASS",
    "BUILD_CHECKED_MAP",
    "SEQUENCE_GET",
    "SEQUENCE_SET",
    "LIST_DEL",
    "REFINE_TYPE",
    "PRIMITIVE_LOAD_CONST",
    "RETURN_PRIMITIVE",
    "TP_ALLOC",
    "BUILD_CHECKED_LIST",
    "LOAD_TYPE",
    "LOAD_METHOD_STATIC",
}
