Executors.cxx

Go to the documentation of this file.
00001 // @(#)root/pyroot:$Id: Executors.cxx 37357 2010-12-06 22:22:35Z wlav $
00002 // Author: Wim Lavrijsen, Jan 2005
00003 
00004 // Bindings
00005 #include "PyROOT.h"
00006 #include "PyStrings.h"
00007 #include "Executors.h"
00008 #include "ObjectProxy.h"
00009 #include "PyBufferFactory.h"
00010 #include "RootWrapper.h"
00011 #include "Utility.h"
00012 
00013 // ROOT
00014 #include "TClass.h"
00015 #include "TClassEdit.h"
00016 #include "DllImport.h"
00017 
00018 // CINT
00019 #include "Api.h"
00020 
00021 // Standard
00022 #include <utility>
00023 #include <sstream>
00024 #include <Riostream.h>
00025 
00026 
00027 //- data ______________________________________________________________________
00028 PyROOT::ExecFactories_t PyROOT::gExecFactories;
00029 
00030 
00031 //- executors for built-ins ---------------------------------------------------
00032 PyObject* PyROOT::TBoolExecutor::Execute( G__CallFunc* func, void* self )
00033 {
00034 // execute <func> with argument <self>, construct python bool return value
00035    PyObject* result = (bool)func->ExecInt( self ) ? Py_True : Py_False;
00036    Py_INCREF( result );
00037    return result;
00038 }
00039 
00040 PyObject* PyROOT::TLongExecutor::Execute( G__CallFunc* func, void* self )
00041 {
00042 // execute <func> with argument <self>, construct python long return value
00043    return PyLong_FromLong( (Long_t)func->ExecInt( self ) );
00044 }
00045 
00046 //____________________________________________________________________________
00047 PyObject* PyROOT::TCharExecutor::Execute( G__CallFunc* func, void* self )
00048 {
00049 // execute <func> with argument <self>, construct python string return value
00050    return PyROOT_PyUnicode_FromFormat( "%c", (int)func->ExecInt( self ) );
00051 }
00052 
00053 //____________________________________________________________________________
00054 PyObject* PyROOT::TIntExecutor::Execute( G__CallFunc* func, void* self )
00055 {
00056 // execute <func> with argument <self>, construct python int return value
00057    return PyInt_FromLong( (Long_t)func->ExecInt( self ) );
00058 }
00059 
00060 //____________________________________________________________________________
00061 PyObject* PyROOT::TULongExecutor::Execute( G__CallFunc* func, void* self )
00062 {
00063 // execute <func> with argument <self>, construct python unsigned long return value
00064    return PyLong_FromUnsignedLong( (ULong_t)func->ExecInt( self ) );
00065 }
00066 
00067 //____________________________________________________________________________
00068 PyObject* PyROOT::TLongLongExecutor::Execute( G__CallFunc* func, void* self )
00069 {
00070 // execute <func> with argument <self>, construct python long long return value
00071    return PyLong_FromLongLong( (Long64_t)G__Longlong( func->Execute( self ) ) );
00072 }
00073 
00074 //____________________________________________________________________________
00075 PyObject* PyROOT::TULongLongExecutor::Execute( G__CallFunc* func, void* self )
00076 {
00077 // execute <func> with argument <self>, construct python unsigned long long return value
00078    return PyLong_FromUnsignedLongLong( (ULong64_t)G__ULonglong( func->Execute( self ) ) );
00079 }
00080 
00081 //____________________________________________________________________________
00082 PyObject* PyROOT::TDoubleExecutor::Execute( G__CallFunc* func, void* self )
00083 {
00084 // execute <func> with argument <self>, construct python float return value
00085    return PyFloat_FromDouble( (double)func->ExecDouble( self ) );
00086 }
00087 
00088 //____________________________________________________________________________
00089 Bool_t PyROOT::TRefExecutor::SetAssignable( PyObject* pyobject )
00090 {
00091 // prepare "buffer" for by-ref returns, used with __setitem__
00092    if ( pyobject != 0 ) {
00093       Py_INCREF( pyobject );
00094       fAssignable = pyobject;
00095       return kTRUE;
00096    }
00097 
00098    fAssignable = 0;
00099    return kFALSE;
00100 }
00101 
00102 //____________________________________________________________________________
00103 #define PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( name, type, stype, F1, F2, CF )  \
00104 PyObject* PyROOT::T##name##RefExecutor::Execute( G__CallFunc* func, void* self )\
00105 {                                                                            \
00106    if ( ! fAssignable )                                                      \
00107       return F1( (stype)func->CF( self ) );                                  \
00108    else {                                                                    \
00109       const G__value& result = func->Execute( self );                        \
00110       *((type*)result.ref) = (type)F2( fAssignable );                        \
00111       Py_DECREF( fAssignable );                                              \
00112       fAssignable = 0;                                                       \
00113       Py_INCREF( Py_None );                                                  \
00114       return Py_None;                                                        \
00115    }                                                                         \
00116 }
00117 
00118 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Short,  Short_t,  Long_t,   PyInt_FromLong,     PyLong_AsLong,    ExecInt )
00119 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( UShort, UShort_t, ULong_t,  PyInt_FromLong,     PyLongOrInt_AsULong, ExecInt )
00120 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Int,    Int_t,    Long_t,   PyInt_FromLong,     PyLong_AsLong,    ExecInt )
00121 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( UInt,   UInt_t,   ULong_t,  PyLong_FromUnsignedLong, PyLongOrInt_AsULong, ExecInt )
00122 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Long,   Long_t,   Long_t,   PyLong_FromLong,    PyLong_AsLong,    ExecInt )
00123 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( ULong,  ULong_t,  ULong_t,  PyLong_FromUnsignedLong, PyLongOrInt_AsULong, ExecInt )
00124 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Float,  Float_t,  Double_t, PyFloat_FromDouble, PyFloat_AsDouble, ExecDouble )
00125 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Double, Double_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble, ExecDouble )
00126 
00127 //____________________________________________________________________________
00128 PyObject* PyROOT::TSTLStringRefExecutor::Execute( G__CallFunc* func, void* self )
00129 {
00130 // execute <func> with argument <self>, return python string return value
00131    if ( ! fAssignable ) {
00132       return PyROOT_PyUnicode_FromString( ((std::string*)func->ExecInt( self ))->c_str() );
00133    } else {
00134       std::string* result = (std::string*)func->ExecInt( self );
00135       *result = std::string( PyROOT_PyUnicode_AsString( fAssignable ) );
00136 
00137       Py_DECREF( fAssignable );
00138       fAssignable = 0;
00139 
00140       Py_INCREF( Py_None );
00141       return Py_None;
00142    }
00143 }
00144 
00145 //____________________________________________________________________________
00146 PyObject* PyROOT::TVoidExecutor::Execute( G__CallFunc* func, void* self )
00147 {
00148 // execute <func> with argument <self>, return None
00149    func->Exec( self );
00150    Py_INCREF( Py_None );
00151    return Py_None;
00152 }
00153 
00154 //____________________________________________________________________________
00155 PyObject* PyROOT::TCStringExecutor::Execute( G__CallFunc* func, void* self )
00156 {
00157 // execute <func> with argument <self>, construct python string return value
00158    char* result = (char*)func->ExecInt( self );
00159    if ( ! result ) {
00160       Py_INCREF( PyStrings::gEmptyString );
00161       return PyStrings::gEmptyString;
00162    }
00163 
00164    return PyROOT_PyUnicode_FromString( result );
00165 }
00166 
00167 
00168 //- pointer/array executors ---------------------------------------------------
00169 PyObject* PyROOT::TVoidArrayExecutor::Execute( G__CallFunc* func, void* self )
00170 {
00171 // execute <func> with argument <self>, construct python long return value
00172    return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)func->ExecInt( self ), 1 );
00173 }
00174 
00175 //____________________________________________________________________________
00176 #define PYROOT_IMPLEMENT_ARRAY_EXECUTOR( name, type )                        \
00177 PyObject* PyROOT::T##name##ArrayExecutor::Execute( G__CallFunc* func, void* self )\
00178 {                                                                            \
00179    return BufFac_t::Instance()->PyBuffer_FromMemory( (type*)func->ExecInt( self ) );\
00180 }
00181 
00182 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( Short,  Short_t )
00183 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( UShort, UShort_t )
00184 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( Int,    Int_t )
00185 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( UInt,   UInt_t )
00186 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( Long,   Long_t )
00187 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( ULong,  ULong_t )
00188 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( Float,  Float_t )
00189 PYROOT_IMPLEMENT_ARRAY_EXECUTOR( Double, Double_t )
00190 
00191 
00192 //- special cases ------------------------------------------------------------
00193 PyObject* PyROOT::TSTLStringExecutor::Execute( G__CallFunc* func, void* self )
00194 {
00195 // execute <func> with argument <self>, construct python string return value
00196    std::string* result = (std::string*)func->ExecInt( self );
00197    if ( ! result ) {
00198       Py_INCREF( PyStrings::gEmptyString );
00199       return PyStrings::gEmptyString;
00200    }
00201 
00202    PyObject* pyresult = PyROOT_PyUnicode_FromString( result->c_str() );
00203 
00204 // stop CINT from tracking the object, then force delete
00205    G__pop_tempobject_nodel();
00206    delete result;
00207 
00208    return pyresult;
00209 }
00210 
00211 //____________________________________________________________________________
00212 PyObject* PyROOT::TTGlobalExecutor::Execute( G__CallFunc* func, void* self )
00213 {
00214 // execute <func> with argument <self>, construct python ROOT object return value
00215    return BindRootGlobal( (TGlobal*)func->ExecInt( self ) );
00216 }
00217 
00218 //____________________________________________________________________________
00219 PyObject* PyROOT::TRootObjectExecutor::Execute( G__CallFunc* func, void* self )
00220 {
00221 // execute <func> with argument <self>, construct python ROOT object return value
00222    return BindRootObject( (void*)func->ExecInt( self ), fClass );
00223 }
00224 
00225 //____________________________________________________________________________
00226 PyObject* PyROOT::TRootObjectByValueExecutor::Execute( G__CallFunc* func, void* self )
00227 {
00228 // execution will bring a temporary in existence
00229    void* result = (void*)func->ExecInt( self );
00230    if ( ! result ) {
00231       if ( ! PyErr_Occurred() )         // callee may have set a python error itself
00232          PyErr_SetString( PyExc_ValueError, "NULL result where temporary expected" );
00233       return 0;
00234    }
00235 
00236 // stop CINT from tracking the object, so that ownership is ours
00237    G__pop_tempobject_nodel();
00238 
00239 // the result can then be bound
00240    ObjectProxy* pyobj = (ObjectProxy*)BindRootObjectNoCast( result, fClass );
00241    if ( ! pyobj )
00242       return 0;
00243 
00244 // python ref counting will now control this object's life span
00245    pyobj->fFlags |= ObjectProxy::kIsOwner;
00246    return (PyObject*)pyobj;
00247 }
00248 
00249 //____________________________________________________________________________
00250 PyObject* PyROOT::TRootObjectRefExecutor::Execute( G__CallFunc* func, void* self )
00251 {
00252    PyObject* result = BindRootObject( (void*)func->ExecInt( self ), fClass );
00253    if ( ! result || ! fAssignable )
00254       return result;
00255    else {
00256    // this generic code is quite slow compared to its C++ equivalent ...
00257       PyObject* res2 = PyObject_CallMethod( result,
00258          const_cast< char* >( "__assign__" ), const_cast< char* >( "O" ), fAssignable );
00259 
00260       Py_DECREF( result );
00261       Py_DECREF( fAssignable );
00262       fAssignable = 0;
00263 
00264       if ( res2 ) {
00265          Py_DECREF( res2 );             // typically, *this from operator=()
00266          Py_INCREF( Py_None );
00267          return Py_None;
00268       }
00269 
00270       return 0;
00271    }
00272 }
00273 
00274 //____________________________________________________________________________
00275 PyObject* PyROOT::TConstructorExecutor::Execute( G__CallFunc* func, void* klass )
00276 {
00277 // package return address in PyObject* for caller to handle appropriately
00278    return (PyObject*)func->ExecInt( klass );
00279 }
00280 
00281 //____________________________________________________________________________
00282 PyObject* PyROOT::TPyObjectExecutor::Execute( G__CallFunc* func, void* self )
00283 {
00284 // execute <func> with argument <self>, return python object
00285    return (PyObject*)func->ExecInt( self );
00286 }
00287 
00288 
00289 //- factories -----------------------------------------------------------------
00290 PyROOT::TExecutor* PyROOT::CreateExecutor( const std::string& fullType )
00291 {
00292 // The matching of the fulltype to an executor factory goes through up to 4 levels:
00293 //   1) full, qualified match
00294 //   2) drop '&' as as by ref/full type is often pretty much the same python-wise
00295 //   3) ROOT classes, either by ref/ptr or by value
00296 //   4) additional special case for enums
00297 //
00298 // If all fails, void is used, which will cause the return type to be ignored on use
00299 
00300 // resolve typedefs etc., and collect qualifiers
00301    G__TypeInfo ti( fullType.c_str() );
00302    std::string resolvedType = ti.TrueName();
00303    if ( ! ti.IsValid() )
00304       resolvedType = fullType;     // otherwise, resolvedType will be "(unknown)"
00305    const std::string& cpd = Utility::Compound( resolvedType );
00306    std::string realType = TClassEdit::ShortType( resolvedType.c_str(), 1 );
00307 
00308 // a full, qualified matching executor is preferred
00309    ExecFactories_t::iterator h = gExecFactories.find( realType + cpd );
00310    if ( h != gExecFactories.end() )
00311       return (h->second)();
00312 
00313 // accept ref as by value
00314    if ( cpd == "&" ) {
00315       h = gExecFactories.find( realType );
00316       if ( h != gExecFactories.end() )
00317          return (h->second)();
00318    }
00319 
00320 // ROOT classes and special cases (enum)
00321    TExecutor* result = 0;
00322    if ( TClass* klass = TClass::GetClass( realType.c_str() ) ) {
00323       if ( cpd == "" )
00324          result = new TRootObjectByValueExecutor( klass );
00325       else if ( cpd == "&" )
00326          result = new TRootObjectRefExecutor( klass );
00327       else
00328          result = new TRootObjectExecutor( klass );
00329    } else {
00330    // could still be an enum ...
00331       if ( ti.Property() & G__BIT_ISENUM )
00332          h = gExecFactories.find( "UInt_t" );
00333       else {
00334          std::stringstream s;
00335          s << "return type not handled (using void): " << fullType << std::ends;
00336          PyErr_Warn( PyExc_RuntimeWarning, (char*)s.str().c_str() );
00337          h = gExecFactories.find( "void" );
00338       }
00339    }
00340 
00341    if ( ! result && h != gExecFactories.end() )
00342    // executor factory available, use it to create executor
00343       result = (h->second)();
00344 
00345    return result;                  // may still be null
00346 }
00347 
00348 //____________________________________________________________________________
00349 #define PYROOT_EXECUTOR_FACTORY( name )                \
00350 TExecutor* Create##name##Executor()                    \
00351 {                                                      \
00352    return new T##name##Executor;                       \
00353 }
00354 
00355 namespace {
00356 
00357    using namespace PyROOT;
00358 
00359 // use macro rather than template for portability ...
00360    PYROOT_EXECUTOR_FACTORY( Bool )
00361    PYROOT_EXECUTOR_FACTORY( Char )
00362    PYROOT_EXECUTOR_FACTORY( ShortRef )
00363    PYROOT_EXECUTOR_FACTORY( UShortRef )
00364    PYROOT_EXECUTOR_FACTORY( Int )
00365    PYROOT_EXECUTOR_FACTORY( IntRef )
00366    PYROOT_EXECUTOR_FACTORY( UIntRef )
00367    PYROOT_EXECUTOR_FACTORY( ULong )
00368    PYROOT_EXECUTOR_FACTORY( ULongRef )
00369    PYROOT_EXECUTOR_FACTORY( Long )
00370    PYROOT_EXECUTOR_FACTORY( LongRef )
00371    PYROOT_EXECUTOR_FACTORY( FloatRef )
00372    PYROOT_EXECUTOR_FACTORY( Double )
00373    PYROOT_EXECUTOR_FACTORY( DoubleRef )
00374    PYROOT_EXECUTOR_FACTORY( Void )
00375    PYROOT_EXECUTOR_FACTORY( LongLong )
00376    PYROOT_EXECUTOR_FACTORY( ULongLong )
00377    PYROOT_EXECUTOR_FACTORY( CString )
00378    PYROOT_EXECUTOR_FACTORY( VoidArray )
00379    PYROOT_EXECUTOR_FACTORY( ShortArray )
00380    PYROOT_EXECUTOR_FACTORY( UShortArray )
00381    PYROOT_EXECUTOR_FACTORY( IntArray )
00382    PYROOT_EXECUTOR_FACTORY( UIntArray )
00383    PYROOT_EXECUTOR_FACTORY( LongArray )
00384    PYROOT_EXECUTOR_FACTORY( ULongArray )
00385    PYROOT_EXECUTOR_FACTORY( FloatArray )
00386    PYROOT_EXECUTOR_FACTORY( DoubleArray )
00387    PYROOT_EXECUTOR_FACTORY( STLString )
00388    PYROOT_EXECUTOR_FACTORY( STLStringRef )
00389    PYROOT_EXECUTOR_FACTORY( TGlobal )
00390    PYROOT_EXECUTOR_FACTORY( Constructor )
00391    PYROOT_EXECUTOR_FACTORY( PyObject )
00392 
00393 // executor factories for ROOT types
00394    typedef std::pair< const char*, ExecutorFactory_t > NFp_t;
00395 
00396    NFp_t factories_[] = {
00397    // factories for built-ins
00398       NFp_t( "char",               &CreateCharExecutor                ),
00399       NFp_t( "unsigned char",      &CreateCharExecutor                ),
00400       NFp_t( "short",              &CreateIntExecutor                 ),
00401       NFp_t( "short&",             &CreateShortRefExecutor            ),
00402       NFp_t( "unsigned short",     &CreateIntExecutor                 ),
00403       NFp_t( "unsigned short&",    &CreateUShortRefExecutor           ),
00404       NFp_t( "int",                &CreateIntExecutor                 ),
00405       NFp_t( "int&",               &CreateIntRefExecutor              ),
00406       NFp_t( "unsigned int",       &CreateULongExecutor               ),
00407       NFp_t( "unsigned int&",      &CreateUIntRefExecutor             ),
00408       NFp_t( "UInt_t", /* enum */  &CreateULongExecutor               ),
00409       NFp_t( "long",               &CreateLongExecutor                ),
00410       NFp_t( "long&",              &CreateLongRefExecutor             ),
00411       NFp_t( "unsigned long",      &CreateULongExecutor               ),
00412       NFp_t( "unsigned long&",     &CreateULongRefExecutor            ),
00413       NFp_t( "long long",          &CreateLongLongExecutor            ),
00414       NFp_t( "unsigned long long", &CreateULongLongExecutor           ),
00415       NFp_t( "float",              &CreateDoubleExecutor              ),
00416       NFp_t( "float&",             &CreateFloatRefExecutor            ),
00417       NFp_t( "double",             &CreateDoubleExecutor              ),
00418       NFp_t( "double&",            &CreateDoubleRefExecutor           ),
00419       NFp_t( "void",               &CreateVoidExecutor                ),
00420       NFp_t( "bool",               &CreateBoolExecutor                ),
00421       NFp_t( "const char*",        &CreateCStringExecutor             ),
00422       NFp_t( "char*",              &CreateCStringExecutor             ),
00423 
00424    // pointer/array factories
00425       NFp_t( "void*",              &CreateVoidArrayExecutor           ),
00426       NFp_t( "short*",             &CreateShortArrayExecutor          ),
00427       NFp_t( "unsigned short*",    &CreateUShortArrayExecutor         ),
00428       NFp_t( "int*",               &CreateIntArrayExecutor            ),
00429       NFp_t( "unsigned int*",      &CreateUIntArrayExecutor           ),
00430       NFp_t( "long*",              &CreateLongArrayExecutor           ),
00431       NFp_t( "unsigned long*",     &CreateULongArrayExecutor          ),
00432       NFp_t( "float*",             &CreateFloatArrayExecutor          ),
00433       NFp_t( "double*",            &CreateDoubleArrayExecutor         ),
00434 
00435    // factories for special cases
00436       NFp_t( "std::string",        &CreateSTLStringExecutor           ),
00437       NFp_t( "string",             &CreateSTLStringExecutor           ),
00438       NFp_t( "std::string&",       &CreateSTLStringRefExecutor        ),
00439       NFp_t( "string&",            &CreateSTLStringRefExecutor        ),
00440       NFp_t( "TGlobal*",           &CreateTGlobalExecutor             ),
00441       NFp_t( "__init__",           &CreateConstructorExecutor         ),
00442       NFp_t( "PyObject*",          &CreatePyObjectExecutor            ),
00443       NFp_t( "_object*",           &CreatePyObjectExecutor            ),
00444       NFp_t( "FILE*",              &CreateVoidArrayExecutor           )
00445    };
00446 
00447    struct InitExecFactories_t {
00448    public:
00449       InitExecFactories_t()
00450       {
00451          int nf = sizeof( factories_ ) / sizeof( factories_[ 0 ] );
00452          for ( int i = 0; i < nf; ++i ) {
00453             gExecFactories[ factories_[ i ].first ] = factories_[ i ].second;
00454          }
00455       }
00456    } initExecvFactories_;
00457 
00458 } // unnamed namespace

Generated on Tue Jul 5 14:10:12 2011 for ROOT_528-00b_version by  doxygen 1.5.1