Modified BytecodeFlowBuilder and AddressFlowBuilder to use a named tuple for representing bytecode instructions.

This commit is contained in:
Jon Riehl 2013-06-11 16:44:15 -05:00
commit 68030d51d1
2 changed files with 19 additions and 13 deletions

View file

@ -4,7 +4,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from .byte_flow import BytecodeFlowBuilder, demo_flow_builder from .byte_flow import Instr, BytecodeFlowBuilder, demo_flow_builder
from .opcode_util import build_basic_blocks, itercodeobjs from .opcode_util import build_basic_blocks, itercodeobjs
# ______________________________________________________________________ # ______________________________________________________________________
@ -39,7 +39,7 @@ class AddressFlowBuilder(BytecodeFlowBuilder):
del self.stack[-pops:] del self.stack[-pops:]
else: else:
stk_args = [] stk_args = []
ret_val = (i, op, opname, arg, stk_args) ret_val = Instr(i, op, opname, arg, stk_args)
if pushes: if pushes:
self.stack.append(ret_val) self.stack.append(ret_val)
self.block.append(ret_val) self.block.append(ret_val)
@ -49,13 +49,13 @@ class AddressFlowBuilder(BytecodeFlowBuilder):
# References top of stack without popping, so we can't use the # References top of stack without popping, so we can't use the
# generic machinery. # generic machinery.
opname = self.opmap[op][0] opname = self.opmap[op][0]
ret_val = i, op, opname, arg, [self.stack[-1][0]] ret_val = Instr(i, op, opname, arg, [self.stack[-1][0]])
self.stack.append(ret_val) self.stack.append(ret_val)
self.block.append(ret_val) self.block.append(ret_val)
return ret_val return ret_val
def op_JUMP_IF_FALSE (self, i, op, arg): def op_JUMP_IF_FALSE (self, i, op, arg):
ret_val = i, op, self.opnames[op], arg, [self.stack[-1][0]] ret_val = Instr(i, op, self.opnames[op], arg, [self.stack[-1][0]])
self.block.append(ret_val) self.block.append(ret_val)
return ret_val return ret_val
@ -66,7 +66,7 @@ class AddressFlowBuilder(BytecodeFlowBuilder):
opcodes.''' opcodes.'''
elem = self.stack.pop() elem = self.stack.pop()
container = self.stack[-arg] container = self.stack[-arg]
ret_val = i, op, self.opnames[op], arg, [container[0], elem[0]] ret_val = Instr(i, op, self.opnames[op], arg, [container[0], elem[0]])
self.block.append(ret_val) self.block.append(ret_val)
return ret_val return ret_val

View file

@ -6,6 +6,7 @@ import dis
import opcode import opcode
import pprint import pprint
import inspect import inspect
from collections import namedtuple
from .bytecode_visitor import BasicBlockVisitor from .bytecode_visitor import BasicBlockVisitor
from . import opcode_util from . import opcode_util
@ -14,6 +15,11 @@ from . import byte_control
# ______________________________________________________________________ # ______________________________________________________________________
# Class definition(s) # Class definition(s)
Instr = namedtuple('Instr', ('address', 'opcode', 'opname', 'oparg',
'stackargs'))
# ______________________________________________________________________
class BytecodeFlowBuilder (BasicBlockVisitor): class BytecodeFlowBuilder (BasicBlockVisitor):
'''Transforms a CFG into a bytecode "flow tree". '''Transforms a CFG into a bytecode "flow tree".
@ -47,7 +53,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
del self.stack[-pops:] del self.stack[-pops:]
else: else:
stk_args = [] stk_args = []
ret_val = (i, op, opname, arg, stk_args) ret_val = Instr(i, op, opname, arg, stk_args)
if pushes: if pushes:
self.stack.append(ret_val) self.stack.append(ret_val)
if appends: if appends:
@ -174,7 +180,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
# References top of stack without popping, so we can't use the # References top of stack without popping, so we can't use the
# generic machinery. # generic machinery.
opname = self.opmap[op][0] opname = self.opmap[op][0]
ret_val = i, op, opname, arg, [self.stack[-1]] ret_val = Instr(i, op, opname, arg, [self.stack[-1]])
self.stack.append(ret_val) self.stack.append(ret_val)
return ret_val return ret_val
@ -197,7 +203,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
op_JUMP_FORWARD = _op op_JUMP_FORWARD = _op
def op_JUMP_IF_FALSE (self, i, op, arg): def op_JUMP_IF_FALSE (self, i, op, arg):
ret_val = i, op, self.opnames[op], arg, [self.stack[-1]] ret_val = Instr(i, op, self.opnames[op], arg, [self.stack[-1]])
self.block.append(ret_val) self.block.append(ret_val)
return ret_val return ret_val
@ -210,7 +216,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
opcodes.''' opcodes.'''
elem = self.stack.pop() elem = self.stack.pop()
container = self.stack[-arg] container = self.stack[-arg]
ret_val = i, op, self.opnames[op], arg, [container, elem] ret_val = Instr(i, op, self.opnames[op], arg, [container, elem])
self.block.append(ret_val) self.block.append(ret_val)
return ret_val return ret_val
@ -255,7 +261,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
def _op_SETUP (self, i, op, arg): def _op_SETUP (self, i, op, arg):
self.control_stack.append((i, op, arg, len(self.stack))) self.control_stack.append((i, op, arg, len(self.stack)))
ret_val = i, op, self.opnames[op], arg, [] ret_val = Instr(i, op, self.opnames[op], arg, [])
self.block.append(ret_val) self.block.append(ret_val)
return ret_val return ret_val
@ -269,9 +275,9 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
# the value stack (the exit ), and once on the handler frame. # the value stack (the exit ), and once on the handler frame.
ctx = self.stack.pop() ctx = self.stack.pop()
# We signal that the value is an exit handler by setting arg to None # We signal that the value is an exit handler by setting arg to None
exit_handler = i, op, self.opnames[op], None, [ctx] exit_handler = Instr(i, op, self.opnames[op], None, [ctx])
self.stack.append(exit_handler) self.stack.append(exit_handler)
ret_val = i, op, self.opnames[op], arg, [ctx] ret_val = Instr(i, op, self.opnames[op], arg, [ctx])
self.control_stack.append((i, op, arg, len(self.stack))) self.control_stack.append((i, op, arg, len(self.stack)))
self.stack.append(ret_val) self.stack.append(ret_val)
self.block.append(ret_val) self.block.append(ret_val)
@ -301,7 +307,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor):
opname = self.opnames[op] opname = self.opnames[op]
while arg > 0: while arg > 0:
arg -= 1 arg -= 1
ret_val = i, op, opname, arg, [seq] ret_val = Instr(i, op, opname, arg, [seq])
self.stack.append(ret_val) self.stack.append(ret_val)
return ret_val return ret_val