-
Notifications
You must be signed in to change notification settings - Fork 248
/
CObjects.cpp
157 lines (129 loc) · 3.43 KB
/
CObjects.cpp
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
#ifndef COBJECTS_CPP
#define COBJECTS_CPP
/*****************************************************************************
* C interface
*
* These are exported using the CObject API
*/
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-function"
#endif
#include "greenlet_exceptions.hpp"
#include "greenlet_internal.hpp"
#include "greenlet_refs.hpp"
#include "TThreadStateDestroy.cpp"
#include "PyGreenlet.hpp"
using greenlet::PyErrOccurred;
using greenlet::Require;
extern "C" {
static PyGreenlet*
PyGreenlet_GetCurrent(void)
{
return GET_THREAD_STATE().state().get_current().relinquish_ownership();
}
static int
PyGreenlet_SetParent(PyGreenlet* g, PyGreenlet* nparent)
{
return green_setparent((PyGreenlet*)g, (PyObject*)nparent, NULL);
}
static PyGreenlet*
PyGreenlet_New(PyObject* run, PyGreenlet* parent)
{
using greenlet::refs::NewDictReference;
// In the past, we didn't use green_new and green_init, but that
// was a maintenance issue because we duplicated code. This way is
// much safer, but slightly slower. If that's a problem, we could
// refactor green_init to separate argument parsing from initialization.
OwnedGreenlet g = OwnedGreenlet::consuming(green_new(&PyGreenlet_Type, nullptr, nullptr));
if (!g) {
return NULL;
}
try {
NewDictReference kwargs;
if (run) {
kwargs.SetItem(mod_globs->str_run, run);
}
if (parent) {
kwargs.SetItem("parent", (PyObject*)parent);
}
Require(green_init(g.borrow(), mod_globs->empty_tuple, kwargs.borrow()));
}
catch (const PyErrOccurred&) {
return nullptr;
}
return g.relinquish_ownership();
}
static PyObject*
PyGreenlet_Switch(PyGreenlet* self, PyObject* args, PyObject* kwargs)
{
if (!PyGreenlet_Check(self)) {
PyErr_BadArgument();
return NULL;
}
if (args == NULL) {
args = mod_globs->empty_tuple;
}
if (kwargs == NULL || !PyDict_Check(kwargs)) {
kwargs = NULL;
}
return green_switch(self, args, kwargs);
}
static PyObject*
PyGreenlet_Throw(PyGreenlet* self, PyObject* typ, PyObject* val, PyObject* tb)
{
if (!PyGreenlet_Check(self)) {
PyErr_BadArgument();
return nullptr;
}
try {
PyErrPieces err_pieces(typ, val, tb);
return internal_green_throw(self, err_pieces).relinquish_ownership();
}
catch (const PyErrOccurred&) {
return nullptr;
}
}
static int
Extern_PyGreenlet_MAIN(PyGreenlet* self)
{
if (!PyGreenlet_Check(self)) {
PyErr_BadArgument();
return -1;
}
return self->pimpl->main();
}
static int
Extern_PyGreenlet_ACTIVE(PyGreenlet* self)
{
if (!PyGreenlet_Check(self)) {
PyErr_BadArgument();
return -1;
}
return self->pimpl->active();
}
static int
Extern_PyGreenlet_STARTED(PyGreenlet* self)
{
if (!PyGreenlet_Check(self)) {
PyErr_BadArgument();
return -1;
}
return self->pimpl->started();
}
static PyGreenlet*
Extern_PyGreenlet_GET_PARENT(PyGreenlet* self)
{
if (!PyGreenlet_Check(self)) {
PyErr_BadArgument();
return NULL;
}
// This can return NULL even if there is no exception
return self->pimpl->parent().acquire();
}
} // extern C.
/** End C API ****************************************************************/
#ifdef __clang__
# pragma clang diagnostic pop
#endif
#endif