/pypy/objspace/std/frame.py
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
- """StdObjSpace custom opcode implementations"""
- import operator
- from rpython.rlib.rarithmetic import ovfcheck
- from rpython.tool.sourcetools import func_renamer
- from pypy.interpreter.pyframe import PyFrame
- from pypy.interpreter.error import oefmt
- from pypy.objspace.std.intobject import W_IntObject
- from pypy.objspace.std.listobject import W_ListObject
- class BaseFrame(PyFrame):
- """These opcodes are always overridden."""
- def LIST_APPEND(self, oparg, next_instr):
- w = self.popvalue()
- v = self.peekvalue(oparg - 1)
- if type(v) is W_ListObject:
- v.append(w)
- else:
- raise AssertionError
- def _intshortcut(spaceopname):
- if spaceopname.startswith('inplace_'):
- opname = spaceopname[len('inplace_'):]
- funcprefix = 'int_'
- else:
- opname = spaceopname
- funcprefix = 'int_BINARY_'
- op = getattr(operator, opname)
- int_op = getattr(W_IntObject, 'descr_' + opname)
- @func_renamer(funcprefix + spaceopname.upper())
- def opimpl(self, oparg, next_instr):
- space = self.space
- space_op = getattr(space, spaceopname)
- w_2 = self.popvalue()
- w_1 = self.popvalue()
- if type(w_1) is W_IntObject and type(w_2) is W_IntObject:
- try:
- z = ovfcheck(op(w_1.intval, w_2.intval))
- except OverflowError:
- w_result = int_op(w_1, space, w_2)
- else:
- w_result = space.newint(z)
- else:
- w_result = space_op(w_1, w_2)
- self.pushvalue(w_result)
- return opimpl
- int_BINARY_ADD = _intshortcut('add')
- int_INPLACE_ADD = _intshortcut('inplace_add')
- int_BINARY_SUBTRACT = _intshortcut('sub')
- int_INPLACE_SUBTRACT = _intshortcut('inplace_sub')
- def list_BINARY_SUBSCR(self, oparg, next_instr):
- space = self.space
- w_2 = self.popvalue()
- w_1 = self.popvalue()
- if type(w_1) is W_ListObject and type(w_2) is W_IntObject:
- try:
- w_result = w_1.getitem(w_2.intval)
- except IndexError:
- raise oefmt(space.w_IndexError, "list index out of range")
- else:
- w_result = space.getitem(w_1, w_2)
- self.pushvalue(w_result)
- def build_frame(space):
- """Consider the objspace config and return a patched frame object."""
- class StdObjSpaceFrame(BaseFrame):
- pass
- if space.config.objspace.std.intshortcut:
- StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD
- StdObjSpaceFrame.INPLACE_ADD = int_INPLACE_ADD
- StdObjSpaceFrame.BINARY_SUBTRACT = int_BINARY_SUBTRACT
- StdObjSpaceFrame.INPLACE_SUBTRACT = int_INPLACE_SUBTRACT
- if space.config.objspace.std.optimized_list_getitem:
- StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR
- from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD
- StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD
- StdObjSpaceFrame.CALL_METHOD = CALL_METHOD
- return StdObjSpaceFrame