14 #include "TClassEdit.h" 41 if ( fRelease ) fSave = PyEval_SaveThread();
46 if ( fRelease ) PyEval_RestoreThread( fSave );
56 #define PYROOT_IMPL_GILCALL( rtype, tcode ) \ 57 static inline rtype GILCall##tcode( \ 58 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, PyROOT::TCallContext* ctxt ) {\ 59 GILControl gc( ctxt ); \ 60 return Cppyy::Call##tcode( method, self, &ctxt->fArgs ); \ 78 GILControl gc( ctxt );
79 return Cppyy::CallO( method,
self, &ctxt->fArgs, klass );
84 GILControl gc( ctxt );
102 PyObject* PyROOT::TBoolExecutor::Execute(
106 Bool_t retval = GILCallB( method,
self, ctxt );
115 PyObject* PyROOT::TBoolConstRefExecutor::Execute(
125 PyObject* PyROOT::TCharExecutor::Execute(
135 PyObject* PyROOT::TCharConstRefExecutor::Execute(
145 PyObject* PyROOT::TUCharExecutor::Execute(
155 PyObject* PyROOT::TUCharConstRefExecutor::Execute(
164 PyObject* PyROOT::TIntExecutor::Execute(
167 return PyInt_FromLong( (
Int_t)GILCallI( method,
self, ctxt ) );
173 PyObject* PyROOT::TShortExecutor::Execute(
176 return PyInt_FromLong( (
Short_t)GILCallH( method,
self, ctxt ) );
182 PyObject* PyROOT::TLongExecutor::Execute(
185 return PyLong_FromLong( (
Long_t)GILCallL( method,
self, ctxt ) );
191 PyObject* PyROOT::TULongExecutor::Execute(
194 return PyLong_FromUnsignedLong( (
ULong_t)GILCallLL( method,
self, ctxt ) );
200 PyObject* PyROOT::TLongLongExecutor::Execute(
204 return PyLong_FromLongLong( result );
210 PyObject* PyROOT::TULongLongExecutor::Execute(
220 PyObject* PyROOT::TFloatExecutor::Execute(
223 return PyFloat_FromDouble( (
Double_t)GILCallF( method,
self, ctxt ) );
229 PyObject* PyROOT::TDoubleExecutor::Execute(
232 return PyFloat_FromDouble( (
Double_t)GILCallD( method,
self, ctxt ) );
238 PyObject* PyROOT::TLongDoubleExecutor::Execute(
241 return PyFloat_FromDouble( (
Double_t)GILCallLD( method,
self, ctxt ) );
249 if ( pyobject != 0 ) {
250 Py_INCREF( pyobject );
251 fAssignable = pyobject;
261 #define PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( name, type, stype, F1, F2 ) \ 262 PyObject* PyROOT::T##name##RefExecutor::Execute( \ 263 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, TCallContext* ctxt )\ 265 type* ref = (type*)GILCallR( method, self, ctxt ); \ 266 if ( ! fAssignable ) \ 267 return F1( (stype)*ref ); \ 269 *ref = (type)F2( fAssignable ); \ 270 Py_DECREF( fAssignable ); \ 272 Py_INCREF( Py_None ); \ 293 LongDouble,
LongDouble_t, LongDouble_t, PyFloat_FromDouble, PyFloat_AsDouble )
301 if ( ! fAssignable ) {
302 std::string*
result = (std::string*)GILCallR( method,
self, ctxt );
305 std::string*
result = (std::string*)GILCallR( method,
self, ctxt );
306 *result = std::string(
309 Py_DECREF( fAssignable );
312 Py_INCREF( Py_None );
320 PyObject* PyROOT::TVoidExecutor::Execute(
323 GILCallV( method,
self, ctxt );
324 Py_INCREF( Py_None );
331 PyObject* PyROOT::TCStringExecutor::Execute(
334 char*
result = (
char*)GILCallS( method,
self, ctxt );
345 PyObject* PyROOT::TVoidArrayExecutor::Execute(
359 #define PYROOT_IMPLEMENT_ARRAY_EXECUTOR( name, type ) \ 360 PyObject* PyROOT::T##name##ArrayExecutor::Execute( \ 361 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, TCallContext* ctxt )\ 363 return BufFac_t::Instance()->PyBuffer_FromMemory( (type*)GILCallR( method, self, ctxt ) );\ 378 PyObject* PyROOT::TSTLStringExecutor::Execute(
384 std::string*
result = (std::string*)
GILCallO( method,
self, ctxt, sSTLStringScope );
400 PyObject* PyROOT::TTGlobalExecutor::Execute(
412 return BindCppObject( (
void*)GILCallR( method,
self, ctxt ), fClass );
424 if ( ! PyErr_Occurred() )
425 PyErr_SetString( PyExc_ValueError,
"NULL result where temporary expected" );
447 if ( ! result || ! fAssignable )
451 PyObject* assign = PyObject_GetAttrString( result, const_cast< char* >(
"__assign__" ) );
454 PyObject* descr = PyObject_Str( result );
456 PyErr_Format( PyExc_TypeError,
"can not assign to return object (%s)",
459 PyErr_SetString( PyExc_TypeError,
"can not assign to result" );
463 Py_DECREF( fAssignable ); fAssignable = 0;
467 PyObject* res2 = PyObject_CallFunction( assign, const_cast< char* >(
"O" ), fAssignable );
471 Py_DECREF( fAssignable ); fAssignable = 0;
475 Py_INCREF( Py_None );
511 if ( ! PyErr_Occurred() )
512 PyErr_SetString( PyExc_ValueError,
"NULL result where temporary expected" );
611 return BindCppObjectArray( (
void*)GILCallR( method,
self, ctxt ), fClass, fArraySize );
618 PyObject* PyROOT::TConstructorExecutor::Execute(
627 PyObject* PyROOT::TPyObjectExecutor::Execute(
630 return (
PyObject*)GILCallR( method,
self, ctxt );
649 return (h->second)();
657 return (h->second)();
661 std::string realType = TClassEdit::ShortType( resolvedType.c_str(), 1 );
666 return (h->second)();
673 realType = TClassEdit::CleanType( realType.substr( 0, realType.rfind(
"(") ).c_str(), 1 );
677 return (h->second)();
685 if ( ! methods.empty() ) {
691 }
else if ( cpd ==
"*" ) {
693 }
else if ( cpd ==
"&" ) {
707 else if ( cpd ==
"&" )
709 else if ( cpd ==
"**" )
711 else if ( cpd ==
"*&" || cpd ==
"&*" )
713 else if ( cpd ==
"[]" ) {
728 s <<
"creating executor for unknown type \"" << fullType <<
"\"" << std::ends;
729 PyErr_Warn( PyExc_RuntimeWarning, (
char*)s.str().c_str() );
736 result = (h->second)();
743 #define PYROOT_EXECUTOR_FACTORY( name ) \ 744 TExecutor* Create##name##Executor() \ 746 return new T##name##Executor; \ 802 typedef std::pair< const char*, ExecutorFactory_t > NFp_t;
804 NFp_t factories_[] = {
806 NFp_t(
"bool", &CreateBoolExecutor ),
807 NFp_t(
"bool&", &CreateBoolRefExecutor ),
808 NFp_t(
"const bool&", &CreateBoolConstRefExecutor ),
809 NFp_t(
"char", &CreateCharExecutor ),
810 NFp_t(
"signed char", &CreateCharExecutor ),
811 NFp_t(
"unsigned char", &CreateUCharExecutor ),
812 NFp_t(
"char&", &CreateCharRefExecutor ),
813 NFp_t(
"signed char&", &CreateCharRefExecutor ),
814 NFp_t(
"unsigned char&", &CreateUCharRefExecutor ),
815 NFp_t(
"const char&", &CreateCharConstRefExecutor ),
816 NFp_t(
"const signed char&", &CreateCharConstRefExecutor ),
817 NFp_t(
"const unsigned char&", &CreateUCharConstRefExecutor ),
818 NFp_t(
"short", &CreateShortExecutor ),
819 NFp_t(
"short&", &CreateShortRefExecutor ),
820 NFp_t(
"unsigned short", &CreateIntExecutor ),
821 NFp_t(
"unsigned short&", &CreateUShortRefExecutor ),
822 NFp_t(
"int", &CreateIntExecutor ),
823 NFp_t(
"int&", &CreateIntRefExecutor ),
824 NFp_t(
"unsigned int", &CreateULongExecutor ),
825 NFp_t(
"unsigned int&", &CreateUIntRefExecutor ),
826 NFp_t(
"UInt_t", &CreateULongExecutor ),
827 NFp_t(
"UInt_t&", &CreateUIntRefExecutor ),
828 NFp_t(
"long", &CreateLongExecutor ),
829 NFp_t(
"long&", &CreateLongRefExecutor ),
830 NFp_t(
"unsigned long", &CreateULongExecutor ),
831 NFp_t(
"unsigned long&", &CreateULongRefExecutor ),
832 NFp_t(
"long long", &CreateLongLongExecutor ),
833 NFp_t(
"Long64_t", &CreateLongLongExecutor ),
834 NFp_t(
"long long&", &CreateLongLongRefExecutor ),
835 NFp_t(
"Long64_t&", &CreateLongLongRefExecutor ),
836 NFp_t(
"unsigned long long", &CreateULongLongExecutor ),
837 NFp_t(
"ULong64_t", &CreateULongLongExecutor ),
838 NFp_t(
"unsigned long long&", &CreateULongLongRefExecutor ),
839 NFp_t(
"ULong64_t&", &CreateULongLongRefExecutor ),
841 NFp_t(
"float", &CreateFloatExecutor ),
842 NFp_t(
"float&", &CreateFloatRefExecutor ),
843 NFp_t(
"Float16_t", &CreateFloatExecutor ),
844 NFp_t(
"Float16_t&", &CreateFloatRefExecutor ),
845 NFp_t(
"double", &CreateDoubleExecutor ),
846 NFp_t(
"double&", &CreateDoubleRefExecutor ),
847 NFp_t(
"Double32_t", &CreateDoubleExecutor ),
848 NFp_t(
"Double32_t&", &CreateDoubleRefExecutor ),
849 NFp_t(
"long double", &CreateLongDoubleExecutor ),
850 NFp_t(
"long double&", &CreateLongDoubleRefExecutor ),
851 NFp_t(
"void", &CreateVoidExecutor ),
854 NFp_t(
"void*", &CreateVoidArrayExecutor ),
855 NFp_t(
"bool*", &CreateBoolArrayExecutor ),
856 NFp_t(
"short*", &CreateShortArrayExecutor ),
857 NFp_t(
"unsigned short*", &CreateUShortArrayExecutor ),
858 NFp_t(
"int*", &CreateIntArrayExecutor ),
859 NFp_t(
"unsigned int*", &CreateUIntArrayExecutor ),
860 NFp_t(
"UInt_t*", &CreateUIntArrayExecutor ),
861 NFp_t(
"long*", &CreateLongArrayExecutor ),
862 NFp_t(
"unsigned long*", &CreateULongArrayExecutor ),
863 NFp_t(
"float*", &CreateFloatArrayExecutor ),
864 NFp_t(
"double*", &CreateDoubleArrayExecutor ),
867 NFp_t(
"const char*", &CreateCStringExecutor ),
868 NFp_t(
"char*", &CreateCStringExecutor ),
869 NFp_t(
"std::string", &CreateSTLStringExecutor ),
870 NFp_t(
"string", &CreateSTLStringExecutor ),
871 NFp_t(
"std::string&", &CreateSTLStringRefExecutor ),
872 NFp_t(
"string&", &CreateSTLStringRefExecutor ),
873 NFp_t(
"TGlobal*", &CreateTGlobalExecutor ),
874 NFp_t(
"__init__", &CreateConstructorExecutor ),
875 NFp_t(
"PyObject*", &CreatePyObjectExecutor ),
876 NFp_t(
"_object*", &CreatePyObjectExecutor ),
877 NFp_t(
"FILE*", &CreateVoidArrayExecutor )
880 struct InitExecFactories_t {
882 InitExecFactories_t()
885 int nf =
sizeof( factories_ ) /
sizeof( factories_[ 0 ] );
886 for (
int i = 0; i < nf; ++i ) {
890 } initExecvFactories_;
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
#define PyBytes_CheckExact
static PyObject * PyROOT_PyBool_FromInt(Int_t b)
#define PyROOT_PyUnicode_FromString
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python ROOT object (ignoring ref) return ptr v...
#define PyROOT_PyUnicode_GET_SIZE
#define PYROOT_EXECUTOR_FACTORY(name)
RooArgList L(const RooAbsArg &v1)
TExecutor * CreateExecutor(const std::string &fullType, Bool_t manage_smart_ptr=kTRUE)
std::vector< TCppMethod_t > GetMethodsFromName(TCppScope_t scope, const std::string &name)
#define PYROOT_IMPLEMENT_ARRAY_EXECUTOR(name, type)
ExecFactories_t gExecFactories
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Int_t size)
TODO: this function exists for symmetry; need to figure out if it's useful.
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python ROOT object return ptr value ...
TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, void *args, TCppType_t result_type)
std::vector< TParameter > fArgs
TCppObject_t CallConstructor(TCppMethod_t method, TCppType_t type, void *args)
Bool_t ReleasesGIL(UInt_t flags)
#define PyROOT_PyUnicode_FromFormat
std::string ResolveName(const std::string &cppitem_name)
static Cppyy::TCppObject_t GILCallConstructor(Cppyy::TCppMethod_t method, Cppyy::TCppType_t klass, PyROOT::TCallContext *ctxt)
PyLong_FromUnsignedLongLong
void SetSmartPtr(void *address, Cppyy::TCppType_t ptrType)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct TTupleOfInstances from return value ...
#define PyROOT_PyUnicode_AsString
R__EXTERN PyObject * gNullPtrObject
ULong_t PyLongOrInt_AsULong(PyObject *pyobject)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
smart pointer excutor
RooArgSet S(const RooAbsArg &v1)
#define PYROOT_IMPL_GILCALL(rtype, tcode)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python proxy object return value ...
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execution will bring a temporary in existence
#define PyROOT_PyUnicode_FromStringAndSize
PyObject * BindCppGlobal(TGlobal *)
gbl == 0 means global does not exist (rather than gbl is NULL pointer)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
smart pointer excutor
ULong64_t PyLongOrInt_AsULong64(PyObject *pyobject)
Convert <pyobject> to C++ unsigned long long, with bounds checking.
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE, Bool_t isValue=kFALSE)
only known or knowable objects will be bound (null object is ok)
virtual Bool_t SetAssignable(PyObject *)
prepare "buffer" for by-ref returns, used with setitem
Global variables class (global variables are obtained from CINT).
static Cppyy::TCppObject_t GILCallO(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, PyROOT::TCallContext *ctxt, Cppyy::TCppType_t klass)
PyObject * PyBuffer_FromMemory(Bool_t *buf, Py_ssize_t size=-1)
#define PYROOT_IMPLEMENT_BASIC_REFEXECUTOR(name, type, stype, F1, F2)
TCppScope_t GetScope(const std::string &scope_name)
std::string GetMethodResultType(TCppMethod_t)
unsigned long long ULong64_t
Bool_t IsSmartPtr(const std::string &)
static TPyBufferFactory * Instance()
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
executor binds the result to the left-hand side, overwriting if an old object
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
std::map< std::string, ExecutorFactory_t > ExecFactories_t
Py_ssize_t ArraySize(const std::string &name)
Extract size from an array type, if available.
#define PyBytes_AS_STRING
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE)
if the object is a null pointer, return a typed one (as needed for overloading)
Bool_t IsEnum(const std::string &type_name)
R__EXTERN PyObject * gEmptyString
static PyObject * PyROOT_PyUnicode_FromInt(Int_t c)
const std::string Compound(const std::string &name)
Break down the compound of a fully qualified type name.