Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CallContext.h
Go to the documentation of this file.
1#ifndef CPYRT_CALLCONTEXT_H
2#define CPYRT_CALLCONTEXT_H
3
4#include "Python.h"
5#include "cppjit_interop.h"
6
7// Standard
8#include <cstdint>
9#include <vector>
10
11#include <sys/types.h>
12
13namespace cppjit::cpyrt {
14
15// Parameter and the call-ABI constants (SMALL_ARGS_N, DIRECT_CALL) come
16// from the interop callcontext.h via cppjit_interop.h
17
18// extra call information
21 : fCurScope(nullptr), fPyContext(nullptr), fFlags(0), fArgsVec(nullptr),
22 fNArgs(0), fTemps(nullptr) {}
23 CallContext(const CallContext&) = delete;
26 if (fTemps)
27 Cleanup();
28 delete fArgsVec;
29 }
30
32 kNone = 0x000000,
33 kIsSorted = 0x000001, // if method overload priority determined
34 kIsCreator = 0x000002, // if method creates python-owned objects
35 kIsConstructor = 0x000004, // if method is a C++ constructor
36 kHaveImplicit = 0x000008, // indicate that implicit converters are available
37 kAllowImplicit = 0x000010, // indicate that implicit conversions are allowed
38 kNoImplicit = 0x000020, // disable implicit to prevent recursion
39 kCallDirect = 0x000040, // call wrapped method directly, no inheritance
40 kFromDescr = 0x000080, // initiated from a descriptor
41 kUseHeuristics = 0x000100, // if method applies heuristics memory policy
43 0x000200, // enable implicit conversion to smart pointers
44 kReleaseGIL = 0x000400, // if method should release the GIL
45 kSetLifeLine = 0x000800, // if return value is part of 'this'
46 kNeverLifeLine = 0x001000, // if the return value is never part of 'this'
47 kPyException = 0x002000, // Python exception during method execution
48 kCppException = 0x004000, // C++ exception during method execution
49 kProtected = 0x008000, // if method should return on signals
50 kUseFFI = 0x010000, // not implemented
51 kIsPseudoFunc = 0x020000, // internal, used for introspection
52 };
53
54 // Policies about memory handling and signal safety
55 static bool SetGlobalPolicy(ECallFlags e, bool enabled);
56
57 static uint32_t& GlobalPolicyFlags();
58
59 void AddTemporary(PyObject* pyobj);
60 void Cleanup();
61
62 Parameter* GetArgs(size_t sz) {
63 if (sz != (size_t)-1)
64 fNArgs = sz;
65 if (fNArgs <= SMALL_ARGS_N)
66 return fArgs;
67 if (!fArgsVec)
68 fArgsVec = new std::vector<Parameter>();
69 fArgsVec->resize(fNArgs);
70 return fArgsVec->data();
71 }
72
74 if (fNArgs <= SMALL_ARGS_N)
75 return fArgs;
76 return fArgsVec->data();
77 }
78
79 size_t GetSize() { return fNArgs; }
80 size_t GetEncodedSize() {
81 return fNArgs | ((fFlags & kCallDirect) ? DIRECT_CALL : 0);
82 }
83
84public:
85 // info/status
88 uint32_t fFlags;
89
90private:
95
96 // payload
98 std::vector<Parameter>* fArgsVec;
99 size_t fNArgs;
101};
102
103inline bool IsSorted(uint64_t flags) { return flags & CallContext::kIsSorted; }
104
105inline bool IsCreator(uint64_t flags) {
106 return flags & CallContext::kIsCreator;
107}
108
109inline bool IsConstructor(uint64_t flags) {
110 return flags & CallContext::kIsConstructor;
111}
112
113inline bool HaveImplicit(CallContext* ctxt) {
114 return ctxt ? (!(ctxt->fFlags & CallContext::kNoImplicit) &&
116 : false;
117}
118
119inline bool AllowImplicit(CallContext* ctxt) {
120 return ctxt ? (!(ctxt->fFlags & CallContext::kNoImplicit) &&
122 : false;
123}
124
125inline bool NoImplicit(CallContext* ctxt) {
126 return ctxt ? (ctxt->fFlags & CallContext::kNoImplicit) : false;
127}
128
129inline bool ReleasesGIL(CallContext* ctxt) {
130 return ctxt ? (ctxt->fFlags & CallContext::kReleaseGIL) : false;
131}
132
133inline bool UseStrictOwnership() {
135 return !(CC::GlobalPolicyFlags() & CC::kUseHeuristics);
136}
137
138// kImplicitSmartPtrConversion is a global policy (set through
139// cppyy.SetImplicitSmartPointerConversion), but it can also be requested for a
140// single call through the call context, so check both words - as is done for
141// kProtected in CPPMethod::Execute.
144 return (CC::GlobalPolicyFlags() & CC::kImplicitSmartPtrConversion) ||
145 (ctxt && (ctxt->fFlags & CC::kImplicitSmartPtrConversion));
146}
147
148template <CallContext::ECallFlags F> class CallContextRAII {
149public:
151 fPrior = fCtxt->fFlags & F;
152 fCtxt->fFlags |= F;
153 }
157 if (!fPrior)
158 fCtxt->fFlags &= ~F;
159 }
160
161private:
163 bool fPrior;
164};
165
166} // namespace cppjit::cpyrt
167
168#endif // !CPYRT_CALLCONTEXT_H
_object PyObject
#define e(i)
Definition RSha256.hxx:103
#define DIRECT_CALL
Definition callcontext.h:9
CallContextRAII(CallContext *ctxt)
CallContextRAII & operator=(const CallContextRAII &)=delete
CallContextRAII(const CallContextRAII &)=delete
bool IsConstructor(uint64_t flags)
bool IsSorted(uint64_t flags)
bool IsCreator(uint64_t flags)
bool NoImplicit(CallContext *ctxt)
bool AllowImplicit(CallContext *ctxt)
bool AllowImplicitSmartPtrConversion(CallContext *ctxt)
bool HaveImplicit(CallContext *ctxt)
bool ReleasesGIL(CallContext *ctxt)
bool UseStrictOwnership()
const int SMALL_ARGS_N
Definition callcontext.h:14
Cpp::DeclRef TCppScope_t
Definition API.h:41
static bool SetGlobalPolicy(ECallFlags e, bool enabled)
void AddTemporary(PyObject *pyobj)
Parameter fArgs[SMALL_ARGS_N]
Definition CallContext.h:97
std::vector< Parameter > * fArgsVec
Definition CallContext.h:98
CallContext(const CallContext &)=delete
static uint32_t & GlobalPolicyFlags()
CallContext & operator=(const CallContext &)=delete
Parameter * GetArgs(size_t sz)
Definition CallContext.h:62
interop::TCppScope_t fCurScope
Definition CallContext.h:86