blob: 5c59c20d79c05801a313114f983420c1fa5fc3af [file] [log] [blame]
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01001#include <lauxlib.h>
2#include <lua.h>
3#include <lualib.h>
4
Thierry FOURNIER380d0932015-01-23 14:27:52 +01005#include <ebpttree.h>
6
7#include <common/cfgparse.h>
8
9#include <types/hlua.h>
10#include <types/proxy.h>
11
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +010012/* Lua uses longjmp to perform yield or throwing errors. This
13 * macro is used only for identifying the function that can
14 * not return because a longjmp is executed.
15 * __LJMP marks a prototype of hlua file that can use longjmp.
16 * WILL_LJMP() marks an lua function that will use longjmp.
17 * MAY_LJMP() marks an lua function that may use longjmp.
18 */
19#define __LJMP
20#define WILL_LJMP(func) func
21#define MAY_LJMP(func) func
22
Thierry FOURNIER380d0932015-01-23 14:27:52 +010023/* The main Lua execution context. */
24struct hlua gL;
25
26/* Store the fast lua context for coroutines. This tree uses the
27 * Lua stack pointer value as indexed entry, and store the associated
28 * hlua context.
29 */
30struct eb_root hlua_ctx = EB_ROOT_UNIQUE;
31
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +010032/* Used to check an Lua function type in the stack. It creates and
33 * returns a reference of the function. This function throws an
34 * error if the rgument is not a "function".
35 */
36__LJMP unsigned int hlua_checkfunction(lua_State *L, int argno)
37{
38 if (!lua_isfunction(L, argno)) {
39 const char *msg = lua_pushfstring(L, "function expected, got %s", luaL_typename(L, -1));
40 WILL_LJMP(luaL_argerror(L, argno, msg));
41 }
42 lua_pushvalue(L, argno);
43 return luaL_ref(L, LUA_REGISTRYINDEX);
44}
45
46/* The three following functions are useful for adding entries
47 * in a table. These functions takes a string and respectively an
48 * integer, a string or a function and add it to the table in the
49 * top of the stack.
50 *
51 * These functions throws an error if no more stack size is
52 * available.
53 */
54__LJMP static inline void hlua_class_const_int(lua_State *L, const char *name,
55 unsigned int value)
56{
57 if (!lua_checkstack(L, 2))
58 WILL_LJMP(luaL_error(L, "full stack"));
59 lua_pushstring(L, name);
60 lua_pushunsigned(L, value);
61 lua_settable(L, -3);
62}
63__LJMP static inline void hlua_class_const_str(lua_State *L, const char *name,
64 const char *value)
65{
66 if (!lua_checkstack(L, 2))
67 WILL_LJMP(luaL_error(L, "full stack"));
68 lua_pushstring(L, name);
69 lua_pushstring(L, value);
70 lua_settable(L, -3);
71}
72__LJMP static inline void hlua_class_function(lua_State *L, const char *name,
73 int (*function)(lua_State *L))
74{
75 if (!lua_checkstack(L, 2))
76 WILL_LJMP(luaL_error(L, "full stack"));
77 lua_pushstring(L, name);
78 lua_pushcclosure(L, function, 0);
79 lua_settable(L, -3);
80}
81
82/* This function check the number of arguments available in the
83 * stack. If the number of arguments available is not the same
84 * then <nb> an error is throwed.
85 */
86__LJMP static inline void check_args(lua_State *L, int nb, char *fcn)
87{
88 if (lua_gettop(L) == nb)
89 return;
90 WILL_LJMP(luaL_error(L, "'%s' needs %d arguments", fcn, nb));
91}
92
93/* Return true if the data in stack[<ud>] is an object of
94 * type <class_ref>.
95 */
96static int hlua_udataistype(lua_State *L, int ud, int class_ref)
97{
98 void *p = lua_touserdata(L, ud);
99 if (!p)
100 return 0;
101
102 if (!lua_getmetatable(L, ud))
103 return 0;
104
105 lua_rawgeti(L, LUA_REGISTRYINDEX, class_ref);
106 if (!lua_rawequal(L, -1, -2)) {
107 lua_pop(L, 2);
108 return 0;
109 }
110
111 lua_pop(L, 2);
112 return 1;
113}
114
115/* Return an object of the expected type, or throws an error. */
116__LJMP static void *hlua_checkudata(lua_State *L, int ud, int class_ref)
117{
118 if (!hlua_udataistype(L, ud, class_ref))
119 WILL_LJMP(luaL_argerror(L, 1, NULL));
120 return lua_touserdata(L, ud);
121}
122
123/* This fucntion push an error string prefixed by the file name
124 * and the line number where the error is encountered.
125 */
126static int hlua_pusherror(lua_State *L, const char *fmt, ...)
127{
128 va_list argp;
129 va_start(argp, fmt);
130 luaL_where(L, 1);
131 lua_pushvfstring(L, fmt, argp);
132 va_end(argp);
133 lua_concat(L, 2);
134 return 1;
135}
136
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100137/*
138 * The following functions are used to make correspondance between the the
139 * executed lua pointer and the "struct hlua *" that contain the context.
140 * They run with the tree head "hlua_ctx", they just perform lookup in the
141 * tree.
142 *
143 * - hlua_gethlua : return the hlua context associated with an lua_State.
144 * - hlua_delhlua : remove the association between hlua context and lua_state.
145 * - hlua_sethlua : create the association between hlua context and lua_state.
146 */
147static inline struct hlua *hlua_gethlua(lua_State *L)
148{
149 struct ebpt_node *node;
150
151 node = ebpt_lookup(&hlua_ctx, L);
152 if (!node)
153 return NULL;
154 return ebpt_entry(node, struct hlua, node);
155}
156static inline void hlua_delhlua(struct hlua *hlua)
157{
158 if (hlua->node.key)
159 ebpt_delete(&hlua->node);
160}
161static inline void hlua_sethlua(struct hlua *hlua)
162{
163 hlua->node.key = hlua->T;
164 ebpt_insert(&hlua_ctx, &hlua->node);
165}
166
167/* This function initialises the Lua environment stored in the session.
168 * It must be called at the start of the session. This function creates
169 * an LUA coroutine. It can not be use to crete the main LUA context.
170 */
171int hlua_ctx_init(struct hlua *lua, struct task *task)
172{
173 lua->Mref = LUA_REFNIL;
174 lua->state = HLUA_STOP;
175 lua->T = lua_newthread(gL.T);
176 if (!lua->T) {
177 lua->Tref = LUA_REFNIL;
178 return 0;
179 }
180 hlua_sethlua(lua);
181 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
182 lua->task = task;
183 return 1;
184}
185
186/* Used to destroy the Lua coroutine when the attached session or task
187 * is destroyed. The destroy also the memory context. The struct "lua"
188 * is not freed.
189 */
190void hlua_ctx_destroy(struct hlua *lua)
191{
192 /* Remove context. */
193 hlua_delhlua(lua);
194
195 /* The thread is garbage collected by Lua. */
196 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
197 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
198}
199
200/* This function is used to restore the Lua context when a coroutine
201 * fails. This function copy the common memory between old coroutine
202 * and the new coroutine. The old coroutine is destroyed, and its
203 * replaced by the new coroutine.
204 * If the flag "keep_msg" is set, the last entry of the old is assumed
205 * as string error message and it is copied in the new stack.
206 */
207static int hlua_ctx_renew(struct hlua *lua, int keep_msg)
208{
209 lua_State *T;
210 int new_ref;
211
212 /* Renew the main LUA stack doesn't have sense. */
213 if (lua == &gL)
214 return 0;
215
216 /* Remove context. */
217 hlua_delhlua(lua);
218
219 /* New Lua coroutine. */
220 T = lua_newthread(gL.T);
221 if (!T)
222 return 0;
223
224 /* Copy last error message. */
225 if (keep_msg)
226 lua_xmove(lua->T, T, 1);
227
228 /* Copy data between the coroutines. */
229 lua_rawgeti(lua->T, LUA_REGISTRYINDEX, lua->Mref);
230 lua_xmove(lua->T, T, 1);
231 new_ref = luaL_ref(T, LUA_REGISTRYINDEX); /* Valur poped. */
232
233 /* Destroy old data. */
234 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
235
236 /* The thread is garbage collected by Lua. */
237 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
238
239 /* Fill the struct with the new coroutine values. */
240 lua->Mref = new_ref;
241 lua->T = T;
242 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
243
244 /* Set context. */
245 hlua_sethlua(lua);
246
247 return 1;
248}
249
250/* This function start or resumes the Lua stack execution. If the flag
251 * "yield_allowed" if no set and the LUA stack execution returns a yield
252 * The function return an error.
253 *
254 * The function can returns 4 values:
255 * - HLUA_E_OK : The execution is terminated without any errors.
256 * - HLUA_E_AGAIN : The execution must continue at the next associated
257 * task wakeup.
258 * - HLUA_E_ERRMSG : An error has occured, an error message is set in
259 * the top of the stack.
260 * - HLUA_E_ERR : An error has occured without error message.
261 *
262 * If an error occured, the stack is renewed and it is ready to run new
263 * LUA code.
264 */
265static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
266{
267 int ret;
268 const char *msg;
269
270 lua->state = HLUA_RUN;
271
272 /* Call the function. */
273 ret = lua_resume(lua->T, gL.T, lua->nargs);
274 switch (ret) {
275
276 case LUA_OK:
277 ret = HLUA_E_OK;
278 break;
279
280 case LUA_YIELD:
281 if (!yield_allowed) {
282 lua_settop(lua->T, 0); /* Empty the stack. */
283 if (!lua_checkstack(lua->T, 1)) {
284 ret = HLUA_E_ERR;
285 break;
286 }
287 lua_pushfstring(lua->T, "yield not allowed");
288 ret = HLUA_E_ERRMSG;
289 break;
290 }
291 ret = HLUA_E_AGAIN;
292 break;
293
294 case LUA_ERRRUN:
295 if (!lua_checkstack(lua->T, 1)) {
296 ret = HLUA_E_ERR;
297 break;
298 }
299 msg = lua_tostring(lua->T, -1);
300 lua_settop(lua->T, 0); /* Empty the stack. */
301 lua_pop(lua->T, 1);
302 if (msg)
303 lua_pushfstring(lua->T, "runtime error: %s", msg);
304 else
305 lua_pushfstring(lua->T, "unknown runtime error");
306 ret = HLUA_E_ERRMSG;
307 break;
308
309 case LUA_ERRMEM:
310 lua_settop(lua->T, 0); /* Empty the stack. */
311 if (!lua_checkstack(lua->T, 1)) {
312 ret = HLUA_E_ERR;
313 break;
314 }
315 lua_pushfstring(lua->T, "out of memory error");
316 ret = HLUA_E_ERRMSG;
317 break;
318
319 case LUA_ERRERR:
320 if (!lua_checkstack(lua->T, 1)) {
321 ret = HLUA_E_ERR;
322 break;
323 }
324 msg = lua_tostring(lua->T, -1);
325 lua_settop(lua->T, 0); /* Empty the stack. */
326 lua_pop(lua->T, 1);
327 if (msg)
328 lua_pushfstring(lua->T, "message handler error: %s", msg);
329 else
330 lua_pushfstring(lua->T, "message handler error");
331 ret = HLUA_E_ERRMSG;
332 break;
333
334 default:
335 lua_settop(lua->T, 0); /* Empty the stack. */
336 if (!lua_checkstack(lua->T, 1)) {
337 ret = HLUA_E_ERR;
338 break;
339 }
340 lua_pushfstring(lua->T, "unknonwn error");
341 ret = HLUA_E_ERRMSG;
342 break;
343 }
344
345 switch (ret) {
346 case HLUA_E_AGAIN:
347 break;
348
349 case HLUA_E_ERRMSG:
350 hlua_ctx_renew(lua, 1);
351 lua->state = HLUA_STOP;
352 break;
353
354 case HLUA_E_ERR:
355 lua->state = HLUA_STOP;
356 hlua_ctx_renew(lua, 0);
357 break;
358
359 case HLUA_E_OK:
360 lua->state = HLUA_STOP;
361 break;
362 }
363
364 return ret;
365}
366
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +0100367void hlua_init(void)
368{
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100369 /* Init main lua stack. */
370 gL.Mref = LUA_REFNIL;
371 gL.state = HLUA_STOP;
372 gL.T = luaL_newstate();
373 hlua_sethlua(&gL);
374 gL.Tref = LUA_REFNIL;
375 gL.task = NULL;
376
377 /* Initialise lua. */
378 luaL_openlibs(gL.T);
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +0100379}