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