Example #1
0
 def compute_result_annotation(self, s_l, s_sizehint):
     from rpython.annotator import model as annmodel
     if annmodel.s_None.contains(s_l):
         return  # first argument is only None so far, but we
         # expect a generalization later
     if not isinstance(s_l, annmodel.SomeList):
         raise annmodel.AnnotatorError("First argument must be a list")
     if not isinstance(s_sizehint, annmodel.SomeInteger):
         raise annmodel.AnnotatorError("Second argument must be an integer")
     s_l.listdef.listitem.resize()
Example #2
0
    def addpendingblock(self, graph, block, cells):
        """Register an entry point into block with the given input cells."""
        if graph in self.fixed_graphs:
            # special case for annotating/rtyping in several phases: calling
            # a graph that has already been rtyped.  Safety-check the new
            # annotations that are passed in, and don't annotate the old
            # graph -- it's already low-level operations!
            for a, s_newarg in zip(block.inputargs, cells):
                s_oldarg = a.annotation
                # XXX: Should use s_oldarg.contains(s_newarg) but that breaks
                # PyPy translation
                if annmodel.unionof(s_oldarg, s_newarg) != s_oldarg:
                    raise annmodel.AnnotatorError(
                        "Late-stage annotation is not allowed to modify the "
                        "existing annotation for variable %s: %s" %
                        (a, s_oldarg))

        else:
            assert not self.frozen
            if block not in self.annotated:
                self.bindinputargs(graph, block, cells)
            else:
                self.mergeinputargs(graph, block, cells)
            if not self.annotated[block]:
                self.pendingblocks[block] = graph
Example #3
0
    def complete(self):
        """Process pending blocks until none is left."""
        while True:
            self.complete_pending_blocks()
            self.policy.no_more_blocks_to_annotate(self)
            if not self.pendingblocks:
                break  # finished
        # make sure that the return variables of all graphs is annotated
        if self.added_blocks is not None:
            newgraphs = [self.annotated[block] for block in self.added_blocks]
            newgraphs = dict.fromkeys(newgraphs)
            got_blocked_blocks = False in newgraphs
        else:
            newgraphs = self.translator.graphs  #all of them
            got_blocked_blocks = False in self.annotated.values()
        if got_blocked_blocks:
            for graph in self.blocked_graphs.values():
                self.blocked_graphs[graph] = True

            blocked_blocks = [
                block for block, done in self.annotated.items()
                if done is False
            ]
            assert len(blocked_blocks) == len(self.blocked_blocks)

            text = format_blocked_annotation_error(self, self.blocked_blocks)
            #raise SystemExit()
            raise annmodel.AnnotatorError(text)
        for graph in newgraphs:
            v = graph.getreturnvar()
            if v.annotation is None:
                self.setbinding(v, annmodel.s_ImpossibleValue)
        # policy-dependent computation
        self.bookkeeper.compute_at_fixpoint()
Example #4
0
 def getattr(self, s_attr):
     if not s_attr.is_constant():
         raise annmodel.AnnotatorError(
             "non-constant attr name in getattr()")
     attrname = s_attr.const
     TYPE = STAT_FIELD_TYPES[attrname]
     return lltype_to_annotation(TYPE)
Example #5
0
 def compute_result_annotation(self, s_l):
     from rpython.annotator import model as annmodel
     if annmodel.s_None.contains(s_l):
         pass  # first argument is only None so far, but we
         # expect a generalization later
     elif not isinstance(s_l, annmodel.SomeList):
         raise annmodel.AnnotatorError("First argument must be a list")
     return annmodel.SomeInteger(nonneg=True)
Example #6
0
    def complete(self):
        """Process pending blocks until none is left."""
        while True:
            self.complete_pending_blocks()
            self.policy.no_more_blocks_to_annotate(self)
            if not self.pendingblocks:
                break  # finished
        # make sure that the return variables of all graphs is annotated
        if self.added_blocks is not None:
            newgraphs = [self.annotated[block] for block in self.added_blocks]
            newgraphs = dict.fromkeys(newgraphs)
            got_blocked_blocks = False in newgraphs
        else:
            newgraphs = self.translator.graphs  #all of them
            got_blocked_blocks = False in self.annotated.values()
        if self.failed_blocks:
            text = ('Annotation failed, %s errors were recorded:' %
                    len(self.errors))
            text += '\n-----'.join(str(e) for e in self.errors)
            raise annmodel.AnnotatorError(text)

        if got_blocked_blocks:
            for graph in self.blocked_graphs.values():
                self.blocked_graphs[graph] = True

            blocked_blocks = [
                block for block, done in self.annotated.items()
                if done is False
            ]
            assert len(blocked_blocks) == len(self.blocked_blocks)

            text = format_blocked_annotation_error(self, self.blocked_blocks)
            #raise SystemExit()
            raise annmodel.AnnotatorError(text)
        for graph in newgraphs:
            v = graph.getreturnvar()
            if v.annotation is None:
                self.setbinding(v, s_ImpossibleValue)
            v = graph.exceptblock.inputargs[1]
            if v.annotation is not None and v.annotation.can_be_none():
                raise annmodel.AnnotatorError(
                    "%r is found by annotation to possibly raise None, "
                    "but the None was not suppressed by the flow space" %
                    (graph, ))
Example #7
0
 def getattr(self, s_attr):
     if not s_attr.is_constant():
         raise annmodel.AnnotatorError("non-constant attr name in getattr()")
     attrname = s_attr.const
     if attrname in ('st_atime', 'st_mtime', 'st_ctime'):
         # like CPython, in RPython we can read the st_Xtime
         # attribute and get a floating-point result.  We can also
         # get a full-precision bigint with get_stat_ns_as_bigint().
         # The floating-point result is computed like a property
         # by _ll_get_st_Xtime().
         TYPE = lltype.Float
     else:
         TYPE = STAT_FIELD_TYPES[attrname]
     return lltype_to_annotation(TYPE)
Example #8
0
def all_values(s):
    """Return the exhaustive list of possible values matching annotation `s`.

    Raises `AnnotatorError` if no such (reasonably small) finite list exists.
    """
    if s.is_constant():
        return [s.const]
    elif isinstance(s, SomePBC):
        values = []
        assert not s.can_be_None, "memo call: cannot mix None and PBCs"
        for desc in s.descriptions:
            if desc.pyobj is None:
                raise annmodel.AnnotatorError(
                    "memo call with a class or PBC that has no "
                    "corresponding Python object (%r)" % (desc, ))
            values.append(desc.pyobj)
        return values
    elif isinstance(s, SomeImpossibleValue):
        return []
    elif isinstance(s, SomeBool):
        return [False, True]
    else:
        raise annmodel.AnnotatorError("memo call: argument must be a class "
                                      "or a frozen PBC, got %r" % (s, ))
Example #9
0
def specialize_argvalue(funcdesc, args_s, *argindices):
    from rpython.annotator.model import SomePBC
    key = []
    for i in argindices:
        s = args_s[i]
        if s.is_constant():
            key.append(s.const)
        elif isinstance(s, SomePBC) and len(s.descriptions) == 1:
            # for test_specialize_arg_bound_method
            desc, = s.descriptions
            key.append(desc)
        else:
            raise annmodel.AnnotatorError("specialize:arg(%d): argument not "
                                          "constant: %r" % (i, s))
    key = tuple(key)
    return maybe_star_args(funcdesc, key, args_s)
Example #10
0
def memo(funcdesc, args_s):
    # call the function now, and collect possible results

    # the list of all possible tuples of arguments to give to the memo function
    possiblevalues = cartesian_product([all_values(s_arg) for s_arg in args_s])

    # a MemoTable factory -- one MemoTable per family of arguments that can
    # be called together, merged via a UnionFind.
    bookkeeper = funcdesc.bookkeeper
    try:
        memotables = bookkeeper.all_specializations[funcdesc]
    except KeyError:
        func = funcdesc.pyobj
        if func is None:
            raise annmodel.AnnotatorError(
                "memo call: no Python function object"
                "to call (%r)" % (funcdesc, ))

        def compute_one_result(args):
            value = func(*args)
            memotable = MemoTable(funcdesc, args, value)
            memotable.register_finish()
            return memotable

        memotables = UnionFind(compute_one_result)
        bookkeeper.all_specializations[funcdesc] = memotables

    # merge the MemoTables for the individual argument combinations
    firstvalues = possiblevalues.next()
    _, _, memotable = memotables.find(firstvalues)
    for values in possiblevalues:
        _, _, memotable = memotables.union(firstvalues, values)

    if memotable.graph is not None:
        return memotable.graph  # if already computed
    else:
        # otherwise, for now, return the union of each possible result
        return unionof(
            *[bookkeeper.immutablevalue(v) for v in memotable.table.values()])
Example #11
0
def memo(funcdesc, arglist_s):
    from rpython.annotator.model import SomePBC, SomeImpossibleValue, SomeBool
    from rpython.annotator.model import unionof
    # call the function now, and collect possible results
    argvalues = []
    for s in arglist_s:
        if s.is_constant():
            values = [s.const]
        elif isinstance(s, SomePBC):
            values = []
            assert not s.can_be_None, "memo call: cannot mix None and PBCs"
            for desc in s.descriptions:
                if desc.pyobj is None:
                    raise annmodel.AnnotatorError(
                        "memo call with a class or PBC that has no "
                        "corresponding Python object (%r)" % (desc, ))
                values.append(desc.pyobj)
        elif isinstance(s, SomeImpossibleValue):
            return s  # we will probably get more possible args later
        elif isinstance(s, SomeBool):
            values = [False, True]
        else:
            raise annmodel.AnnotatorError(
                "memo call: argument must be a class "
                "or a frozen PBC, got %r" % (s, ))
        argvalues.append(values)
    # the list of all possible tuples of arguments to give to the memo function
    possiblevalues = cartesian_product(argvalues)

    # a MemoTable factory -- one MemoTable per family of arguments that can
    # be called together, merged via a UnionFind.
    bookkeeper = funcdesc.bookkeeper
    try:
        memotables = bookkeeper.all_specializations[funcdesc]
    except KeyError:
        func = funcdesc.pyobj
        if func is None:
            raise annmodel.AnnotatorError(
                "memo call: no Python function object"
                "to call (%r)" % (funcdesc, ))

        def compute_one_result(args):
            value = func(*args)
            memotable = MemoTable(funcdesc, args, value)
            memotable.register_finish()
            return memotable

        memotables = UnionFind(compute_one_result)
        bookkeeper.all_specializations[funcdesc] = memotables

    # merge the MemoTables for the individual argument combinations
    firstvalues = possiblevalues.next()
    _, _, memotable = memotables.find(firstvalues)
    for values in possiblevalues:
        _, _, memotable = memotables.union(firstvalues, values)

    if memotable.graph is not None:
        return memotable.graph  # if already computed
    else:
        # otherwise, for now, return the union of each possible result
        return unionof(
            *[bookkeeper.immutablevalue(v) for v in memotable.table.values()])