[Subversion] / BytecodeAssembler / README.txt  

Diff of /BytecodeAssembler/README.txt

Parent Directory | Revision Log

version 2631, Mon Aug 2 19:34:21 2010 UTC version 2732, Sat Apr 4 00:47:53 2015 UTC
Line 210 
Line 210 
 that maps each ``set_lineno()`` to the corresponding position in the bytecode.  that maps each ``set_lineno()`` to the corresponding position in the bytecode.
   
 And of course, the resulting code objects can be run with ``eval()`` or  And of course, the resulting code objects can be run with ``eval()`` or
 ``exec``, or used with ``new.function`` to create a function::  ``exec``, or used with ``new.function``/``types.FunctionType`` to create a
   function::
   
     >>> eval(c.code())      >>> eval(c.code())
     42      42
   
     >>> exec c.code()   # exec discards the return value, so no output here      >>> exec(c.code())   # exec discards the return value, so no output here
   
     >>> import new      >>> try:
     >>> f = new.function(c.code(), globals())      ...     from new import function
       ... except ImportError:  # Python 3 workarounds
       ...     from types import FunctionType as function
       ...     long = int
       ...     unicode = str
   
       >>> f = function(c.code(), globals())
     >>> f()      >>> f()
     42      42
   
Line 339 
Line 346 
     >>> c.RETURN_VALUE()      >>> c.RETURN_VALUE()
   
     >>> eval(c.code())          # computes type(27)      >>> eval(c.code())          # computes type(27)
     <type 'int'>      <... 'int'>
   
     >>> c = Code()      >>> c = Code()
     >>> c.LOAD_CONST(dict)      >>> c.LOAD_CONST(dict)
Line 475 
Line 482 
 ``None``, or Python code object, it is treated as though it was passed to  ``None``, or Python code object, it is treated as though it was passed to
 the ``LOAD_CONST`` method directly::  the ``LOAD_CONST`` method directly::
   
   
   
     >>> c = Code()      >>> c = Code()
     >>> c(1, 2L, 3.0, 4j+5, "6", u"7", False, None, c.code())      >>> c(1, long(2), 3.0, 4j+5, "6", unicode("7"), False, None, c.code())
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (1)        0           0 LOAD_CONST               1 (1)
                   3 LOAD_CONST               2 (2L)                    3 LOAD_CONST               2 (2...)
                   6 LOAD_CONST               3 (3.0)                    6 LOAD_CONST               3 (3.0)
                   9 LOAD_CONST               4 ((5+4j))                    9 LOAD_CONST               4 ((5+4j))
                  12 LOAD_CONST               5 ('6')                   12 LOAD_CONST               5 ('6')
                  15 LOAD_CONST               6 (u'7')                   15 LOAD_CONST               6 (...'7')
                  18 LOAD_CONST               7 (False)                   18 LOAD_CONST               7 (False)
                  21 LOAD_CONST               0 (None)                   21 LOAD_CONST               0 (None)
                  24 LOAD_CONST               8 (<code object <lambda> at ...>)                   24 LOAD_CONST               8 (<code object <lambda>...>)
   
 Note that although some values of different types may compare equal to each  Note that although some values of different types may compare equal to each
 other, ``Code`` objects will not substitute a value of a different type than  other, ``Code`` objects will not substitute a value of a different type than
 the one you requested::  the one you requested::
   
     >>> c = Code()      >>> c = Code()
     >>> c(1, True, 1.0, 1L)     # equal, but different types      >>> c(1, True, 1.0)     # equal, but different types
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (1)        0           0 LOAD_CONST               1 (1)
                   3 LOAD_CONST               2 (True)                    3 LOAD_CONST               2 (True)
                   6 LOAD_CONST               3 (1.0)                    6 LOAD_CONST               3 (1.0)
                   9 LOAD_CONST               4 (1L)  
   
 Simple Containers  Simple Containers
 -----------------  -----------------
Line 680 
Line 688 
   
   
     >>> Getattr(Const(object), '__class__') # const expression, const result      >>> Getattr(Const(object), '__class__') # const expression, const result
     Const(<type 'type'>)      Const(<... 'type'>)
   
 Or the attribute name can be an expression, in which case a ``getattr()`` call  Or the attribute name can be an expression, in which case a ``getattr()`` call
 is compiled instead::  is compiled instead::
Line 1029 
Line 1037 
   
     >>> from peak.util.assembler import const_value      >>> from peak.util.assembler import const_value
   
     >>> simple_values = [1, 2L, 3.0, 4j+5, "6", u"7", False, None, c.code()]      >>> simple_values = [1, long(2), 3.0, 4j+5, "6", unicode("7"), False, None, c.code()]
   
     >>> map(const_value, simple_values)      >>> list(map(const_value, simple_values))
     [1, 2L, 3.0, (5+4j), '6', u'7', False, None, <code object <lambda> ...>]      [1, 2..., 3.0, (5+4j), '6', ...'7', False, None, <code object <lambda>...>]
   
 Values wrapped in a ``Const()`` are also returned as-is::  Values wrapped in a ``Const()`` are also returned as-is::
   
     >>> map(const_value, map(Const, simple_values))      >>> list(map(const_value, map(Const, simple_values)))
     [1, 2L, 3.0, (5+4j), '6', u'7', False, None, <code object <lambda> ...>]      [1, 2..., 3.0, (5+4j), '6', ...'7', False, None, <code object <lambda>...>]
   
 But no other node types produce constant values; instead, ``NotAConstant`` is  But no other node types produce constant values; instead, ``NotAConstant`` is
 raised::  raised::
Line 1086 
Line 1094 
 ``Const`` node instead of a ``Call`` node::  ``Const`` node instead of a ``Call`` node::
   
     >>> Call( Const(type), [1] )      >>> Call( Const(type), [1] )
     Const(<type 'int'>)      Const(<... 'int'>)
   
 Thus, you can also take the ``const_value()`` of such calls::  Thus, you can also take the ``const_value()`` of such calls::
   
Line 1097 
Line 1105 
 passed in to another ``Call``::  passed in to another ``Call``::
   
     >>> Call(Const(type), [Call( Const(dict), [], [('x',27)] )])      >>> Call(Const(type), [Call( Const(dict), [], [('x',27)] )])
     Const(<type 'dict'>)      Const(<... 'dict'>)
   
 Notice that this folding takes place eagerly, during AST construction.  If you  Notice that this folding takes place eagerly, during AST construction.  If you
 want to implement delayed folding after constant propagation or variable  want to implement delayed folding after constant propagation or variable
Line 1111 
Line 1119 
     >>> c = Code()      >>> c = Code()
     >>> c( Call(Const(type), [1]) )      >>> c( Call(Const(type), [1]) )
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (<type 'int'>)        0           0 LOAD_CONST               1 (<... 'int'>)
   
     >>> c = Code()      >>> c = Code()
     >>> c( Call(Const(type), [1], fold=False) )      >>> c( Call(Const(type), [1], fold=False) )
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (<type 'type'>)        0           0 LOAD_CONST               1 (<... 'type'>)
                   3 LOAD_CONST               2 (1)                    3 LOAD_CONST               2 (1)
                   6 CALL_FUNCTION            1                    6 CALL_FUNCTION            1
   
Line 1387 
Line 1395 
     >>> Getattr = nodetype()(Getattr)      >>> Getattr = nodetype()(Getattr)
   
     >>> const_value(Getattr(1, '__class__'))      >>> const_value(Getattr(1, '__class__'))
     <type 'int'>      <... 'int'>
   
 The ``fold_args()`` function tries to evaluate the node immediately, if all of  The ``fold_args()`` function tries to evaluate the node immediately, if all of
 its arguments are constants, by creating a temporary ``Code`` object, and  its arguments are constants, by creating a temporary ``Code`` object, and
Line 1422 
Line 1430 
     ...     pass      ...     pass
   
     >>> c = Code.from_function(f1)      >>> c = Code.from_function(f1)
     >>> f2 = new.function(c.code(), globals())      >>> f2 = function(c.code(), globals())
   
     >>> import inspect      >>> import inspect
   
Line 1451 
Line 1459 
     >>> def f3(a, (b,c), (d,(e,f))):      >>> def f3(a, (b,c), (d,(e,f))):
     ...     pass      ...     pass
   
     >>> f4 = new.function(Code.from_function(f3).code(), globals())      >>> f4 = function(Code.from_function(f3).code(), globals())
     >>> dis(f4)      >>> dis(f4)
       0           0 LOAD_FAST                1 (.1)        0           0 LOAD_FAST                1 (.1)
                   3 UNPACK_SEQUENCE          2                    3 UNPACK_SEQUENCE          2
Line 1509 
Line 1517 
     >>> c.LOAD_CONST(42)      >>> c.LOAD_CONST(42)
     >>> c.RETURN_VALUE()      >>> c.RETURN_VALUE()
   
     >>> f = new.function(c.code(), globals())      >>> f = function(c.code(), globals())
     >>> f(1,2,3)      >>> f(1,2,3)
     42      42
   
Line 1645 
Line 1653 
   
     >>> c = Code()      >>> c = Code()
     >>> fwd = c.JUMP_FORWARD()      >>> fwd = c.JUMP_FORWARD()
     >>> print c.stack_size  # forward jump marks stack size as unknown      >>> print(c.stack_size)  # forward jump marks stack size as unknown
     None      None
   
     >>> c.LOAD_CONST(42)      >>> c.LOAD_CONST(42)
Line 1871 
Line 1879 
                     POP_BLOCK                      POP_BLOCK
                     JUMP_FORWARD            L4                      JUMP_FORWARD            L4
             L1:     DUP_TOP              L1:     DUP_TOP
                     LOAD_CONST               2 (<...exceptions.KeyError...>)                      LOAD_CONST               2 (<...KeyError...>)
                     COMPARE_OP              10 (exception match)                      COMPARE_OP              10 (exception match)
                     JUMP_IF_FALSE           L2                      JUMP_IF_FALSE           L2
                     POP_TOP                      POP_TOP
Line 1882 
Line 1890 
                     JUMP_FORWARD            L5                      JUMP_FORWARD            L5
             L2:     POP_TOP              L2:     POP_TOP
                     DUP_TOP                      DUP_TOP
                     LOAD_CONST               4 (<...exceptions.TypeError...>)                      LOAD_CONST               4 (<...TypeError...>)
                     COMPARE_OP              10 (exception match)                      COMPARE_OP              10 (exception match)
                     JUMP_IF_FALSE           L3                      JUMP_IF_FALSE           L3
                     POP_TOP                      POP_TOP
Line 2067 
Line 2075 
 clause, and a loop body::  clause, and a loop body::
   
     >>> from peak.util.assembler import For      >>> from peak.util.assembler import For
     >>> y = Call(Const(range), (3,))      >>> y = Call(Const(list), (Call(Const(range), (3,)),))
     >>> x = LocalAssign('x')      >>> x = LocalAssign('x')
     >>> body = Suite([Local('x'), Code.PRINT_EXPR])      >>> body = Suite([Local('x'), Code.PRINT_EXPR])
   
Line 2283 
Line 2291 
     >>> c.return_(Function(Return(Local('a')), 'f', ['a'], defaults=[42]))      >>> c.return_(Function(Return(Local('a')), 'f', ['a'], defaults=[42]))
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (42)        0           0 LOAD_CONST               1 (42)
                   3 LOAD_CONST               2 (<... f ..., file "<string>", line -1>)                    3 LOAD_CONST               2 (<... f..., file ...<string>..., line ...>)
                   6 MAKE_FUNCTION            1                    6 MAKE_FUNCTION            1
                   9 RETURN_VALUE                    9 RETURN_VALUE
   
Line 2314 
Line 2322 
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (99)        0           0 LOAD_CONST               1 (99)
                   3 LOAD_CONST               2 (66)                    3 LOAD_CONST               2 (66)
                   6 LOAD_CONST               3 (<... f ..., file "<string>", line -1>)                    6 LOAD_CONST               3 (<... f..., file ...<string>..., line ...>)
                   9 MAKE_FUNCTION            2                    9 MAKE_FUNCTION            2
                  12 RETURN_VALUE                   12 RETURN_VALUE
   
Line 2327 
Line 2335 
   
     >>> dis(f)      >>> dis(f)
       0           0 LOAD_CLOSURE             0 (a)        0           0 LOAD_CLOSURE             0 (a)
                   ... LOAD_CONST               1 (<... <lambda> ..., file "<string>", line -1>)                    ... LOAD_CONST               1 (<... <lambda>..., file ...<string>..., line ...>)
                   ... MAKE_CLOSURE             0                    ... MAKE_CLOSURE             0
                   ... RETURN_VALUE                    ... RETURN_VALUE
   
Line 2669 
Line 2677 
     >>> c.stack_size      >>> c.stack_size
     0      0
     >>> if sys.version>='2.7':      >>> if sys.version>='2.7':
     ...     print c.stack_history == [0, 1, 1, 1,    0, 0, 0, None, None, 1]      ...     print(c.stack_history == [0, 1, 1, 1,    0, 0, 0, None, None, 1])
     ... else:      ... else:
     ...     print c.stack_history == [0, 1, 1, 1, 1, 1, 1, 0, None, None, 1]      ...     print(c.stack_history == [0, 1, 1, 1, 1, 1, 1, 0, None, None, 1])
     True      True
   
   
Line 2967 
Line 2975 
     >>> c = Code()      >>> c = Code()
     >>> c.return_(Call(Const(type), [], [], (1,)))      >>> c.return_(Call(Const(type), [], [], (1,)))
     >>> dis(c.code())      >>> dis(c.code())
       0           0 LOAD_CONST               1 (<type 'int'>)        0           0 LOAD_CONST               1 (<... 'int'>)
                   3 RETURN_VALUE                    3 RETURN_VALUE
   
   
Line 2997 
Line 3005 
                     POP_BLOCK                      POP_BLOCK
                     JUMP_FORWARD            L3                      JUMP_FORWARD            L3
             L1:     DUP_TOP              L1:     DUP_TOP
                     LOAD_CONST               1 (<...exceptions.AttributeError...>)                      LOAD_CONST               1 (<...AttributeError...>)
                     COMPARE_OP              10 (exception match)                      COMPARE_OP              10 (exception match)
                     JUMP_IF_FALSE           L2                      JUMP_IF_FALSE           L2
                     POP_TOP                      POP_TOP
                     POP_TOP                      POP_TOP
                     POP_TOP                      POP_TOP
                     POP_TOP                      POP_TOP
                     LOAD_CONST               2 (<type 'type'>)                      LOAD_CONST               2 (<... 'type'>)
                     ROT_TWO                      ROT_TWO
                     CALL_FUNCTION            1                      CALL_FUNCTION            1
                     JUMP_FORWARD            L3                      JUMP_FORWARD            L3
Line 3012 
Line 3020 
                     END_FINALLY                      END_FINALLY
             L3:     RETURN_VALUE              L3:     RETURN_VALUE
   
     >>> type_or_class.func_code = c.code()      >>> type_or_class.__code__ = type_or_class.func_code = c.code()
     >>> type_or_class(23)      >>> type_or_class(23)
     <type 'int'>      <... 'int'>
   
   
   
Line 3069 
Line 3077 
     >>> c(Switch(Local('x'), [(1,Return(42)),(2,Return("foo"))], Return(27)))      >>> c(Switch(Local('x'), [(1,Return(42)),(2,Return("foo"))], Return(27)))
     >>> c.return_()      >>> c.return_()
   
     >>> f = new.function(c.code(), globals())      >>> f = function(c.code(), globals())
     >>> f(1)      >>> f(1)
     42      42
     >>> f(2)      >>> f(2)
Line 3079 
Line 3087 
   
     >>> dump(c.code())      >>> dump(c.code())
                     SETUP_LOOP              L2                      SETUP_LOOP              L2
                     LOAD_CONST               1 (<...method get of dict...>)                      LOAD_CONST               1 (<...method ...get of ...>)
                     LOAD_FAST                0 (x)                      LOAD_FAST                0 (x)
                     CALL_FUNCTION            1                      CALL_FUNCTION            1
                     JUMP_IF_FALSE           L1                      JUMP_IF_FALSE           L1
Line 3107 
Line 3115 
 * Exhaustive tests of all opcodes' stack history effects  * Exhaustive tests of all opcodes' stack history effects
   
 * Test wide jumps and wide argument generation in general  * Test wide jumps and wide argument generation in general
   
   * Remove/renumber local variables when a local is converted to free/cell
   


Generate output suitable for use with a patch program
Legend:
Removed from v.2631  
changed lines
  Added in v.2732

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help