File: interp_object.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 (301 lines) | stat: -rw-r--r-- 11,204 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
import os
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.debug import ll_assert
from pypy.interpreter.error import OperationError, oefmt
import pypy.module.__builtin__.operation as operation
from pypy.objspace.std.bytesobject import invoke_bytes_method
from pypy.module._hpy_universal.apiset import API
from . import llapi

HPy_RichCmpOp = llapi.cts.gettype('HPy_RichCmpOp')

@API.func("int HPy_IsTrue(HPyContext *ctx, HPy h)", error_value=API.int(-1))
def HPy_IsTrue(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    return API.int(space.is_true(w_obj))

@API.func("HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy h_name)")
def HPy_GetAttr(space, handles, ctx, h_obj, h_name):
    w_obj = handles.deref(h_obj)
    w_name = handles.deref(h_name)
    w_res = space.getattr(w_obj, w_name)
    return handles.new(w_res)

@API.func("HPy HPy_GetAttr_s(HPyContext *ctx, HPy h_obj, const char *name)")
def HPy_GetAttr_s(space, handles, ctx, h_obj, name):
    w_obj = handles.deref(h_obj)
    w_name = API.ccharp2text(space, name)
    w_res = space.getattr(w_obj, w_name)
    return handles.new(w_res)


@API.func("int HPy_HasAttr(HPyContext *ctx, HPy h_obj, HPy h_name)",
          error_value='CANNOT_FAIL')
def HPy_HasAttr(space, handles, ctx, h_obj, h_name):
    w_obj = handles.deref(h_obj)
    w_name = handles.deref(h_name)
    return _HasAttr(space, w_obj, w_name)

@API.func("int HPy_HasAttr_s(HPyContext *ctx, HPy h_obj, const char *name)",
          error_value='CANNOT_FAIL')
def HPy_HasAttr_s(space, handles, ctx, h_obj, name):
    w_obj = handles.deref(h_obj)
    w_name = API.ccharp2text(space, name)
    return _HasAttr(space, w_obj, w_name)

def _HasAttr(space, w_obj, w_name):
    try:
        w_res = operation.hasattr(space, w_obj, w_name)
        return API.int(space.is_true(w_res))
    except OperationError:
        return API.int(0)


@API.func("int HPy_SetAttr(HPyContext *ctx, HPy h_obj, HPy h_name, HPy h_value)",
          error_value=API.int(-1))
def HPy_SetAttr(space, handles, ctx, h_obj, h_name, h_value):
    w_obj = handles.deref(h_obj)
    w_name = handles.deref(h_name)
    if not h_value:
        operation.delattr(space, w_obj, w_name)
    else:
        w_value = handles.deref(h_value)
        operation.setattr(space, w_obj, w_name, w_value)
    return API.int(0)

@API.func("int HPy_SetAttr_s(HPyContext *ctx, HPy h_obj, const char *name, HPy h_value)",
          error_value=API.int(-1))
def HPy_SetAttr_s(space, handles, ctx, h_obj, name, h_value):
    w_obj = handles.deref(h_obj)
    w_name = API.ccharp2text(space, name)
    if not h_value:
        operation.delattr(space, w_obj, w_name)
    else:
        w_value = handles.deref(h_value)
        operation.setattr(space, w_obj, w_name, w_value)
    return API.int(0)


@API.func("int HPyCallable_Check(HPyContext *ctx, HPy h)", error_value='CANNOT_FAIL')
def HPyCallable_Check(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    return API.int(space.is_true(space.callable(w_obj)))


@API.func("HPy HPy_GetItem(HPyContext *ctx, HPy h_obj, HPy h_key)")
def HPy_GetItem(space, handles, ctx, h_obj, h_key):
    w_obj = handles.deref(h_obj)
    w_key = handles.deref(h_key)
    w_res = space.getitem(w_obj, w_key)
    return handles.new(w_res)

@API.func("HPy HPy_GetItem_i(HPyContext *ctx, HPy h_obj, HPy_ssize_t idx)")
def HPy_GetItem_i(space, handles, ctx, h_obj, idx):
    w_obj = handles.deref(h_obj)
    w_key = space.newint(idx)
    w_res = space.getitem(w_obj, w_key)
    return handles.new(w_res)

@API.func("HPy HPy_GetItem_s(HPyContext *ctx, HPy h_obj, const char *key)")
def HPy_GetItem_s(space, handles, ctx, h_obj, key):
    w_obj = handles.deref(h_obj)
    w_key = API.ccharp2text(space, key)
    w_res = space.getitem(w_obj, w_key)
    return handles.new(w_res)


@API.func("int HPy_SetItem(HPyContext *ctx, HPy h_obj, HPy h_key, HPy h_val)",
          error_value=API.int(-1))
def HPy_SetItem(space, handles, ctx, h_obj, h_key, h_val):
    w_obj = handles.deref(h_obj)
    w_key = handles.deref(h_key)
    w_val = handles.deref(h_val)
    space.setitem(w_obj, w_key, w_val)
    return API.int(0)

@API.func("int HPy_SetItem_i(HPyContext *ctx, HPy h_obj, HPy_ssize_t idx, HPy h_val)",
          error_value=API.int(-1))
def HPy_SetItem_i(space, handles, ctx, h_obj, idx, h_val):
    w_obj = handles.deref(h_obj)
    w_key = space.newint(idx)
    w_val = handles.deref(h_val)
    space.setitem(w_obj, w_key, w_val)
    return API.int(0)

@API.func("int HPy_SetItem_s(HPyContext *ctx, HPy h_obj, const char *key, HPy h_val)",
          error_value=API.int(-1))
def HPy_SetItem_s(space, handles, ctx, h_obj, key, h_val):
    w_obj = handles.deref(h_obj)
    w_key = API.ccharp2text(space, key)
    w_val = handles.deref(h_val)
    space.setitem(w_obj, w_key, w_val)
    return API.int(0)

@API.func("HPy HPy_Repr(HPyContext *ctx, HPy h_obj)")
def HPy_Repr(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    if w_obj is None:
        w_res = space.newtext("<NULL>")
    else:
        w_res = space.repr(w_obj)
    return handles.new(w_res)

@API.func("HPy HPy_Str(HPyContext *ctx, HPy h_obj)")
def HPy_Str(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    if w_obj is None:
        w_res = space.newtext("<NULL>")
    else:
        w_res = space.str(w_obj)
    return handles.new(w_res)

@API.func("HPy HPy_ASCII(HPyContext *ctx, HPy h_obj)")
def HPy_ASCII(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    w_res = operation.ascii(space, w_obj)
    return handles.new(w_res)

@API.func("HPy HPy_Bytes(HPyContext *ctx, HPy h_obj)")
def HPy_Bytes(space, handles, ctx, h_obj):
    # XXX: cpyext checks and returns <NULL>. Add a test to HPy and fix here
    w_obj = handles.deref(h_obj)
    if space.type(w_obj) is space.w_bytes:
        # XXX write a test for this case
        return handles.dup(h_obj)
    w_result = invoke_bytes_method(space, w_obj)
    if w_result is not None:
        return handles.new(w_result)
    # return PyBytes_FromObject(space, w_obj)
    # XXX: write a test for this case
    buffer = space.buffer_w(w_obj, space.BUF_FULL_RO)
    w_res = space.newbytes(buffer.as_str())
    return handles.new(w_res)

@API.func("HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op)")
def HPy_RichCompare(space, handles, ctx, v, w, op):
    w_o1 = handles.deref(v)
    w_o2 = handles.deref(w)
    w_result = rich_compare(space, w_o1, w_o2, op)
    return handles.new(w_result)

def rich_compare(space, w_o1, w_o2, opid_int):
    opid = rffi.cast(lltype.Signed, opid_int)
    if opid == HPy_RichCmpOp.HPy_LT:
        return space.lt(w_o1, w_o2)
    elif opid == HPy_RichCmpOp.HPy_LE:
        return space.le(w_o1, w_o2)
    elif opid == HPy_RichCmpOp.HPy_EQ:
        return space.eq(w_o1, w_o2)
    elif opid == HPy_RichCmpOp.HPy_NE:
        return space.ne(w_o1, w_o2)
    elif opid == HPy_RichCmpOp.HPy_GT:
        return space.gt(w_o1, w_o2)
    elif opid == HPy_RichCmpOp.HPy_GE:
        return space.ge(w_o1, w_o2)
    else:
        raise oefmt(space.w_SystemError, "Bad internal call!")


@API.func("int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op)",
          error_value=API.int(-1))
def HPy_RichCompareBool(space, handles, ctx, v, w, op):
    w_o1 = handles.deref(v)
    w_o2 = handles.deref(w)
    # Quick result when objects are the same.
    # Guarantees that identity implies equality.
    if space.is_w(w_o1, w_o2):
        opid = rffi.cast(lltype.Signed, op)
        if opid == HPy_RichCmpOp.HPy_EQ:
            return API.int(1)
        if opid == HPy_RichCmpOp.HPy_NE:
            return API.int(0)
    w_result = rich_compare(space, w_o1, w_o2, op)
    return API.int(space.is_true(w_result))

@API.func("HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj)", error_value=-1)
def HPy_Hash(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    return API.cts.cast('HPy_hash_t', space.hash_w(w_obj))

@API.func("HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h)", error_value=-1)
def HPy_Length(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    if not w_obj:
        # equivalent to null_error() call in PyObject_Size
        raise oefmt(space.w_SystemError, "invalid object")
    return space.len_w(w_obj)

@API.func("HPy HPy_Type(HPyContext *ctx, HPy obj)")
def HPy_Type(space, handles, ctx, h_obj):
    w_obj = handles.deref(h_obj)
    return handles.new(space.type(w_obj))

@API.func("int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type)",
          error_value=API.int(0))
def HPy_TypeCheck(space, handles, ctx, h_obj, h_type):
    w_obj = handles.deref(h_obj)
    w_type = handles.deref(h_type)
    ll_assert(space.isinstance_w(w_type, space.w_type), "h_type is not a type object")
    assert space.isinstance_w(w_type, space.w_type)
    try:
        return API.int(space.issubtype_w(space.type(w_obj), w_type))
    except:
        # print "issubtype_w failed", space.text_w(space.repr(w_obj)), w_type.name
        pass
    return API.int(0)

@API.func("int HPy_Is(HPyContext *ctx, HPy obj, HPy other)",
          error_value='CANNOT_FAIL')
def HPy_Is(space, handles, ctx, h_obj, h_other):
    if not h_obj:
        return API.int(not bool(h_other))
    if not h_other:
        return API.int(0)
    w_obj = handles.deref(h_obj)
    w_other = handles.deref(h_other)
    return API.int(space.is_w(w_obj, w_other))

@API.func("void _HPy_Dump(HPyContext *ctx, HPy h)")
def _HPy_Dump(space, handles, ctx, h_obj):
    # this is a debugging helper meant to be called from gdb. As such, we
    # write directly to stderr, bypassing sys.stderr&co.
    stderr = 2
    w_obj = handles.deref(h_obj)
    w_type = space.type(w_obj)
    os.write(stderr, "object type     : %r\n" % (w_type,))
    os.write(stderr, "object type name: %s\n" % (w_type.name,))
    os.write(stderr, "object rpy repr : %r\n" % (w_obj,))
    try:
        w_repr = space.repr(w_obj)
        s = space.text_w(w_repr)
        os.write(stderr, "object repr     : %s\n" % (s,))
    except:
        os.write(stderr, "objec repr      : <failed>\n")

@API.func("int _HPy_Contains(HPyContext *ctx, HPy container, HPy key)", error_value=API.int(-1))
def _HPy_Contains(space, handles, ctx, h_container, h_key):
    w_container = handles.deref(h_container)
    w_key = handles.deref(h_key)
    w_res = space.contains(w_container, w_key)
    return API.int(space.int_w(w_res))

@API.func("int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key)", error_value=API.int(-1))
def HPy_DelItem(space, handles, ctx, h_obj, h_key):
    w_obj = handles.deref(h_obj)
    w_key = handles.deref(h_key)
    space.delitem(w_obj, w_key)
    return API.int(0)

@API.func("int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t key)", error_value=API.int(-1))
def HPy_DelItem_i(space, handles, ctx, h_obj, key):
    w_obj = handles.deref(h_obj)
    w_key = space.newint(key)
    space.delitem(w_obj, w_key)
    return API.int(0)

@API.func("int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *key)", error_value=API.int(-1))
def HPy_DelItem_s(space, handles, ctx, h_obj, key):
    w_obj = handles.deref(h_obj)
    w_key = API.ccharp2text(space, key)
    space.delitem(w_obj, w_key)
    return API.int(0)