1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
"""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
|