| 1 | /** |
| 2 | * Copyright (c) 2006-2023 LOVE Development Team |
| 3 | * |
| 4 | * This software is provided 'as-is', without any express or implied |
| 5 | * warranty. In no event will the authors be held liable for any damages |
| 6 | * arising from the use of this software. |
| 7 | * |
| 8 | * Permission is granted to anyone to use this software for any purpose, |
| 9 | * including commercial applications, and to alter it and redistribute it |
| 10 | * freely, subject to the following restrictions: |
| 11 | * |
| 12 | * 1. The origin of this software must not be misrepresented; you must not |
| 13 | * claim that you wrote the original software. If you use this software |
| 14 | * in a product, an acknowledgment in the product documentation would be |
| 15 | * appreciated but is not required. |
| 16 | * 2. Altered source versions must be plainly marked as such, and must not be |
| 17 | * misrepresented as being the original software. |
| 18 | * 3. This notice may not be removed or altered from any source distribution. |
| 19 | **/ |
| 20 | |
| 21 | #ifndef LOVE_RUNTIME_H |
| 22 | #define LOVE_RUNTIME_H |
| 23 | |
| 24 | // LOVE |
| 25 | #include "config.h" |
| 26 | #include "types.h" |
| 27 | #include "deprecation.h" |
| 28 | |
| 29 | // Lua |
| 30 | extern "C" { |
| 31 | #define LUA_COMPAT_ALL |
| 32 | #include <lua.h> |
| 33 | #include <lualib.h> |
| 34 | #include <lauxlib.h> |
| 35 | } |
| 36 | |
| 37 | // C++ |
| 38 | #include <exception> |
| 39 | #include <algorithm> |
| 40 | |
| 41 | namespace love |
| 42 | { |
| 43 | |
| 44 | // Forward declarations. |
| 45 | class Object; |
| 46 | class Module; |
| 47 | class Reference; |
| 48 | |
| 49 | template<typename T> |
| 50 | class StrongRef; |
| 51 | |
| 52 | /** |
| 53 | * Registries represent special tables which can be accessed with |
| 54 | * luax_insistregistry and luax_getregistry. |
| 55 | **/ |
| 56 | enum Registry |
| 57 | { |
| 58 | REGISTRY_MODULES, |
| 59 | REGISTRY_OBJECTS |
| 60 | }; |
| 61 | |
| 62 | /** |
| 63 | * This structure wraps all Lua-exposed objects. It exists in the |
| 64 | * Lua state as a full userdata (so we can catch __gc "events"), |
| 65 | * though the Object it refers to is light userdata in the sense |
| 66 | * that it is not allocated by the Lua VM. |
| 67 | **/ |
| 68 | struct Proxy |
| 69 | { |
| 70 | // Holds type information (see types.h). |
| 71 | love::Type *type; |
| 72 | |
| 73 | // Pointer to the actual object. |
| 74 | Object *object; |
| 75 | }; |
| 76 | |
| 77 | /** |
| 78 | * A Module with Lua wrapper functions and other data. |
| 79 | **/ |
| 80 | struct WrappedModule |
| 81 | { |
| 82 | // The module containing the functions. |
| 83 | Module *module; |
| 84 | |
| 85 | // The name for the table to put the functions in, without the 'love'-prefix. |
| 86 | const char *name; |
| 87 | |
| 88 | // The type of this module. |
| 89 | love::Type *type; |
| 90 | |
| 91 | // The functions of the module (last element {0,0}). |
| 92 | const luaL_Reg *functions; |
| 93 | |
| 94 | // A list of functions which expose the types of the modules (last element 0). |
| 95 | const lua_CFunction *types; |
| 96 | }; |
| 97 | |
| 98 | /** |
| 99 | * Returns a reference to the top stack element (-1) if the value |
| 100 | * is of the specified type. If the value is incorrect, zero is returned. |
| 101 | * |
| 102 | * In any case, the top stack element is popped, regardless of its type. |
| 103 | **/ |
| 104 | Reference *luax_refif(lua_State *L, int type); |
| 105 | |
| 106 | /** |
| 107 | * Prints the current contents of the stack. Only useful for debugging. |
| 108 | * @param L The Lua state. |
| 109 | **/ |
| 110 | void luax_printstack(lua_State *L); |
| 111 | |
| 112 | /** |
| 113 | * Traceback function for use with lua_pcall. Calls debug.traceback. |
| 114 | **/ |
| 115 | int luax_traceback(lua_State *L); |
| 116 | |
| 117 | /** |
| 118 | * Gets whether the value at idx is an array of tables. |
| 119 | **/ |
| 120 | bool luax_isarrayoftables(lua_State *L, int idx); |
| 121 | |
| 122 | /** |
| 123 | * Converts the value at idx to a bool. It follow the same rules |
| 124 | * as lua_toboolean, but returns a bool instead of an int. |
| 125 | * @param L The Lua state. |
| 126 | * @param idx The index on the Lua stack. |
| 127 | * @return True if the value evaluates to true, false otherwise. |
| 128 | **/ |
| 129 | bool luax_toboolean(lua_State *L, int idx); |
| 130 | |
| 131 | /** |
| 132 | * Returns the boolean value at idx. Causes a Lua error if the value is not |
| 133 | * a boolean. |
| 134 | **/ |
| 135 | bool luax_checkboolean(lua_State *L, int idx); |
| 136 | |
| 137 | /** |
| 138 | * Pushes a bool onto the stack. It's the same as lua_pushboolean, |
| 139 | * but with bool instead of int. |
| 140 | * @param L The Lua state. |
| 141 | * @param b The bool to push. |
| 142 | **/ |
| 143 | void luax_pushboolean(lua_State *L, bool b); |
| 144 | |
| 145 | /** |
| 146 | * Converts the value at idx to a bool, or if not present, b is returned. |
| 147 | * @param L The Lua state. |
| 148 | * @param idx The index of the Lua stack. |
| 149 | * @param b The value to return if no value exist at the specified index. |
| 150 | * @return True if the value evaluates to true, false otherwise. |
| 151 | **/ |
| 152 | bool luax_optboolean(lua_State *L, int idx, bool b); |
| 153 | |
| 154 | /** |
| 155 | * Converts the value at idx to a std::string. It takes care of the string |
| 156 | * size and possible embedded nulls. |
| 157 | * @param L The Lua state. |
| 158 | * @param idx The index on the Lua stack. |
| 159 | * @return Copy of the string at the specified index. |
| 160 | **/ |
| 161 | std::string luax_tostring(lua_State *L, int idx); |
| 162 | |
| 163 | /** |
| 164 | * Converts the value at idx to a std::string. It takes care of the string |
| 165 | * size and possible embedded nulls. |
| 166 | * @param L The Lua state. |
| 167 | * @param idx The index on the Lua stack. |
| 168 | * @return Copy of the string at the specified index. |
| 169 | **/ |
| 170 | std::string luax_checkstring(lua_State *L, int idx); |
| 171 | |
| 172 | /** |
| 173 | * Pushes a std::string onto the stack. It uses the length of the string |
| 174 | * for lua_pushlstring's len argument. |
| 175 | * @param L The Lua state. |
| 176 | * @param str The string to push. |
| 177 | **/ |
| 178 | void luax_pushstring(lua_State *L, const std::string &str); |
| 179 | |
| 180 | /** |
| 181 | * Pushes a pointer onto the stack as a string (i.e. a new string with a length |
| 182 | * of 4 or 8 will be created, containing the given address in its bytes). |
| 183 | * This is a workaround for lua_pushlightuserdata not working on systems which |
| 184 | * use more than the lower 47 bits of address space, when LuaJIT is used. |
| 185 | **/ |
| 186 | void luax_pushpointerasstring(lua_State *L, const void *pointer); |
| 187 | |
| 188 | |
| 189 | bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue); |
| 190 | int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue); |
| 191 | double luax_numberflag(lua_State *L, int table_index, const char *key, double defaultValue); |
| 192 | |
| 193 | int luax_checkintflag(lua_State *L, int table_index, const char *key); |
| 194 | |
| 195 | /** |
| 196 | * Convert the value at the specified index to an Lua number, and then |
| 197 | * convert to a float. |
| 198 | * |
| 199 | * @param L The Lua state. |
| 200 | * @param idx The index on the stack. |
| 201 | */ |
| 202 | inline float luax_tofloat(lua_State *L, int idx) |
| 203 | { |
| 204 | return static_cast<float>(lua_tonumber(L, idx)); |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * Like luax_tofloat, but checks that the value is a number. |
| 209 | * |
| 210 | * @see luax_tofloat |
| 211 | */ |
| 212 | inline float luax_checkfloat(lua_State *L, int idx) |
| 213 | { |
| 214 | return static_cast<float>(luaL_checknumber(L, idx)); |
| 215 | } |
| 216 | |
| 217 | inline lua_Number luax_checknumberclamped01(lua_State *L, int idx) |
| 218 | { |
| 219 | return std::min(std::max(luaL_checknumber(L, idx), 0.0), 1.0); |
| 220 | } |
| 221 | |
| 222 | inline lua_Number luax_optnumberclamped01(lua_State *L, int idx, double def) |
| 223 | { |
| 224 | return std::min(std::max(luaL_optnumber(L, idx, def), 0.0), 1.0); |
| 225 | } |
| 226 | |
| 227 | /** |
| 228 | * Require at least 'min' number of items on the stack. |
| 229 | * @param L The Lua state. |
| 230 | * @param min The minimum number of items on the stack. |
| 231 | * @return Zero if conditions are met, otherwise a Lua error (longjmp). |
| 232 | **/ |
| 233 | int luax_assert_argc(lua_State *L, int min); |
| 234 | |
| 235 | /** |
| 236 | * Require at least 'min', but more than 'max' items on the stack. |
| 237 | * @param L The Lua state. |
| 238 | * @param min The minimum number of items on the stack. |
| 239 | * @param max The maximum number of items on the stack. |
| 240 | * @return Zero if conditions are met, otherwise a Lua error (longjmp). |
| 241 | **/ |
| 242 | int luax_assert_argc(lua_State *L, int min, int max); |
| 243 | |
| 244 | /** |
| 245 | * Require that the value at idx is a function. |
| 246 | * @param L The Lua state. |
| 247 | *@param idx The index on the stack. |
| 248 | **/ |
| 249 | int luax_assert_function(lua_State *L, int idx); |
| 250 | |
| 251 | /** |
| 252 | * Require that the value at idx is not nil. If it is, the function throws an |
| 253 | * error using an optional error string at idx+1. |
| 254 | * @param L The Lua state. |
| 255 | * @param idx The index on the stack. |
| 256 | **/ |
| 257 | int luax_assert_nilerror(lua_State *L, int idx); |
| 258 | |
| 259 | /** |
| 260 | * Registers all functions in the array l (see luaL_Reg) into the table at the |
| 261 | * top of the stack. |
| 262 | * Similar to Lua 5.2's luaL_setfuncs without the upvalues, and to Lua 5.1's |
| 263 | * luaL_register without the library name. |
| 264 | **/ |
| 265 | void luax_setfuncs(lua_State *L, const luaL_Reg *l); |
| 266 | |
| 267 | /** |
| 268 | * Loads a Lua module using the 'require' function. Leaves the return result on |
| 269 | * the stack. |
| 270 | * @param name The name of the module to require. |
| 271 | **/ |
| 272 | int luax_require(lua_State *L, const char *name); |
| 273 | |
| 274 | /** |
| 275 | * Register a module in the love table. The love table will be created if it does not exist. |
| 276 | * NOTE: The module-object is expected to have a +1 reference count before calling |
| 277 | * this function, as it doesn't retain the object itself but Lua will release it |
| 278 | * upon garbage collection. |
| 279 | * @param L The Lua state. |
| 280 | **/ |
| 281 | int luax_register_module(lua_State *L, const WrappedModule &m); |
| 282 | |
| 283 | /** |
| 284 | * Inserts a module with 'name' into the package.preloaded table. |
| 285 | * @param f The function to be called when the module is opened. |
| 286 | * @param name The name of the module, with 'love'-prefix, for instance 'love.graphics'. |
| 287 | **/ |
| 288 | int luax_preload(lua_State *L, lua_CFunction f, const char *name); |
| 289 | |
| 290 | /** |
| 291 | * Register a new type. |
| 292 | * NOTE: The type is passed by pointer instead of reference because calling va_start |
| 293 | * on a reference is undefined behaviour. |
| 294 | * @param type The type. |
| 295 | * @param ... The list of lists of member functions for the type. (of type luaL_Reg*) |
| 296 | **/ |
| 297 | int luax_register_type(lua_State *L, love::Type *type, ...); |
| 298 | |
| 299 | /** |
| 300 | * Pushes the metatable of the specified type onto the stack. |
| 301 | **/ |
| 302 | void luax_gettypemetatable(lua_State *L, const love::Type &type); |
| 303 | |
| 304 | /** |
| 305 | * Do a table.insert from C |
| 306 | * @param L the state |
| 307 | * @param tindex the stack index of the table |
| 308 | * @param vindex the stack index of the value |
| 309 | * @param pos the position to insert it in |
| 310 | **/ |
| 311 | int luax_table_insert(lua_State *L, int tindex, int vindex, int pos = -1); |
| 312 | |
| 313 | /** |
| 314 | * Register a new searcher function for package.loaders. This can for instance enable |
| 315 | * loading of files through love.filesystem using standard require. |
| 316 | * @param L The Lua state. |
| 317 | * @param f The searcher function. |
| 318 | * @param pos The position to insert the loader in. |
| 319 | **/ |
| 320 | int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1); |
| 321 | |
| 322 | /** |
| 323 | * Pushes a Lua representation of the given object onto the stack, creating and |
| 324 | * storing the Lua representation in a weak table if it doesn't exist yet. |
| 325 | * NOTE: The object will be retained by Lua and released upon garbage collection. |
| 326 | * @param L The Lua state. |
| 327 | * @param type The type information of the object. |
| 328 | * @param object The pointer to the actual object. |
| 329 | **/ |
| 330 | void luax_pushtype(lua_State *L, love::Type &type, love::Object *object); |
| 331 | |
| 332 | template <typename T> |
| 333 | void luax_pushtype(lua_State *L, T *object) |
| 334 | { |
| 335 | luax_pushtype(L, T::type, object); |
| 336 | } |
| 337 | |
| 338 | template <typename T> |
| 339 | void luax_pushtype(lua_State *L, StrongRef<T> &object) |
| 340 | { |
| 341 | luax_pushtype(L, T::type, object); |
| 342 | } |
| 343 | |
| 344 | /** |
| 345 | * Creates a new Lua representation of the given object *without* checking if it |
| 346 | * exists yet, and *without* storing it in a weak table. |
| 347 | * This should only be used when performance is an extreme concern and the |
| 348 | * object is not ever expected to be pushed to Lua again, as it prevents the |
| 349 | * Lua-side objects from working in some cases when used as keys in tables. |
| 350 | * NOTE: The object will be retained by Lua and released upon garbage collection. |
| 351 | * @param L The Lua state. |
| 352 | * @param type The type information of the object. |
| 353 | * @param object The pointer to the actual object. |
| 354 | **/ |
| 355 | void luax_rawnewtype(lua_State *L, love::Type &type, love::Object *object); |
| 356 | |
| 357 | /** |
| 358 | * Checks whether the value at idx is a certain type. |
| 359 | * @param L The Lua state. |
| 360 | * @param idx The index on the stack. |
| 361 | * @param type The type to check for. |
| 362 | * @return True if the value is Proxy of the specified type, false otherwise. |
| 363 | **/ |
| 364 | bool luax_istype(lua_State *L, int idx, love::Type &type); |
| 365 | |
| 366 | /** |
| 367 | * Gets the function love.module.function and puts it on top of the stack (alone). If the |
| 368 | * love table, the module, or the function does not exist, an error is returned. |
| 369 | * @return An error if nonexistent, or 1 if successful. |
| 370 | **/ |
| 371 | int luax_getfunction(lua_State *L, const char *module, const char *function); |
| 372 | |
| 373 | /** |
| 374 | * Converts an object into another object by the specified function love.module.function. |
| 375 | * The conversion function must accept a single object of the relevant type as a parameter, |
| 376 | * and returnone value. If the function does not exist (see luax_getfunction), an error is returned. |
| 377 | * |
| 378 | * Note that the initial object at idx is replaced by the new object. |
| 379 | * |
| 380 | * @param L The Lua state. |
| 381 | * @param idx The index on the stack. |
| 382 | * @param module The module in the love table. |
| 383 | * @param function The function in the module. |
| 384 | **/ |
| 385 | int luax_convobj(lua_State *L, int idx, const char *module, const char *function); |
| 386 | |
| 387 | /** |
| 388 | * Converts an object into another object by the specified function love.module.function. |
| 389 | * The conversion function must accept a single object of the relevant type as its first parameter, |
| 390 | * and return one value. If the function does not exist (see luax_getfunction), an error is returned. |
| 391 | * |
| 392 | * Note that the initial object at idx is replaced by the new object. |
| 393 | * |
| 394 | * @param L The Lua state. |
| 395 | * @param idxs An array of indices on the stack. |
| 396 | * @param n How many arguments are being passed. |
| 397 | * @param module The module in the love table. |
| 398 | * @param function The function in the module. |
| 399 | **/ |
| 400 | int luax_convobj(lua_State *L, const int idxs[], int n, const char *module, const char *function); |
| 401 | int luax_convobj(lua_State *L, const std::vector<int>& idxs, const char *module, const char *function); |
| 402 | |
| 403 | // pcall versions of the above |
| 404 | int luax_pconvobj(lua_State *L, int idx, const char *module, const char *function); |
| 405 | int luax_pconvobj(lua_State *L, const int idxs[], int n, const char *module, const char *function); |
| 406 | int luax_pconvobj(lua_State *L, const std::vector<int>& idxs, const char *module, const char *function); |
| 407 | |
| 408 | /** |
| 409 | * 'Insist' that a table 'k' exists in the table at idx. Insistence involves that the |
| 410 | * table (k) is created if it does not exist in the table at idx. The table at idx must |
| 411 | * pre-exist, however. Also note that if the a non-table value exists at the specified |
| 412 | * location, it will be overwritten with a new table. The insisted table, and only the |
| 413 | * insisted table, will be placed on top of the stack. |
| 414 | * |
| 415 | * @param idx The index on the stack containing a table. |
| 416 | * @param k The name of the table we are insisting exist. |
| 417 | **/ |
| 418 | int luax_insist(lua_State *L, int idx, const char *k); |
| 419 | |
| 420 | /** |
| 421 | * Insist that a global table 'k' exists. See luax_insist. |
| 422 | * @param k The name of the table we are insisting exist. |
| 423 | **/ |
| 424 | int luax_insistglobal(lua_State *L, const char *k); |
| 425 | |
| 426 | /** |
| 427 | * Insists that a table 'k' exists inside the 'love' table. See luax_insist. |
| 428 | * @param k The name of the table we are insisting exist. |
| 429 | **/ |
| 430 | int luax_insistlove(lua_State *L, const char *k); |
| 431 | |
| 432 | /** |
| 433 | * Pushes the table 'k' in the love table onto the stack. Pushes nil if the |
| 434 | * table doesn't exist. |
| 435 | * @param k The name of the table we want to get. |
| 436 | **/ |
| 437 | int luax_getlove(lua_State *L, const char *k); |
| 438 | |
| 439 | /** |
| 440 | * Gets (creates if needed) the specified Registry, and pushes it into the |
| 441 | * stack. |
| 442 | * @param L The Lua state. |
| 443 | * @param r The Registry to get. |
| 444 | **/ |
| 445 | int luax_insistregistry(lua_State *L, Registry r); |
| 446 | |
| 447 | /** |
| 448 | * Gets the specified Registry, and pushes it onto the stack. Pushes nil if the |
| 449 | * registry hasn't been created (see luax_insistregistry.) |
| 450 | * @param L The Lua state. |
| 451 | * @param r The Registry to get. |
| 452 | **/ |
| 453 | int luax_getregistry(lua_State *L, Registry r); |
| 454 | |
| 455 | /** |
| 456 | * Gets (and pins if needed) a "pinned" Lua thread (coroutine) in the specified |
| 457 | * Lua state. This will usually be the main Lua thread, unless the first call |
| 458 | * to this function for a specific Lua state is made from within a coroutine. |
| 459 | * NOTE: This does not push anything to the stack. |
| 460 | **/ |
| 461 | lua_State *luax_insistpinnedthread(lua_State *L); |
| 462 | |
| 463 | /** |
| 464 | * Gets a "pinned" Lua thread (coroutine) in the specified Lua state. This will |
| 465 | * usually be the main Lua thread. This can be used to access global variables |
| 466 | * in a specific Lua state without needing another alive lua_State value. |
| 467 | * PRECONDITION: luax_insistpinnedthread must have been called on a lua_State |
| 468 | * value corresponding to the Lua state which will be used with this function. |
| 469 | * NOTE: This does not push anything to the stack. |
| 470 | **/ |
| 471 | lua_State *luax_getpinnedthread(lua_State *L); |
| 472 | |
| 473 | /** |
| 474 | * Mark a function as deprecated. Should only be called inside wrapper function |
| 475 | * code. |
| 476 | **/ |
| 477 | void luax_markdeprecated(lua_State *L, const char *name, APIType api); |
| 478 | void luax_markdeprecated(lua_State *L, const char *name, APIType api, DeprecationType type, const char *replacement); |
| 479 | |
| 480 | extern "C" { // Also called from luasocket |
| 481 | int luax_typerror(lua_State *L, int narg, const char *tname); |
| 482 | } |
| 483 | |
| 484 | int luax_enumerror(lua_State *L, const char *enumName, const char *value); |
| 485 | int luax_enumerror(lua_State *L, const char *enumName, const std::vector<std::string> &values, const char *value); |
| 486 | |
| 487 | template <typename T> |
| 488 | void luax_checktablefields(lua_State *L, int idx, const char *enumName, bool (*getConstant)(const char *, T &)) |
| 489 | { |
| 490 | luaL_checktype(L, idx, LUA_TTABLE); |
| 491 | |
| 492 | // We want to error for invalid / misspelled fields in the table. |
| 493 | lua_pushnil(L); |
| 494 | while (lua_next(L, idx)) |
| 495 | { |
| 496 | if (lua_type(L, -2) != LUA_TSTRING) |
| 497 | luax_typerror(L, -2, "string" ); |
| 498 | |
| 499 | const char *key = luaL_checkstring(L, -2); |
| 500 | T constantvalue; |
| 501 | |
| 502 | if (!getConstant(key, constantvalue)) |
| 503 | luax_enumerror(L, enumName, key); |
| 504 | |
| 505 | lua_pop(L, 1); |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | void luax_runwrapper(lua_State *L, const char *filedata, size_t datalen, const char *filename, const love::Type &type, void *ffifuncs); |
| 510 | |
| 511 | /** |
| 512 | * Calls luax_objlen/lua_rawlen depending on version |
| 513 | **/ |
| 514 | size_t luax_objlen(lua_State *L, int ndx); |
| 515 | |
| 516 | extern "C" { // Called by enet and luasocket |
| 517 | void luax_register(lua_State *L, const char *name, const luaL_Reg *l); |
| 518 | int luax_c_insistglobal(lua_State *L, const char *k); |
| 519 | } |
| 520 | |
| 521 | /** |
| 522 | * Like luax_totype, but causes an error if the value at idx is not Proxy, |
| 523 | * or is not the specified type. |
| 524 | * @param L The Lua state. |
| 525 | * @param idx The index on the stack. |
| 526 | * @param type The type bit. |
| 527 | **/ |
| 528 | template <typename T> |
| 529 | T *luax_checktype(lua_State *L, int idx, const love::Type &type) |
| 530 | { |
| 531 | if (lua_type(L, idx) != LUA_TUSERDATA) |
| 532 | { |
| 533 | const char *name = type.getName(); |
| 534 | luax_typerror(L, idx, name); |
| 535 | } |
| 536 | |
| 537 | Proxy *u = (Proxy *)lua_touserdata(L, idx); |
| 538 | |
| 539 | if (u->type == nullptr || !u->type->isa(type)) |
| 540 | { |
| 541 | const char *name = type.getName(); |
| 542 | luax_typerror(L, idx, name); |
| 543 | } |
| 544 | |
| 545 | if (u->object == nullptr) |
| 546 | luaL_error(L, "Cannot use object after it has been released." ); |
| 547 | |
| 548 | return (T *)u->object; |
| 549 | } |
| 550 | |
| 551 | template <typename T> |
| 552 | T *luax_checktype(lua_State *L, int idx) |
| 553 | { |
| 554 | return luax_checktype<T>(L, idx, T::type); |
| 555 | } |
| 556 | |
| 557 | template <typename T> |
| 558 | T *luax_ffi_checktype(Proxy *p, const love::Type &type = T::type) |
| 559 | { |
| 560 | // FIXME: We need better type-checking... |
| 561 | if (p == nullptr || p->object == nullptr || p->type == nullptr || !p->type->isa(type)) |
| 562 | return nullptr; |
| 563 | return (T *) p->object; |
| 564 | } |
| 565 | |
| 566 | template <typename T> |
| 567 | T *luax_getmodule(lua_State *L, const love::Type &type) |
| 568 | { |
| 569 | const char *name = type.getName(); |
| 570 | |
| 571 | luax_insistregistry(L, REGISTRY_MODULES); |
| 572 | lua_getfield(L, -1, name); |
| 573 | |
| 574 | if (!lua_isuserdata(L, -1)) |
| 575 | luaL_error(L, "Tried to get nonexistent module %s." , name); |
| 576 | |
| 577 | Proxy *u = (Proxy *)lua_touserdata(L, -1); |
| 578 | |
| 579 | if (u->type == nullptr || !u->type->isa(type)) |
| 580 | luaL_error(L, "Incorrect module %s" , name); |
| 581 | |
| 582 | lua_pop(L, 2); |
| 583 | |
| 584 | return (T *)u->object; |
| 585 | } |
| 586 | |
| 587 | template <typename T> |
| 588 | T *luax_getmodule(lua_State *L) |
| 589 | { |
| 590 | return luax_getmodule<T>(L, T::type); |
| 591 | } |
| 592 | |
| 593 | template <typename T> |
| 594 | T *luax_optmodule(lua_State *L, const love::Type &type) |
| 595 | { |
| 596 | const char *name = type.getName(); |
| 597 | |
| 598 | luax_insistregistry(L, REGISTRY_MODULES); |
| 599 | lua_getfield(L, -1, name); |
| 600 | |
| 601 | if (!lua_isuserdata(L, -1)) |
| 602 | { |
| 603 | lua_pop(L, 2); |
| 604 | return 0; |
| 605 | } |
| 606 | |
| 607 | Proxy *u = (Proxy *)lua_touserdata(L, -1); |
| 608 | |
| 609 | if (!u->type->isa(type)) |
| 610 | luaL_error(L, "Incorrect module %s" , name); |
| 611 | |
| 612 | lua_pop(L, 2); |
| 613 | |
| 614 | return (T *) u->object; |
| 615 | } |
| 616 | |
| 617 | template <typename T> |
| 618 | T *luax_optmodule(lua_State *L) |
| 619 | { |
| 620 | return luax_optmodule<T>(L, T::type); |
| 621 | } |
| 622 | |
| 623 | /** |
| 624 | * Converts the value at idx to the specified type without checking that |
| 625 | * this conversion is valid. If the type has been previously verified with |
| 626 | * luax_istype, then this can be safely used. Otherwise, use luax_checktype. |
| 627 | * @param L The Lua state. |
| 628 | * @param idx The index on the stack. |
| 629 | * @param type The type of the object. |
| 630 | **/ |
| 631 | template <typename T> |
| 632 | T *luax_totype(lua_State *L, int idx, const love::Type& /*type*/) |
| 633 | { |
| 634 | T *o = (T *)(((Proxy *)lua_touserdata(L, idx))->object); |
| 635 | |
| 636 | if (o == nullptr) |
| 637 | luaL_error(L, "Cannot use object after it has been released." ); |
| 638 | |
| 639 | return o; |
| 640 | } |
| 641 | |
| 642 | template <typename T> |
| 643 | T *luax_totype(lua_State *L, int idx) |
| 644 | { |
| 645 | return luax_totype<T>(L, idx, T::type); |
| 646 | } |
| 647 | |
| 648 | Type *luax_type(lua_State *L, int idx); |
| 649 | |
| 650 | /** |
| 651 | * Converts any exceptions thrown by the passed lambda function into a Lua error. |
| 652 | * lua_error (and luaL_error) cannot be called from inside the exception handler |
| 653 | * because they use longjmp, which causes undefined behaviour when the |
| 654 | * destructor of the exception would have been called. |
| 655 | **/ |
| 656 | template <typename T> |
| 657 | int luax_catchexcept(lua_State *L, const T& func) |
| 658 | { |
| 659 | bool should_error = false; |
| 660 | |
| 661 | try |
| 662 | { |
| 663 | func(); |
| 664 | } |
| 665 | catch (const std::exception &e) |
| 666 | { |
| 667 | should_error = true; |
| 668 | lua_pushstring(L, e.what()); |
| 669 | } |
| 670 | |
| 671 | if (should_error) |
| 672 | return luaL_error(L, "%s" , lua_tostring(L, -1)); |
| 673 | |
| 674 | return 0; |
| 675 | } |
| 676 | |
| 677 | template <typename T, typename F> |
| 678 | int luax_catchexcept(lua_State *L, const T& func, const F& finallyfunc) |
| 679 | { |
| 680 | bool should_error = false; |
| 681 | |
| 682 | try |
| 683 | { |
| 684 | func(); |
| 685 | } |
| 686 | catch (const std::exception &e) |
| 687 | { |
| 688 | should_error = true; |
| 689 | lua_pushstring(L, e.what()); |
| 690 | } |
| 691 | |
| 692 | finallyfunc(should_error); |
| 693 | |
| 694 | if (should_error) |
| 695 | return luaL_error(L, "%s" , lua_tostring(L, -1)); |
| 696 | |
| 697 | return 0; |
| 698 | } |
| 699 | |
| 700 | /** |
| 701 | * Compatibility shim for lua_resume |
| 702 | * Exported because it's used in the launcher |
| 703 | **/ |
| 704 | LOVE_EXPORT int luax_resume(lua_State *L, int nargs, int* nres); |
| 705 | |
| 706 | } // love |
| 707 | |
| 708 | #endif // LOVE_RUNTIME_H |
| 709 | |