Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CPPGetSetItem.cxx
Go to the documentation of this file.
1// Bindings
2#include "cpyrt.h"
3
4using namespace cppjit;
5#include "CPPGetSetItem.h"
6#include "Executors.h"
7
8//- private helpers -----------------------------------------------------------
9static inline void unroll(cpyrt_PyArgs_t packed_args, cpyrt_PyArgs_t unrolled,
10 Py_ssize_t nArgs) {
11 // Unroll up to nArgs arguments from packed_args into unrolled.
12 for (int i = 0, iur = 0; i < nArgs; ++i, ++iur) {
13 PyObject* item = cpyrt_PyArgs_GET_ITEM(packed_args, i);
14 if (PyTuple_Check(item)) {
15 for (int j = 0; j < PyTuple_GET_SIZE(item); ++j, ++iur) {
16 PyObject* subitem = PyTuple_GET_ITEM(item, j);
17 Py_INCREF(subitem);
18 cpyrt_PyArgs_SET_ITEM(unrolled, iur, subitem);
19 }
20 } else {
21 Py_INCREF(item);
22 cpyrt_PyArgs_SET_ITEM(unrolled, iur, item);
23 }
24 }
25}
26
27//- protected members ---------------------------------------------------------
29 // basic call will do
30 if (!CPPMethod::InitExecutor_(executor))
31 return false;
32
33 // check to make sure we're dealing with a RefExecutor
34 if (!dynamic_cast<RefExecutor*>(executor)) {
35 PyErr_Format(PyExc_NotImplementedError,
36 "no __setitem__ handler for return type (%s)",
37 this->GetReturnTypeName().c_str());
38 return false;
39 }
40
41 return true;
42}
43
44//-----------------------------------------------------------------------------
46 // Prepare executor with a buffer for the return value.
47 Py_ssize_t nArgs = cpyrt_PyArgs_GET_SIZE(cargs.fArgs, cargs.fNArgsf);
48 if (nArgs <= 1) {
49 PyErr_SetString(PyExc_TypeError, "insufficient arguments to __setitem__");
50 return false;
51 }
52
53 // use the last element of args for assignment upon return, then slice it from
54 // the (unrolled) actual arguments
55 ((RefExecutor*)this->GetExecutor())
56 ->SetAssignable(cpyrt_PyArgs_GET_ITEM(cargs.fArgs, nArgs - 1));
57
58 // see whether any of the arguments is a tuple to be unrolled
59 Py_ssize_t realsize = 0;
60 for (Py_ssize_t i = 0; i < nArgs - 1; ++i) {
61 PyObject* item = cpyrt_PyArgs_GET_ITEM(cargs.fArgs, i);
62 realsize += PyTuple_Check(item) ? PyTuple_GET_SIZE(item) : 1;
63 }
64
65 // unroll any tuples, if present in the arguments
66 if (realsize != nArgs - 1) {
67 cpyrt_PyArgs_t unrolled =
68 (PyObject**)PyMem_Malloc(realsize * sizeof(PyObject*));
69 unroll(cargs.fArgs, unrolled, nArgs - 1);
70 cargs.fArgs = unrolled;
72 }
73 cargs.fNArgsf = realsize;
74
75 // continue normal method processing
76 return CPPMethod::ProcessArgs(cargs);
77}
78
79//-----------------------------------------------------------------------------
81 // Unroll tuples for call, otherwise just like regular CPPMethod of
82 // __getitem__.
83 Py_ssize_t nArgs = cpyrt_PyArgs_GET_SIZE(cargs.fArgs, cargs.fNArgsf);
84
85 // see whether any of the arguments is a tuple to be unrolled
86 Py_ssize_t realsize = 0;
87 for (Py_ssize_t i = 0; i < nArgs; ++i) {
88 PyObject* item = cpyrt_PyArgs_GET_ITEM(cargs.fArgs, i);
89 realsize += PyTuple_Check(item) ? PyTuple_GET_SIZE(item) : 1;
90 }
91
92 // unroll any tuples, if present in the arguments
93 if (realsize != nArgs) {
94 cpyrt_PyArgs_t packed_args = cargs.fArgs;
95 cargs.fArgs = (PyObject**)PyMem_Malloc(realsize * sizeof(PyObject*));
97 cargs.fNArgsf = realsize;
98 unroll(packed_args, cargs.fArgs, nArgs);
99 }
100
101 // continue normal method processing
102 return CPPMethod::ProcessArgs(cargs);
103}
static void unroll(cpyrt_PyArgs_t packed_args, cpyrt_PyArgs_t unrolled, Py_ssize_t nArgs)
_object PyObject
bool ProcessArgs(PyCallArgs &args) override
virtual bool InitExecutor_(Executor *&, CallContext *ctxt=nullptr)
std::string GetReturnTypeName()
virtual bool ProcessArgs(PyCallArgs &args)
bool InitExecutor_(Executor *&, CallContext *ctxt=nullptr) override
bool ProcessArgs(PyCallArgs &args) override
cpyrt_PyArgs_t fArgs
Definition CPPMethod.h:35
static PyObject * cpyrt_PyArgs_SET_ITEM(cpyrt_PyArgs_t args, Py_ssize_t i, PyObject *item)
Definition cpyrt.h:86
PyObject *const * cpyrt_PyArgs_t
Definition cpyrt.h:81
static Py_ssize_t cpyrt_PyArgs_GET_SIZE(cpyrt_PyArgs_t, size_t nargsf)
Definition cpyrt.h:90
static PyObject * cpyrt_PyArgs_GET_ITEM(cpyrt_PyArgs_t args, Py_ssize_t i)
Definition cpyrt.h:82
Definition API.cxx:34