[Tutor] bytecode primer, and avoiding a monster download
eryksun
eryksun at gmail.com
Tue May 28 03:15:59 CEST 2013
On Mon, May 27, 2013 at 4:01 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> I was looking at the bytecode doc page as a break from the Lutz book,
> since I like Assembler-type code due to its total non-ambiguity, but
> the page doesn't say much. Is there a doc somewhere that corresponds
> some of the bytecode to Python source? I thought rot_1, 2, 3, and 4
> looked useful, but it would take awhile to disassemble random programs
> to see what source they come from.
Are you referring to the documentation of the dis module?
http://docs.python.org/2/library/dis
AFAIK, that's all the documentation there is. Heed the warning in bold
that bytecode is an implementation detail of the target virtual
machine. For example, Jython creates a .class file containing JVM
bytecode, and its code objects don't even have a co_code attribute...
I once manually instantiated a CPython 2.x code object to create a
very simple function with a default argument. Here was my first and
only attempt, FWIW:
from opcode import opmap
from types import FunctionType, CodeType
from inspect import CO_OPTIMIZED, CO_NEWLOCALS, CO_NOFREE
OP = type('OP', (), opmap)
def foo1(x='spam'):
print x
foo2 = FunctionType(
CodeType( # func_code
1, # co_argcount
1, # co_nlocals
1, # co_stacksize
CO_OPTIMIZED | # co_flags
CO_NEWLOCALS |
CO_NOFREE,
str(bytearray([ # co_code
OP.LOAD_FAST, 0, 0, # stack.push(fastlocals[0])
# x is fastlocals[0]
OP.PRINT_ITEM, # print stack.pop()
OP.PRINT_NEWLINE,
OP.LOAD_CONST, 0, 0, # stack.push(co_consts[0])
# co_consts[0] is None
OP.RETURN_VALUE, # return stack.pop()
])),
(None,), # co_consts
(), # co_names
('x',), # co_varnames
__file__, # co_filename
'foo2', # co_name
10, # co_firstlineno
'\x00\x01', # co_lnotab,
# see: Objects/lnotab_notes.txt
(), # co_freevars
(), # co_cellvars
),
globals(), # func_globals
'foo2', # func_name
('spam',), # func_defaults
None, # func_closure
)
For example:
>>> foo2()
spam
>>> foo2('eggs')
eggs
There's an assembler package on PyPI that does this for real, if this
sort of thing interests you:
https://pypi.python.org/pypi/BytecodeAssembler
As to the VM's ROT operations, I'm not sure what you mean by seeing
"what source they come from". They simply manipulate the top 2, 3, or
4 items on the frame's stack:
ROT_TWO()
Swaps the two top-most stack items.
ROT_THREE()
Lifts second and third stack item one position up,
moves top down to position three.
ROT_FOUR()
Lifts second, third and forth stack item one position up,
moves top down to position four.
More information about the Tutor
mailing list