예제 #1
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)
            elif inst.is_jump:
                # this catches e.g. try... except
                l = Loc(self.bytecode.func_id.filename, inst.lineno)
                if inst.opname in {"SETUP_EXCEPT", "SETUP_FINALLY"}:
                    msg = "'try' block not supported until python3.7 or later"
                else:
                    msg = "Use of unsupported opcode (%s) found" % inst.opname
                raise UnsupportedError(msg, loc=l)
            else:
                # Non-jump instructions are ignored
                pass  # intentionally

        # 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.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():
            if self.graph.in_loops(b):
                inloopblocks.add(b)

        self.backbone = backbone - inloopblocks
예제 #2
0
 def op_CALL_FUNCTION_EX(self, state, inst):
     if inst.arg & 1:
         errmsg = "CALL_FUNCTION_EX with **kwargs not supported"
         raise UnsupportedError(errmsg)
     vararg = state.pop()
     func = state.pop()
     res = state.make_temp()
     state.append(inst, func=func, vararg=vararg, res=res)
     state.push(res)
예제 #3
0
 def dispatch(self, state):
     inst = state.get_inst()
     _logger.debug("dispatch pc=%s, inst=%s", state._pc, inst)
     fn = getattr(self, "op_{}".format(inst.opname), None)
     if fn is not None:
         fn(state, inst)
     else:
         msg = "Use of unsupported opcode (%s) found" % inst.opname
         raise UnsupportedError(msg, loc=self.get_debug_loc(inst.lineno))
예제 #4
0
def literal_unroll_impl(container):
    from numba.errors import UnsupportedError
    if sys.version_info[:2] < (3, 6):
        raise UnsupportedError(
            "literal_unroll is only support in Python > 3.5")

    def impl(container):
        return container

    return impl
예제 #5
0
 def op_POP_EXCEPT(self, state, inst):
     blk = state.pop_block()
     if blk['kind'] not in {BlockKind('EXCEPT'), BlockKind('FINALLY')}:
         raise UnsupportedError(
             "POP_EXCEPT got an unexpected block: {}".format(blk['kind']),
             loc=self.get_debug_loc(inst.lineno),
         )
     state.pop()
     state.pop()
     state.pop()
     # Forces a new block
     state.fork(pc=inst.next)
예제 #6
0
 def op_RAISE_VARARGS(self, state, inst):
     in_exc_block = any([
         state.get_top_block("EXCEPT") is not None,
         state.get_top_block("FINALLY") is not None
     ])
     if inst.arg == 0:
         exc = None
         if in_exc_block:
             raise UnsupportedError(
                 "The re-raising of an exception is not yet supported.",
                 loc=self.get_debug_loc(inst.lineno),
             )
     elif inst.arg == 1:
         exc = state.pop()
     else:
         raise ValueError("Multiple argument raise is not supported.")
     state.append(inst, exc=exc)
     state.terminate()
예제 #7
0
 def op_POP_FINALLY(self, state, inst):
     # we don't emulate the exact stack behavior
     if inst.arg != 0:
         msg = ('Unsupported use of a bytecode related to try..finally'
                ' or a with-context')
         raise UnsupportedError(msg, loc=self.get_debug_loc(inst.lineno))