PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/rtyper/llannotation.py

https://bitbucket.org/pypy/pypy/
Python | 201 lines | 159 code | 35 blank | 7 comment | 14 complexity | ee8d2c65648a467488112bd2c6fe09cb MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """
  2. Code for annotating low-level thingies.
  3. """
  4. from rpython.tool.pairtype import pair, pairtype
  5. from rpython.annotator.model import (
  6. SomeObject, SomeSingleFloat, SomeFloat, SomeLongFloat, SomeChar,
  7. SomeUnicodeCodePoint, SomeInteger, SomeImpossibleValue,
  8. s_None, s_Bool, UnionError, AnnotatorError)
  9. from rpython.rtyper.lltypesystem import lltype, llmemory
  10. from rpython.rtyper.lltypesystem.lltype import SomePtr
  11. from rpython.rtyper.lltypesystem.llmemory import (
  12. SomeAddress, SomeTypedAddressAccess)
  13. class __extend__(pairtype(SomeAddress, SomeAddress)):
  14. def union((s_addr1, s_addr2)):
  15. return SomeAddress()
  16. def sub((s_addr1, s_addr2)):
  17. from rpython.annotator.bookkeeper import getbookkeeper
  18. if s_addr1.is_null_address() and s_addr2.is_null_address():
  19. return getbookkeeper().immutablevalue(0)
  20. return SomeInteger()
  21. def is_((s_addr1, s_addr2)):
  22. assert False, "comparisons with is not supported by addresses"
  23. class __extend__(pairtype(SomeTypedAddressAccess, SomeTypedAddressAccess)):
  24. def union((s_taa1, s_taa2)):
  25. assert s_taa1.type == s_taa2.type
  26. return s_taa1
  27. class __extend__(pairtype(SomeTypedAddressAccess, SomeInteger)):
  28. def getitem((s_taa, s_int)):
  29. return lltype_to_annotation(s_taa.type)
  30. getitem.can_only_throw = []
  31. def setitem((s_taa, s_int), s_value):
  32. assert annotation_to_lltype(s_value) is s_taa.type
  33. setitem.can_only_throw = []
  34. class __extend__(pairtype(SomeAddress, SomeInteger)):
  35. def add((s_addr, s_int)):
  36. return SomeAddress()
  37. def sub((s_addr, s_int)):
  38. return SomeAddress()
  39. class __extend__(pairtype(SomeAddress, SomeImpossibleValue)):
  40. # need to override this specifically to hide the 'raise UnionError'
  41. # of pairtype(SomeAddress, SomeObject).
  42. def union((s_addr, s_imp)):
  43. return s_addr
  44. class __extend__(pairtype(SomeImpossibleValue, SomeAddress)):
  45. # need to override this specifically to hide the 'raise UnionError'
  46. # of pairtype(SomeObject, SomeAddress).
  47. def union((s_imp, s_addr)):
  48. return s_addr
  49. class __extend__(pairtype(SomeAddress, SomeObject)):
  50. def union((s_addr, s_obj)):
  51. raise UnionError(s_addr, s_obj)
  52. class __extend__(pairtype(SomeObject, SomeAddress)):
  53. def union((s_obj, s_addr)):
  54. raise UnionError(s_obj, s_addr)
  55. class SomeInteriorPtr(SomePtr):
  56. def __init__(self, ll_ptrtype):
  57. assert isinstance(ll_ptrtype, lltype.InteriorPtr)
  58. self.ll_ptrtype = ll_ptrtype
  59. class SomeLLADTMeth(SomeObject):
  60. immutable = True
  61. def __init__(self, ll_ptrtype, func):
  62. self.ll_ptrtype = ll_ptrtype
  63. self.func = func
  64. def can_be_none(self):
  65. return False
  66. def call(self, args):
  67. from rpython.annotator.bookkeeper import getbookkeeper
  68. bookkeeper = getbookkeeper()
  69. s_func = bookkeeper.immutablevalue(self.func)
  70. return s_func.call(args.prepend(lltype_to_annotation(self.ll_ptrtype)))
  71. class __extend__(pairtype(SomePtr, SomePtr)):
  72. def union((p1, p2)):
  73. if p1.ll_ptrtype != p2.ll_ptrtype:
  74. raise UnionError(p1, p2)
  75. return SomePtr(p1.ll_ptrtype)
  76. class __extend__(pairtype(SomePtr, SomeInteger)):
  77. def getitem((p, int1)):
  78. example = p.ll_ptrtype._example()
  79. try:
  80. v = example[0]
  81. except IndexError:
  82. return None # impossible value, e.g. FixedSizeArray(0)
  83. return ll_to_annotation(v)
  84. getitem.can_only_throw = []
  85. def setitem((p, int1), s_value): # just doing checking
  86. example = p.ll_ptrtype._example()
  87. if example[0] is not None: # ignore Void s_value
  88. v_lltype = annotation_to_lltype(s_value)
  89. example[0] = v_lltype._defl()
  90. setitem.can_only_throw = []
  91. class __extend__(pairtype(SomePtr, SomeObject)):
  92. def union((p, obj)):
  93. raise UnionError(p, obj)
  94. def getitem((p, obj)):
  95. raise AnnotatorError("ptr %r getitem index not an int: %r" %
  96. (p.ll_ptrtype, obj))
  97. def setitem((p, obj), s_value):
  98. raise AnnotatorError("ptr %r setitem index not an int: %r" %
  99. (p.ll_ptrtype, obj))
  100. class __extend__(pairtype(SomeObject, SomePtr)):
  101. def union((obj, p2)):
  102. return pair(p2, obj).union()
  103. annotation_to_ll_map = [
  104. (SomeSingleFloat(), lltype.SingleFloat),
  105. (s_None, lltype.Void), # also matches SomeImpossibleValue()
  106. (s_Bool, lltype.Bool),
  107. (SomeFloat(), lltype.Float),
  108. (SomeLongFloat(), lltype.LongFloat),
  109. (SomeChar(), lltype.Char),
  110. (SomeUnicodeCodePoint(), lltype.UniChar),
  111. (SomeAddress(), llmemory.Address),
  112. ]
  113. def annotation_to_lltype(s_val, info=None):
  114. if isinstance(s_val, SomeInteriorPtr):
  115. p = s_val.ll_ptrtype
  116. if 0 in p.offsets:
  117. assert list(p.offsets).count(0) == 1
  118. return lltype.Ptr(lltype.Ptr(p.PARENTTYPE)._interior_ptr_type_with_index(p.TO))
  119. else:
  120. return lltype.Ptr(p.PARENTTYPE)
  121. if isinstance(s_val, SomePtr):
  122. return s_val.ll_ptrtype
  123. if type(s_val) is SomeInteger:
  124. return lltype.build_number(None, s_val.knowntype)
  125. for witness, T in annotation_to_ll_map:
  126. if witness.contains(s_val):
  127. return T
  128. if info is None:
  129. info = ''
  130. else:
  131. info = '%s: ' % info
  132. raise ValueError("%sshould return a low-level type,\ngot instead %r" % (
  133. info, s_val))
  134. ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map])
  135. def lltype_to_annotation(T):
  136. try:
  137. s = ll_to_annotation_map.get(T)
  138. except TypeError:
  139. s = None # unhashable T, e.g. a Ptr(GcForwardReference())
  140. if s is None:
  141. if isinstance(T, lltype.Typedef):
  142. return lltype_to_annotation(T.OF)
  143. if isinstance(T, lltype.Number):
  144. return SomeInteger(knowntype=T._type)
  145. elif isinstance(T, lltype.InteriorPtr):
  146. return SomeInteriorPtr(T)
  147. else:
  148. return SomePtr(T)
  149. else:
  150. return s
  151. def ll_to_annotation(v):
  152. if v is None:
  153. # i think we can only get here in the case of void-returning
  154. # functions
  155. return s_None
  156. if isinstance(v, lltype._interior_ptr):
  157. ob = v._parent
  158. if ob is None:
  159. raise RuntimeError
  160. T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets)
  161. return SomeInteriorPtr(T)
  162. return lltype_to_annotation(lltype.typeOf(v))