File: frame.py

package info (click to toggle)
pypy3 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 111,848 kB
  • sloc: python: 1,291,746; ansic: 74,281; asm: 5,187; cpp: 3,017; sh: 2,533; makefile: 544; xml: 243; lisp: 45; csh: 21; awk: 4
file content (91 lines) | stat: -rw-r--r-- 2,942 bytes parent folder | download | duplicates (5)
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