File: interp_long.py

package info (click to toggle)
pypy3 7.3.11%2Bdfsg-2%2Bdeb12u3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 201,024 kB
  • sloc: python: 1,950,308; ansic: 517,580; sh: 21,417; asm: 14,419; cpp: 4,263; makefile: 4,228; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 11; awk: 4
file content (140 lines) | stat: -rw-r--r-- 5,772 bytes parent folder | download
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib.rarithmetic import maxint
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.interpreter.error import OperationError, oefmt
from pypy.module._hpy_universal.apiset import API


@API.func("HPy HPyLong_FromLong(HPyContext *ctx, long value)")
def HPyLong_FromLong(space, handles, ctx, value):
    # XXX: cpyext does space.newlong: write a test and fix
    w_obj = space.newint(rffi.cast(lltype.Signed, value))
    return handles.new(w_obj)

@API.func("HPy HPyLong_FromUnsignedLong(HPyContext *ctx, unsigned long value)")
def HPyLong_FromUnsignedLong(space, handles, ctx, v):
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

@API.func("HPy HPyLong_FromLongLong(HPyContext *ctx, long long v)")
def HPyLong_FromLongLong(space, handles, ctx, v):
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

@API.func("HPy HPyLong_FromUnsignedLongLong(HPyContext *ctx, unsigned long long v)")
def HPyLong_FromUnsignedLongLong(space, handles, ctx, v):
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

@API.func("HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value)")
def HPyLong_FromSize_t(space, handles, ctx, v):
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

@API.func("HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value)")
def HPyLong_FromSsize_t(space, handles, ctx, v):
    # XXX: cpyext uses space.newlong: is there any difference?
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

ULONG_MASK = (2 ** (8 * rffi.sizeof(rffi.ULONG)) -1)
ULONG_MAX = (2 ** (8 * rffi.sizeof(rffi.ULONG)) -1)
LONG_MAX = (2 ** (8 * rffi.sizeof(rffi.ULONG) - 1) -1)
LONG_MIN = (-2 ** (8 * rffi.sizeof(rffi.ULONG) - 1))
need_to_check = maxint > ULONG_MAX

@API.func("long HPyLong_AsLong(HPyContext *ctx, HPy h)",
          error_value=API.cast("long", -1))
def HPyLong_AsLong(space, handles, ctx, h):
    w_long = handles.deref(h)
    val = space.int_w(space.int(w_long))
    if need_to_check and (val > LONG_MAX or val < LONG_MIN):
        # On win64 space.int_w will succeed for 8-byte ints
        # but long is 4 bytes. So we must check manually
        raise oefmt(space.w_OverflowError,
                    "Python int too large to convert to C long")
    return rffi.cast(rffi.LONG, val)

@API.func("unsigned long HPyLong_AsUnsignedLong(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long", -1))
def HPyLong_AsUnsignedLong(space, handles, ctx, h):
    w_long = handles.deref(h)
    try:
        val = space.uint_w(w_long)
    except OperationError as e:
        if e.match(space, space.w_ValueError):
            e.w_type = space.w_OverflowError
        raise
    if need_to_check and val > ULONG_MAX:
        # On win64 space.uint_w will succeed for 8-byte ints
        # but long is 4 bytes. So we must check manually
        raise oefmt(space.w_OverflowError,
                    "Python int too large to convert to C unsigned long")
    return rffi.cast(rffi.ULONG, val)

@API.func("unsigned long HPyLong_AsUnsignedLongMask(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long", -1))
def HPyLong_AsUnsignedLongMask(space, handles, ctx, h):
    w_long = handles.deref(h)
    num = space.bigint_w(w_long)
    val = num.uintmask()
    if need_to_check and not we_are_translated():
        # On win64 num.uintmask will succeed for 8-byte ints
        # but unsigned long is 4 bytes.
        # The cast below is sufficient when translated, but
        # we need an extra check when running on CPython.
        val &= ULONG_MASK
    return rffi.cast(rffi.ULONG, val)

@API.func("long long HPyLong_AsLongLong(HPyContext *ctx, HPy h)",
          error_value=API.cast("long long", -1))
def HPyLong_AsLongLong(space, handles, ctx, h):
    w_long = handles.deref(h)
    return rffi.cast(rffi.LONGLONG, space.r_longlong_w(w_long))

@API.func("unsigned long long HPyLong_AsUnsignedLongLong(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long long", -1))
def HPyLong_AsUnsignedLongLong(space, handles, ctx, h):
    w_long = handles.deref(h)
    try:
        return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(
            w_long, allow_conversion=False))
    except OperationError as e:
        if e.match(space, space.w_ValueError):
            e.w_type = space.w_OverflowError
        raise

@API.func("unsigned long long HPyLong_AsUnsignedLongLongMask(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long long", -1))
def HPyLong_AsUnsignedLongLongMask(space, handles, ctx, h):
    w_long = handles.deref(h)
    num = space.bigint_w(w_long)
    return num.ulonglongmask()

@API.func("size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h)",
          error_value=API.cast("size_t", -1))
def HPyLong_AsSize_t(space, handles, ctx, h):
    w_long = handles.deref(h)
    try:
        return space.uint_w(w_long)
    except OperationError as e:
        if e.match(space, space.w_ValueError):
            e.w_type = space.w_OverflowError
        raise

@API.func("HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h)",
          error_value=API.cast("ssize_t", -1))
def HPyLong_AsSsize_t(space, handles, ctx, h):
    w_long = handles.deref(h)
    return space.int_w(w_long, allow_conversion=False)

@API.func("void * HPyLong_AsVoidPtr(HPyContext *ctx, HPy h)")
def HPyLong_AsVoidPtr(space, handles, ctx, h):
    w_long = handles.deref(h)
    return rffi.cast(rffi.VOIDP, space.int_w(w_long, allow_conversion=False))

@API.func("double HPyLong_AsDouble(HPyContext *ctx, HPy h)",
          error_value=-1.0)
def HPyLong_AsDouble(space, handles, ctx, h):
    w_long = handles.deref(h)
    return space.float_w(w_long)