1 #ifndef LUA_SCRIPT_PRIVATE_H
2 #define LUA_SCRIPT_PRIVATE_H 1
3 
4 #include "dlua-script.h"
5 #include "lualib.h"
6 #include "lauxlib.h"
7 #include "dlua-compat.h"
8 
9 /* consistency helpers */
10 #define lua_isstring(L, n) (lua_isstring((L), (n)) == 1)
11 #define lua_isnumber(L, n) (lua_isnumber((L), (n)) == 1)
12 #define lua_toboolean(L, n) (lua_toboolean((L), (n)) == 1)
13 #define lua_pushboolean(L, b) lua_pushboolean((L), (b) ? 1 : 0)
14 #define lua_isinteger(L, n) (lua_isinteger((L), (n)) == 1)
15 
16 #define DLUA_TABLE_STRING(n, val) { .name = (n),\
17 				    .type = DLUA_TABLE_VALUE_STRING, .v.s = (val) }
18 #define DLUA_TABLE_INTEGER(n, val) { .name = (n), \
19 				    .type = DLUA_TABLE_VALUE_INTEGER, .v.i = (val) }
20 #define DLUA_TABLE_ENUM(n) { .name = #n, \
21 			     .type = DLUA_TABLE_VALUE_INTEGER, .v.i = (n) }
22 #define DLUA_TABLE_DOUBLE(n, val) { .name = (n), \
23 				    .type = DLUA_TABLE_VALUE_DOUBLE, .v.d = (val) }
24 #define DLUA_TABLE_BOOLEAN(n, val) { .name = (n), \
25 				     .type = DLUA_TABLE_VALUE_BOOLEAN, .v.b = (val) }
26 #define DLUA_TABLE_NULL(n, s) { .name = (n), \
27 			        .type = DLUA_TABLE_VALUE_NULL }
28 #define DLUA_TABLE_END { .name = NULL }
29 
30 #define DLUA_REQUIRE_ARGS_IN(L, x, y) \
31 	STMT_START { \
32 		if (lua_gettop(L) < (x) || lua_gettop(L) > (y)) { \
33 			return luaL_error((L), "expected %d to %d arguments, got %d", \
34 					  (x), (y), lua_gettop(L)); \
35 		} \
36 	} STMT_END
37 #define DLUA_REQUIRE_ARGS(L, x) \
38 	STMT_START { \
39 		if (lua_gettop(L) != (x)) { \
40 			return luaL_error((L), "expected %d arguments, got %d", \
41 					  (x), lua_gettop(L)); \
42 		} \
43 	} STMT_END
44 
45 struct dlua_script {
46 	struct dlua_script *prev,*next;
47 	pool_t pool;
48 
49 	lua_State *L; /* base lua context */
50 
51 	struct event *event;
52 	const char *filename;
53 	struct istream *in;
54 	ssize_t last_read;
55 
56 	int ref;
57 	bool init:1;
58 };
59 
60 enum dlua_table_value_type {
61 	DLUA_TABLE_VALUE_STRING = 0,
62 	DLUA_TABLE_VALUE_INTEGER,
63 	DLUA_TABLE_VALUE_DOUBLE,
64 	DLUA_TABLE_VALUE_BOOLEAN,
65 	DLUA_TABLE_VALUE_NULL
66 };
67 
68 struct dlua_table_values {
69 	const char *name;
70 	enum dlua_table_value_type type;
71 	union {
72 		const char *s;
73 		ptrdiff_t i;
74 		double d;
75 		bool b;
76 	} v;
77 };
78 
79 typedef void dlua_pcall_yieldable_callback_t(lua_State *L, void *context, int status);
80 
81 extern struct event_category event_category_lua;
82 
83 /* assorted wrappers for lua_foo(), but operating on a struct dlua_script */
84 void dlua_register(struct dlua_script *script, const char *name,
85 		   lua_CFunction f);
86 
87 /* Get dlua_script from lua_State */
88 struct dlua_script *dlua_script_from_state(lua_State *L);
89 
90 /* register 'dovecot' global */
91 void dlua_dovecot_register(struct dlua_script *script);
92 
93 /* push 'dovecot' global on top of stack */
94 void dlua_get_dovecot(lua_State *L);
95 
96 /* assign values to table on idx */
97 void dlua_set_members(lua_State *L, const struct dlua_table_values *values, int idx);
98 
99 /* push event to top of stack */
100 void dlua_push_event(lua_State *L, struct event *event);
101 
102 /* get event from given stack position */
103 struct event *dlua_check_event(lua_State *L, int arg);
104 
105 /* improved lua_pushfstring, can handle full C format support */
106 const char *dlua_push_vfstring(lua_State *L, const char *fmt, va_list argp) ATTR_FORMAT(2, 0);
107 const char *dlua_push_fstring(lua_State *L, const char *fmt, ...) ATTR_FORMAT(2, 3);
108 
109 /* improved luaL_error, can handle full C format support */
110 int dluaL_error(lua_State *L, const char *fmt, ...) ATTR_FORMAT(2, 3);
111 #define luaL_error(...) dluaL_error(__VA_ARGS__)
112 
113 /*
114  * Returns field from a Lua table
115  *
116  * There are different variants of these that allow for different key types
117  * and different value types.  In general, the function name scheme is:
118  *
119  *	dlua_table_get_<return type>_by_<key type>
120  *
121  * The _by_{str,int} variants use the supplied field value as the table key.
122  *
123  * The _by_thread variants use the current thread's thread object as the
124  * table key.
125  *
126  * Returns:
127  *   -1 = incompatible value type
128  *    0 = nil or not found
129  *    1 = value found
130  */
131 int dlua_table_get_luainteger_by_str(lua_State *L, int idx, const char *field, lua_Integer *value_r);
132 int dlua_table_get_int_by_str(lua_State *L, int idx, const char *field, int *value_r);
133 int dlua_table_get_intmax_by_str(lua_State *L, int idx, const char *field, intmax_t *value_r);
134 int dlua_table_get_uint_by_str(lua_State *L, int idx, const char *field, unsigned int *value_r);
135 int dlua_table_get_uintmax_by_str(lua_State *L, int idx, const char *field, uintmax_t *value_r);
136 int dlua_table_get_number_by_str(lua_State *L, int idx, const char *field, lua_Number *value_r);
137 int dlua_table_get_bool_by_str(lua_State *L, int idx, const char *field, bool *value_r);
138 int dlua_table_get_string_by_str(lua_State *L, int idx, const char *field, const char **value_r);
139 int dlua_table_get_data_by_str(lua_State *L, int idx, const char *field, const unsigned char **value_r, size_t *len_r);
140 
141 int dlua_table_get_luainteger_by_int(lua_State *L, int idx, lua_Integer field, lua_Integer *value_r);
142 int dlua_table_get_int_by_int(lua_State *L, int idx, lua_Integer field, int *value_r);
143 int dlua_table_get_intmax_by_int(lua_State *L, int idx, lua_Integer field, intmax_t *value_r);
144 int dlua_table_get_uint_by_int(lua_State *L, int idx, lua_Integer field, unsigned int *value_r);
145 int dlua_table_get_uintmax_by_int(lua_State *L, int idx, lua_Integer field, uintmax_t *value_r);
146 int dlua_table_get_number_by_int(lua_State *L, int idx, lua_Integer field, lua_Number *value_r);
147 int dlua_table_get_bool_by_int(lua_State *L, int idx, lua_Integer field, bool *value_r);
148 int dlua_table_get_string_by_int(lua_State *L, int idx, lua_Integer field, const char **value_r);
149 int dlua_table_get_data_by_int(lua_State *L, int idx, lua_Integer field, const unsigned char **value_r, size_t *len_r);
150 
151 int dlua_table_get_luainteger_by_thread(lua_State *L, int idx, lua_Integer *value_r);
152 int dlua_table_get_int_by_thread(lua_State *L, int idx, int *value_r);
153 int dlua_table_get_intmax_by_thread(lua_State *L, int idx, intmax_t *value_r);
154 int dlua_table_get_uint_by_thread(lua_State *L, int idx, unsigned int *value_r);
155 int dlua_table_get_uintmax_by_thread(lua_State *L, int idx, uintmax_t *value_r);
156 int dlua_table_get_number_by_thread(lua_State *L, int idx, lua_Number *value_r);
157 int dlua_table_get_bool_by_thread(lua_State *L, int idx, bool *value_r);
158 int dlua_table_get_string_by_thread(lua_State *L, int idx, const char **value_r);
159 int dlua_table_get_data_by_thread(lua_State *L, int idx, const unsigned char **value_r, size_t *len_r);
160 
161 /*
162  * Pushes onto the stack the value t[k], where t is the value at the given
163  * index and k is field argument.  Unlike lua_gettable(), this function
164  * checks the type of the retrieved value against the passed in type.
165  * [-1,+0..1,e]
166  *
167  * There are different variants of these that allow for different key types.
168  * In general, the function name scheme is:
169  *
170  *	dlua_table_get_by_<key type>
171  *
172  * The _by_{str,int} variants use the supplied field value as the table key.
173  *
174  * The _by_thread variants use the current thread's thread object as the
175  * table key.
176  *
177  * Returns:
178  *   -1 = incompatible value type (nothing is pushed)
179  *    0 = nil or not found (nothing is pushed)
180  *    1 = value found (retrieved value is pushed to the top of the stack)
181  */
182 int dlua_table_get_by_str(lua_State *L, int idx, int type, const char *field);
183 int dlua_table_get_by_int(lua_State *L, int idx, int type, lua_Integer field);
184 int dlua_table_get_by_thread(lua_State *L, int idx, int type);
185 
186 /* call a function in a script.
187 
188   **NOTE**: This function works differently than lua_pcall:
189 
190     return value:
191      -1 = error
192      0+ = number of result(s)
193 
194 */
195 int dlua_pcall(lua_State *L, const char *func_name, int nargs, int nresults,
196 	       const char **error_r);
197 
198 /* dumps current stack as i_debug lines */
199 void dlua_dump_stack(lua_State *L);
200 
201 /* Create new thread and keep track of it. */
202 lua_State *dlua_script_new_thread(struct dlua_script *script);
203 
204 /* Close thread. */
205 void dlua_script_close_thread(struct dlua_script *script, lua_State **_L);
206 
207 #ifdef DLUA_WITH_YIELDS
208 /*
209  * Call a function with nargs in a way that supports yielding.
210  *
211  * When the specified function returns, the callback will be called with the
212  * supplied context pointer and a status integer indicating whether an error
213  * occurred (-1) or whether execution completed successfully (0+).  In the
214  * case of a successful completion, the status will indicate the number of
215  * results returned by the function.  On failure, the top of the stack
216  * contains the error object.
217  *
218  * Returns:
219  *  -1 = if function name refers to a non-function type
220  *   0 = function called, callback will be called in the future
221  */
222 int dlua_pcall_yieldable(lua_State *L, const char *func_name, int nargs,
223 			 dlua_pcall_yieldable_callback_t *callback,
224 			 void *context, const char **error_r);
225 #define dlua_pcall_yieldable(L, func_name, nargs, callback, context, error_r) \
226 	dlua_pcall_yieldable(L, TRUE ? func_name : \
227 		CALLBACK_TYPECHECK(callback, void (*)(lua_State *, typeof(context), int)), \
228 		nargs, (dlua_pcall_yieldable_callback_t *)callback, context, error_r)
229 /*
230  * Resume yielded function execution.
231  *
232  * The nargs argument indicates how many items from the top of the stack
233  * should be "returned" by the yield.
234  *
235  * This function is to be called from other API callbacks to resume
236  * execution of the Lua script.  For example, if a Lua script invokes a
237  * function to perform I/O, the function would start the async I/O and yield
238  * from the script.  Eventually, the I/O completion callback executes, which
239  * would call dlua_pcall_yieldable_resume() to continue executing the Lua
240  * script with the supplied arguments.
241  *
242  * Note: The actual execution doesn't resume immediately.  Rather, it is
243  * scheduled to start in the near future via a timeout.
244  */
245 void dlua_pcall_yieldable_resume(lua_State *L, int nargs);
246 #endif
247 
248 /* initialize/free script's thread table */
249 void dlua_init_thread_table(struct dlua_script *script);
250 void dlua_free_thread_table(struct dlua_script *script);
251 
252 /* thread local storage (TLS) getters & setters */
253 void dlua_tls_set_ptr(lua_State *L, const char *name, void *ptr);
254 void *dlua_tls_get_ptr(lua_State *L, const char *name);
255 void dlua_tls_set_int(lua_State *L, const char *name, lua_Integer i);
256 lua_Integer dlua_tls_get_int(lua_State *L, const char *name);
257 
258 /* free a thread local storage (TLS) value */
259 void dlua_tls_clear(lua_State *L, const char *name);
260 
261 #endif
262