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 |