Ejemplo n.º 1
0
def _compute_annotation(t, bookkeeper=None):
    from rpython.rtyper.lltypesystem import lltype
    from rpython.rtyper.llannotation import lltype_to_annotation
    if isinstance(t, SomeObject):
        return t
    elif isinstance(t, lltype.LowLevelType):
        return lltype_to_annotation(t)
    elif isinstance(t, list):
        assert len(t) == 1, "We do not support type joining in list"
        listdef = ListDef(bookkeeper,
                          annotation(t[0]),
                          mutated=True,
                          resized=True)
        return SomeList(listdef)
    elif isinstance(t, tuple):
        return SomeTuple(tuple([annotation(i) for i in t]))
    elif isinstance(t, dict):
        assert len(t) == 1, "We do not support type joining in dict"
        result = SomeDict(
            DictDef(bookkeeper, annotation(t.keys()[0]),
                    annotation(t.values()[0])))
        return result
    elif type(t) is types.NoneType:
        return s_None
    elif extregistry.is_registered(t):
        entry = extregistry.lookup(t)
        entry.bookkeeper = bookkeeper
        return entry.compute_result_annotation()
    else:
        return annotationoftype(t, bookkeeper)
Ejemplo n.º 2
0
 def getdictdef(self, is_r_dict=False, force_non_null=False):
     """Get the DictDef associated with the current position."""
     try:
         dictdef = self.dictdefs[self.position_key]
     except KeyError:
         dictdef = DictDef(self,
                           is_r_dict=is_r_dict,
                           force_non_null=force_non_null)
         self.dictdefs[self.position_key] = dictdef
     return dictdef
Ejemplo n.º 3
0
 def immutablevalue(self, x):
     """The most precise SomeValue instance that contains the
     immutable value x."""
     # convert unbound methods to the underlying function
     if hasattr(x, 'im_self') and x.im_self is None:
         x = x.im_func
         assert not hasattr(x, 'im_self')
     tp = type(x)
     if issubclass(tp, Symbolic):  # symbolic constants support
         result = x.annotation()
         result.const_box = Constant(x)
         return result
     if tp is bool:
         result = SomeBool()
     elif tp is int:
         result = SomeInteger(nonneg=x >= 0)
     elif tp is long:
         if -sys.maxint - 1 <= x <= sys.maxint:
             x = int(x)
             result = SomeInteger(nonneg=x >= 0)
         else:
             raise Exception("seeing a prebuilt long (value %s)" % hex(x))
     elif issubclass(tp, str):  # py.lib uses annotated str subclasses
         no_nul = not '\x00' in x
         if len(x) == 1:
             result = SomeChar(no_nul=no_nul)
         else:
             result = SomeString(no_nul=no_nul)
     elif tp is unicode:
         if len(x) == 1:
             result = SomeUnicodeCodePoint()
         else:
             result = SomeUnicodeString()
     elif tp is bytearray:
         result = SomeByteArray()
     elif tp is tuple:
         result = SomeTuple(items=[self.immutablevalue(e) for e in x])
     elif tp is float:
         result = SomeFloat()
     elif tp is list:
         key = Constant(x)
         try:
             return self.immutable_cache[key]
         except KeyError:
             result = SomeList(ListDef(self, s_ImpossibleValue))
             self.immutable_cache[key] = result
             for e in x:
                 result.listdef.generalize(self.immutablevalue(e))
             result.const_box = key
             return result
     elif (tp is dict or tp is r_dict or tp is SomeOrderedDict.knowntype
           or tp is r_ordereddict):
         key = Constant(x)
         try:
             return self.immutable_cache[key]
         except KeyError:
             if tp is SomeOrderedDict.knowntype or tp is r_ordereddict:
                 cls = SomeOrderedDict
             else:
                 cls = SomeDict
             is_r_dict = issubclass(tp, r_dict)
             result = cls(
                 DictDef(self,
                         s_ImpossibleValue,
                         s_ImpossibleValue,
                         is_r_dict=is_r_dict))
             self.immutable_cache[key] = result
             if is_r_dict:
                 s_eqfn = self.immutablevalue(x.key_eq)
                 s_hashfn = self.immutablevalue(x.key_hash)
                 result.dictdef.dictkey.update_rdict_annotations(
                     s_eqfn, s_hashfn)
             seen_elements = 0
             while seen_elements != len(x):
                 items = x.items()
                 for ek, ev in items:
                     result.dictdef.generalize_key(self.immutablevalue(ek))
                     result.dictdef.generalize_value(
                         self.immutablevalue(ev))
                     result.dictdef.seen_prebuilt_key(ek)
                 seen_elements = len(items)
                 # if the dictionary grew during the iteration,
                 # start over again
             result.const_box = key
             return result
     elif tp is weakref.ReferenceType:
         x1 = x()
         if x1 is None:
             result = SomeWeakRef(None)  # dead weakref
         else:
             s1 = self.immutablevalue(x1)
             assert isinstance(s1, SomeInstance)
             result = SomeWeakRef(s1.classdef)
     elif tp is property:
         return SomeProperty(x)
     elif ishashable(x) and x in BUILTIN_ANALYZERS:
         _module = getattr(x, "__module__", "unknown")
         result = SomeBuiltin(BUILTIN_ANALYZERS[x],
                              methodname="%s.%s" % (_module, x.__name__))
     elif extregistry.is_registered(x):
         entry = extregistry.lookup(x)
         result = entry.compute_annotation_bk(self)
     elif tp is type:
         result = SomeConstantType(x, self)
     elif callable(x):
         if hasattr(x, 'im_self') and hasattr(x, 'im_func'):
             # on top of PyPy, for cases like 'l.append' where 'l' is a
             # global constant list, the find_method() returns non-None
             s_self = self.immutablevalue(x.im_self)
             result = s_self.find_method(x.im_func.__name__)
         elif hasattr(x, '__self__') and x.__self__ is not None:
             # for cases like 'l.append' where 'l' is a global constant list
             s_self = self.immutablevalue(x.__self__)
             result = s_self.find_method(x.__name__)
             assert result is not None
         else:
             result = None
         if result is None:
             result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '_freeze_'):
         assert x._freeze_() is True
         # user-defined classes can define a method _freeze_(), which
         # is called when a prebuilt instance is found.  If the method
         # returns True, the instance is considered immutable and becomes
         # a SomePBC().  Otherwise it's just SomeInstance().
         result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '__class__') \
              and x.__class__.__module__ != '__builtin__':
         if hasattr(x, '_cleanup_'):
             x._cleanup_()
         self.see_mutable(x)
         result = SomeInstance(self.getuniqueclassdef(x.__class__))
     elif x is None:
         return s_None
     else:
         raise Exception("Don't know how to represent %r" % (x, ))
     result.const = x
     return result
Ejemplo n.º 4
0
def dict(keytype, valuetype):
    dictdef = DictDef(None, keytype, valuetype)
    return model.SomeDict(dictdef)
Ejemplo n.º 5
0
 def immutablevalue(self, x, need_const=True):
     """The most precise SomeValue instance that contains the
     immutable value x."""
     # convert unbound methods to the underlying function
     if hasattr(x, 'im_self') and x.im_self is None:
         x = x.im_func
         assert not hasattr(x, 'im_self')
     tp = type(x)
     if issubclass(tp, Symbolic): # symbolic constants support
         result = x.annotation()
         result.const_box = Constant(x)
         return result
     if tp is bool:
         result = SomeBool()
     elif tp is int:
         result = SomeInteger(nonneg = x>=0)
     elif tp is long:
         if -sys.maxint-1 <= x <= sys.maxint:
             x = int(x)
             result = SomeInteger(nonneg = x>=0)
         else:
             raise Exception("seeing a prebuilt long (value %s)" % hex(x))
     elif issubclass(tp, str): # py.lib uses annotated str subclasses
         no_nul = not '\x00' in x
         if len(x) == 1:
             result = SomeChar(no_nul=no_nul)
         else:
             result = SomeString(no_nul=no_nul)
     elif tp is unicode:
         if len(x) == 1:
             result = SomeUnicodeCodePoint()
         else:
             result = SomeUnicodeString()
     elif tp is bytearray:
         result = SomeByteArray()
     elif tp is tuple:
         result = SomeTuple(items = [self.immutablevalue(e, need_const) for e in x])
     elif tp is float:
         result = SomeFloat()
     elif tp is list:
         if need_const:
             key = Constant(x)
             try:
                 return self.immutable_cache[key]
             except KeyError:
                 result = SomeList(ListDef(self, s_ImpossibleValue))
                 self.immutable_cache[key] = result
                 for e in x:
                     result.listdef.generalize(self.immutablevalue(e))
                 result.const_box = key
                 return result
         else:
             listdef = ListDef(self, s_ImpossibleValue)
             for e in x:
                 listdef.generalize(self.immutablevalue(e, False))
             result = SomeList(listdef)
     elif tp is dict or tp is r_dict:
         if need_const:
             key = Constant(x)
             try:
                 return self.immutable_cache[key]
             except KeyError:
                 result = SomeDict(DictDef(self,
                                           s_ImpossibleValue,
                                           s_ImpossibleValue,
                                           is_r_dict = tp is r_dict))
                 self.immutable_cache[key] = result
                 if tp is r_dict:
                     s_eqfn = self.immutablevalue(x.key_eq)
                     s_hashfn = self.immutablevalue(x.key_hash)
                     result.dictdef.dictkey.update_rdict_annotations(s_eqfn,
                                                                     s_hashfn)
                 seen_elements = 0
                 while seen_elements != len(x):
                     items = x.items()
                     for ek, ev in items:
                         result.dictdef.generalize_key(self.immutablevalue(ek))
                         result.dictdef.generalize_value(self.immutablevalue(ev))
                         result.dictdef.seen_prebuilt_key(ek)
                     seen_elements = len(items)
                     # if the dictionary grew during the iteration,
                     # start over again
                 result.const_box = key
                 return result
         else:
             dictdef = DictDef(self,
             s_ImpossibleValue,
             s_ImpossibleValue,
             is_r_dict = tp is r_dict)
             if tp is r_dict:
                 s_eqfn = self.immutablevalue(x.key_eq)
                 s_hashfn = self.immutablevalue(x.key_hash)
                 dictdef.dictkey.update_rdict_annotations(s_eqfn,
                     s_hashfn)
             for ek, ev in x.iteritems():
                 dictdef.generalize_key(self.immutablevalue(ek, False))
                 dictdef.generalize_value(self.immutablevalue(ev, False))
                 dictdef.seen_prebuilt_key(ek)
             result = SomeDict(dictdef)
     elif tp is weakref.ReferenceType:
         x1 = x()
         if x1 is None:
             result = SomeWeakRef(None)    # dead weakref
         else:
             s1 = self.immutablevalue(x1)
             assert isinstance(s1, SomeInstance)
             result = SomeWeakRef(s1.classdef)
     elif ishashable(x) and x in BUILTIN_ANALYZERS:
         _module = getattr(x,"__module__","unknown")
         result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__))
     elif extregistry.is_registered(x):
         entry = extregistry.lookup(x)
         result = entry.compute_annotation_bk(self)
     elif isinstance(x, lltype._ptr):
         result = SomePtr(lltype.typeOf(x))
     elif isinstance(x, llmemory.fakeaddress):
         result = SomeAddress()
     elif tp is type:
         if (x is type(None) or      # add cases here if needed
             x.__module__ == 'rpython.rtyper.lltypesystem.lltype'):
             result = SomeType()
         else:
             result = SomePBC([self.getdesc(x)])
     elif callable(x):
         if hasattr(x, 'im_self') and hasattr(x, 'im_func'):
             # on top of PyPy, for cases like 'l.append' where 'l' is a
             # global constant list, the find_method() returns non-None
             s_self = self.immutablevalue(x.im_self, need_const)
             result = s_self.find_method(x.im_func.__name__)
         elif hasattr(x, '__self__') and x.__self__ is not None:
             # for cases like 'l.append' where 'l' is a global constant list
             s_self = self.immutablevalue(x.__self__, need_const)
             result = s_self.find_method(x.__name__)
             assert result is not None
         else:
             result = None
         if result is None:
             result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '_freeze_'):
         assert x._freeze_() is True
         # user-defined classes can define a method _freeze_(), which
         # is called when a prebuilt instance is found.  If the method
         # returns True, the instance is considered immutable and becomes
         # a SomePBC().  Otherwise it's just SomeInstance().
         result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '__class__') \
              and x.__class__.__module__ != '__builtin__':
         if hasattr(x, '_cleanup_'):
             x._cleanup_()
         self.see_mutable(x)
         result = SomeInstance(self.getuniqueclassdef(x.__class__))
     elif x is None:
         return s_None
     else:
         raise Exception("Don't know how to represent %r" % (x,))
     if need_const:
         result.const = x
     return result