This python code:
import dis
def f():
a=[1,2,3]
dis.dis(f)
generates this output:
2 0 RESUME 0
3 2 BUILD_LIST 0
4 LOAD_CONST 1 ((1, 2, 3))
6 LIST_EXTEND 1
8 STORE_FAST 0 (a)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
I am confused about the array building process.
My guess is that:
BUILD_LIST 0sets a marker, or maybe a placeholder for the list's pointer?.LOAD_CONST 1puts all the elements of the #1 constant (that happens to be that tuple), one at the time from the last to the first in the machine stack.LIST_EXTEND 1pops and adds one element from the machine stack at the time to the list, until reaching the marker (I don't know what the1would be for).STORE_FASTnow we have the pointer on top, so this instruction finally binds the pointer to the #0 identifier that happens to bea.
Is this correct? (edit: no, the guess is incorrect)
Cpython executes its bytecodes in a stack-based virtual machine. Now let's start explaining the
disoutput line-by line.BUILD_LIST 0Here
BUILD_LISTis theopcodeand0is theoparg. This will create an empty list and push it onto the top of the stack.After this operation the stack state will be
LOAD_CONST 1This will pushes
(1, 2, 3)(ie,co_consts[1]) to the top of the stack.stack state has now changed to
LIST_EXTEND 1This will first
popthe iterable from the top of the stack(which is(1, 2, 3)).PEEK(oparg)will then get theopargth(which is 1) element of the stack without removing it(which is thelistobject).PEEK(n)expands to#define PEEK(n) (stack_pointer[-(n)])The
_PyList_ExtendAPI extends the list with the iterable in-placeNow the stack state would be:
STORE_FASTStores
STACK.pop()into the local variablea(co_varnames\[var_num\]).