如何从操作码和参数列表创建Python字节码?
有没有简单的方法可以从一个包含操作码和它们参数的二元组列表中创建Python字节码呢?
比如说:
>>> bytecode_compile([
('LOAD_CONST', 2),
('STORE_FAST', 'a'),
('LOAD_FAST', 'a'),
('RETURN_VALUE',)])
'd\x01\x00}\x00\x00|\x00\x00S'
2 个回答
3
我觉得目前没有专门为Python的“字节码汇编”提供的工具,但自己动手做一个也许并不难。在Python的源代码中,具体位置是Python-X.Y.Z/Include/opcode.h,这里列出了所有的字节码和它们需要的参数。
4
我在这里详细写过这个内容,所以不想重复,但我会给一些总结性的评论。
这确实是可行的,但我在想这到底有多实用。链接里详细介绍了如何运行和编写这些东西。
字节码在不同版本之间可能会有变化,包括操作码(opcode)、操作码的名称,或者操作码的语义。实际上,从Python 3.6开始,字节码变成了词码(wordcode)。
不过,如果你决定走这条路,最近xdis库新增了一个list2bytecode()
函数,可以用来做这个。
如果你更喜欢在文本文件中工作,就像大多数汇编代码那样,我写了xasm来实现这个。下面是一些可以使用的汇编代码示例:
# Python bytecode 3.6 (3379)
# Method Name: five
# Filename: /tmp/five.pl
# Argument count: 0
# Kw-only arguments: 0
# Number of locals: 0
# Stack size: 1
# Flags: 0x00000043 (NOFREE | NEWLOCALS | OPTIMIZED)
# First Line: 1
# Constants:
# 0: None
# 1: 5
2:
LOAD_CONST (5)
RETURN_VALUE
# Method Name: <module>
# Filename: /tmp/five.pl
# Argument count: 0
# Kw-only arguments: 0
# Number of locals: 0
# Stack size: 2
# Flags: 0x00000040 (NOFREE)
# First Line: 1
# Constants:
# 0: <code object five at 0x0000>
# 1: 'five'
# 2: None
# Names:
# 0: five
# 1: print
1:
LOAD_CONST 0 (<code object five at 0x0000>)
LOAD_CONST ('five')
MAKE_FUNCTION 0
STORE_NAME (five)
3:
LOAD_NAME (print)
LOAD_NAME (five)
CALL_FUNCTION 0
CALL_FUNCTION 1
POP_TOP
LOAD_CONST (None)
RETURN_VALUE