#include #include #include #include "luaincl.h" #include "VirtualMachine.h" namespace OrxScript { // --------------------------------------------------------------------------- //============================================================================ // int printMessage //--------------------------------------------------------------------------- // Prints a message to the console // // Parameter Dir Description // --------- --- ----------- // lua IN State variable // // Return // ------ // Number of return varaibles on the stack // //============================================================================ static int printMessage (lua_State *lua) { assert (lua_isstring (lua,1)); const char *msg = lua_tostring (lua, 1); // get caller lua_Debug ar; memset (&ar, 0, sizeof(ar)); lua_getstack (lua, 1, &ar); lua_getinfo (lua, "Snl", &ar); // debug output const char *str = ar.source; printf ("script: %s -- at %s(%d)\n", msg, str, ar.currentline); return 0; } //============================================================================ // LuaVirtualMachine::LuaVirtualMachine //--------------------------------------------------------------------------- // Constructor. Setups the default VM state // // Parameter Dir Description // --------- --- ----------- // // // Return // ------ // None. // //============================================================================ LuaVirtualMachine::LuaVirtualMachine (void) : luaState (NULL) { machineIsOk = false; } //============================================================================ // LuaVirtualMachine::LuaVirtualMachine //--------------------------------------------------------------------------- // Destructor. Closes the VM // // Parameter Dir Description // --------- --- ----------- // // // Return // ------ // None. // //============================================================================ LuaVirtualMachine::~LuaVirtualMachine (void) { if (luaState != NULL) { lua_close (luaState); } } //============================================================================ // LuaVirtualMachine::Panic //--------------------------------------------------------------------------- // When things in Lua go wrong (ever called in protected mode??) // // Parameter Dir Description // --------- --- ----------- // lua IN State variable // // Return // ------ // None. // //============================================================================ void LuaVirtualMachine::panic (lua_State *lua) {} //============================================================================ // bool LuaVirtualMachine::init //--------------------------------------------------------------------------- // Initialises the VM, open lua, makes sure things are OK // // Parameter Dir Description // --------- --- ----------- // None. // // Return // ------ // Success. // //============================================================================ bool LuaVirtualMachine::init (void) { // Open Lua! if (isOk ()) destroy (); luaState = lua_open (); if (luaState) { machineIsOk = true; // Load util libs into lua luaopen_base (luaState); luaopen_table (luaState); luaopen_string (luaState); luaopen_math (luaState); luaopen_debug (luaState); luaopen_io (luaState); luaopen_loadlib (luaState); // setup global printing (trace) lua_pushcclosure (luaState, printMessage, 0); lua_setglobal (luaState, "trace"); lua_atpanic (luaState, (lua_CFunction) LuaVirtualMachine::panic); return true; } return false; } //============================================================================ // bool LuaVirtualMachine::destroy //--------------------------------------------------------------------------- // Clears the current Lua state // // Parameter Dir Description // --------- --- ----------- // None. // // Return // ------ // Success. // //============================================================================ bool LuaVirtualMachine::destroy (void) { if (luaState) { lua_close (luaState); luaState = NULL; machineIsOk = false; } return true; } //============================================================================ // bool LuaVirtualMachine::runFile //--------------------------------------------------------------------------- // Compiles and runs a lua script file // // Parameter Dir Description // --------- --- ----------- // strFilename IN Filename to compile and run // // Return // ------ // Success. // //============================================================================ bool LuaVirtualMachine::runFile (const std::string& strFilename) { bool fSuccess = false; int iErr = 0; if ((iErr = luaL_loadfile (luaState, strFilename.c_str())) == 0) { // Call main... if ((iErr = lua_pcall (luaState, 0, LUA_MULTRET, 0)) == 0) { fSuccess = true; } } /* if (fSuccess == false) { if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr); } */ return fSuccess; } //============================================================================ // bool LuaVirtualMachine::runBuffer //--------------------------------------------------------------------------- // Compiles and runs a pre-compiled data buffer // // Parameter Dir Description // --------- --- ----------- // pbBuffer IN Buffer to run // szLen IN Length of buffer // strName IN Name of Buffer // // Return // ------ // Success. // //============================================================================ bool LuaVirtualMachine::runBuffer (const unsigned char *pbBuffer, size_t szLen, const char *strName /* = NULL */) { bool fSuccess = false; int iErr = 0; if (strName == NULL) { strName = "Temp"; } if ((iErr = luaL_loadbuffer (luaState, (const char *) pbBuffer, szLen, strName)) == 0) { // Call main... if ((iErr = lua_pcall (luaState, 0, LUA_MULTRET, 0)) == 0) { fSuccess = true; } } /* if (fSuccess == false) { if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr); } */ return fSuccess; } //============================================================================ // LuaVirtualMachine::callFunction //--------------------------------------------------------------------------- // Calls a function that is already on the stack // // Parameter Dir Description // --------- --- ----------- // nArgs IN Args that are aleady on the stack // nReturns IN Number of expected returns (will be on the stack) // // Return // ------ // Success. // //============================================================================ bool LuaVirtualMachine::callFunction (int nArgs, int nReturns /* = 0 */) { bool fSuccess = false; if (lua_isfunction (luaState, -nArgs-1)) { int iErr = 0; iErr = lua_pcall (luaState, nArgs, nReturns, 0); if (iErr == 0) { fSuccess = true; } /*else { if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr); } */ } return fSuccess; } }