]> git.r.bdr.sh - rbdr/pico-engine/blob - LuaVirtualMachine.cpp
0ad5096622c30fcc13fe7445ce371961005e7a10
[rbdr/pico-engine] / LuaVirtualMachine.cpp
1 // ---------------------------------------------------------------------------
2 // FILE NAME : LuaVirtualMachine.cpp
3 // ---------------------------------------------------------------------------
4 // DESCRIPTION :
5 //
6 // Lua virtual machine implementation
7 //
8 // ---------------------------------------------------------------------------
9 // VERSION : 1.00
10 // DATE : 1-Sep-2005
11 // AUTHOR : Richard Shephard
12 // ---------------------------------------------------------------------------
13 // LIBRARY INCLUDE FILES
14 #include "luainc.h"
15 #include "luavirtualmachine.h"
16 #include <assert.h>
17 #include <string.h>
18 #include <stdio.h>
19 // ---------------------------------------------------------------------------
20
21
22 //============================================================================
23 // int printMessage
24 //---------------------------------------------------------------------------
25 // Prints a message to the console
26 //
27 // Parameter Dir Description
28 // --------- --- -----------
29 // lua IN State variable
30 //
31 // Return
32 // ------
33 // Number of return varaibles on the stack
34 //
35 //============================================================================
36 static int printMessage (lua_State *lua)
37 {
38 assert (lua_isstring (lua,1));
39
40 const char *msg = lua_tostring (lua, 1);
41
42 // get caller
43 lua_Debug ar;
44 memset (&ar, 0, sizeof(ar));
45 lua_getstack (lua, 1, &ar);
46 lua_getinfo (lua, "Snl", &ar);
47
48 // debug output
49 const char *str = ar.source;
50 printf ("script: %s -- at %s(%d)\n", msg, str, ar.currentline);
51 return 0;
52 }
53
54 //============================================================================
55 // CLuaVirtualMachine::CLuaVirtualMachine
56 //---------------------------------------------------------------------------
57 // Constructor. Setups the default VM state
58 //
59 // Parameter Dir Description
60 // --------- --- -----------
61 //
62 //
63 // Return
64 // ------
65 // None.
66 //
67 //============================================================================
68 CLuaVirtualMachine::CLuaVirtualMachine (void) : m_pState (NULL), m_pDbg (NULL)
69 {
70 m_fIsOk = false;
71 }
72
73 //============================================================================
74 // CLuaVirtualMachine::CLuaVirtualMachine
75 //---------------------------------------------------------------------------
76 // Destructor. Closes the VM
77 //
78 // Parameter Dir Description
79 // --------- --- -----------
80 //
81 //
82 // Return
83 // ------
84 // None.
85 //
86 //============================================================================
87 CLuaVirtualMachine::~CLuaVirtualMachine (void)
88 {
89 if (m_pState != NULL)
90 {
91 lua_close (m_pState);
92 }
93 }
94
95 //============================================================================
96 // CLuaVirtualMachine::Panic
97 //---------------------------------------------------------------------------
98 // When things in Lua go wrong (ever called in protected mode??)
99 //
100 // Parameter Dir Description
101 // --------- --- -----------
102 // lua IN State variable
103 //
104 // Return
105 // ------
106 // None.
107 //
108 //============================================================================
109 void CLuaVirtualMachine::Panic (lua_State *lua)
110 {
111 }
112
113 //============================================================================
114 // bool CLuaVirtualMachine::InitialiseVM
115 //---------------------------------------------------------------------------
116 // Initialises the VM, open lua, makes sure things are OK
117 //
118 // Parameter Dir Description
119 // --------- --- -----------
120 // None.
121 //
122 // Return
123 // ------
124 // Success.
125 //
126 //============================================================================
127 bool CLuaVirtualMachine::InitialiseVM (void)
128 {
129 // Open Lua!
130 if (Ok ()) DestroyVM ();
131
132 m_pState = lua_open ();
133
134 if (m_pState)
135 {
136 m_fIsOk = true;
137
138 // Load util libs into lua
139 luaL_openlibs (m_pState);
140
141 // setup global printing (trace)
142 lua_pushcclosure (m_pState, printMessage, 0);
143 lua_setglobal (m_pState, "trace");
144
145 lua_atpanic (m_pState, (lua_CFunction) CLuaVirtualMachine::Panic);
146
147 return true;
148 }
149
150 return false;
151 }
152
153 //============================================================================
154 // bool CLuaVirtualMachine::DestroyVM
155 //---------------------------------------------------------------------------
156 // Clears the current Lua state
157 //
158 // Parameter Dir Description
159 // --------- --- -----------
160 // None.
161 //
162 // Return
163 // ------
164 // Success.
165 //
166 //============================================================================
167 bool CLuaVirtualMachine::DestroyVM (void)
168 {
169 if (m_pState)
170 {
171 lua_close (m_pState);
172 m_pState = NULL;
173 m_fIsOk = false;
174 }
175 return true;
176 }
177
178
179 //============================================================================
180 // bool CLuaVirtualMachine::RunFile
181 //---------------------------------------------------------------------------
182 // Compiles and runs a lua script file
183 //
184 // Parameter Dir Description
185 // --------- --- -----------
186 // strFilename IN Filename to compile and run
187 //
188 // Return
189 // ------
190 // Success.
191 //
192 //============================================================================
193 bool CLuaVirtualMachine::RunFile (const char *strFilename)
194 {
195 bool fSuccess = false;
196 int iErr = 0;
197
198 if ((iErr = luaL_loadfile (m_pState, strFilename)) == 0)
199 {
200 // Call main...
201 if ((iErr = lua_pcall (m_pState, 0, LUA_MULTRET, 0)) == 0)
202 {
203 fSuccess = true;
204 }
205 }
206
207 if (fSuccess == false)
208 {
209 if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr);
210 }
211
212 return fSuccess;
213 }
214
215 //============================================================================
216 // bool CLuaVirtualMachine::RunBuffer
217 //---------------------------------------------------------------------------
218 // Compiles and runs a pre-compiled data buffer
219 //
220 // Parameter Dir Description
221 // --------- --- -----------
222 // pbBuffer IN Buffer to run
223 // szLen IN Length of buffer
224 // strName IN Name of Buffer
225 //
226 // Return
227 // ------
228 // Success.
229 //
230 //============================================================================
231 bool CLuaVirtualMachine::RunBuffer (const unsigned char *pbBuffer, size_t szLen, const char *strName /* = NULL */)
232 {
233 bool fSuccess = false;
234 int iErr = 0;
235
236 if (strName == NULL)
237 {
238 strName = "Temp";
239 }
240
241 if ((iErr = luaL_loadbuffer (m_pState, (const char *) pbBuffer, szLen, strName)) == 0)
242 {
243 // Call main...
244 if ((iErr = lua_pcall (m_pState, 0, LUA_MULTRET, 0)) == 0)
245 {
246 fSuccess = true;
247 }
248 }
249
250 if (fSuccess == false)
251 {
252 if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr);
253 }
254
255 return fSuccess;
256
257 }
258
259 //============================================================================
260 // CLuaVirtualMachine::CallFunction
261 //---------------------------------------------------------------------------
262 // Calls a function that is already on the stack
263 //
264 // Parameter Dir Description
265 // --------- --- -----------
266 // nArgs IN Args that are aleady on the stack
267 // nReturns IN Number of expected returns (will be on the stack)
268 //
269 // Return
270 // ------
271 // Success.
272 //
273 //============================================================================
274 bool CLuaVirtualMachine::CallFunction (int nArgs, int nReturns /* = 0 */)
275 {
276 bool fSuccess = false;
277
278 if (lua_isfunction (m_pState, -nArgs-1))
279 {
280 int iErr = 0;
281 iErr = lua_pcall (m_pState, nArgs, nReturns, 0);
282
283 if (iErr == 0)
284 {
285 fSuccess = true;
286 }
287 else
288 {
289 if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr);
290 }
291 }
292
293 return fSuccess;
294 }
295