Beispiel #1
0
 def seed_return(self, typ):
     """Seeding of return value is optional.
     """
     for blk in utils.dict_itervalues(self.blocks):
         inst = blk.terminator
         if isinstance(inst, ir.Return):
             self.typevars[inst.value.name].lock(typ)
Beispiel #2
0
 def seed_return(self, typ):
     """Seeding of return value is optional.
     """
     for blk in utils.dict_itervalues(self.blocks):
         inst = blk.terminator
         if isinstance(inst, ir.Return):
             self.typevars[inst.value.name].lock(typ)
Beispiel #3
0
    def run(self):
        for inst in self._iter_inst():
            fname = "op_%s" % inst.opname
            fn = getattr(self, fname, None)
            if fn is not None:
                fn(inst)
            else:
                assert not inst.is_jump, inst

        # Close all blocks
        for cur, nxt in zip(self.blockseq, self.blockseq[1:]):
            blk = self.blocks[cur]
            if not blk.outgoing_jumps and not blk.terminating:
                blk.outgoing_jumps[nxt] = 0

        graph = CFGraph()
        for b in self.blocks:
            graph.add_node(b)
        for b in self.blocks.values():
            for out, pops in b.outgoing_jumps.items():
                graph.add_edge(b.offset, out, pops)
        graph.set_entry_point(min(self.blocks))
        graph.process()
        self.graph = graph

        # Fill incoming
        for b in utils.dict_itervalues(self.blocks):
            for out, pops in b.outgoing_jumps.items():
                self.blocks[out].incoming_jumps[b.offset] = pops

        # Find liveblocks
        self.liveblocks = dict((i, self.blocks[i])
                               for i in self.graph.nodes())

        for lastblk in reversed(self.blockseq):
            if lastblk in self.liveblocks:
                break
        else:
            raise AssertionError("No live block that exits!?")

        # Find backbone
        backbone = self.graph.backbone()
        # Filter out in loop blocks (Assuming no other cyclic control blocks)
        # This is to unavoid variable defined in loops to be considered as
        # function scope.
        inloopblocks = set()

        for b in self.blocks.keys():
            for s, e in self._loops:
                if s <= b < e:
                    inloopblocks.add(b)

        self.backbone = backbone - inloopblocks
Beispiel #4
0
 def _start_new_block(self, inst):
     self.loc = ir.Loc(filename=self.bytecode.filename, line=inst.lineno)
     oldblock = self.current_block
     self.insert_block(inst.offset)
     # Ensure the last block is terminated
     if oldblock is not None and not oldblock.is_terminated:
         jmp = ir.Jump(inst.offset, loc=self.loc)
         oldblock.append(jmp)
         # Get DFA block info
     self.dfainfo = self.dfa.infos[self.current_block_offset]
     self.assigner = Assigner()
     # Notify listeners for the new block
     for fn in utils.dict_itervalues(self._block_actions):
         fn(self.current_block_offset, self.current_block)
Beispiel #5
0
 def _start_new_block(self, inst):
     self.loc = ir.Loc(filename=self.bytecode.filename, line=inst.lineno)
     oldblock = self.current_block
     self.insert_block(inst.offset)
     # Ensure the last block is terminated
     if oldblock is not None and not oldblock.is_terminated:
         jmp = ir.Jump(inst.offset, loc=self.loc)
         oldblock.append(jmp)
         # Get DFA block info
     self.dfainfo = self.dfa.infos[self.current_block_offset]
     # Insert PHI
     self._insert_phi()
     # Notify listeners for the new block
     for fn in utils.dict_itervalues(self._block_actions):
         fn(self.current_block_offset, self.current_block)
Beispiel #6
0
    def run(self):
        for inst in self._iter_inst():
            fname = "op_%s" % inst.opname
            fn = getattr(self, fname, None)
            if fn is not None:
                fn(inst)
            else:
                assert not inst.is_jump, inst

        # Close all blocks
        for cur, nxt in zip(self.blockseq, self.blockseq[1:]):
            blk = self.blocks[cur]
            if not blk.outgoing and not blk.terminating:
                blk.outgoing.add(nxt)

        # Fill incoming
        for b in utils.dict_itervalues(self.blocks):
            for out in b.outgoing:
                self.blocks[out].incoming.add(b.offset)

        # Find liveblocks
        self.dead_block_elimin()

        # Find dominators
        self.doms = find_dominators(self.liveblocks)

        for lastblk in reversed(self.blockseq):
            if lastblk in self.liveblocks:
                break
        else:
            raise AssertionError("No live block that exits!?")

        # Find backbone
        backbone = set(self.doms[lastblk])
        # Filter out in loop blocks (Assuming no other cyclic control blocks)
        # This is to unavoid variable defined in loops to be considered as
        # function scope.
        inloopblocks = set()

        for b in self.blocks.keys():
            for s, e in self._loops:
                if s <= b < e:
                    inloopblocks.add(b)

        self.backbone = backbone - inloopblocks
Beispiel #7
0
    def get_return_type(self, typemap):
        rettypes = set()
        for blk in utils.dict_itervalues(self.blocks):
            term = blk.terminator
            if isinstance(term, ir.Return):
                rettypes.add(typemap[term.value.name])

        if types.none in rettypes:
            # Special case None return
            rettypes = rettypes - set([types.none])
            if rettypes:
                unified = self.context.unify_types(*rettypes)
                return types.Optional(unified)
            else:
                return types.none
        else:
            unified = self.context.unify_types(*rettypes)
            return unified
Beispiel #8
0
    def get_return_type(self, typemap):
        rettypes = set()
        for blk in utils.dict_itervalues(self.blocks):
            term = blk.terminator
            if isinstance(term, ir.Return):
                rettypes.add(typemap[term.value.name])

        if types.none in rettypes:
            # Special case None return
            rettypes = rettypes - set([types.none])
            if rettypes:
                unified = self.context.unify_types(*rettypes)
                return types.Optional(unified)
            else:
                return types.none
        else:
            unified = self.context.unify_types(*rettypes)
            return unified
Beispiel #9
0
    def run(self):
        for inst in self._iter_inst():
            fname = "op_%s" % inst.opname
            fn = getattr(self, fname, None)
            if fn is not None:
                fn(inst)
            else:
                assert not inst.is_jump, inst

        # Close all blocks
        for cur, nxt in zip(self.blockseq, self.blockseq[1:]):
            blk = self.blocks[cur]
            if not blk.outgoing and not blk.terminating:
                blk.outgoing.add(nxt)

        # Fill incoming
        for b in utils.dict_itervalues(self.blocks):
            for out in b.outgoing:
                self.blocks[out].incoming.add(b.offset)

        # Find liveblocks
        self.dead_block_elimin()

        # Find dominators
        self.doms = find_dominators(self.liveblocks)

        for lastblk in reversed(self.blockseq):
            if lastblk in self.liveblocks:
                break
        else:
            raise AssertionError("No live block that exits!?")

        # Find backbone
        backbone = set(self.doms[lastblk])
        # Filter out in loop blocks (Assuming no other cyclic control blocks)
        inloopblocks = set()
        for b in self.blocks.keys():
            for s, e in self._loops:
                if s <= b < e:
                    inloopblocks.add(b)
        self.backbone = backbone - inloopblocks
Beispiel #10
0
    def run_block(self, blk):
        tempassign = {}
        removeset = set()

        for offset, inst in enumerate(blk.body):
            self.mark_asssignment(tempassign, offset, inst)

        for bag in utils.dict_itervalues(tempassign):
            if len(bag) == 2:
                off1, off2 = bag
                first = blk.body[off1]
                second = blk.body[off2]
                inst = ir.Assign(value=first.value, target=second.target, loc=first.loc)
                # Replacement the second instruction
                blk.body[off2] = inst
                # Remove the first
                removeset.add(off1)

        # Remove from the highest offset to the lowest to preserve order
        for off in reversed(sorted(removeset)):
            del blk.body[off]
Beispiel #11
0
    def run_block(self, blk):
        tempassign = {}
        removeset = set()

        for offset, inst in enumerate(blk.body):
            self.mark_asssignment(tempassign, offset, inst)

        for bag in utils.dict_itervalues(tempassign):
            if len(bag) == 2:
                off1, off2 = bag
                first = blk.body[off1]
                second = blk.body[off2]
                inst = ir.Assign(value=first.value, target=second.target,
                                 loc=first.loc)
                # Replacement the second instruction
                blk.body[off2] = inst
                # Remove the first
                removeset.add(off1)

        # Remove from the highest offset to the lowest to preserve order
        for off in reversed(sorted(removeset)):
            del blk.body[off]
Beispiel #12
0
 def dump(self):
     for blk in utils.dict_itervalues(self.infos):
         blk.dump()
Beispiel #13
0
 def __iter__(self):
     return utils.dict_itervalues(self.table)
Beispiel #14
0
 def get_state_token(self):
     """The algorithm is monotonic.  It can only grow the typesets.
     The sum of all lengths of type sets is a cheap and accurate
     description of our progress.
     """
     return sum(len(tv) for tv in utils.dict_itervalues(self.typevars))
Beispiel #15
0
 def build_constrain(self):
     for blk in utils.dict_itervalues(self.blocks):
         for inst in blk.body:
             self.constrain_statement(inst)
Beispiel #16
0
 def cleanup(self):
     for var in utils.dict_itervalues(self.varmap):
         self.decref(self.builder.load(var))
Beispiel #17
0
 def get_state_token(self):
     """The algorithm is monotonic.  It can only grow the typesets.
     The sum of all lengths of type sets is a cheap and accurate
     description of our progress.
     """
     return sum(len(tv) for tv in utils.dict_itervalues(self.typevars))
Beispiel #18
0
 def build_constrain(self):
     for blk in utils.dict_itervalues(self.blocks):
         for inst in blk.body:
             self.constrain_statement(inst)
Beispiel #19
0
 def verify(self):
     for b in utils.dict_itervalues(self.blocks):
         b.verify()
Beispiel #20
0
 def __iter__(self):
     return utils.dict_itervalues(self.table)
Beispiel #21
0
 def verify(self):
     for b in utils.dict_itervalues(self.blocks):
         b.verify()
Beispiel #22
0
 def dump(self):
     for blk in utils.dict_itervalues(self.infos):
         blk.dump()
Beispiel #23
0
 def cleanup(self):
     for var in utils.dict_itervalues(self.varmap):
         self.decref(self.builder.load(var))