Python bytecode STORE_NAME

Peter Otten __peter__ at web.de
Wed Nov 19 04:14:58 EST 2008


schwarz at cs.au.dk wrote:

> As part of some research I am doing a Python Virtual Machine in Java,
> and the exact semantics of the STORE_NAME bytecode is unclear to be,
> so I was hoping somebody here could clarify it.
> The STORE_NAME bytecode is supposed to set a value for a name in the
> current scope. However, the following piece of code:
> 
> def hello(who):
>     print "Hello", who
>     return hello(who)
> print "Say:"
> hello("World")
> 
> Results in this bytecode for the top level:
> 1, LOAD_CONST, 1
> 4, MAKE_FUNCTION, 0
> 7, STORE_NAME, 0
> 10, LOAD_CONST, 2
> 13, PRINT_ITEM, None
> 14, PRINT_NEWLINE, None
> 15, LOAD_NAME, 0
> 18, LOAD_CONST, 3
> 21, CALL_FUNCTION, 1
> 24, POP_TOP, None
> 25, LOAD_CONST, 0
> 28, RETURN_VALUE, None
> 
> And this bytecode for the hello function:
> 1, LOAD_CONST, 1
> 4, PRINT_ITEM, None
> 5, LOAD_FAST, 0
> 8, PRINT_ITEM, None
> 9, PRINT_NEWLINE, None
> 10, LOAD_GLOBAL, 1
> 13, LOAD_FAST, 0
> 16, CALL_FUNCTION, 1
> 19, RETURN_VALUE, None
> 20, LOAD_CONST, 0
> 23, RETURN_VALUE, None
> 
> The first column are the byte numbers, and the last column contains
> the arguments to the byte codes if they take any.
> 
> The function is stored using STORE_NAME with offset 0 in the module
> scope, but it is loaded from inside the hello method using LOAD_GLOBAL
> with offset 1. My questions are: Does STORE_NAME add things to the
> global scope when used top level? And why is the offset different?

Every code object has its own co_names attribute (a tuple). The arguments
are offsets into that tuple.

Using Python 2.5 I can't reproduce your example, I get 0 offsets in both
cases. Here's a simpler one:

>>> import dis
>>> def f():
...     x
...     y
...
>>> def g():
...     y
...
>>> dis.dis(f)
  2           0 LOAD_GLOBAL              0 (x)
              3 POP_TOP

  3           4 LOAD_GLOBAL              1 (y)
              7 POP_TOP
              8 LOAD_CONST               0 (None)
             11 RETURN_VALUE
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (y)
              3 POP_TOP
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE
>>> f.func_code.co_names
('x', 'y')
>>> g.func_code.co_names
('y',)

Peter



More information about the Python-list mailing list