mirror of
https://github.com/python/cpython.git
synced 2025-08-16 23:01:34 +00:00
GH-103963: Make dis display names of args for intrinsics opcodes (#104029)
This commit is contained in:
parent
65a49c6553
commit
872cbc6132
6 changed files with 110 additions and 17 deletions
|
@ -1,6 +1,7 @@
|
||||||
|
// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py
|
||||||
|
|
||||||
/* Unary Functions: */
|
/* Unary Functions: */
|
||||||
|
#define INTRINSIC_1_INVALID 0
|
||||||
#define INTRINSIC_PRINT 1
|
#define INTRINSIC_PRINT 1
|
||||||
#define INTRINSIC_IMPORT_STAR 2
|
#define INTRINSIC_IMPORT_STAR 2
|
||||||
#define INTRINSIC_STOPITERATION_ERROR 3
|
#define INTRINSIC_STOPITERATION_ERROR 3
|
||||||
|
@ -12,15 +13,12 @@
|
||||||
|
|
||||||
|
|
||||||
/* Binary Functions: */
|
/* Binary Functions: */
|
||||||
|
#define INTRINSIC_2_INVALID 0
|
||||||
#define INTRINSIC_PREP_RERAISE_STAR 1
|
#define INTRINSIC_PREP_RERAISE_STAR 1
|
||||||
|
|
||||||
#define MAX_INTRINSIC_2 1
|
#define MAX_INTRINSIC_2 1
|
||||||
|
|
||||||
|
|
||||||
typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
|
typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
|
||||||
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
|
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
|
||||||
|
|
||||||
extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
|
extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
|
||||||
extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
|
extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ from opcode import (
|
||||||
_cache_format,
|
_cache_format,
|
||||||
_inline_cache_entries,
|
_inline_cache_entries,
|
||||||
_nb_ops,
|
_nb_ops,
|
||||||
|
_intrinsic_1_descs,
|
||||||
|
_intrinsic_2_descs,
|
||||||
_specializations,
|
_specializations,
|
||||||
_specialized_instructions,
|
_specialized_instructions,
|
||||||
)
|
)
|
||||||
|
@ -42,6 +44,8 @@ FOR_ITER = opmap['FOR_ITER']
|
||||||
SEND = opmap['SEND']
|
SEND = opmap['SEND']
|
||||||
LOAD_ATTR = opmap['LOAD_ATTR']
|
LOAD_ATTR = opmap['LOAD_ATTR']
|
||||||
LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR']
|
LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR']
|
||||||
|
CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1']
|
||||||
|
CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2']
|
||||||
|
|
||||||
CACHE = opmap["CACHE"]
|
CACHE = opmap["CACHE"]
|
||||||
|
|
||||||
|
@ -506,6 +510,10 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
|
||||||
if arg & (1<<i))
|
if arg & (1<<i))
|
||||||
elif deop == BINARY_OP:
|
elif deop == BINARY_OP:
|
||||||
_, argrepr = _nb_ops[arg]
|
_, argrepr = _nb_ops[arg]
|
||||||
|
elif deop == CALL_INTRINSIC_1:
|
||||||
|
argrepr = _intrinsic_1_descs[arg]
|
||||||
|
elif deop == CALL_INTRINSIC_2:
|
||||||
|
argrepr = _intrinsic_2_descs[arg]
|
||||||
yield Instruction(_all_opname[op], op,
|
yield Instruction(_all_opname[op], op,
|
||||||
arg, argval, argrepr,
|
arg, argval, argrepr,
|
||||||
offset, starts_line, is_jump_target, positions)
|
offset, starts_line, is_jump_target, positions)
|
||||||
|
|
|
@ -306,6 +306,21 @@ _nb_ops = [
|
||||||
("NB_INPLACE_XOR", "^="),
|
("NB_INPLACE_XOR", "^="),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
_intrinsic_1_descs = [
|
||||||
|
"INTRINSIC_1_INVALID",
|
||||||
|
"INTRINSIC_PRINT",
|
||||||
|
"INTRINSIC_IMPORT_STAR",
|
||||||
|
"INTRINSIC_STOPITERATION_ERROR",
|
||||||
|
"INTRINSIC_ASYNC_GEN_WRAP",
|
||||||
|
"INTRINSIC_UNARY_POSITIVE",
|
||||||
|
"INTRINSIC_LIST_TO_TUPLE",
|
||||||
|
]
|
||||||
|
|
||||||
|
_intrinsic_2_descs = [
|
||||||
|
'INTRINSIC_2_INVALID',
|
||||||
|
'INTRINSIC_PREP_RERAISE_STAR',
|
||||||
|
]
|
||||||
|
|
||||||
_specializations = {
|
_specializations = {
|
||||||
"BINARY_OP": [
|
"BINARY_OP": [
|
||||||
"BINARY_OP_ADD_FLOAT",
|
"BINARY_OP_ADD_FLOAT",
|
||||||
|
|
|
@ -247,6 +247,35 @@ dis_kw_names = """\
|
||||||
""" % (wrap_func_w_kwargs.__code__.co_firstlineno,
|
""" % (wrap_func_w_kwargs.__code__.co_firstlineno,
|
||||||
wrap_func_w_kwargs.__code__.co_firstlineno + 1)
|
wrap_func_w_kwargs.__code__.co_firstlineno + 1)
|
||||||
|
|
||||||
|
dis_intrinsic_1_2 = """\
|
||||||
|
0 RESUME 0
|
||||||
|
|
||||||
|
1 LOAD_CONST 0 (0)
|
||||||
|
LOAD_CONST 1 (('*',))
|
||||||
|
IMPORT_NAME 0 (math)
|
||||||
|
CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR)
|
||||||
|
POP_TOP
|
||||||
|
RETURN_CONST 2 (None)
|
||||||
|
"""
|
||||||
|
|
||||||
|
dis_intrinsic_1_5 = """\
|
||||||
|
0 RESUME 0
|
||||||
|
|
||||||
|
1 LOAD_NAME 0 (a)
|
||||||
|
CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE)
|
||||||
|
RETURN_VALUE
|
||||||
|
"""
|
||||||
|
|
||||||
|
dis_intrinsic_1_6 = """\
|
||||||
|
0 RESUME 0
|
||||||
|
|
||||||
|
1 BUILD_LIST 0
|
||||||
|
LOAD_NAME 0 (a)
|
||||||
|
LIST_EXTEND 1
|
||||||
|
CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE)
|
||||||
|
RETURN_VALUE
|
||||||
|
"""
|
||||||
|
|
||||||
_BIG_LINENO_FORMAT = """\
|
_BIG_LINENO_FORMAT = """\
|
||||||
1 RESUME 0
|
1 RESUME 0
|
||||||
|
|
||||||
|
@ -549,7 +578,7 @@ dis_asyncwith = """\
|
||||||
>> COPY 3
|
>> COPY 3
|
||||||
POP_EXCEPT
|
POP_EXCEPT
|
||||||
RERAISE 1
|
RERAISE 1
|
||||||
>> CALL_INTRINSIC_1 3
|
>> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR)
|
||||||
RERAISE 1
|
RERAISE 1
|
||||||
ExceptionTable:
|
ExceptionTable:
|
||||||
12 rows
|
12 rows
|
||||||
|
@ -942,6 +971,16 @@ class DisTests(DisTestBase):
|
||||||
# Test that value is displayed for KW_NAMES
|
# Test that value is displayed for KW_NAMES
|
||||||
self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names)
|
self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names)
|
||||||
|
|
||||||
|
def test_intrinsic_1(self):
|
||||||
|
# Test that argrepr is displayed for CALL_INTRINSIC_1
|
||||||
|
self.do_disassembly_test("from math import *", dis_intrinsic_1_2)
|
||||||
|
self.do_disassembly_test("+a", dis_intrinsic_1_5)
|
||||||
|
self.do_disassembly_test("(*a,)", dis_intrinsic_1_6)
|
||||||
|
|
||||||
|
def test_intrinsic_2(self):
|
||||||
|
self.assertIn("CALL_INTRINSIC_2 1 (INTRINSIC_PREP_RERAISE_STAR)",
|
||||||
|
self.get_disassembly("try: pass\nexcept* Exception: x"))
|
||||||
|
|
||||||
def test_big_linenos(self):
|
def test_big_linenos(self):
|
||||||
def func(count):
|
def func(count):
|
||||||
namespace = {}
|
namespace = {}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Make :mod:`dis` display the names of the args for :opcode:`CALL_INTRINSIC_*`.
|
|
@ -52,6 +52,18 @@ internal_footer = """
|
||||||
#endif // !Py_INTERNAL_OPCODE_H
|
#endif // !Py_INTERNAL_OPCODE_H
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
intrinsic_header = f"""
|
||||||
|
// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
|
||||||
|
|
||||||
|
""".lstrip()
|
||||||
|
|
||||||
|
intrinsic_footer = """
|
||||||
|
typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
|
||||||
|
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
|
||||||
|
extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
|
||||||
|
extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
|
||||||
|
"""
|
||||||
|
|
||||||
DEFINE = "#define {:<38} {:>3}\n"
|
DEFINE = "#define {:<38} {:>3}\n"
|
||||||
|
|
||||||
UINT32_MASK = (1<<32)-1
|
UINT32_MASK = (1<<32)-1
|
||||||
|
@ -67,7 +79,9 @@ def write_int_array_from_ops(name, ops, out):
|
||||||
assert bits == 0
|
assert bits == 0
|
||||||
out.write(f"}};\n")
|
out.write(f"}};\n")
|
||||||
|
|
||||||
def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/internal/pycore_opcode.h'):
|
def main(opcode_py, outfile='Include/opcode.h',
|
||||||
|
internaloutfile='Include/internal/pycore_opcode.h',
|
||||||
|
intrinsicoutfile='Include/internal/pycore_intrinsics.h'):
|
||||||
opcode = {}
|
opcode = {}
|
||||||
if hasattr(tokenize, 'open'):
|
if hasattr(tokenize, 'open'):
|
||||||
fp = tokenize.open(opcode_py) # Python 3.2+
|
fp = tokenize.open(opcode_py) # Python 3.2+
|
||||||
|
@ -107,9 +121,11 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna
|
||||||
opname_including_specialized[next_op] = name
|
opname_including_specialized[next_op] = name
|
||||||
used[next_op] = True
|
used[next_op] = True
|
||||||
|
|
||||||
with open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj:
|
with open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj, open(
|
||||||
|
intrinsicoutfile, "w") as nobj:
|
||||||
fobj.write(header)
|
fobj.write(header)
|
||||||
iobj.write(internal_header)
|
iobj.write(internal_header)
|
||||||
|
nobj.write(intrinsic_header)
|
||||||
|
|
||||||
for name in opname:
|
for name in opname:
|
||||||
if name in opmap:
|
if name in opmap:
|
||||||
|
@ -172,6 +188,22 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna
|
||||||
for i, (op, _) in enumerate(opcode["_nb_ops"]):
|
for i, (op, _) in enumerate(opcode["_nb_ops"]):
|
||||||
fobj.write(DEFINE.format(op, i))
|
fobj.write(DEFINE.format(op, i))
|
||||||
|
|
||||||
|
nobj.write("/* Unary Functions: */")
|
||||||
|
nobj.write("\n")
|
||||||
|
for i, op in enumerate(opcode["_intrinsic_1_descs"]):
|
||||||
|
nobj.write(DEFINE.format(op, i))
|
||||||
|
nobj.write("\n")
|
||||||
|
nobj.write(DEFINE.format("MAX_INTRINSIC_1", i))
|
||||||
|
|
||||||
|
nobj.write("\n\n")
|
||||||
|
nobj.write("/* Binary Functions: */\n")
|
||||||
|
for i, op in enumerate(opcode["_intrinsic_2_descs"]):
|
||||||
|
nobj.write(DEFINE.format(op, i))
|
||||||
|
nobj.write("\n")
|
||||||
|
nobj.write(DEFINE.format("MAX_INTRINSIC_2", i))
|
||||||
|
|
||||||
|
nobj.write(intrinsic_footer)
|
||||||
|
|
||||||
fobj.write("\n")
|
fobj.write("\n")
|
||||||
fobj.write("/* Defined in Lib/opcode.py */\n")
|
fobj.write("/* Defined in Lib/opcode.py */\n")
|
||||||
fobj.write(f"#define ENABLE_SPECIALIZATION {int(ENABLE_SPECIALIZATION)}")
|
fobj.write(f"#define ENABLE_SPECIALIZATION {int(ENABLE_SPECIALIZATION)}")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue