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

/pypy/rpython/lltypesystem/lloperation.py

https://bitbucket.org/pypy/pypy/
Python | 601 lines | 453 code | 84 blank | 64 comment | 33 complexity | 32ffa4672d78e47a9f426a475c46a728 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """
  2. The table of all LL operations.
  3. """
  4. from pypy.rpython.extregistry import ExtRegistryEntry
  5. from pypy.tool.descriptor import roproperty
  6. class LLOp(object):
  7. def __init__(self, sideeffects=True, canfold=False, canraise=(),
  8. pyobj=False, canmallocgc=False, canrun=False, oo=False,
  9. tryfold=False):
  10. # self.opname = ... (set afterwards)
  11. if canfold:
  12. sideeffects = False
  13. # The operation has no side-effects: it can be removed
  14. # if its result is not used
  15. self.sideeffects = sideeffects
  16. # Can be safely constant-folded: no side-effects
  17. # and always gives the same result for given args
  18. self.canfold = canfold
  19. # Can *try* to fold the operation, but it may raise on you
  20. self.tryfold = tryfold or canfold
  21. # Exceptions that can be raised
  22. self.canraise = canraise
  23. assert isinstance(canraise, tuple)
  24. assert not canraise or not canfold
  25. # The operation manipulates PyObjects
  26. self.pyobj = pyobj
  27. # The operation can go a GC malloc
  28. self.canmallocgc = canmallocgc
  29. if canmallocgc:
  30. if (MemoryError not in self.canraise and
  31. Exception not in self.canraise):
  32. self.canraise += (MemoryError,)
  33. # The operation can be run directly with __call__
  34. self.canrun = canrun or canfold
  35. # The operation belongs to the ootypesystem
  36. self.oo = oo
  37. # __________ make the LLOp instances callable from LL helpers __________
  38. __name__ = property(lambda self: 'llop_'+self.opname)
  39. def __call__(self, RESULTTYPE, *args):
  40. # llop is meant to be rtyped and not called directly, unless it is
  41. # a canfold=True operation
  42. fold = self.fold
  43. if getattr(fold, 'need_result_type', False):
  44. val = fold(RESULTTYPE, *args)
  45. else:
  46. val = fold(*args)
  47. if RESULTTYPE is not lltype.Void:
  48. val = lltype.enforce(RESULTTYPE, val)
  49. return val
  50. def get_fold_impl(self):
  51. global lltype # <- lazy import hack, worth an XXX
  52. from pypy.rpython.lltypesystem import lltype
  53. if self.canrun:
  54. if self.oo:
  55. from pypy.rpython.ootypesystem.ooopimpl import get_op_impl
  56. else:
  57. from pypy.rpython.lltypesystem.opimpl import get_op_impl
  58. op_impl = get_op_impl(self.opname)
  59. else:
  60. error = TypeError("cannot constant-fold operation %r" % (
  61. self.opname,))
  62. def op_impl(*args):
  63. raise error
  64. # cache the implementation function into 'self'
  65. self.fold = op_impl
  66. return op_impl
  67. fold = roproperty(get_fold_impl)
  68. def is_pure(self, args_v):
  69. if self.canfold: # canfold => pure operation
  70. return True
  71. if self is llop.debug_assert: # debug_assert is pure enough
  72. return True
  73. # reading from immutable (lltype)
  74. if self is llop.getfield or self is llop.getarrayitem:
  75. field = getattr(args_v[1], 'value', None)
  76. return args_v[0].concretetype.TO._immutable_field(field)
  77. # reading from immutable (ootype) (xxx what about arrays?)
  78. if self is llop.oogetfield:
  79. field = getattr(args_v[1], 'value', None)
  80. return args_v[0].concretetype._immutable_field(field)
  81. # default
  82. return False
  83. def __repr__(self):
  84. return '<LLOp %s>' % (getattr(self, 'opname', '?'),)
  85. class _LLOP(object):
  86. def _freeze_(self):
  87. return True
  88. llop = _LLOP()
  89. class VoidMarker(object):
  90. # marker wrapper for void arguments to llops
  91. def __init__(self, value):
  92. self.value = value
  93. def _freeze_(self):
  94. return True
  95. def void(value):
  96. return VoidMarker(value)
  97. class Entry(ExtRegistryEntry):
  98. _about_ = void
  99. def compute_result_annotation(self, s_value):
  100. assert s_value.is_constant()
  101. from pypy.annotation.bookkeeper import getbookkeeper
  102. bk = getbookkeeper()
  103. return bk.immutablevalue(VoidMarker(s_value.const))
  104. def specialize_call(self, hop):
  105. from pypy.rpython.lltypesystem import lltype
  106. return hop.inputconst(lltype.Void, None)
  107. def enum_ops_without_sideeffects(raising_is_ok=False):
  108. """Enumerate operations that have no side-effects
  109. (see also enum_foldable_ops)."""
  110. for opname, opdesc in LL_OPERATIONS.iteritems():
  111. if not opdesc.sideeffects:
  112. if not opdesc.canraise or raising_is_ok:
  113. yield opname
  114. def enum_foldable_ops(_ignored=None):
  115. """Enumerate operations that can be constant-folded."""
  116. for opname, opdesc in LL_OPERATIONS.iteritems():
  117. if opdesc.canfold:
  118. assert not opdesc.canraise
  119. yield opname
  120. class Entry(ExtRegistryEntry):
  121. "Annotation and rtyping of LLOp instances, which are callable."
  122. _type_ = LLOp
  123. def compute_result_annotation(self, RESULTTYPE, *args):
  124. from pypy.annotation.model import lltype_to_annotation
  125. assert RESULTTYPE.is_constant()
  126. return lltype_to_annotation(RESULTTYPE.const)
  127. def specialize_call(self, hop):
  128. from pypy.rpython.lltypesystem import lltype
  129. op = self.instance # the LLOp object that was called
  130. args_v = []
  131. for i, s_arg in enumerate(hop.args_s[1:]):
  132. if s_arg.is_constant() and isinstance(s_arg.const, VoidMarker):
  133. v_arg = hop.inputconst(lltype.Void, s_arg.const.value)
  134. else:
  135. v_arg = hop.inputarg(hop.args_r[i+1], i+1)
  136. args_v.append(v_arg)
  137. if op.canraise:
  138. hop.exception_is_here()
  139. else:
  140. hop.exception_cannot_occur()
  141. return hop.genop(op.opname, args_v, resulttype=hop.r_result.lowleveltype)
  142. # ____________________________________________________________
  143. #
  144. # This list corresponds to the operations implemented by the LLInterpreter.
  145. # Note that many exception-raising operations can be replaced by calls
  146. # to helper functions in pypy.rpython.raisingops.raisingops.
  147. # ***** Run test_lloperation after changes. *****
  148. LL_OPERATIONS = {
  149. 'direct_call': LLOp(canraise=(Exception,)),
  150. 'indirect_call': LLOp(canraise=(Exception,)),
  151. # __________ numeric operations __________
  152. 'bool_not': LLOp(canfold=True),
  153. 'char_lt': LLOp(canfold=True),
  154. 'char_le': LLOp(canfold=True),
  155. 'char_eq': LLOp(canfold=True),
  156. 'char_ne': LLOp(canfold=True),
  157. 'char_gt': LLOp(canfold=True),
  158. 'char_ge': LLOp(canfold=True),
  159. 'unichar_eq': LLOp(canfold=True),
  160. 'unichar_ne': LLOp(canfold=True),
  161. 'int_is_true': LLOp(canfold=True),
  162. 'int_neg': LLOp(canfold=True),
  163. 'int_neg_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  164. 'int_abs': LLOp(canfold=True),
  165. 'int_abs_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  166. 'int_invert': LLOp(canfold=True),
  167. 'int_add': LLOp(canfold=True),
  168. 'int_sub': LLOp(canfold=True),
  169. 'int_mul': LLOp(canfold=True),
  170. 'int_floordiv': LLOp(canfold=True),
  171. 'int_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  172. 'int_mod': LLOp(canfold=True),
  173. 'int_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  174. 'int_lt': LLOp(canfold=True),
  175. 'int_le': LLOp(canfold=True),
  176. 'int_eq': LLOp(canfold=True),
  177. 'int_ne': LLOp(canfold=True),
  178. 'int_gt': LLOp(canfold=True),
  179. 'int_ge': LLOp(canfold=True),
  180. 'int_and': LLOp(canfold=True),
  181. 'int_or': LLOp(canfold=True),
  182. 'int_lshift': LLOp(canfold=True),
  183. 'int_rshift': LLOp(canfold=True),
  184. 'int_xor': LLOp(canfold=True),
  185. 'int_between': LLOp(canfold=True), # a <= b < c
  186. 'int_add_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  187. 'int_add_nonneg_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  188. # ^^^ more efficient version when 2nd arg is nonneg
  189. 'int_sub_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  190. 'int_mul_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  191. # the following operations overflow in one case: (-sys.maxint-1) // (-1)
  192. 'int_floordiv_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  193. 'int_floordiv_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError),
  194. tryfold=True),
  195. 'int_mod_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  196. 'int_mod_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError),
  197. tryfold=True),
  198. 'int_lshift_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
  199. 'uint_is_true': LLOp(canfold=True),
  200. 'uint_invert': LLOp(canfold=True),
  201. 'uint_add': LLOp(canfold=True),
  202. 'uint_sub': LLOp(canfold=True),
  203. 'uint_mul': LLOp(canfold=True),
  204. 'uint_floordiv': LLOp(canfold=True),
  205. 'uint_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  206. 'uint_mod': LLOp(canfold=True),
  207. 'uint_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  208. 'uint_lt': LLOp(canfold=True),
  209. 'uint_le': LLOp(canfold=True),
  210. 'uint_eq': LLOp(canfold=True),
  211. 'uint_ne': LLOp(canfold=True),
  212. 'uint_gt': LLOp(canfold=True),
  213. 'uint_ge': LLOp(canfold=True),
  214. 'uint_and': LLOp(canfold=True),
  215. 'uint_or': LLOp(canfold=True),
  216. 'uint_lshift': LLOp(canfold=True), # args (r_uint, int)
  217. 'uint_rshift': LLOp(canfold=True), # args (r_uint, int)
  218. 'uint_xor': LLOp(canfold=True),
  219. 'float_is_true': LLOp(canfold=True), # it really means "x != 0.0"
  220. 'float_neg': LLOp(canfold=True),
  221. 'float_abs': LLOp(canfold=True),
  222. 'float_add': LLOp(canfold=True),
  223. 'float_sub': LLOp(canfold=True),
  224. 'float_mul': LLOp(canfold=True),
  225. 'float_truediv': LLOp(canfold=True),
  226. 'float_lt': LLOp(canfold=True),
  227. 'float_le': LLOp(canfold=True),
  228. 'float_eq': LLOp(canfold=True),
  229. 'float_ne': LLOp(canfold=True),
  230. 'float_gt': LLOp(canfold=True),
  231. 'float_ge': LLOp(canfold=True),
  232. # don't implement float_mod, use math.fmod instead
  233. # don't implement float_pow, use math.pow instead
  234. 'llong_is_true': LLOp(canfold=True),
  235. 'llong_neg': LLOp(canfold=True),
  236. 'llong_abs': LLOp(canfold=True),
  237. 'llong_invert': LLOp(canfold=True),
  238. 'llong_add': LLOp(canfold=True),
  239. 'llong_sub': LLOp(canfold=True),
  240. 'llong_mul': LLOp(canfold=True),
  241. 'llong_floordiv': LLOp(canfold=True),
  242. 'llong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  243. 'llong_mod': LLOp(canfold=True),
  244. 'llong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  245. 'llong_lt': LLOp(canfold=True),
  246. 'llong_le': LLOp(canfold=True),
  247. 'llong_eq': LLOp(canfold=True),
  248. 'llong_ne': LLOp(canfold=True),
  249. 'llong_gt': LLOp(canfold=True),
  250. 'llong_ge': LLOp(canfold=True),
  251. 'llong_and': LLOp(canfold=True),
  252. 'llong_or': LLOp(canfold=True),
  253. 'llong_lshift': LLOp(canfold=True), # args (r_longlong, int)
  254. 'llong_rshift': LLOp(canfold=True), # args (r_longlong, int)
  255. 'llong_xor': LLOp(canfold=True),
  256. 'ullong_is_true': LLOp(canfold=True),
  257. 'ullong_invert': LLOp(canfold=True),
  258. 'ullong_add': LLOp(canfold=True),
  259. 'ullong_sub': LLOp(canfold=True),
  260. 'ullong_mul': LLOp(canfold=True),
  261. 'ullong_floordiv': LLOp(canfold=True),
  262. 'ullong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  263. 'ullong_mod': LLOp(canfold=True),
  264. 'ullong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
  265. 'ullong_lt': LLOp(canfold=True),
  266. 'ullong_le': LLOp(canfold=True),
  267. 'ullong_eq': LLOp(canfold=True),
  268. 'ullong_ne': LLOp(canfold=True),
  269. 'ullong_gt': LLOp(canfold=True),
  270. 'ullong_ge': LLOp(canfold=True),
  271. 'ullong_and': LLOp(canfold=True),
  272. 'ullong_or': LLOp(canfold=True),
  273. 'ullong_lshift': LLOp(canfold=True), # args (r_ulonglong, int)
  274. 'ullong_rshift': LLOp(canfold=True), # args (r_ulonglong, int)
  275. 'ullong_xor': LLOp(canfold=True),
  276. 'cast_primitive': LLOp(canfold=True),
  277. 'cast_bool_to_int': LLOp(canfold=True),
  278. 'cast_bool_to_uint': LLOp(canfold=True),
  279. 'cast_bool_to_float': LLOp(canfold=True),
  280. 'cast_char_to_int': LLOp(canfold=True),
  281. 'cast_unichar_to_int': LLOp(canfold=True),
  282. 'cast_int_to_char': LLOp(canfold=True),
  283. 'cast_int_to_unichar': LLOp(canfold=True),
  284. 'cast_int_to_uint': LLOp(canfold=True),
  285. 'cast_int_to_float': LLOp(canfold=True),
  286. 'cast_int_to_longlong': LLOp(canfold=True),
  287. 'cast_uint_to_int': LLOp(canfold=True),
  288. 'cast_uint_to_float': LLOp(canfold=True),
  289. 'cast_longlong_to_float' :LLOp(canfold=True),
  290. 'cast_ulonglong_to_float':LLOp(canfold=True),
  291. 'cast_float_to_int': LLOp(canfold=True),
  292. 'cast_float_to_uint': LLOp(canfold=True),
  293. 'cast_float_to_longlong' :LLOp(canfold=True),
  294. 'cast_float_to_ulonglong':LLOp(canfold=True),
  295. 'truncate_longlong_to_int':LLOp(canfold=True),
  296. 'force_cast': LLOp(sideeffects=False), # only for rffi.cast()
  297. # __________ pointer operations __________
  298. 'malloc': LLOp(canmallocgc=True),
  299. 'malloc_varsize': LLOp(canmallocgc=True),
  300. 'malloc_nonmovable': LLOp(canmallocgc=True),
  301. 'malloc_nonmovable_varsize':LLOp(canmallocgc=True),
  302. 'shrink_array': LLOp(canrun=True),
  303. 'zero_gc_pointers_inside': LLOp(),
  304. 'free': LLOp(),
  305. 'getfield': LLOp(sideeffects=False, canrun=True),
  306. 'getarrayitem': LLOp(sideeffects=False, canrun=True),
  307. 'getarraysize': LLOp(canfold=True),
  308. 'getsubstruct': LLOp(canfold=True),
  309. 'getinteriorfield': LLOp(sideeffects=False, canrun=True),
  310. 'getinteriorarraysize': LLOp(canfold=True),
  311. 'setinteriorfield': LLOp(),
  312. 'bare_setinteriorfield': LLOp(),
  313. 'getarraysubstruct': LLOp(canfold=True),
  314. 'setfield': LLOp(),
  315. 'bare_setfield': LLOp(),
  316. 'setarrayitem': LLOp(),
  317. 'bare_setarrayitem': LLOp(),
  318. 'cast_pointer': LLOp(canfold=True),
  319. 'ptr_eq': LLOp(canfold=True),
  320. 'ptr_ne': LLOp(canfold=True),
  321. 'ptr_nonzero': LLOp(canfold=True),
  322. 'ptr_iszero': LLOp(canfold=True),
  323. 'cast_ptr_to_int': LLOp(sideeffects=False),
  324. 'cast_int_to_ptr': LLOp(sideeffects=False),
  325. 'direct_fieldptr': LLOp(canfold=True),
  326. 'direct_arrayitems': LLOp(canfold=True),
  327. 'direct_ptradd': LLOp(canfold=True),
  328. 'cast_opaque_ptr': LLOp(sideeffects=False),
  329. # __________ address operations __________
  330. 'boehm_malloc': LLOp(),
  331. 'boehm_malloc_atomic': LLOp(),
  332. 'boehm_register_finalizer': LLOp(),
  333. 'boehm_disappearing_link': LLOp(),
  334. 'raw_malloc': LLOp(),
  335. 'raw_malloc_usage': LLOp(sideeffects=False),
  336. 'raw_free': LLOp(),
  337. 'raw_memclear': LLOp(),
  338. 'raw_memcopy': LLOp(),
  339. 'raw_memmove': LLOp(),
  340. 'raw_load': LLOp(sideeffects=False),
  341. 'raw_store': LLOp(),
  342. 'stack_malloc': LLOp(), # mmh
  343. 'track_alloc_start': LLOp(),
  344. 'track_alloc_stop': LLOp(),
  345. 'adr_add': LLOp(canfold=True),
  346. 'adr_sub': LLOp(canfold=True),
  347. 'adr_delta': LLOp(canfold=True),
  348. 'adr_lt': LLOp(canfold=True),
  349. 'adr_le': LLOp(canfold=True),
  350. 'adr_eq': LLOp(canfold=True),
  351. 'adr_ne': LLOp(canfold=True),
  352. 'adr_gt': LLOp(canfold=True),
  353. 'adr_ge': LLOp(canfold=True),
  354. 'cast_ptr_to_adr': LLOp(sideeffects=False),
  355. 'cast_adr_to_ptr': LLOp(canfold=True),
  356. 'cast_adr_to_int': LLOp(sideeffects=False),
  357. 'cast_int_to_adr': LLOp(canfold=True),
  358. 'get_group_member': LLOp(canfold=True),
  359. 'get_next_group_member':LLOp(canfold=True),
  360. 'is_group_member_nonzero':LLOp(canfold=True),
  361. 'extract_ushort': LLOp(canfold=True),
  362. 'combine_ushort': LLOp(canfold=True),
  363. 'gc_gettypeptr_group': LLOp(canfold=True),
  364. 'get_member_index': LLOp(canfold=True),
  365. # __________ used by the JIT ________
  366. 'jit_marker': LLOp(),
  367. 'jit_force_virtualizable':LLOp(canrun=True),
  368. 'jit_force_virtual': LLOp(canrun=True),
  369. 'jit_is_virtual': LLOp(canrun=True),
  370. 'jit_force_quasi_immutable': LLOp(canrun=True),
  371. 'jit_record_known_class' : LLOp(canrun=True),
  372. 'get_exception_addr': LLOp(),
  373. 'get_exc_value_addr': LLOp(),
  374. 'do_malloc_fixedsize_clear':LLOp(canmallocgc=True),
  375. 'do_malloc_varsize_clear': LLOp(canmallocgc=True),
  376. 'get_write_barrier_failing_case': LLOp(sideeffects=False),
  377. 'get_write_barrier_from_array_failing_case': LLOp(sideeffects=False),
  378. 'gc_get_type_info_group': LLOp(sideeffects=False),
  379. 'll_read_timestamp': LLOp(canrun=True),
  380. # __________ GC operations __________
  381. 'gc__collect': LLOp(canmallocgc=True),
  382. 'gc_free': LLOp(),
  383. 'gc_fetch_exception': LLOp(),
  384. 'gc_restore_exception': LLOp(),
  385. 'gc_call_rtti_destructor': LLOp(),
  386. 'gc_deallocate': LLOp(),
  387. 'gc_push_alive_pyobj': LLOp(),
  388. 'gc_pop_alive_pyobj': LLOp(),
  389. 'gc_reload_possibly_moved': LLOp(),
  390. # see rlib/objectmodel for gc_identityhash and gc_id
  391. 'gc_identityhash': LLOp(sideeffects=False, canmallocgc=True),
  392. 'gc_id': LLOp(sideeffects=False, canmallocgc=True),
  393. 'gc_obtain_free_space': LLOp(),
  394. 'gc_set_max_heap_size': LLOp(),
  395. 'gc_can_move' : LLOp(sideeffects=False),
  396. 'gc_thread_prepare' : LLOp(canmallocgc=True),
  397. 'gc_thread_run' : LLOp(),
  398. 'gc_thread_start' : LLOp(),
  399. 'gc_thread_die' : LLOp(),
  400. 'gc_thread_before_fork':LLOp(), # returns an opaque address
  401. 'gc_thread_after_fork': LLOp(), # arguments: (result_of_fork, opaqueaddr)
  402. 'gc_assume_young_pointers': LLOp(canrun=True),
  403. 'gc_writebarrier_before_copy': LLOp(canrun=True),
  404. 'gc_heap_stats' : LLOp(canmallocgc=True),
  405. 'gc_get_rpy_roots' : LLOp(),
  406. 'gc_get_rpy_referents': LLOp(),
  407. 'gc_get_rpy_memory_usage': LLOp(),
  408. 'gc_get_rpy_type_index': LLOp(),
  409. 'gc_is_rpy_instance' : LLOp(),
  410. 'gc_dump_rpy_heap' : LLOp(),
  411. 'gc_typeids_z' : LLOp(),
  412. 'gc_add_memory_pressure': LLOp(),
  413. # ------- JIT & GC interaction, only for some GCs ----------
  414. 'gc_adr_of_nursery_free' : LLOp(),
  415. # ^^^ returns an address of nursery free pointer, for later modifications
  416. 'gc_adr_of_nursery_top' : LLOp(),
  417. # ^^^ returns an address of pointer, since it can change at runtime
  418. 'gc_adr_of_root_stack_base': LLOp(),
  419. 'gc_adr_of_root_stack_top': LLOp(),
  420. # returns the address of gcdata.root_stack_base/top (for shadowstack only)
  421. # for asmgcroot support to get the address of various static structures
  422. # see translator/c/src/mem.h for the valid indices
  423. 'gc_asmgcroot_static': LLOp(sideeffects=False),
  424. 'gc_stack_bottom': LLOp(canrun=True),
  425. # for stacklet+shadowstack support
  426. 'gc_shadowstackref_new': LLOp(canmallocgc=True),
  427. 'gc_shadowstackref_context': LLOp(),
  428. 'gc_shadowstackref_destroy': LLOp(),
  429. 'gc_save_current_state_away': LLOp(),
  430. 'gc_forget_current_state': LLOp(),
  431. 'gc_restore_state_from': LLOp(),
  432. 'gc_start_fresh_new_state': LLOp(),
  433. # NOTE NOTE NOTE! don't forget *** canmallocgc=True *** for anything that
  434. # can malloc a GC object.
  435. # __________ weakrefs __________
  436. 'weakref_create': LLOp(sideeffects=False, canmallocgc=True),
  437. 'weakref_deref': LLOp(sideeffects=False),
  438. 'cast_ptr_to_weakrefptr': LLOp(sideeffects=False), # no-op type hiding
  439. 'cast_weakrefptr_to_ptr': LLOp(sideeffects=False), # no-op type revealing
  440. # __________ misc operations __________
  441. 'stack_current': LLOp(sideeffects=False),
  442. 'keepalive': LLOp(),
  443. 'same_as': LLOp(canfold=True),
  444. 'hint': LLOp(),
  445. 'check_no_more_arg': LLOp(canraise=(Exception,)),
  446. 'check_self_nonzero': LLOp(canraise=(Exception,)),
  447. 'decode_arg': LLOp(canraise=(Exception,)),
  448. 'decode_arg_def': LLOp(canraise=(Exception,)),
  449. 'getslice': LLOp(canraise=(Exception,)),
  450. 'check_and_clear_exc': LLOp(),
  451. # __________ debugging __________
  452. 'debug_view': LLOp(),
  453. 'debug_print': LLOp(canrun=True),
  454. 'debug_start': LLOp(canrun=True),
  455. 'debug_stop': LLOp(canrun=True),
  456. 'have_debug_prints': LLOp(canrun=True),
  457. 'debug_offset': LLOp(canrun=True),
  458. 'debug_flush': LLOp(canrun=True),
  459. 'debug_assert': LLOp(tryfold=True),
  460. 'debug_fatalerror': LLOp(),
  461. 'debug_llinterpcall': LLOp(canraise=(Exception,)),
  462. # Python func call 'res=arg[0](*arg[1:])'
  463. # in backends, abort() or whatever is fine
  464. 'debug_start_traceback': LLOp(),
  465. 'debug_record_traceback': LLOp(),
  466. 'debug_catch_exception': LLOp(),
  467. 'debug_reraise_traceback': LLOp(),
  468. 'debug_print_traceback': LLOp(),
  469. 'debug_nonnull_pointer': LLOp(canrun=True),
  470. # __________ instrumentation _________
  471. 'instrument_count': LLOp(),
  472. # __________ ootype operations __________
  473. 'new': LLOp(oo=True, canraise=(MemoryError,)),
  474. 'runtimenew': LLOp(oo=True, canraise=(MemoryError,)),
  475. 'oonewcustomdict': LLOp(oo=True, canraise=(MemoryError,)),
  476. 'oonewarray': LLOp(oo=True, canraise=(MemoryError,)),
  477. 'oosetfield': LLOp(oo=True),
  478. 'oogetfield': LLOp(oo=True, sideeffects=False, canrun=True),
  479. 'oosend': LLOp(oo=True, canraise=(Exception,)),
  480. 'ooupcast': LLOp(oo=True, canfold=True),
  481. 'oodowncast': LLOp(oo=True, canfold=True),
  482. 'cast_to_object': LLOp(oo=True, canfold=True),
  483. 'cast_from_object': LLOp(oo=True, canfold=True),
  484. 'oononnull': LLOp(oo=True, canfold=True),
  485. 'ooisnot': LLOp(oo=True, canfold=True),
  486. 'ooisnull': LLOp(oo=True, canfold=True),
  487. 'oois': LLOp(oo=True, canfold=True),
  488. 'instanceof': LLOp(oo=True, canfold=True),
  489. 'classof': LLOp(oo=True, canfold=True),
  490. 'subclassof': LLOp(oo=True, canfold=True),
  491. 'oostring': LLOp(oo=True, sideeffects=False),
  492. 'oobox_int': LLOp(oo=True, sideeffects=False),
  493. 'oounbox_int': LLOp(oo=True, sideeffects=False),
  494. 'ooparse_int': LLOp(oo=True, canraise=(ValueError,)),
  495. 'ooparse_float': LLOp(oo=True, canraise=(ValueError,)),
  496. 'oounicode': LLOp(oo=True, canraise=(UnicodeDecodeError,)),
  497. }
  498. # ***** Run test_lloperation after changes. *****
  499. # __________ operations on PyObjects __________
  500. from pypy.objspace.flow.operation import FunctionByName
  501. opimpls = FunctionByName.copy()
  502. opimpls['is_true'] = bool
  503. for opname in opimpls:
  504. LL_OPERATIONS[opname] = LLOp(canraise=(Exception,), pyobj=True)
  505. LL_OPERATIONS['simple_call'] = LLOp(canraise=(Exception,), pyobj=True)
  506. del opname, FunctionByName
  507. # ____________________________________________________________
  508. # Post-processing
  509. # Stick the opnames into the LLOp instances
  510. for opname, opdesc in LL_OPERATIONS.iteritems():
  511. opdesc.opname = opname
  512. del opname, opdesc
  513. # Also export all operations in an attribute-based namespace.
  514. # Example usage from LL helpers: z = llop.int_add(Signed, x, y)
  515. for opname, opdesc in LL_OPERATIONS.iteritems():
  516. setattr(llop, opname, opdesc)
  517. del opname, opdesc