summaryrefslogtreecommitdiffstats
path: root/Lib/opcode.py
blob: f8487522bfdc6979eacfd4e303ce63656662e11a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

"""
opcode module - potentially shared between dis and other modules which
operate on bytecodes (e.g. peephole optimizers).
"""


# Note that __all__ is further extended below
__all__ = ["cmp_op", "stack_effect", "hascompare"]

import _opcode
from _opcode import stack_effect

import sys
# The build uses older versions of Python which do not have _opcode_metadata
if sys.version_info[:2] >= (3, 13):
    from _opcode_metadata import _specializations, _specialized_opmap
    from _opcode_metadata import opmap, HAVE_ARGUMENT, MIN_INSTRUMENTED_OPCODE
    EXTENDED_ARG = opmap['EXTENDED_ARG']

    opname = ['<%r>' % (op,) for op in range(max(opmap.values()) + 1)]
    for op, i in opmap.items():
        opname[i] = op

    __all__.extend(["opname", "opmap", "HAVE_ARGUMENT", "EXTENDED_ARG"])

cmp_op = ('<', '<=', '==', '!=', '>', '>=')

# The build uses older versions of Python which do not have _opcode.has_* functions
if sys.version_info[:2] >= (3, 13):
    # These lists are documented as part of the dis module's API
    hasarg = [op for op in opmap.values() if _opcode.has_arg(op)]
    hasconst = [op for op in opmap.values() if _opcode.has_const(op)]
    hasname = [op for op in opmap.values() if _opcode.has_name(op)]
    hasjump = [op for op in opmap.values() if _opcode.has_jump(op)]
    hasjrel = hasjump  # for backward compatibility
    hasjabs = []
    hasfree = [op for op in opmap.values() if _opcode.has_free(op)]
    haslocal = [op for op in opmap.values() if _opcode.has_local(op)]
    hasexc = [op for op in opmap.values() if _opcode.has_exc(op)]

    __all__.extend(["hasarg", "hasconst", "hasname", "hasjump", "hasjrel",
                    "hasjabs", "hasfree", "haslocal", "hasexc"])

    _intrinsic_1_descs = _opcode.get_intrinsic1_descs()
    _intrinsic_2_descs = _opcode.get_intrinsic2_descs()
    _nb_ops = _opcode.get_nb_ops()

    hascompare = [opmap["COMPARE_OP"]]

_cache_format = {
    "LOAD_GLOBAL": {
        "counter": 1,
        "index": 1,
        "module_keys_version": 1,
        "builtin_keys_version": 1,
    },
    "BINARY_OP": {
        "counter": 1,
    },
    "UNPACK_SEQUENCE": {
        "counter": 1,
    },
    "COMPARE_OP": {
        "counter": 1,
    },
    "BINARY_SUBSCR": {
        "counter": 1,
    },
    "FOR_ITER": {
        "counter": 1,
    },
    "LOAD_SUPER_ATTR": {
        "counter": 1,
    },
    "LOAD_ATTR": {
        "counter": 1,
        "version": 2,
        "keys_version": 2,
        "descr": 4,
    },
    "STORE_ATTR": {
        "counter": 1,
        "version": 2,
        "index": 1,
    },
    "CALL": {
        "counter": 1,
        "func_version": 2,
    },
    "STORE_SUBSCR": {
        "counter": 1,
    },
    "SEND": {
        "counter": 1,
    },
    "JUMP_BACKWARD": {
        "counter": 1,
    },
    "TO_BOOL": {
        "counter": 1,
        "version": 2,
    },
}

_inline_cache_entries = {
    name : sum(value.values()) for (name, value) in _cache_format.items()
}