File: capsule.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 (101 lines) | stat: -rw-r--r-- 4,012 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
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.module.cpyext.api import (bootstrap_function, slot_function,
    PyObject, build_type_checkers, cts, parse_dir)
from pypy.module.cpyext.pyobject import (make_ref, from_ref,
    make_typedescr, track_reference)
from pypy.interpreter.error import oefmt
from pypy.objspace.std.capsuleobject import W_Capsule

cts.parse_header(parse_dir / 'cpyext_capsule.h')
PyCapsule = cts.gettype("PyCapsule")

@bootstrap_function
def init_capsuleobject(space):
    "Type description of PyCapsuleobject"
    make_typedescr(W_Capsule.typedef,
                   basestruct=PyCapsule,
                   attach=capsule_attach,
                   realize=capsule_realize,
                   dealloc=capsule_dealloc,
                  )

def capsule_attach(space, py_obj, w_obj, w_userdata=None):
    """
    Fills a newly allocated PyCapsule with the given capsule object. The
    value must only be modified through PyCapsule_Set interfaces
    """
    assert isinstance(w_obj, W_Capsule)
    pycapsule_obj = cts.cast("PyCapsule*", py_obj)
    pycapsule_obj.c_pointer = w_obj.pointer
    pycapsule_obj.c_name = w_obj.name
    pycapsule_obj.c_context = w_obj.context

def capsule_realize(space, obj):
    # Allocate and fill a w_obj from a pyobj
    py_obj = cts.cast("PyCapsule*", obj)
    w_obj = W_Capsule(space, py_obj.c_pointer, py_obj.c_name)
    w_obj.context = py_obj.c_context
    track_reference(space, obj, w_obj)
    return w_obj

@slot_function([PyObject], lltype.Void)
def capsule_dealloc(space, py_obj):
    """Frees allocated PyBytesObject resources.
    """
    from pypy.module.cpyext.object import _dealloc
    py_capsule = cts.cast("PyCapsule *", py_obj)
    if py_capsule.c_destructor:
        py_capsule.c_destructor(py_obj)
    _dealloc(space, py_obj)

@cts.decl("""PyObject *
    PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)""",
    result_is_ll=True)
def PyCapsule_New(space, pointer, name, destructor):
    if not pointer:
        raise oefmt(space.w_ValueError, "PyCapsule_New called with null pointer")
    w_obj = W_Capsule(space, pointer, name)
    pyobj = cts.cast("PyCapsule *", make_ref(space, w_obj))
    pyobj.c_destructor = destructor
    return pyobj

@cts.decl("int PyCapsule_SetPointer(PyObject *capsule, void *pointer)", error=-1)
def PyCapsule_SetPointer(space, py_obj, pointer):
    # Set both the capsule and the w_obj. We can't use the attach/realize
    # mechanism since this is in-place modification
    py_capsule = cts.cast("PyCapsule*", py_obj)
    py_capsule.c_pointer = pointer
    w_obj = from_ref(space, py_obj)
    assert isinstance(w_obj, W_Capsule)
    w_obj.pointer = pointer
    return 0

@cts.decl("int PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor)", error=-1)
def PyCapsule_SetDestructor(space, py_obj, destructor):
    # Set both the capsule and the w_obj. We can't use the attach/realize
    # mechanism since this is in-place modification
    py_capsule = cts.cast("PyCapsule*", py_obj)
    py_capsule.c_destructor = destructor
    return 0

@cts.decl("int PyCapsule_SetName(PyObject *capsule, const char *name)", error=-1)
def PyCapsule_SetName(space, py_obj, name):
    # Set both the capsule and the w_obj. We can't use the attach/realize
    # mechanism since this is in-place modification
    py_capsule = cts.cast("PyCapsule*", py_obj)
    py_capsule.c_name = name
    w_obj = from_ref(space, py_obj)
    assert isinstance(w_obj, W_Capsule)
    w_obj.name = name
    return 0

@cts.decl("int PyCapsule_SetContext(PyObject *capsule, void *context)", error=-1)
def PyCapsule_SetContext(space, py_obj, context):
    # Set both the capsule and the w_obj. We can't use the attach/realize
    # mechanism since this is in-place modification
    py_capsule = cts.cast("PyCapsule*", py_obj)
    py_capsule.c_context = context
    w_obj = from_ref(space, py_obj)
    assert isinstance(w_obj, W_Capsule)
    w_obj.context = context
    return 0