Pol  Revision:cb584c9
syshookscript.cpp
Go to the documentation of this file.
1 
8 #include "syshookscript.h"
9 
10 #include <exception>
11 #include <stddef.h>
12 #include <string>
13 
14 #include "../bscript/berror.h"
15 #include "../bscript/eprog.h"
16 #include "../bscript/executor.h"
17 #include "../clib/clib.h"
18 #include "../clib/logfacility.h"
19 #include "scrsched.h"
20 
21 namespace Pol
22 {
23 namespace Core
24 {
25 using namespace Bscript;
26 ExportScript::ExportScript( const Plib::Package* pkg, std::string scriptname )
27 {
28  if ( scriptname.find( ".ecl" ) == std::string::npos )
29  scriptname += ".ecl";
30  sd.config( scriptname, pkg, "", true );
31 }
32 
33 ExportScript::ExportScript( const ScriptDef& isd ) : sd( isd ) {}
34 
36 {
38  return ob.isTrue();
39 }
40 
41 const std::string& ExportScript::scriptname() const
42 {
43  return sd.name();
44 }
45 
46 bool ExportScript::FindExportedFunction( const std::string& name, unsigned args,
47  unsigned& PC ) const
48 {
49  const EScriptProgram* prog = uoexec.prog();
50  for ( unsigned i = 0; i < prog->exported_functions.size(); ++i )
51  {
52  const EPExportedFunction* exportedfunc = &prog->exported_functions[i];
53  if ( stricmp( exportedfunc->name.c_str(), name.c_str() ) == 0 )
54  {
55  if ( args != exportedfunc->nargs )
56  {
57  INFO_PRINT << "Exported function " << name << " in script " << scriptname() << " takes "
58  << exportedfunc->nargs << " parameters, expected " << args << "\n";
59  return false;
60  }
61  PC = exportedfunc->PC;
62  return true;
63  }
64  }
65  return false;
66 }
67 
68 bool ExportScript::FindExportedFunction( const char* name, unsigned args, unsigned& PC ) const
69 {
70  const EScriptProgram* prog = uoexec.prog();
71  for ( unsigned i = 0; i < prog->exported_functions.size(); ++i )
72  {
73  const EPExportedFunction* exportedfunc = &prog->exported_functions[i];
74  if ( stricmp( exportedfunc->name.c_str(), name ) == 0 )
75  {
76  if ( args != exportedfunc->nargs )
77  {
78  INFO_PRINT << "Exported function " << name << " in script " << scriptname() << " takes "
79  << exportedfunc->nargs << " parameters, expected " << args << "\n";
80  return false;
81  }
82  PC = exportedfunc->PC;
83  return true;
84  }
85  }
86  return false;
87 }
88 
89 
90 bool ExportScript::call( unsigned PC, BObjectImp* p0, BObjectImp* p1, BObjectImp* p2,
91  BObjectImp* p3 )
92 {
93  try
94  {
95  // build backup if function is called inside the same script
96  BackupStruct backup;
97  SaveStack( backup );
98 
99  uoexec.initForFnCall( PC );
100 
101  uoexec.pushArg( p0 );
102  uoexec.pushArg( p1 );
103  uoexec.pushArg( p2 );
104  uoexec.pushArg( p3 );
105 
106  uoexec.exec();
107 
108  bool istrue;
109 
110  if ( uoexec.error() )
111  istrue = false;
112  else if ( uoexec.ValueStack.empty() )
113  istrue = false;
114  else
115  {
116  istrue = uoexec.ValueStack.back().get()->isTrue();
117  uoexec.ValueStack.pop_back();
118  }
119 
120  // delete current state and reenable backup
121  LoadStack( backup );
122 
123  return istrue;
124  }
125  catch ( std::exception& ) //...
126  {
127  return false;
128  }
129 }
130 
131 bool ExportScript::call( unsigned PC, BObjectImp* p0, BObjectImp* p1, BObjectImp* p2 )
132 {
133  try
134  {
135  // build backup if function is called inside the same script
136  BackupStruct backup;
137  SaveStack( backup );
138 
139  uoexec.initForFnCall( PC );
140 
141  uoexec.pushArg( p0 );
142  uoexec.pushArg( p1 );
143  uoexec.pushArg( p2 );
144 
145  uoexec.exec();
146 
147  bool istrue;
148 
149  if ( uoexec.error() )
150  istrue = false;
151  else if ( uoexec.ValueStack.empty() )
152  istrue = false;
153  else
154  {
155  istrue = uoexec.ValueStack.back().get()->isTrue();
156  uoexec.ValueStack.pop_back();
157  }
158 
159  // delete current state and reenable backup
160  LoadStack( backup );
161 
162  return istrue;
163  }
164  catch ( std::exception& ) //...
165  {
166  return false;
167  }
168 }
169 
170 bool ExportScript::call( unsigned PC, BObjectImp* p0, BObjectImp* p1 )
171 {
172  try
173  {
174  // build backup if function is called inside the same script
175  BackupStruct backup;
176  SaveStack( backup );
177 
178  uoexec.initForFnCall( PC );
179 
180  uoexec.pushArg( p0 );
181  uoexec.pushArg( p1 );
182 
183  uoexec.exec();
184 
185  bool istrue;
186 
187  if ( uoexec.error() )
188  istrue = false;
189  else if ( uoexec.ValueStack.empty() )
190  istrue = false;
191  else
192  {
193  istrue = uoexec.ValueStack.back().get()->isTrue();
194  uoexec.ValueStack.pop_back();
195  }
196 
197  // delete current state and reenable backup
198  LoadStack( backup );
199 
200  return istrue;
201  }
202  catch ( std::exception& ) //...
203  {
204  return false;
205  }
206 }
207 
208 bool ExportScript::call( unsigned PC, BObjectImp* p0 )
209 {
210  try
211  {
212  // build backup if function is called inside the same script
213  BackupStruct backup;
214  SaveStack( backup );
215 
216  uoexec.initForFnCall( PC );
217 
218  uoexec.pushArg( p0 );
219 
220  uoexec.exec();
221 
222  bool istrue;
223 
224  if ( uoexec.error() )
225  istrue = false;
226  else if ( uoexec.ValueStack.empty() )
227  istrue = false;
228  else
229  {
230  istrue = uoexec.ValueStack.back().get()->isTrue();
231  uoexec.ValueStack.pop_back();
232  }
233 
234  // delete current state and reenable backup
235  LoadStack( backup );
236 
237  return istrue;
238  }
239  catch ( std::exception& ) //...
240  {
241  return false;
242  }
243 }
244 std::string ExportScript::call_string( unsigned PC, BObjectImp* p0, BObjectImp* p1 )
245 {
246  try
247  {
248  // build backup if function is called inside the same script
249  BackupStruct backup;
250  SaveStack( backup );
251 
252  uoexec.initForFnCall( PC );
253 
254  uoexec.pushArg( p0 );
255  uoexec.pushArg( p1 );
256 
257  uoexec.exec();
258 
259  std::string ret;
260 
261  if ( uoexec.error() )
262  ret = "error";
263  else if ( uoexec.ValueStack.empty() )
264  ret = "error";
265  else
266  {
267  ret = uoexec.ValueStack.back().get()->impptr()->getStringRep();
268  uoexec.ValueStack.pop_back();
269  }
270 
271  // delete current state and reenable backup
272  LoadStack( backup );
273 
274  return ret;
275  }
276  catch ( std::exception& ) //...
277  {
278  return "exception";
279  }
280 }
281 
282 std::string ExportScript::call_string( unsigned PC, BObjectImp* p0, BObjectImp* p1, BObjectImp* p2 )
283 {
284  try
285  {
286  // build backup if function is called inside the same script
287  BackupStruct backup;
288  SaveStack( backup );
289 
290  uoexec.initForFnCall( PC );
291 
292  uoexec.pushArg( p0 );
293  uoexec.pushArg( p1 );
294  uoexec.pushArg( p2 );
295 
296  uoexec.exec();
297 
298  std::string ret;
299 
300  if ( uoexec.error() )
301  ret = "error";
302  else if ( uoexec.ValueStack.empty() )
303  ret = "error";
304  else
305  {
306  ret = uoexec.ValueStack.back().get()->impptr()->getStringRep();
307  uoexec.ValueStack.pop_back();
308  }
309 
310  // delete current state and reenable backup
311  LoadStack( backup );
312 
313  return ret;
314  }
315  catch ( std::exception& ) //...
316  {
317  return "exception";
318  }
319 }
320 
321 int ExportScript::call_long( unsigned PC, BObjectImp* p0 )
322 {
323  try
324  {
325  // build backup if function is called inside the same script
326  BackupStruct backup;
327  SaveStack( backup );
328 
329  uoexec.initForFnCall( PC );
330 
331  uoexec.pushArg( p0 );
332 
333  uoexec.exec();
334 
335  int ret;
336 
337  if ( uoexec.error() )
338  ret = 0;
339  else if ( uoexec.ValueStack.empty() )
340  ret = 0;
341  else
342  {
343  BObjectImp* imp = uoexec.ValueStack.back().get()->impptr();
344  if ( imp->isa( BObjectImp::OTLong ) )
345  {
346  BLong* pLong = static_cast<BLong*>( imp );
347  ret = pLong->value();
348  }
349  else
350  {
351  ret = 0;
352  }
353  uoexec.ValueStack.pop_back();
354  }
355 
356  // delete current state and reenable backup
357  LoadStack( backup );
358 
359  return ret;
360  }
361  catch ( std::exception& ) //...
362  {
363  return 0;
364  }
365 }
366 
367 int ExportScript::call_long( unsigned PC, BObjectImp* p0, BObjectImp* p1 )
368 {
369  try
370  {
371  // build backup if function is called inside the same script
372  BackupStruct backup;
373  SaveStack( backup );
374 
375  uoexec.initForFnCall( PC );
376 
377  uoexec.pushArg( p0 );
378  uoexec.pushArg( p1 );
379 
380  uoexec.exec();
381 
382  int ret;
383 
384  if ( uoexec.error() )
385  ret = 0;
386  else if ( uoexec.ValueStack.empty() )
387  ret = 0;
388  else
389  {
390  BObjectImp* imp = uoexec.ValueStack.back().get()->impptr();
391  if ( imp->isa( BObjectImp::OTLong ) )
392  {
393  BLong* pLong = static_cast<BLong*>( imp );
394  ret = pLong->value();
395  }
396  else
397  {
398  ret = 0;
399  }
400  uoexec.ValueStack.pop_back();
401  }
402 
403  // delete current state and reenable backup
404  LoadStack( backup );
405 
406  return ret;
407  }
408  catch ( std::exception& ) //...
409  {
410  return 0;
411  }
412 }
413 
414 BObjectImp* ExportScript::call( unsigned PC, BObjectImp* p0, std::vector<BObjectRef>& pmore )
415 {
416  try
417  {
418  // build backup if function is called inside the same script
419  BackupStruct backup;
420  SaveStack( backup );
421 
422  uoexec.initForFnCall( PC );
423 
424  uoexec.pushArg( p0 );
425  size_t n = pmore.size();
426  for ( size_t i = 0; i < n; ++i )
427  { // push BObjectRef so params can be pass-by-ref
428  uoexec.pushArg( pmore[i] );
429  }
430 
431  uoexec.exec();
432 
433  BObjectImp* ret;
434 
435  if ( uoexec.error() )
436  ret = new BError( "Error during execution" );
437  else if ( uoexec.ValueStack.empty() )
438  ret = new BError( "There was no return value??" );
439  else
440  {
441  ret = uoexec.ValueStack.back()->impptr()->copy();
442  uoexec.ValueStack.pop_back();
443  }
444 
445  // delete current state and reenable backup
446  LoadStack( backup );
447 
448  return ret;
449  }
450  catch ( std::exception& ) //...
451  {
452  return new BError( "Exception during execution" );
453  }
454 }
455 
457 {
458  try
459  {
460  // build backup if function is called inside the same script
461  BackupStruct backup;
462  SaveStack( backup );
463 
464  uoexec.initForFnCall( PC );
465 
466  uoexec.pushArg( p0 );
467  size_t n = pmore.size();
468  for ( size_t i = 0; i < n; ++i )
469  {
470  uoexec.pushArg( pmore[i].get() );
471  }
472 
473  uoexec.exec();
474  BObjectImp* ret;
475 
476  if ( uoexec.error() )
477  ret = new BError( "Error during execution" );
478  else if ( uoexec.ValueStack.empty() )
479  ret = new BError( "There was no return value??" );
480  else
481  {
482  ret = uoexec.ValueStack.back()->impptr()->copy();
483  uoexec.ValueStack.pop_back();
484  }
485 
486  // delete current state and reenable backup
487  LoadStack( backup );
488 
489  return BObject( ret );
490  }
491  catch ( std::exception& ) //...
492  {
493  return BObject( new BError( "Exception during execution" ) );
494  }
495 }
496 
498 {
499  try
500  {
501  // build backup if function is called inside the same script
502  BackupStruct backup;
503  SaveStack( backup );
504 
505  uoexec.initForFnCall( PC );
506 
507  uoexec.pushArg( p0 );
508  uoexec.pushArg( p1 );
509 
510  uoexec.exec();
511 
512  BObjectImp* ret;
513 
514  if ( uoexec.error() )
515  ret = new BError( "Error during execution" );
516  else if ( uoexec.ValueStack.empty() )
517  ret = new BError( "There was no return value??" );
518  else
519  {
520  ret = uoexec.ValueStack.back()->impptr()->copy();
521  uoexec.ValueStack.pop_back();
522  }
523 
524  // delete current state and reenable backup
525  LoadStack( backup );
526 
527  return BObject( ret );
528  }
529  catch ( std::exception& ) //...
530  {
531  return BObject( new BError( "Exception during execution" ) );
532  }
533 }
534 
536 {
537  try
538  {
539  // build backup if function is called inside the same script
540  BackupStruct backup;
541  SaveStack( backup );
542 
543  uoexec.initForFnCall( PC );
544 
545  uoexec.pushArg( p0 );
546  uoexec.pushArg( p1 );
547  uoexec.pushArg( p2 );
548 
549  uoexec.exec();
550  BObjectImp* ret;
551 
552  if ( uoexec.error() )
553  ret = new BError( "Error during execution" );
554  else if ( uoexec.ValueStack.empty() )
555  ret = new BError( "There was no return value??" );
556  else
557  {
558  ret = uoexec.ValueStack.back()->impptr()->copy();
559  uoexec.ValueStack.pop_back();
560  }
561 
562  // delete current state and reenable backup
563  LoadStack( backup );
564 
565  return BObject( ret );
566  }
567  catch ( std::exception& ) //...
568  {
569  return BObject( new BError( "Exception during execution" ) );
570  }
571 }
572 
574 {
575  if ( uoexec.PC != 0 )
576  {
577  backup.PC = uoexec.PC;
578  while ( !uoexec.ValueStack.empty() )
579  {
580  backup.ValueStack.push_back( uoexec.ValueStack.back() );
581  uoexec.ValueStack.pop_back();
582  }
583  if ( ( uoexec.Locals2 != nullptr ) && ( !uoexec.Locals2->empty() ) )
584  {
585  backup.Locals.reset( new BObjectRefVec );
586  backup.Locals->assign( uoexec.Locals2->begin(), uoexec.Locals2->end() );
587  }
588  }
589  else
590  backup.PC = 0;
591 }
592 
594 {
595  if ( backup.PC != 0 )
596  {
597  uoexec.initForFnCall( backup.PC );
598  while ( !backup.ValueStack.empty() )
599  {
600  uoexec.ValueStack.push_back( backup.ValueStack.back() );
601  backup.ValueStack.pop_back();
602  }
603  if ( backup.Locals.get() != nullptr )
604  {
605  delete uoexec.Locals2;
606  uoexec.Locals2 = backup.Locals.release();
607  }
608  }
609 }
610 
612 {
613  return sd.estimatedSize() + uoexec.sizeEstimate();
614 }
615 }
616 }
void SaveStack(Bscript::BackupStruct &backup)
const EScriptProgram * prog() const
Definition: executor.h:423
std::string call_string(unsigned PC, Bscript::BObjectImp *p0, Bscript::BObjectImp *p1)
int value() const
Definition: bobject.h:592
ValueStackCont ValueStack
Definition: executor.h:77
const std::string & scriptname() const
ValueStackCont ValueStack
Definition: executor.h:120
bool isa(BObjectType type) const
Definition: bobject.h:353
Bscript::BObject call_object(unsigned PC, Bscript::BObjectImp *p0, Bscript::BObjectImp *p1)
std::vector< EPExportedFunction > exported_functions
Definition: eprog.h:117
std::vector< BObjectRef > BObjectRefVec
Definition: exectype.h:21
size_t estimatedSize() const
Definition: scrdef.cpp:140
bool error() const
Definition: executor.h:442
bool call(unsigned PC, Bscript::BObjectImp *p0)
void LoadStack(Bscript::BackupStruct &backup)
const std::string & name() const
Definition: scrdef.h:45
void pushArg(BObjectImp *arg)
Definition: executor.cpp:3021
bool FindExportedFunction(const std::string &name, unsigned args, unsigned &PC) const
virtual size_t sizeEstimate() const POL_OVERRIDE
Definition: uoexec.cpp:80
size_t estimateSize() const
ExportScript(const Plib::Package *pkg, std::string scriptname)
bool isTrue() const
Definition: bobject.h:384
std::string name
Definition: osmod.cpp:943
BObjectRefVec * Locals2
Definition: executor.h:115
std::vector< ref_ptr< BObjectImp > > BObjectImpRefVec
Definition: bobject.h:409
#define INFO_PRINT
Definition: logfacility.h:223
void initForFnCall(unsigned in_PC)
Definition: executor.cpp:2986
std::unique_ptr< BObjectRefVec > Locals
Definition: executor.h:76
Definition: berror.cpp:12
BObjectImp * run_executor_to_completion(UOExecutor &ex, const ScriptDef &script)
Definition: scrsched.cpp:367
int call_long(unsigned PC, Bscript::BObjectImp *p0)