|
Pol
Revision:476adb3
|
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 }