File: interp_long.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (141 lines) | stat: -rw-r--r-- 5,769 bytes parent folder | download | duplicates (2)
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
141
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_FromInt32_t(HPyContext *ctx, int value)")
def HPyLong_FromInt32_t(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_FromUInt32_t(HPyContext *ctx, unsigned int value)")
def HPyLong_FromUInt32_t(space, handles, ctx, v):
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

# On windows, long is 4 bytes, on all platforms long long is 8
@API.func("HPy HPyLong_FromInt64_t(HPyContext *ctx, long long v)")
def HPyLong_FromInt64_t(space, handles, ctx, v):
    w_obj = space.newlong_from_rarith_int(v)
    return handles.new(w_obj)

@API.func("HPy HPyLong_FromUInt64_t(HPyContext *ctx, unsigned long long v)")
def HPyLong_FromUInt64_t(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_AsInt32_t(HPyContext *ctx, HPy h)",
          error_value=API.cast("long", -1))
def HPyLong_AsInt32_t(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_AsUInt32_t(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long", -1))
def HPyLong_AsUInt32_t(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_AsUInt32_tMask(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long", -1))
def HPyLong_AsUInt32_tMask(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_AsInt64_t(HPyContext *ctx, HPy h)",
          error_value=API.cast("long long", -1))
def HPyLong_AsInt64_t(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_AsUInt64_t(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long long", -1))
def HPyLong_AsUInt64_t(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_AsUInt64_tMask(HPyContext *ctx, HPy h)",
          error_value=API.cast("unsigned long long", -1))
def HPyLong_AsUInt64_tMask(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)