aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/opcode.py
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2022-07-01 15:33:35 +0100
committerGitHub <noreply@github.com>2022-07-01 15:33:35 +0100
commitc57aad777afc6c0b382981ee9e4bc94c03bf5f68 (patch)
tree39128a485e3372715a4b2fe4e03d7117e0fba9fc /Lib/opcode.py
parentbe80db14c432c621e44920f8fd95a3f3191aca9b (diff)
downloadcpython-c57aad777afc6c0b382981ee9e4bc94c03bf5f68.tar.gz
cpython-c57aad777afc6c0b382981ee9e4bc94c03bf5f68.zip
gh-94216: add pseudo instructions to the dis/opcodes modules (GH-94241)
Diffstat (limited to 'Lib/opcode.py')
-rw-r--r--Lib/opcode.py62
1 files changed, 54 insertions, 8 deletions
diff --git a/Lib/opcode.py b/Lib/opcode.py
index c7bc12a1fba..8a07fb75b2e 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -4,9 +4,9 @@ opcode module - potentially shared between dis and other modules which
operate on bytecodes (e.g. peephole optimizers).
"""
-__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
- "haslocal", "hascompare", "hasfree", "opname", "opmap",
- "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"]
+__all__ = ["cmp_op", "hasarg", "hasconst", "hasname", "hasjrel", "hasjabs",
+ "haslocal", "hascompare", "hasfree", "hasexc", "opname", "opmap",
+ "HAVE_ARGUMENT", "EXTENDED_ARG"]
# It's a chicken-and-egg I'm afraid:
# We're imported before _opcode's made.
@@ -23,6 +23,7 @@ except ImportError:
cmp_op = ('<', '<=', '==', '!=', '>', '>=')
+hasarg = []
hasconst = []
hasname = []
hasjrel = []
@@ -30,13 +31,21 @@ hasjabs = []
haslocal = []
hascompare = []
hasfree = []
-hasnargs = [] # unused
+hasexc = []
+
+def is_pseudo(op):
+ return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE
+
+oplists = [hasarg, hasconst, hasname, hasjrel, hasjabs,
+ haslocal, hascompare, hasfree, hasexc]
opmap = {}
-opname = ['<%r>' % (op,) for op in range(256)]
+
+## pseudo opcodes (used in the compiler) mapped to the values
+## they can become in the actual code.
+_pseudo_ops = {}
def def_op(name, op):
- opname[op] = name
opmap[name] = op
def name_op(name, op):
@@ -51,6 +60,17 @@ def jabs_op(name, op):
def_op(name, op)
hasjabs.append(op)
+def pseudo_op(name, op, real_ops):
+ def_op(name, op)
+ _pseudo_ops[name] = real_ops
+ # add the pseudo opcode to the lists its targets are in
+ for oplist in oplists:
+ res = [opmap[rop] in oplist for rop in real_ops]
+ if any(res):
+ assert all(res)
+ oplist.append(op)
+
+
# Instruction opcodes for compiled code
# Blank lines correspond to available opcodes
@@ -105,7 +125,7 @@ def_op('ASYNC_GEN_WRAP', 87)
def_op('PREP_RERAISE_STAR', 88)
def_op('POP_EXCEPT', 89)
-HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
+HAVE_ARGUMENT = 90 # real opcodes from here have an argument:
name_op('STORE_NAME', 90) # Index in name list
name_op('DELETE_NAME', 91) # ""
@@ -200,8 +220,34 @@ jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174)
jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175)
jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176)
+hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
+
+MIN_PSEUDO_OPCODE = 256
+
+pseudo_op('SETUP_FINALLY', 256, ['NOP'])
+hasexc.append(256)
+pseudo_op('SETUP_CLEANUP', 257, ['NOP'])
+hasexc.append(257)
+pseudo_op('SETUP_WITH', 258, ['NOP'])
+hasexc.append(258)
+pseudo_op('POP_BLOCK', 259, ['NOP'])
+
+pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD'])
+pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT'])
+pseudo_op('POP_JUMP_IF_FALSE', 262, ['POP_JUMP_FORWARD_IF_FALSE', 'POP_JUMP_BACKWARD_IF_FALSE'])
+pseudo_op('POP_JUMP_IF_TRUE', 263, ['POP_JUMP_FORWARD_IF_TRUE', 'POP_JUMP_BACKWARD_IF_TRUE'])
+pseudo_op('POP_JUMP_IF_NONE', 264, ['POP_JUMP_FORWARD_IF_NONE', 'POP_JUMP_BACKWARD_IF_NONE'])
+pseudo_op('POP_JUMP_IF_NOT_NONE', 265, ['POP_JUMP_FORWARD_IF_NOT_NONE', 'POP_JUMP_BACKWARD_IF_NOT_NONE'])
+pseudo_op('LOAD_METHOD', 266, ['LOAD_ATTR'])
+
+MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1
+
+del def_op, name_op, jrel_op, jabs_op, pseudo_op
+
+opname = ['<%r>' % (op,) for op in range(MAX_PSEUDO_OPCODE + 1)]
+for op, i in opmap.items():
+ opname[i] = op
-del def_op, name_op, jrel_op, jabs_op
_nb_ops = [
("NB_ADD", "+"),