|
Pol
Revision:b38175a
|
00001 /* 00002 History 00003 ======= 00004 00005 Notes 00006 ======= 00007 00008 */ 00009 00010 #include "../clib/clib.h" 00011 #include "../clib/logfacility.h" 00012 00013 #include "../bscript/config.h" 00014 #include "../bscript/eprog.h" 00015 #include "../bscript/escriptv.h" 00016 #include "../bscript/filefmt.h" 00017 #include "../bscript/tokens.h" 00018 #include "../bscript/symcont.h" 00019 #include "../bscript/token.h" 00020 #include "../bscript/execmodl.h" 00021 #include "../bscript/executor.h" 00022 00023 #include "../pol/sqlscrobj.h" 00024 #include "../clib/cmdargs.h" 00025 #include "../clib/cfgelem.h" 00026 00027 #include "../pol/module/basicmod.h" 00028 #include "../pol/module/basiciomod.h" 00029 #include "../pol/module/mathmod.h" 00030 #include "../pol/module/sqlmod.h" 00031 #include "../pol/module/utilmod.h" 00032 #include "../pol/module/filemod.h" 00033 #include "../pol/module/cfgmod.h" 00034 #include "../pol/module/datastore.h" 00035 00036 #include "../pol/polcfg.h" 00037 00038 #include "../clib/timer.h" 00039 00040 #include <cstring> 00041 #include <cstdio> 00042 #include <ctime> 00043 00044 #include <iostream> 00045 #include <iomanip> 00046 00047 #ifdef _MSC_VER 00048 #pragma warning(disable:4996) // disable deprecation warning strcpy 00049 #endif 00050 00051 00052 namespace Pol { 00053 namespace Bscript { 00054 void display_bobjectimp_instances(); 00055 } 00056 namespace Runecl { 00057 using namespace Bscript; 00058 using namespace Module; 00059 #if REFPTR_DEBUG 00060 unsigned int ref_counted::_ctor_calls; 00061 #endif 00062 00063 int quiet = 0; 00064 int debug = 0; 00065 bool profile = false; 00066 void usage( void ) 00067 { 00068 ERROR_PRINT << " Usage:\n" 00069 << " " << "RUNECL [options] filespec [filespec ...]\n" 00070 << " Options:\n" 00071 << " -q Quiet\n" 00072 << " -d Debug output\n" 00073 << " -p Profile\n"; 00074 } 00075 00076 void DumpCaseJmp( std::ostream& os, const Token& token, EScriptProgram* /*prog*/ ) 00077 { 00078 const unsigned char* dataptr = token.dataptr; 00079 for ( ;; ) 00080 { 00081 unsigned short offset = *(const unsigned short*)dataptr; 00082 dataptr += 2; 00083 unsigned char type = *dataptr; 00084 dataptr += 1; 00085 if ( type == CASE_TYPE_LONG ) 00086 { 00087 unsigned int lval = *(const unsigned int*)dataptr; 00088 dataptr += 4; 00089 os << "\t" << lval << ": @" << offset << std::endl; 00090 } 00091 else if ( type == CASE_TYPE_DEFAULT ) 00092 { 00093 os << "\tdefault: @" << offset << std::endl; 00094 break; 00095 } 00096 else 00097 { // type is the length of the string, otherwise 00098 os << "\t\"" << std::string((const char*)dataptr, type) << "\": @" << offset << std::endl; 00099 dataptr += type; 00100 } 00101 } 00102 } 00103 00104 Bscript::BObjectImp::BObjectType ot = Bscript::BObjectImp::OTLong; 00105 BApplicObjType aot; 00106 int x; 00107 00108 void foo( BApplicObjType* laot, Bscript::BObjectImp::BObjectType lot ) 00109 { 00110 if ( laot == &aot ) 00111 { 00112 x = 5; 00113 } 00114 00115 if ( lot == Bscript::BObjectImp::OTLong ) 00116 { 00117 x = 6; 00118 } 00119 } 00120 00121 void DumpScript( const char *path ) 00122 { 00123 std::string fname(path); 00124 if ( fname.size() >= 4 ) 00125 fname.replace( fname.size() - 4, 4, ".ecl" ); 00126 00127 Executor E; 00128 E.setViewMode( true ); 00129 E.addModule( new BasicExecutorModule( E ) ); 00130 E.addModule( new BasicIoExecutorModule( E ) ); 00131 E.addModule( new MathExecutorModule( E ) ); 00132 //E.addModule( new SQLExecutorModule( E ) ); 00133 E.addModule( new UtilExecutorModule( E ) ); 00134 E.addModule( new FileAccessExecutorModule( E ) ); 00135 E.addModule( new ConfigFileExecutorModule( E ) ); 00136 E.addModule( new DataFileExecutorModule( E ) ); 00137 00138 ref_ptr<EScriptProgram> program( new EScriptProgram ); 00139 program->read( fname.c_str() ); 00140 E.setProgram( program.get() ); 00141 00142 std::ostringstream os; 00143 program->dump( os ); 00144 INFO_PRINT << os.str(); 00145 00146 /* return; 00147 00148 Token token; 00149 unsigned PC; 00150 for( PC = 0; PC < E.nLines; PC++ ) 00151 { 00152 if (E.getToken(token, PC)) 00153 { 00154 return; 00155 } 00156 else 00157 { 00158 cout << PC << ": " << token; 00159 if (debug) cout << " (" << token.id << "," << token.type << ")"; 00160 cout << endl; 00161 if (token.id == INS_CASEJMP) 00162 { 00163 DumpCaseJmp( cout, token, program.get() ); 00164 } 00165 } 00166 } 00167 */ 00168 } 00169 00170 00171 int exec_script( const char *path ) 00172 { 00173 std::string fname(path); 00174 // TODO: autoconvert to .ecl ? 00175 bool exres; 00176 double seconds; 00177 size_t memory_used; 00178 clock_t clocks; 00179 #ifdef _WIN32 00180 FILETIME dummy; 00181 FILETIME kernelStart, userStart; 00182 FILETIME kernelEnd, userEnd; 00183 #endif 00184 00185 { 00186 Executor E; 00187 E.addModule( new BasicExecutorModule( E ) ); 00188 E.addModule( new BasicIoExecutorModule( E ) ); 00189 E.addModule( new MathExecutorModule( E ) ); 00190 //E.addModule( new SQLExecutorModule( E ) ); 00191 E.addModule( new UtilExecutorModule( E ) ); 00192 E.addModule( new FileAccessExecutorModule( E ) ); 00193 E.addModule( new ConfigFileExecutorModule( E ) ); 00194 E.addModule( new DataFileExecutorModule( E ) ); 00195 00196 ref_ptr<EScriptProgram> program( new EScriptProgram ); 00197 if ( program->read( fname.c_str() ) ) 00198 { 00199 ERROR_PRINT << "Error reading " << fname << "\n"; 00200 return 1; 00201 } 00202 E.setProgram( program.get() ); 00203 00204 E.setDebugLevel( debug ? Executor::INSTRUCTIONS : Executor::NONE ); 00205 clock_t start = clock(); 00206 #ifdef _WIN32 00207 GetThreadTimes( GetCurrentThread(), &dummy, &dummy, &kernelStart, &userStart ); 00208 #endif 00209 00210 exres = E.exec(); 00211 00212 #ifdef _WIN32 00213 GetThreadTimes( GetCurrentThread(), &dummy, &dummy, &kernelEnd, &userEnd ); 00214 #endif 00215 clocks = clock() - start; 00216 seconds = static_cast<double>( clocks ) / CLOCKS_PER_SEC; 00217 00218 memory_used = E.sizeEstimate(); 00219 } 00220 00221 if ( profile ) 00222 { 00223 fmt::Writer tmp; 00224 tmp << "Profiling information: \n" 00225 << "\tEObjectImp constructions: " << eobject_imp_constructions << "\n"; 00226 if ( eobject_imp_count ) 00227 tmp << "\tRemaining BObjectImps: " << eobject_imp_count << "\n"; 00228 tmp << "\tInstruction cycles: " << escript_instr_cycles << "\n" 00229 << "\tInnerExec calls: " << escript_execinstr_calls << "\n" 00230 << "\tClocks: " << clocks << " (" << seconds << " seconds)" << "\n" 00231 #ifdef _WIN32 00232 << "\tKernel Time: " << ( *(__int64*)&kernelEnd ) - ( *(__int64*)&kernelStart ) << "\n" 00233 << "\tUser Time: " << ( *(__int64*)&userEnd ) - ( *(__int64*)&userStart ) << "\n" 00234 #endif 00235 << "\tSpace used: " << memory_used << "\n\n" 00236 00237 << "\tCycles Per Second: " << escript_instr_cycles / seconds << "\n" 00238 << "\tCycles Per Minute: " << 60.0 * escript_instr_cycles / seconds << "\n" 00239 << "\tCycles Per Hour: " << 3600.0 * escript_instr_cycles / seconds << "\n"; 00240 #if BOBJECTIMP_DEBUG 00241 display_bobjectimp_instances(); 00242 #endif 00243 #ifdef ESCRIPT_PROFILE 00244 tmp << "FuncName,Count,Min,Max,Sum,Avarage\n"; 00245 for (escript_profile_map::iterator itr=EscriptProfileMap.begin();itr!=EscriptProfileMap.end();++itr) 00246 { 00247 tmp << itr->first << "," << itr->second.count << "," << itr->second.min << "," << itr->second.max << "," << itr->second.sum << "," 00248 << (itr->second.sum / itr->second.count) << "\n"; 00249 } 00250 #endif 00251 INFO_PRINT << tmp.str(); 00252 } 00253 return exres ? 0 : 1; 00254 } 00255 00256 int run( int argc, char **argv ) 00257 { 00258 for ( int i = 1; i < argc; i++ ) 00259 { 00260 switch ( argv[i][0] ) 00261 { 00262 case '/': case '-': 00263 switch ( argv[i][1] ) 00264 { 00265 case 'a': case 'A': 00266 case 'd': case 'D': 00267 case 'v': case 'V': 00268 case 'q': case 'Q': 00269 case 'p': case 'P': 00270 break; 00271 default: 00272 ERROR_PRINT << "Unknown option: " << argv[i] << "\n"; 00273 usage(); 00274 return 1; 00275 } 00276 break; 00277 default: 00278 return exec_script( argv[i] ); 00279 } 00280 } 00281 return 0; 00282 } 00283 } 00284 int xmain( int argc, char *argv[] ) 00285 { 00286 Clib::StoreCmdArgs( argc, argv ); 00287 00288 int progver = 1; 00289 00290 Runecl::escript_config.max_call_depth = 100; 00291 Runecl::quiet = Clib::FindArg( "q" ) ? 1 : 0; 00292 Runecl::debug = Clib::FindArg( "d" ) ? 1 : 0; 00293 Runecl::profile = Clib::FindArg( "p" ) ? 1 : 0; 00294 Clib::passert_disabled = Clib::FindArg( "a" ) ? false : true; 00295 00296 if ( !Runecl::quiet ) 00297 { 00298 // vX.YY 00299 double vernum = (double)progver + (double)( ESCRIPT_FILE_VER_CURRENT / 100.0f ); 00300 ERROR_PRINT << "EScript Executor v" << vernum << "\n" 00301 << "Copyright (C) 1993-2015 Eric N. Swanson\n\n"; 00302 } 00303 00304 if ( argc == 1 ) 00305 { 00306 Runecl::usage( ); 00307 return 1; 00308 } 00309 00310 const char *todump = Clib::FindArg( "v" ); 00311 if ( todump ) 00312 { 00313 Runecl::DumpScript( todump ); 00314 return 0; 00315 } 00316 00317 return Runecl::run( argc, argv ); 00318 } 00319 }