mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +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 @@ | ||||||
|     _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 @@ | ||||||
| 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 @@ def pseudo_op(name, op, real_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 @@ def wrap_func_w_kwargs(): | ||||||
| """ % (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 @@ async def _asyncwith(c): | ||||||
|         >> 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 @@ def test_kw_names(self): | ||||||
|         # 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 @@ | ||||||
| #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
	
	 Juhi Chandalia
						Juhi Chandalia