1 #pragma once 2 3 extern "C" { 4 #include <lua.h> 5 #include <lauxlib.h> 6 #include <lualib.h> 7 } 8 9 #include <cstdarg> 10 #include <cstdio> 11 #include <map> 12 #include <set> 13 #include <string> 14 #include <vector> 15 16 #include "maybe-bool.h" 17 18 using std::vector; 19 20 class CLua; 21 22 class lua_stack_cleaner 23 { 24 public: lua_stack_cleaner(lua_State * _ls)25 lua_stack_cleaner(lua_State *_ls) : ls(_ls), top(lua_gettop(_ls)) { } ~lua_stack_cleaner()26 ~lua_stack_cleaner() { lua_settop(ls, top); } 27 private: 28 lua_State *ls; 29 int top; 30 }; 31 32 class lua_call_throttle 33 { 34 public: 35 lua_call_throttle(CLua *handle); 36 ~lua_call_throttle(); 37 38 static CLua *find_clua(lua_State *ls); 39 40 private: 41 CLua *lua; 42 43 typedef map<lua_State *, CLua *> lua_clua_map; 44 static lua_clua_map lua_map; 45 }; 46 47 class lua_shutdown_listener 48 { 49 public: 50 virtual ~lua_shutdown_listener(); 51 virtual void shutdown(CLua &lua) = 0; 52 }; 53 54 // A convenience class to keep a reference to a lua object on the stack. 55 // This is useful to hang on to things that cannot be directly retrieved by 56 // C++ code, such as Lua function references. 57 class lua_datum : public lua_shutdown_listener 58 { 59 public: 60 lua_datum(CLua &lua, int stackpos = -1, bool pop = true); 61 lua_datum(const lua_datum &other); 62 63 const lua_datum &operator = (const lua_datum &other); 64 65 void shutdown(CLua &lua) override; 66 67 ~lua_datum(); 68 69 // Push the datum onto the Lua stack. 70 void push() const; 71 72 bool is_table() const; 73 bool is_function() const; 74 bool is_number() const; 75 bool is_string() const; 76 bool is_udata() const; 77 78 public: 79 CLua &lua; 80 81 private: 82 bool need_cleanup; 83 84 private: 85 void set_from(const lua_datum &o); 86 void cleanup(); 87 }; 88 89 class CLua 90 { 91 public: 92 CLua(bool managed = true); 93 ~CLua(); 94 95 static CLua &get_vm(lua_State *); 96 97 lua_State *state(); 98 99 operator lua_State * () 100 { 101 return state(); 102 } 103 104 void save(writer &outf); 105 void save_persist(); 106 void load_persist(); 107 void gc(); 108 109 void setglobal(const char *name); 110 void getglobal(const char *name); 111 112 // Assigns the value on top of the stack to a unique name in the registry 113 // and returns the name. 114 string setuniqregistry(); 115 116 void setregistry(const char *name); 117 void getregistry(const char *name); 118 119 int loadbuffer(const char *buf, size_t size, const char *context); 120 int loadstring(const char *str, const char *context); 121 int execstring(const char *str, const char *context = "init.txt", 122 int nresults = 0); 123 int execfile(const char *filename, 124 bool trusted = false, 125 bool die_on_fail = false, 126 bool force = false); 127 128 void pushglobal(const string &name); 129 130 maybe_bool callmbooleanfn(const char *fn, const char *params, ...); 131 maybe_bool callmaybefn(const char *fn, const char *params, ...); 132 bool callbooleanfn(bool defval, const char *fn, const char *params, ...); 133 bool callfn(const char *fn, int nargs, int nret = 1); 134 bool callfn(const char *fn, const char *params, ...); 135 void fnreturns(const char *params, ...); 136 bool runhook(const char *hook, const char *params, ...); 137 138 void add_shutdown_listener(lua_shutdown_listener *); 139 void remove_shutdown_listener(lua_shutdown_listener *); 140 141 static int file_write(lua_State *ls); 142 static int loadfile(lua_State *ls, const char *file, 143 bool trusted = false, bool die_on_fail = false); 144 static bool is_path_safe(string file, bool trusted = false); 145 146 static bool is_managed_vm(lua_State *ls); 147 148 void print_stack(); 149 150 /* Add the libaries and globals currently used by clua and dlua */ 151 void init_libraries(); 152 153 public: 154 string error; 155 156 // If managed_vm is set, we have to take steps to control badly-behaved 157 // scripts. 158 bool managed_vm; 159 bool shutting_down; 160 int throttle_unit_lines; 161 int throttle_sleep_ms; 162 int throttle_sleep_start, throttle_sleep_end; 163 int n_throttle_sleeps; 164 int mixed_call_depth; 165 int lua_call_depth; 166 int max_mixed_call_depth; 167 int max_lua_call_depth; 168 169 long memory_used; 170 171 static const int MAX_THROTTLE_SLEEPS = 100; 172 173 private: 174 lua_State *_state; 175 typedef set<string> sfset; 176 sfset sourced_files; 177 unsigned int uniqindex; 178 179 vector<lua_shutdown_listener*> shutdown_listeners; 180 181 private: 182 void init_lua(); 183 void set_error(int err, lua_State *ls = nullptr); 184 void init_throttle(); 185 186 static void _getregistry(lua_State *, const char *name); 187 188 void vfnreturns(const char *par, va_list va); 189 190 bool proc_returns(const char *par) const; 191 192 bool calltopfn(lua_State *ls, const char *format, va_list args, 193 int retc = -1, va_list *fnr = nullptr); 194 maybe_bool callmbooleanfn(const char *fn, const char *params, 195 va_list args); 196 maybe_bool callmaybefn(const char *fn, const char *params, 197 va_list args); 198 199 int push_args(lua_State *ls, const char *format, va_list args, 200 va_list *cpto = nullptr); 201 int return_count(lua_State *ls, const char *format); 202 203 struct CLuaSave 204 { 205 const char *filename; 206 FILE *handle; 207 208 FILE *get_file(); 209 }; 210 211 friend class lua_call_throttle; 212 }; 213 214 class lua_text_pattern : public base_pattern 215 { 216 public: 217 lua_text_pattern(const string &pattern); 218 ~lua_text_pattern(); 219 220 bool valid() const override; 221 bool matches(const string &s) const override; 222 pattern_match match_location(const string &s) const override; tostring()223 const string &tostring() const override { return pattern; } 224 225 static bool is_lua_pattern(const string &s); 226 227 private: 228 bool translated; 229 bool isvalid; 230 string pattern; 231 string lua_fn_name; 232 233 static unsigned int lfndx; 234 235 bool translate() const; 236 void pre_pattern(string &pat, string &fn) const; 237 void post_pattern(string &pat, string &fn) const; 238 239 static string new_fn_name(); 240 }; 241 242 // Defined in main.cc 243 #ifdef DEBUG_GLOBALS 244 #define clua (*real_clua) 245 #endif 246 extern CLua clua; 247 248 string quote_lua_string(const string &s); 249