I am having a lot of difficulty understanding Python's bytecode and its dis
module.
import dis
def func():
x = 1
dis.dis(func)
The above code when typed in the interpreter produces the following output:
0 LOAD_CONST 1(1)
3 STORE_FAST 0(x)
6 LOAD_CONST 0(NONE)
9 RETURN_VALUE
E.g.:
What is the meaning of LOAD_CONST
, STORE_FAST
and the numbers like 0
, 3
, 6
and 9
?
A specific resource, where I can find this information would be much appreciated.
The numbers before the bytecodes are offsets into the original binary bytecodes:
Some bytecodes come with additional information (arguments) that influence how each bytecode works, the offset tells you at what position in the bytestream the bytecode was found.
The
LOAD_CONST
bytecode (ASCIId
, hex 64) is followed by two additional bytes encoding a reference to a constant associated with the bytecode, for example. As a result, theSTORE_FAST
opcode (ASCII}
, hex 7D) is found at index 3.The
dis
module documentation lists what each instruction means. ForLOAD_CONST
, it says:which refers to the
co_consts
structure that is always present with a code object; the compiler constructs that:The opcode loads index 1 from that structure (the 01 00 bytes in the bytecode encode a 1), and
dis
has looked that up for you; it is the value1
.The next instruction,
STORE_FAST
is described as:Here TOS refers to Top Of Stack; note that the
LOAD_CONST
just pushed something onto the stack, the1
value.co_varnames
is another structure; it references local variable names, the opcode references index 0:dis
looked that up too, and the name you used in your code isx
. Thus, this opcode stored1
intox
.Another
LOAD_CONST
loadsNone
onto the stack from index 0, followed byRETURN_VALUE
:so this instruction takes the top of the stack (with the
None
constant) and returns from this code block.None
is the default return value for functions without an explicitreturn
statement.You omitted something from the
dis
output, the line numbers:Note the
2
on the first line; that's the line number in the original source that contains the Python code that was used for these instructions. Python code objects haveco_lnotab
andco_firstlineno
attributes that let you map bytecodes back to line numbers in the original source.dis
does this for you when displaying a disassembly.