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 | |