[Subversion] / BytecodeAssembler / README.txt  

View of /BytecodeAssembler/README.txt

Parent Directory | Revision Log
Revision: 2191 - (download)
Sat Jun 17 04:37:36 2006 UTC (17 years, 10 months ago) by pje
File size: 3288 byte(s)
Major update: lots of docs, block support, loops, break, continue,
exception handling, pseudo-"switch" statement demo, .label() renamed to 
.here(), constant folding, const_value() API, NotAConstant exception.
Python Bytecode Assembler
=========================

This is a simple assembler that handles most low-level bytecode details like
jump offsets, stack size tracking, line number table generation, constant and
variable name index tracking, etc.  That way, you can focus your attention on
the desired semantics of your bytecode instead of on these mechanical issues.

Simple usage::

    >>> from peak.util.assembler import Code
    >>> c = Code()
    >>> c.set_lineno(15)   # set the current line number (optional)
    >>> c.LOAD_CONST(42)
    >>> c.set_lineno(16)   # set it as many times as you like
    >>> c.RETURN_VALUE()

    >>> eval(c.code())
    42

    >>> from dis import dis
    >>> dis(c.code())
      15          0 LOAD_CONST               0 (42)
      16          3 RETURN_VALUE

Labels and backpatching forward references::

    >>> c = Code()
    >>> ref = c.JUMP_ABSOLUTE()     # jump w/unspecified target
    >>> c.LOAD_CONST(1)
    >>> ref()                       # resolve the forward reference
    >>> c.RETURN_VALUE()
    >>> dis(c.code())
      0           0 JUMP_ABSOLUTE            6
                  3 LOAD_CONST               0 (1)
            >>    6 RETURN_VALUE


    >>> c = Code()
    >>> lbl = c.label()     # create a label at this point in the code
    >>> c.LOAD_CONST(1)
    >>> ref = c.JUMP_ABSOLUTE(lbl)  # and jump to it
    >>> dis(c.code())
      0     >>    0 LOAD_CONST               0 (1)
                  3 JUMP_ABSOLUTE            0

Code generation using tuples, lists, dicts, calls, constants, globals, etc.::

    >>> c = Code()
    >>> c( ['x', ('y','z')] )
    >>> dis(c.code())
      0           0 LOAD_FAST                0 (x)
                  3 LOAD_FAST                1 (y)
                  6 LOAD_FAST                2 (z)
                  9 BUILD_TUPLE              2
                 12 BUILD_LIST               2

    >>> from peak.util.assembler import Call, Const, Global, Local
    >>> c = Code()
    >>> c.set_lineno(1)
    >>> c.return_(Call(Global('foo'), [Local('q')], [('x',Const(1))],
    ...                Local('starargs'), Local('kwargs')))
    >>> dis(c.code())
      1           0 LOAD_GLOBAL              0 (foo)
                  3 LOAD_FAST                0 (q)
                  6 LOAD_CONST               1 ('x')
                  9 LOAD_CONST               2 (1)
                 12 LOAD_FAST                1 (starargs)
                 15 LOAD_FAST                2 (kwargs)
                 18 CALL_FUNCTION_VAR_KW   257
                 21 RETURN_VALUE

(Code generation is also extensible; any 1-argument callables passed in will
be called on the code object during generation.)

For more examples, see ``assembler.txt`` in the ``peak.util`` package
directory.

There are a few features that aren't tested yet, and not all opcodes may be
fully supported.  Notably, the following features are NOT reliably supported
yet:

* Wide jump addressing (for generated bytecode>64K in size)

* The ``dis()`` module in Python 2.3 has a bug that makes it show incorrect
  line numbers when the difference between two adjacent line numbers is
  greater than 255.  This causes two shallow failures in the current test
  suite when it's run under Python 2.3.

If you find any other issues, please let me know.


cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help