From 68030d51d186885b713c3139942594a8788e859f Mon Sep 17 00:00:00 2001 From: Jon Riehl Date: Tue, 11 Jun 2013 16:44:15 -0500 Subject: [PATCH] Modified BytecodeFlowBuilder and AddressFlowBuilder to use a named tuple for representing bytecode instructions. --- llpython/addr_flow.py | 10 +++++----- llpython/byte_flow.py | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/llpython/addr_flow.py b/llpython/addr_flow.py index 46c4673..d9a774b 100644 --- a/llpython/addr_flow.py +++ b/llpython/addr_flow.py @@ -4,7 +4,7 @@ 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 # ______________________________________________________________________ @@ -39,7 +39,7 @@ class AddressFlowBuilder(BytecodeFlowBuilder): del self.stack[-pops:] else: stk_args = [] - ret_val = (i, op, opname, arg, stk_args) + ret_val = Instr(i, op, opname, arg, stk_args) if pushes: self.stack.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 # generic machinery. 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.block.append(ret_val) return ret_val 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) return ret_val @@ -66,7 +66,7 @@ class AddressFlowBuilder(BytecodeFlowBuilder): opcodes.''' elem = self.stack.pop() 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) return ret_val diff --git a/llpython/byte_flow.py b/llpython/byte_flow.py index 76e1a23..3b9ba76 100644 --- a/llpython/byte_flow.py +++ b/llpython/byte_flow.py @@ -6,6 +6,7 @@ import dis import opcode import pprint import inspect +from collections import namedtuple from .bytecode_visitor import BasicBlockVisitor from . import opcode_util @@ -14,6 +15,11 @@ from . import byte_control # ______________________________________________________________________ # Class definition(s) +Instr = namedtuple('Instr', ('address', 'opcode', 'opname', 'oparg', + 'stackargs')) + +# ______________________________________________________________________ + class BytecodeFlowBuilder (BasicBlockVisitor): '''Transforms a CFG into a bytecode "flow tree". @@ -47,7 +53,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): del self.stack[-pops:] else: stk_args = [] - ret_val = (i, op, opname, arg, stk_args) + ret_val = Instr(i, op, opname, arg, stk_args) if pushes: self.stack.append(ret_val) if appends: @@ -174,7 +180,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): # References top of stack without popping, so we can't use the # generic machinery. 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) return ret_val @@ -197,7 +203,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): op_JUMP_FORWARD = _op 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) return ret_val @@ -210,7 +216,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): opcodes.''' elem = self.stack.pop() 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) return ret_val @@ -255,7 +261,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): def _op_SETUP (self, i, op, arg): 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) return ret_val @@ -269,9 +275,9 @@ class BytecodeFlowBuilder (BasicBlockVisitor): # the value stack (the exit ), and once on the handler frame. ctx = self.stack.pop() # 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) - 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.stack.append(ret_val) self.block.append(ret_val) @@ -301,7 +307,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): opname = self.opnames[op] while arg > 0: arg -= 1 - ret_val = i, op, opname, arg, [seq] + ret_val = Instr(i, op, opname, arg, [seq]) self.stack.append(ret_val) return ret_val