Beispiel #1
0
def cutoff_alwaysraising_block(self, block):
    "Fix a block whose end can never be reached at run-time."
    # search the operation that cannot succeed
    can_succeed = [
        op for op in block.operations if op.result.annotation is not None
    ]
    cannot_succeed = [
        op for op in block.operations if op.result.annotation is None
    ]
    n = len(can_succeed)
    # check consistency
    assert can_succeed == block.operations[:n]
    assert cannot_succeed == block.operations[n:]
    assert 0 <= n < len(block.operations)
    # chop off the unreachable end of the block
    del block.operations[n + 1:]
    self.setbinding(block.operations[n].result, annmodel.s_ImpossibleValue)
    # insert the equivalent of 'raise AssertionError'
    graph = self.annotated[block]
    msg = "Call to %r should have raised an exception" % (getattr(
        graph, 'func', None), )
    c1 = Constant(AssertionError)
    c2 = Constant(AssertionError(msg))
    errlink = Link([c1, c2], graph.exceptblock)
    block.recloseblock(errlink, *block.exits)
    # record new link to make the transformation idempotent
    self.links_followed[errlink] = True
    # fix the annotation of the exceptblock.inputargs
    etype, evalue = graph.exceptblock.inputargs
    s_type = annmodel.SomeType()
    s_type.is_type_of = [evalue]
    s_value = annmodel.SomeInstance(
        self.bookkeeper.getuniqueclassdef(Exception))
    self.setbinding(etype, s_type)
    self.setbinding(evalue, s_value)
    # make sure the bookkeeper knows about AssertionError
    self.bookkeeper.getuniqueclassdef(AssertionError)
Beispiel #2
0
    def follow_link(self, graph, link, knowntypedata):
        in_except_block = False
        v_last_exc_type = link.last_exception  # may be None for non-exception link
        v_last_exc_value = link.last_exc_value  # may be None for non-exception link

        if (isinstance(link.exitcase, (types.ClassType, type))
                and issubclass(link.exitcase, BaseException)):
            assert v_last_exc_type and v_last_exc_value
            s_last_exc_value = self.bookkeeper.valueoftype(link.exitcase)
            s_last_exc_type = annmodel.SomeType()
            if isinstance(v_last_exc_type, Constant):
                s_last_exc_type.const = v_last_exc_type.value
            s_last_exc_type.is_type_of = [v_last_exc_value]

            if isinstance(v_last_exc_type, Variable):
                self.setbinding(v_last_exc_type, s_last_exc_type)
            if isinstance(v_last_exc_value, Variable):
                self.setbinding(v_last_exc_value, s_last_exc_value)

            s_last_exc_type = annmodel.SomeType()
            if isinstance(v_last_exc_type, Constant):
                s_last_exc_type.const = v_last_exc_type.value
            last_exc_value_vars = []
            in_except_block = True

        ignore_link = False
        inputs_s = []
        renaming = {}
        for v_out, v_input in zip(link.args, link.target.inputargs):
            renaming.setdefault(v_out, []).append(v_input)
        for v_out, v_input in zip(link.args, link.target.inputargs):
            if v_out == v_last_exc_type:
                assert in_except_block
                inputs_s.append(s_last_exc_type)
            elif v_out == v_last_exc_value:
                assert in_except_block
                inputs_s.append(s_last_exc_value)
                last_exc_value_vars.append(v_input)
            else:
                s_out = self.annotation(v_out)
                if (link.exitcase, v_out) in knowntypedata:
                    knownvarvalue = knowntypedata[(link.exitcase, v_out)]
                    s_out = pair(s_out, knownvarvalue).improve()
                    # ignore links that try to pass impossible values
                    if s_out == annmodel.s_ImpossibleValue:
                        ignore_link = True

                if hasattr(s_out, 'is_type_of'):
                    renamed_is_type_of = []
                    for v in s_out.is_type_of:
                        new_vs = renaming.get(v, [])
                        renamed_is_type_of += new_vs
                    assert s_out.knowntype is type
                    newcell = annmodel.SomeType()
                    if s_out.is_constant():
                        newcell.const = s_out.const
                    s_out = newcell
                    s_out.is_type_of = renamed_is_type_of

                if hasattr(s_out, 'knowntypedata'):
                    renamed_knowntypedata = {}
                    for (value, v), s in s_out.knowntypedata.items():
                        new_vs = renaming.get(v, [])
                        for new_v in new_vs:
                            renamed_knowntypedata[value, new_v] = s
                    assert isinstance(s_out, annmodel.SomeBool)
                    newcell = annmodel.SomeBool()
                    if s_out.is_constant():
                        newcell.const = s_out.const
                    s_out = newcell
                    s_out.set_knowntypedata(renamed_knowntypedata)

                inputs_s.append(s_out)
        if ignore_link:
            return

        if in_except_block:
            s_last_exc_type.is_type_of = last_exc_value_vars
        self.links_followed[link] = True
        self.addpendingblock(graph, link.target, inputs_s)