Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CPPFunction.cxx
Go to the documentation of this file.
1// Bindings
2#include "cpyrt.h"
3
4using namespace cppjit;
5#include "CPPFunction.h"
6#include "CPPInstance.h"
7
8// Standard
9#include <algorithm>
10
11//- CFunction helpers
12//-----------------------------------------------------------
14 if (cargs.fNArgsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { // mutation allowed?
15 std::swap(((PyObject**)cargs.fArgs - 1)[0], (PyObject*&)cargs.fSelf);
16 cargs.fFlags |= PyCallArgs::kSelfSwap;
17 cargs.fArgs -= 1;
18 cargs.fNArgsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET;
19 cargs.fNArgsf += 1;
20 } else {
21 Py_ssize_t nkwargs = cargs.fKwds ? PyTuple_GET_SIZE(cargs.fKwds) : 0;
22 Py_ssize_t totalargs = PyVectorcall_NARGS(cargs.fNArgsf) + nkwargs;
23 PyObject** newArgs =
24 (PyObject**)PyMem_Malloc((totalargs + 1) * sizeof(PyObject*));
25 if (!newArgs)
26 return false;
27
28 newArgs[0] = (PyObject*)cargs.fSelf;
29 if (0 < totalargs)
30 memcpy((void*)&newArgs[1], cargs.fArgs, totalargs * sizeof(PyObject*));
31 cargs.fArgs = newArgs;
32 cargs.fFlags |= PyCallArgs::kDoFree;
33 cargs.fNArgsf += 1;
34 }
35 return true;
36}
37
39 // add self as part of the function arguments (means bound member)
40 if (cargs.fKwds)
41 return this->ProcessKwds((PyObject*)cargs.fSelf, cargs);
42 return AdjustSelf(cargs);
43}
44
45//- CPPFunction public members
46//--------------------------------------------------
48 size_t nargsf, PyObject* kwds,
49 CallContext* ctxt) {
50 // setup as necessary
51 if (fArgsRequired == -1 && !this->Initialize(ctxt))
52 return nullptr;
53
54 // if function was attached to a class, self will be non-zero and should be
55 // the first function argument, so reorder
56 PyCallArgs cargs{self, args, nargsf, kwds};
57 if (self || kwds) {
58 if (!this->ProcessArgs(cargs))
59 return nullptr;
60 }
61
62 // special case, if this method was inserted as a constructor, then self is
63 // nullptr and it will be the first argument and needs to be used as Python
64 // context
65 if (IsConstructor(ctxt->fFlags) && !ctxt->fPyContext &&
66 cpyrt_PyArgs_GET_SIZE(cargs.fArgs, cargs.fNArgsf)) {
67 ctxt->fPyContext = cargs.fArgs[0];
68 }
69
70 // translate the arguments as normal
71 if (!this->ConvertAndSetArgs(cargs.fArgs, cargs.fNArgsf, ctxt))
72 return nullptr;
73
74 // execute function
75 PyObject* result = this->Execute(nullptr, 0, ctxt);
76
77 // special case, if this method was inserted as a constructor, then if no self
78 // was provided, it will be the first argument and may have been updated
79 if (IsConstructor(ctxt->fFlags) && result && !cargs.fSelf &&
80 cpyrt_PyArgs_GET_SIZE(cargs.fArgs, cargs.fNArgsf) &&
81 CPPInstance_Check(cargs.fArgs[0])) {
82 self = (CPPInstance*)cargs.fArgs[0];
83 Py_INCREF(self);
84 }
85
86 return result;
87}
88
89//----------------------------------------------------------------------------
91 PyObject* cppname =
92 PyUnicode_FromString((GetReturnTypeName() + " (*)").c_str());
93 PyUnicode_AppendAndDel(&cppname, GetSignature(false /* show_formalargs */));
94 return cppname;
95}
96
97//- CPPReverseBinary private helper
98//---------------------------------------------
100 if (cargs.fSelf || cargs.fKwds) {
101 // add self as part of the function arguments (means bound member)
102 if (!this->CPPFunction::ProcessArgs(cargs))
103 return false;
104 }
105
106 // swap the arguments
107 std::swap(((PyObject**)cargs.fArgs)[0], ((PyObject**)cargs.fArgs)[1]);
109
110 return true;
111}
112
113//- CPPReverseBinary public members
114//---------------------------------------------
116 size_t nargsf, PyObject* kwds,
117 CallContext* ctxt) {
118 // This Call() function is very similar to the one of CPPFunction: only
119 // difference is that ProcessArgs() is always called.
120
121 // setup as necessary
122 if (fArgsRequired == -1 && !this->Initialize(ctxt))
123 return nullptr;
124
125 // if function was attached to a class, self will be non-zero and should be
126 // the first function argument, further, the arguments needs swapping
127 PyCallArgs cargs{self, args, nargsf, kwds};
128 if (!this->ProcessArgs(cargs))
129 return nullptr;
130
131 // translate the arguments as normal
132 if (!this->ConvertAndSetArgs(cargs.fArgs, cargs.fNArgsf, ctxt))
133 return nullptr;
134
135 // execute function
136 return this->Execute(nullptr, 0, ctxt);
137}
_object PyObject
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
bool ProcessArgs(PyCallArgs &args) override
PyObject * Call(CPPInstance *&self, cpyrt_PyArgs_t args, size_t nargsf, PyObject *kwds, CallContext *ctxt=nullptr) override
PyObject * GetTypeName() override
bool ProcessKwds(PyObject *self_in, PyCallArgs &args)
PyObject * Call(CPPInstance *&self, cpyrt_PyArgs_t args, size_t nargsf, PyObject *kwds, CallContext *ctxt=nullptr) override
bool ProcessArgs(PyCallArgs &args) override
cpyrt_PyArgs_t fArgs
Definition CPPMethod.h:35
CPPInstance *& fSelf
Definition CPPMethod.h:34
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
bool IsConstructor(uint64_t flags)
bool AdjustSelf(PyCallArgs &cargs)
bool CPPInstance_Check(T *object)
Definition API.cxx:34