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

/pypy/rlib/debug.py

https://github.com/lalitjsraks/pypy
Python | 286 lines | 269 code | 14 blank | 3 comment | 11 complexity | f014adbd645591081177749eb7267b55 MD5 | raw file
  1. import sys, time
  2. from pypy.rpython.extregistry import ExtRegistryEntry
  3. def ll_assert(x, msg):
  4. """After translation to C, this becomes an RPyAssert."""
  5. assert x, msg
  6. class Entry(ExtRegistryEntry):
  7. _about_ = ll_assert
  8. def compute_result_annotation(self, s_x, s_msg):
  9. assert s_msg.is_constant(), ("ll_assert(x, msg): "
  10. "the msg must be constant")
  11. return None
  12. def specialize_call(self, hop):
  13. from pypy.rpython.lltypesystem import lltype
  14. vlist = hop.inputargs(lltype.Bool, lltype.Void)
  15. hop.exception_cannot_occur()
  16. hop.genop('debug_assert', vlist)
  17. def fatalerror(msg, traceback=False):
  18. from pypy.rpython.lltypesystem import lltype
  19. from pypy.rpython.lltypesystem.lloperation import llop
  20. if traceback:
  21. llop.debug_print_traceback(lltype.Void)
  22. llop.debug_fatalerror(lltype.Void, msg)
  23. fatalerror._dont_inline_ = True
  24. class DebugLog(list):
  25. def debug_print(self, *args):
  26. self.append(('debug_print',) + args)
  27. def debug_start(self, category, time=None):
  28. self.append(('debug_start', category, time))
  29. def debug_stop(self, category, time=None):
  30. for i in xrange(len(self)-1, -1, -1):
  31. if self[i][0] == 'debug_start':
  32. assert self[i][1] == category, (
  33. "nesting error: starts with %r but stops with %r" %
  34. (self[i][1], category))
  35. starttime = self[i][2]
  36. if starttime is not None or time is not None:
  37. self[i:] = [(category, starttime, time, self[i+1:])]
  38. else:
  39. self[i:] = [(category, self[i+1:])]
  40. return
  41. assert False, ("nesting error: no start corresponding to stop %r" %
  42. (category,))
  43. def __repr__(self):
  44. import pprint
  45. return pprint.pformat(list(self))
  46. _log = None # patched from tests to be an object of class DebugLog
  47. # or compatible
  48. _stderr = sys.stderr # alternatively, this is patched from tests
  49. # (redirects debug_print(), but not debug_start/stop)
  50. def debug_print(*args):
  51. for arg in args:
  52. print >> _stderr, arg,
  53. print >> _stderr
  54. if _log is not None:
  55. _log.debug_print(*args)
  56. class Entry(ExtRegistryEntry):
  57. _about_ = debug_print
  58. def compute_result_annotation(self, *args_s):
  59. return None
  60. def specialize_call(self, hop):
  61. vlist = hop.inputargs(*hop.args_r)
  62. hop.exception_cannot_occur()
  63. t = hop.rtyper.annotator.translator
  64. if t.config.translation.log:
  65. hop.genop('debug_print', vlist)
  66. if sys.stderr.isatty():
  67. _start_colors_1 = "\033[1m\033[31m"
  68. _start_colors_2 = "\033[31m"
  69. _stop_colors = "\033[0m"
  70. else:
  71. _start_colors_1 = ""
  72. _start_colors_2 = ""
  73. _stop_colors = ""
  74. def debug_start(category):
  75. print >> sys.stderr, '%s[%s] {%s%s' % (_start_colors_1, time.clock(),
  76. category, _stop_colors)
  77. if _log is not None:
  78. _log.debug_start(category)
  79. def debug_stop(category):
  80. print >> sys.stderr, '%s[%s] %s}%s' % (_start_colors_2, time.clock(),
  81. category, _stop_colors)
  82. if _log is not None:
  83. _log.debug_stop(category)
  84. class Entry(ExtRegistryEntry):
  85. _about_ = debug_start, debug_stop
  86. def compute_result_annotation(self, s_category):
  87. return None
  88. def specialize_call(self, hop):
  89. fn = self.instance
  90. string_repr = hop.rtyper.type_system.rstr.string_repr
  91. vlist = hop.inputargs(string_repr)
  92. hop.exception_cannot_occur()
  93. t = hop.rtyper.annotator.translator
  94. if t.config.translation.log:
  95. hop.genop(fn.__name__, vlist)
  96. def have_debug_prints():
  97. # returns True if the next calls to debug_print show up,
  98. # and False if they would not have any effect.
  99. return True
  100. class Entry(ExtRegistryEntry):
  101. _about_ = have_debug_prints
  102. def compute_result_annotation(self):
  103. from pypy.annotation import model as annmodel
  104. t = self.bookkeeper.annotator.translator
  105. if t.config.translation.log:
  106. return annmodel.s_Bool
  107. else:
  108. return self.bookkeeper.immutablevalue(False)
  109. def specialize_call(self, hop):
  110. from pypy.rpython.lltypesystem import lltype
  111. t = hop.rtyper.annotator.translator
  112. hop.exception_cannot_occur()
  113. if t.config.translation.log:
  114. return hop.genop('have_debug_prints', [], resulttype=lltype.Bool)
  115. else:
  116. return hop.inputconst(lltype.Bool, False)
  117. def llinterpcall(RESTYPE, pythonfunction, *args):
  118. """When running on the llinterp, this causes the llinterp to call to
  119. the provided Python function with the run-time value of the given args.
  120. The Python function should return a low-level object of type RESTYPE.
  121. This should never be called after translation: use this only if
  122. running_on_llinterp is true.
  123. """
  124. raise NotImplementedError
  125. class Entry(ExtRegistryEntry):
  126. _about_ = llinterpcall
  127. def compute_result_annotation(self, s_RESTYPE, s_pythonfunction, *args_s):
  128. from pypy.annotation import model as annmodel
  129. from pypy.rpython.lltypesystem import lltype
  130. assert s_RESTYPE.is_constant()
  131. assert s_pythonfunction.is_constant()
  132. s_result = s_RESTYPE.const
  133. if isinstance(s_result, lltype.LowLevelType):
  134. s_result = annmodel.lltype_to_annotation(s_result)
  135. assert isinstance(s_result, annmodel.SomeObject)
  136. return s_result
  137. def specialize_call(self, hop):
  138. from pypy.annotation import model as annmodel
  139. from pypy.rpython.lltypesystem import lltype
  140. RESTYPE = hop.args_s[0].const
  141. if not isinstance(RESTYPE, lltype.LowLevelType):
  142. assert isinstance(RESTYPE, annmodel.SomeObject)
  143. r_result = hop.rtyper.getrepr(RESTYPE)
  144. RESTYPE = r_result.lowleveltype
  145. pythonfunction = hop.args_s[1].const
  146. c_pythonfunction = hop.inputconst(lltype.Void, pythonfunction)
  147. args_v = [hop.inputarg(hop.args_r[i], arg=i)
  148. for i in range(2, hop.nb_args)]
  149. return hop.genop('debug_llinterpcall', [c_pythonfunction] + args_v,
  150. resulttype=RESTYPE)
  151. def check_annotation(arg, checker):
  152. """ Function checking if annotation is as expected when translating,
  153. does nothing when just run. Checker is supposed to be a constant
  154. callable which checks if annotation is as expected,
  155. arguments passed are (current annotation, bookkeeper)
  156. """
  157. return arg
  158. class Entry(ExtRegistryEntry):
  159. _about_ = check_annotation
  160. def compute_result_annotation(self, s_arg, s_checker):
  161. if not s_checker.is_constant():
  162. raise ValueError("Second argument of check_annotation must be constant")
  163. checker = s_checker.const
  164. checker(s_arg, self.bookkeeper)
  165. return s_arg
  166. def specialize_call(self, hop):
  167. hop.exception_cannot_occur()
  168. return hop.inputarg(hop.args_r[0], arg=0)
  169. def make_sure_not_resized(arg):
  170. """ Function checking whether annotation of SomeList is never resized,
  171. useful for debugging. Does nothing when run directly
  172. """
  173. return arg
  174. class Entry(ExtRegistryEntry):
  175. _about_ = make_sure_not_resized
  176. def compute_result_annotation(self, s_arg):
  177. from pypy.annotation.model import SomeList
  178. assert isinstance(s_arg, SomeList)
  179. # the logic behind it is that we try not to propagate
  180. # make_sure_not_resized, when list comprehension is not on
  181. if self.bookkeeper.annotator.translator.config.translation.list_comprehension_operations:
  182. s_arg.listdef.never_resize()
  183. else:
  184. from pypy.annotation.annrpython import log
  185. log.WARNING('make_sure_not_resized called, but has no effect since list_comprehension is off')
  186. return s_arg
  187. def specialize_call(self, hop):
  188. hop.exception_cannot_occur()
  189. return hop.inputarg(hop.args_r[0], arg=0)
  190. def make_sure_not_modified(arg):
  191. """ Function checking whether annotation of SomeList is never resized
  192. and never modified, useful for debugging. Does nothing when run directly
  193. """
  194. return arg
  195. class Entry(ExtRegistryEntry):
  196. _about_ = make_sure_not_modified
  197. def compute_result_annotation(self, s_arg):
  198. from pypy.annotation.model import SomeList
  199. assert isinstance(s_arg, SomeList)
  200. # the logic behind it is that we try not to propagate
  201. # make_sure_not_resized, when list comprehension is not on
  202. if self.bookkeeper.annotator.translator.config.translation.list_comprehension_operations:
  203. s_arg.listdef.never_mutate()
  204. else:
  205. from pypy.annotation.annrpython import log
  206. log.WARNING('make_sure_not_modified called, but has no effect since list_comprehension is off')
  207. return s_arg
  208. def specialize_call(self, hop):
  209. hop.exception_cannot_occur()
  210. return hop.inputarg(hop.args_r[0], arg=0)
  211. class IntegerCanBeNegative(Exception):
  212. pass
  213. class UnexpectedRUInt(Exception):
  214. pass
  215. def check_nonneg(x):
  216. """Give a translation-time error if 'x' is not known to be non-negative.
  217. To help debugging, this also gives a translation-time error if 'x' is
  218. actually typed as an r_uint (in which case the call to check_nonneg()
  219. is a bit strange and probably unexpected).
  220. """
  221. assert type(x)(-1) < 0 # otherwise, 'x' is a r_uint or similar
  222. assert x >= 0
  223. return x
  224. class Entry(ExtRegistryEntry):
  225. _about_ = check_nonneg
  226. def compute_result_annotation(self, s_arg):
  227. from pypy.annotation.model import SomeInteger
  228. if isinstance(s_arg, SomeInteger) and s_arg.unsigned:
  229. raise UnexpectedRUInt("check_nonneg() arg is a %s" % (
  230. s_arg.knowntype,))
  231. s_nonneg = SomeInteger(nonneg=True)
  232. if not s_nonneg.contains(s_arg):
  233. raise IntegerCanBeNegative
  234. return s_arg
  235. def specialize_call(self, hop):
  236. hop.exception_cannot_occur()
  237. return hop.inputarg(hop.args_r[0], arg=0)