PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/objspace/std/frame.py

https://bitbucket.org/pypy/pypy/
Python | 91 lines | 71 code | 17 blank | 3 comment | 17 complexity | dce5e3081347fc98d38a093f4d510cb1 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """StdObjSpace custom opcode implementations"""
  2. import operator
  3. from rpython.rlib.rarithmetic import ovfcheck
  4. from rpython.tool.sourcetools import func_renamer
  5. from pypy.interpreter.pyframe import PyFrame
  6. from pypy.interpreter.error import oefmt
  7. from pypy.objspace.std.intobject import W_IntObject
  8. from pypy.objspace.std.listobject import W_ListObject
  9. class BaseFrame(PyFrame):
  10. """These opcodes are always overridden."""
  11. def LIST_APPEND(self, oparg, next_instr):
  12. w = self.popvalue()
  13. v = self.peekvalue(oparg - 1)
  14. if type(v) is W_ListObject:
  15. v.append(w)
  16. else:
  17. raise AssertionError
  18. def _intshortcut(spaceopname):
  19. if spaceopname.startswith('inplace_'):
  20. opname = spaceopname[len('inplace_'):]
  21. funcprefix = 'int_'
  22. else:
  23. opname = spaceopname
  24. funcprefix = 'int_BINARY_'
  25. op = getattr(operator, opname)
  26. int_op = getattr(W_IntObject, 'descr_' + opname)
  27. @func_renamer(funcprefix + spaceopname.upper())
  28. def opimpl(self, oparg, next_instr):
  29. space = self.space
  30. space_op = getattr(space, spaceopname)
  31. w_2 = self.popvalue()
  32. w_1 = self.popvalue()
  33. if type(w_1) is W_IntObject and type(w_2) is W_IntObject:
  34. try:
  35. z = ovfcheck(op(w_1.intval, w_2.intval))
  36. except OverflowError:
  37. w_result = int_op(w_1, space, w_2)
  38. else:
  39. w_result = space.newint(z)
  40. else:
  41. w_result = space_op(w_1, w_2)
  42. self.pushvalue(w_result)
  43. return opimpl
  44. int_BINARY_ADD = _intshortcut('add')
  45. int_INPLACE_ADD = _intshortcut('inplace_add')
  46. int_BINARY_SUBTRACT = _intshortcut('sub')
  47. int_INPLACE_SUBTRACT = _intshortcut('inplace_sub')
  48. def list_BINARY_SUBSCR(self, oparg, next_instr):
  49. space = self.space
  50. w_2 = self.popvalue()
  51. w_1 = self.popvalue()
  52. if type(w_1) is W_ListObject and type(w_2) is W_IntObject:
  53. try:
  54. w_result = w_1.getitem(w_2.intval)
  55. except IndexError:
  56. raise oefmt(space.w_IndexError, "list index out of range")
  57. else:
  58. w_result = space.getitem(w_1, w_2)
  59. self.pushvalue(w_result)
  60. def build_frame(space):
  61. """Consider the objspace config and return a patched frame object."""
  62. class StdObjSpaceFrame(BaseFrame):
  63. pass
  64. if space.config.objspace.std.intshortcut:
  65. StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD
  66. StdObjSpaceFrame.INPLACE_ADD = int_INPLACE_ADD
  67. StdObjSpaceFrame.BINARY_SUBTRACT = int_BINARY_SUBTRACT
  68. StdObjSpaceFrame.INPLACE_SUBTRACT = int_INPLACE_SUBTRACT
  69. if space.config.objspace.std.optimized_list_getitem:
  70. StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR
  71. from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD
  72. StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD
  73. StdObjSpaceFrame.CALL_METHOD = CALL_METHOD
  74. return StdObjSpaceFrame