Pol  Revision:476adb3
pol/systemhookscript.cpp
Go to the documentation of this file.
00001 /*
00002 History
00003 =======
00004 2009/12/10 Turley:   Method/Syshook definitions now supports :pkg: format
00005 
00006 
00007 Notes
00008 =======
00009 
00010 */
00011 
00012 #include "../clib/stl_inc.h"
00013 #include "../clib/logfacility.h"
00014 
00015 #include "../bscript/berror.h"
00016 
00017 #include "scrsched.h"
00018 #include "syshookscript.h"
00019 #include "../bscript/executor.h"
00020 namespace Pol {
00021   namespace Core {
00022     using namespace Bscript;
00023     ExportScript::ExportScript( const Plib::Package* pkg, std::string scriptname )
00024     {
00025       if ( scriptname.find( ".ecl" ) == string::npos )
00026         scriptname += ".ecl";
00027       sd.config( scriptname, pkg, "", true );
00028     }
00029 
00030     ExportScript::ExportScript( const ScriptDef& isd ) :
00031       sd( isd )
00032     {}
00033 
00034     bool ExportScript::Initialize()
00035     {
00036       BObject ob( run_executor_to_completion( uoexec, sd ) );
00037       return ob.isTrue();
00038     }
00039 
00040     const std::string& ExportScript::scriptname() const
00041     {
00042       return sd.name();
00043     }
00044 
00045     bool ExportScript::FindExportedFunction( const std::string& name, unsigned args, unsigned& PC ) const
00046     {
00047       const EScriptProgram* prog = uoexec.prog();
00048       for ( unsigned i = 0; i < prog->exported_functions.size(); ++i )
00049       {
00050         const EPExportedFunction* exportedfunc = &prog->exported_functions[i];
00051         if ( stricmp( exportedfunc->name.c_str(), name.c_str() ) == 0 )
00052         {
00053           if ( args != exportedfunc->nargs )
00054           {
00055             INFO_PRINT << "Exported function " << name
00056               << " in script " << scriptname()
00057               << " takes " << exportedfunc->nargs
00058               << " parameters, expected " << args << "\n";
00059             return false;
00060           }
00061           PC = exportedfunc->PC;
00062           return true;
00063         }
00064       }
00065       return false;
00066     }
00067 
00068     bool ExportScript::FindExportedFunction( const char* name, unsigned args, unsigned& PC ) const
00069     {
00070       const EScriptProgram* prog = uoexec.prog();
00071       for ( unsigned i = 0; i < prog->exported_functions.size(); ++i )
00072       {
00073         const EPExportedFunction* exportedfunc = &prog->exported_functions[i];
00074         if ( stricmp( exportedfunc->name.c_str(), name ) == 0 )
00075         {
00076           if ( args != exportedfunc->nargs )
00077           {
00078             INFO_PRINT << "Exported function " << name
00079               << " in script " << scriptname()
00080               << " takes " << exportedfunc->nargs
00081               << " parameters, expected " << args << "\n";
00082             return false;
00083           }
00084           PC = exportedfunc->PC;
00085           return true;
00086         }
00087       }
00088       return false;
00089     }
00090 
00091 
00092     bool ExportScript::call( unsigned PC,
00093                              BObjectImp* p0,
00094                              BObjectImp* p1,
00095                              BObjectImp* p2,
00096                              BObjectImp* p3 )
00097     {
00098       try
00099       {
00100         //build backup if function is called inside the same script
00101         BackupStruct backup;
00102         SaveStack( backup );
00103 
00104         uoexec.initForFnCall( PC );
00105 
00106         uoexec.pushArg( p0 );
00107         uoexec.pushArg( p1 );
00108         uoexec.pushArg( p2 );
00109         uoexec.pushArg( p3 );
00110 
00111         uoexec.exec();
00112 
00113         bool istrue;
00114 
00115         if ( uoexec.error() )
00116           istrue = false;
00117         else if ( uoexec.ValueStack.empty() )
00118           istrue = false;
00119         else
00120         {
00121           istrue = uoexec.ValueStack.back().get()->isTrue();
00122           uoexec.ValueStack.pop_back();
00123         }
00124 
00125         // delete current state and reenable backup
00126         LoadStack( backup );
00127 
00128         return istrue;
00129       }
00130       catch ( std::exception& )//...
00131       {
00132         return false;
00133       }
00134     }
00135 
00136     bool ExportScript::call( unsigned PC,
00137                              BObjectImp* p0,
00138                              BObjectImp* p1,
00139                              BObjectImp* p2 )
00140     {
00141       try
00142       {
00143         //build backup if function is called inside the same script
00144         BackupStruct backup;
00145         SaveStack( backup );
00146 
00147         uoexec.initForFnCall( PC );
00148 
00149         uoexec.pushArg( p0 );
00150         uoexec.pushArg( p1 );
00151         uoexec.pushArg( p2 );
00152 
00153         uoexec.exec();
00154 
00155         bool istrue;
00156 
00157         if ( uoexec.error() )
00158           istrue = false;
00159         else if ( uoexec.ValueStack.empty() )
00160           istrue = false;
00161         else
00162         {
00163           istrue = uoexec.ValueStack.back().get()->isTrue();
00164           uoexec.ValueStack.pop_back();
00165         }
00166 
00167         // delete current state and reenable backup
00168         LoadStack( backup );
00169 
00170         return istrue;
00171       }
00172       catch ( std::exception& )//...
00173       {
00174         return false;
00175       }
00176     }
00177 
00178     bool ExportScript::call( unsigned PC,
00179                              BObjectImp* p0,
00180                              BObjectImp* p1 )
00181     {
00182       try
00183       {
00184         //build backup if function is called inside the same script
00185         BackupStruct backup;
00186         SaveStack( backup );
00187 
00188         uoexec.initForFnCall( PC );
00189 
00190         uoexec.pushArg( p0 );
00191         uoexec.pushArg( p1 );
00192 
00193         uoexec.exec();
00194 
00195         bool istrue;
00196 
00197         if ( uoexec.error() )
00198           istrue = false;
00199         else if ( uoexec.ValueStack.empty() )
00200           istrue = false;
00201         else
00202         {
00203           istrue = uoexec.ValueStack.back().get()->isTrue();
00204           uoexec.ValueStack.pop_back();
00205         }
00206 
00207         // delete current state and reenable backup
00208         LoadStack( backup );
00209 
00210         return istrue;
00211       }
00212       catch ( std::exception& )//...
00213       {
00214         return false;
00215       }
00216     }
00217 
00218     bool ExportScript::call( unsigned PC,
00219                              BObjectImp* p0 )
00220     {
00221       try
00222       {
00223         //build backup if function is called inside the same script
00224         BackupStruct backup;
00225         SaveStack( backup );
00226 
00227         uoexec.initForFnCall( PC );
00228 
00229         uoexec.pushArg( p0 );
00230 
00231         uoexec.exec();
00232 
00233         bool istrue;
00234 
00235         if ( uoexec.error() )
00236           istrue = false;
00237         else if ( uoexec.ValueStack.empty() )
00238           istrue = false;
00239         else
00240         {
00241           istrue = uoexec.ValueStack.back().get()->isTrue();
00242           uoexec.ValueStack.pop_back();
00243         }
00244 
00245         // delete current state and reenable backup
00246         LoadStack( backup );
00247 
00248         return istrue;
00249       }
00250       catch ( std::exception& )//...
00251       {
00252         return false;
00253       }
00254     }
00255     std::string ExportScript::call_string(
00256       unsigned PC,
00257       BObjectImp* p0, BObjectImp* p1 )
00258     {
00259       try
00260       {
00261         //build backup if function is called inside the same script
00262         BackupStruct backup;
00263         SaveStack( backup );
00264 
00265         uoexec.initForFnCall( PC );
00266 
00267         uoexec.pushArg( p0 );
00268         uoexec.pushArg( p1 );
00269 
00270         uoexec.exec();
00271 
00272         std::string ret;
00273 
00274         if ( uoexec.error() )
00275           ret = "error";
00276         else if ( uoexec.ValueStack.empty() )
00277           ret = "error";
00278         else
00279         {
00280           ret = uoexec.ValueStack.back().get()->impptr()->getStringRep();
00281           uoexec.ValueStack.pop_back();
00282         }
00283 
00284         // delete current state and reenable backup
00285         LoadStack( backup );
00286 
00287         return ret;
00288       }
00289       catch ( std::exception& )//...
00290       {
00291         return "exception";
00292       }
00293     }
00294 
00295     std::string ExportScript::call_string(
00296       unsigned PC,
00297       BObjectImp* p0, BObjectImp* p1, BObjectImp* p2 )
00298     {
00299       try
00300       {
00301         //build backup if function is called inside the same script
00302         BackupStruct backup;
00303         SaveStack( backup );
00304 
00305         uoexec.initForFnCall( PC );
00306 
00307         uoexec.pushArg( p0 );
00308         uoexec.pushArg( p1 );
00309         uoexec.pushArg( p2 );
00310 
00311         uoexec.exec();
00312 
00313         std::string ret;
00314 
00315         if ( uoexec.error() )
00316           ret = "error";
00317         else if ( uoexec.ValueStack.empty() )
00318           ret = "error";
00319         else
00320         {
00321           ret = uoexec.ValueStack.back().get()->impptr()->getStringRep();
00322           uoexec.ValueStack.pop_back();
00323         }
00324 
00325         // delete current state and reenable backup
00326         LoadStack( backup );
00327 
00328         return ret;
00329       }
00330       catch ( std::exception& )//...
00331       {
00332         return "exception";
00333       }
00334     }
00335 
00336     int ExportScript::call_long(
00337       unsigned PC,
00338       BObjectImp* p0 )
00339     {
00340       try
00341       {
00342         //build backup if function is called inside the same script
00343         BackupStruct backup;
00344         SaveStack( backup );
00345 
00346         uoexec.initForFnCall( PC );
00347 
00348         uoexec.pushArg( p0 );
00349 
00350         uoexec.exec();
00351 
00352         int ret;
00353 
00354         if ( uoexec.error() )
00355           ret = 0;
00356         else if ( uoexec.ValueStack.empty() )
00357           ret = 0;
00358         else
00359         {
00360           BObjectImp* imp = uoexec.ValueStack.back().get()->impptr();
00361           if ( imp->isa( BObjectImp::OTLong ) )
00362           {
00363             BLong* pLong = static_cast<BLong*>( imp );
00364             ret = pLong->value();
00365           }
00366           else
00367           {
00368             ret = 0;
00369           }
00370           uoexec.ValueStack.pop_back();
00371         }
00372 
00373         // delete current state and reenable backup
00374         LoadStack( backup );
00375 
00376         return ret;
00377       }
00378       catch ( std::exception& )//...
00379       {
00380         return 0;
00381       }
00382     }
00383 
00384     int ExportScript::call_long(
00385       unsigned PC,
00386       BObjectImp* p0, BObjectImp* p1 )
00387     {
00388       try
00389       {
00390         //build backup if function is called inside the same script
00391         BackupStruct backup;
00392         SaveStack( backup );
00393 
00394         uoexec.initForFnCall( PC );
00395 
00396         uoexec.pushArg( p0 );
00397         uoexec.pushArg( p1 );
00398 
00399         uoexec.exec();
00400 
00401         int ret;
00402 
00403         if ( uoexec.error() )
00404           ret = 0;
00405         else if ( uoexec.ValueStack.empty() )
00406           ret = 0;
00407         else
00408         {
00409           BObjectImp* imp = uoexec.ValueStack.back().get()->impptr();
00410           if ( imp->isa( BObjectImp::OTLong ) )
00411           {
00412             BLong* pLong = static_cast<BLong*>( imp );
00413             ret = pLong->value();
00414           }
00415           else
00416           {
00417             ret = 0;
00418           }
00419           uoexec.ValueStack.pop_back();
00420         }
00421 
00422         // delete current state and reenable backup
00423         LoadStack( backup );
00424 
00425         return ret;
00426       }
00427       catch ( std::exception& )//...
00428       {
00429         return 0;
00430       }
00431     }
00432 
00433     BObjectImp* ExportScript::call( unsigned PC,
00434                                     BObjectImp* p0,
00435                                     std::vector<BObjectRef>& pmore )
00436     {
00437       try
00438       {
00439         //build backup if function is called inside the same script
00440         BackupStruct backup;
00441         SaveStack( backup );
00442 
00443         uoexec.initForFnCall( PC );
00444 
00445         uoexec.pushArg( p0 );
00446         size_t n = pmore.size();
00447         for ( size_t i = 0; i < n; ++i )
00448         {   // push BObjectRef so params can be pass-by-ref
00449           uoexec.pushArg( pmore[i] );
00450         }
00451 
00452         uoexec.exec();
00453 
00454         BObjectImp* ret;
00455 
00456         if ( uoexec.error() )
00457           ret = new BError( "Error during execution" );
00458         else if ( uoexec.ValueStack.empty() )
00459           ret = new BError( "There was no return value??" );
00460         else
00461         {
00462           ret = uoexec.ValueStack.back()->impptr()->copy();
00463           uoexec.ValueStack.pop_back();
00464         }
00465 
00466         // delete current state and reenable backup
00467         LoadStack( backup );
00468 
00469         return ret;
00470       }
00471       catch ( std::exception& )//...
00472       {
00473         return new BError( "Exception during execution" );
00474       }
00475     }
00476 
00477     BObject ExportScript::call( unsigned PC,
00478                                 BObjectImp* p0,
00479                                 BObjectImpRefVec& pmore )
00480     {
00481       try
00482       {
00483         //build backup if function is called inside the same script
00484         BackupStruct backup;
00485         SaveStack( backup );
00486 
00487         uoexec.initForFnCall( PC );
00488 
00489         uoexec.pushArg( p0 );
00490         size_t n = pmore.size();
00491         for ( size_t i = 0; i < n; ++i )
00492         {
00493           uoexec.pushArg( pmore[i].get() );
00494         }
00495 
00496         uoexec.exec();
00497         BObjectImp* ret;
00498 
00499         if ( uoexec.error() )
00500           ret = new BError( "Error during execution" );
00501         else if ( uoexec.ValueStack.empty() )
00502           ret = new BError( "There was no return value??" );
00503         else
00504         {
00505           ret = uoexec.ValueStack.back()->impptr()->copy();
00506           uoexec.ValueStack.pop_back();
00507         }
00508 
00509         // delete current state and reenable backup
00510         LoadStack( backup );
00511 
00512         return BObject( ret );
00513       }
00514       catch ( std::exception& )//...
00515       {
00516         return BObject( new BError( "Exception during execution" ) );
00517       }
00518     }
00519 
00520     BObject ExportScript::call_object(
00521       unsigned PC,
00522       BObjectImp* p0, BObjectImp* p1 )
00523     {
00524       try
00525       {
00526         //build backup if function is called inside the same script
00527         BackupStruct backup;
00528         SaveStack( backup );
00529 
00530         uoexec.initForFnCall( PC );
00531 
00532         uoexec.pushArg( p0 );
00533         uoexec.pushArg( p1 );
00534 
00535         uoexec.exec();
00536 
00537         BObjectImp* ret;
00538 
00539         if ( uoexec.error() )
00540           ret = new BError( "Error during execution" );
00541         else if ( uoexec.ValueStack.empty() )
00542           ret = new BError( "There was no return value??" );
00543         else
00544         {
00545           ret = uoexec.ValueStack.back()->impptr()->copy();
00546           uoexec.ValueStack.pop_back();
00547         }
00548 
00549         // delete current state and reenable backup
00550         LoadStack( backup );
00551 
00552         return BObject( ret );
00553       }
00554       catch ( std::exception& )//...
00555       {
00556         return BObject( new BError( "Exception during execution" ) );
00557       }
00558     }
00559 
00560     BObject ExportScript::call_object(
00561       unsigned PC,
00562       BObjectImp* p0, BObjectImp* p1, BObjectImp* p2 )
00563     {
00564       try
00565       {
00566         //build backup if function is called inside the same script
00567         BackupStruct backup;
00568         SaveStack( backup );
00569 
00570         uoexec.initForFnCall( PC );
00571 
00572         uoexec.pushArg( p0 );
00573         uoexec.pushArg( p1 );
00574         uoexec.pushArg( p2 );
00575 
00576         uoexec.exec();
00577         BObjectImp* ret;
00578 
00579         if ( uoexec.error() )
00580           ret = new BError( "Error during execution" );
00581         else if ( uoexec.ValueStack.empty() )
00582           ret = new BError( "There was no return value??" );
00583         else
00584         {
00585           ret = uoexec.ValueStack.back()->impptr()->copy();
00586           uoexec.ValueStack.pop_back();
00587         }
00588 
00589         // delete current state and reenable backup
00590         LoadStack( backup );
00591 
00592         return BObject( ret );
00593       }
00594       catch ( std::exception& )//...
00595       {
00596         return BObject( new BError( "Exception during execution" ) );
00597       }
00598     }
00599 
00600     void ExportScript::SaveStack( BackupStruct& backup )
00601     {
00602       if ( uoexec.PC != 0 )
00603       {
00604         backup.PC = uoexec.PC;
00605         while ( !uoexec.ValueStack.empty() )
00606         {
00607           backup.ValueStack.push_back( uoexec.ValueStack.back() );
00608           uoexec.ValueStack.pop_back();
00609         }
00610         if ( ( uoexec.Locals2 != NULL ) && ( !uoexec.Locals2->empty() ) )
00611         {
00612           backup.Locals.reset( new BObjectRefVec );
00613           backup.Locals->assign( uoexec.Locals2->begin(), uoexec.Locals2->end() );
00614         }
00615       }
00616       else
00617         backup.PC = 0;
00618     }
00619 
00620     void ExportScript::LoadStack( BackupStruct& backup )
00621     {
00622       if ( backup.PC != 0 )
00623       {
00624         uoexec.initForFnCall( backup.PC );
00625         while ( !backup.ValueStack.empty() )
00626         {
00627           uoexec.ValueStack.push_back( backup.ValueStack.back() );
00628           backup.ValueStack.pop_back();
00629         }
00630         if ( backup.Locals.get() != NULL )
00631         {
00632           delete uoexec.Locals2;
00633           uoexec.Locals2 = backup.Locals.release();
00634         }
00635       }
00636     }
00637   }
00638 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines