summaryrefslogtreecommitdiff
path: root/src/script/common/c_internal.h
blob: 452c2dd5e098e74198008619fe29c0c90bc99f86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

/******************************************************************************/
/******************************************************************************/
/* WARNING!!!! do NOT add this header in any include file or any code file    */
/*             not being a modapi file!!!!!!!!                                */
/******************************************************************************/
/******************************************************************************/

#pragma once

extern "C" {
#include <lua.h>
#include <lauxlib.h>
}

#include "config.h"
#include "common/c_types.h"


/*
	Define our custom indices into the Lua registry table.

	Lua 5.2 and above define the LUA_RIDX_LAST macro. Only numbers above that
	may be used for custom indices, anything else is reserved.

	Lua 5.1 / LuaJIT do not use any numeric indices (only string indices),
	so we can use numeric indices freely.
*/
#ifdef LUA_RIDX_LAST
#define CUSTOM_RIDX_BASE ((LUA_RIDX_LAST)+1)
#else
#define CUSTOM_RIDX_BASE 1
#endif

#define CUSTOM_RIDX_SCRIPTAPI           (CUSTOM_RIDX_BASE)
#define CUSTOM_RIDX_GLOBALS_BACKUP      (CUSTOM_RIDX_BASE + 1)
#define CUSTOM_RIDX_CURRENT_MOD_NAME    (CUSTOM_RIDX_BASE + 2)
#define CUSTOM_RIDX_BACKTRACE           (CUSTOM_RIDX_BASE + 3)

// Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata
#if defined(__aarch64__) && USE_LUAJIT
/* LuaJIT has a 47-bit limit for lightuserdata on this platform and we cannot
 * assume that the ScriptApi class was allocated at a fitting address. */
#define INDIRECT_SCRIPTAPI_RIDX 1
#else
#define INDIRECT_SCRIPTAPI_RIDX 0
#endif

// Pushes the error handler onto the stack and returns its index
#define PUSH_ERROR_HANDLER(L) \
	(lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE), lua_gettop((L)))

#define PCALL_RESL(L, RES) {                            \
	int result_ = (RES);                                \
	if (result_ != 0) {                                 \
		script_error((L), result_, NULL, __FUNCTION__); \
	}                                                   \
}

#define script_run_callbacks(L, nargs, mode) \
	script_run_callbacks_f((L), (nargs), (mode), __FUNCTION__)

// What script_run_callbacks does with the return values of callbacks.
// Regardless of the mode, if only one callback is defined,
// its return value is the total return value.
// Modes only affect the case where 0 or >= 2 callbacks are defined.
enum RunCallbacksMode
{
	// Returns the return value of the first callback
	// Returns nil if list of callbacks is empty
	RUN_CALLBACKS_MODE_FIRST,
	// Returns the return value of the last callback
	// Returns nil if list of callbacks is empty
	RUN_CALLBACKS_MODE_LAST,
	// If any callback returns a false value, the first such is returned
	// Otherwise, the first callback's return value (trueish) is returned
	// Returns true if list of callbacks is empty
	RUN_CALLBACKS_MODE_AND,
	// Like above, but stops calling callbacks (short circuit)
	// after seeing the first false value
	RUN_CALLBACKS_MODE_AND_SC,
	// If any callback returns a true value, the first such is returned
	// Otherwise, the first callback's return value (falseish) is returned
	// Returns false if list of callbacks is empty
	RUN_CALLBACKS_MODE_OR,
	// Like above, but stops calling callbacks (short circuit)
	// after seeing the first true value
	RUN_CALLBACKS_MODE_OR_SC,
	// Note: "a true value" and "a false value" refer to values that
	// are converted by readParam<bool> to true or false, respectively.
};

std::string script_get_backtrace(lua_State *L);
int script_exception_wrapper(lua_State *L, lua_CFunction f);
void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn);
void script_run_callbacks_f(lua_State *L, int nargs,
	RunCallbacksMode mode, const char *fxn);

enum class DeprecatedHandlingMode {
	Ignore,
	Log,
	Error
};

/**
 * Reads `deprecated_lua_api_handling` in settings, returns cached value.
 *
 * @return DeprecatedHandlingMode
 */
DeprecatedHandlingMode get_deprecated_handling_mode();

/**
 * Handles a deprecation warning based on user settings
 *
 * @param L Lua State
 * @param message The deprecation method
 * @param stack_depth How far on the stack to the first user function (ie: not builtin or core)
 */
void log_deprecated(lua_State *L, const std::string &message,
	int stack_depth=1);