1 | // Copyright (C) 2012-2015 ChaosForge Ltd
|
---|
2 | // http://chaosforge.org/
|
---|
3 | //
|
---|
4 | // This file is part of Nova libraries.
|
---|
5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
6 |
|
---|
7 | #include "nv/lib/lua.hh"
|
---|
8 |
|
---|
9 | #if NV_LUA_VERSION == NV_LUA_5C
|
---|
10 | size_t( *lua_rawlen ) ( lua_State *L, int idx ) = nullptr;
|
---|
11 | int( *lua_absindex ) ( lua_State *L, int idx ) = nullptr;
|
---|
12 | void( *lua_getglobal ) ( lua_State *L, const char *var ) = nullptr;
|
---|
13 | void( *lua_setglobal ) ( lua_State *L, const char *var ) = nullptr;
|
---|
14 | void( *luaL_requiref ) ( lua_State *L, const char *modname, lua_CFunction openf, int glb ) = nullptr;
|
---|
15 | void( *luaL_setmetatable ) ( lua_State *L, const char *tname ) = nullptr;
|
---|
16 | void* ( *luaL_testudata ) ( lua_State *L, int ud, const char *tname ) = nullptr;
|
---|
17 | void( *lua_copy ) ( lua_State *L, int fromidx, int toidx ) = nullptr;
|
---|
18 | int( *lua_compare ) ( lua_State *L, int idx1, int idx2, int op ) = nullptr;
|
---|
19 | void( *lua_rawgetp ) ( lua_State *L, int idx, const void *p ) = nullptr;
|
---|
20 | void( *lua_rawsetp ) ( lua_State *L, int idx, const void *p ) = nullptr;
|
---|
21 | void( *lua_pushglobaltable )( lua_State* L ) = nullptr;
|
---|
22 | void( *luaL_setfuncs ) ( lua_State *L, const luaL_Reg *l, int nup ) = nullptr;
|
---|
23 | int( *luaL_getsubtable ) ( lua_State *L, int idx, const char *fname ) = nullptr;
|
---|
24 |
|
---|
25 | const lua_Number* ( *lua_version ) ( lua_State *L ) = nullptr;
|
---|
26 |
|
---|
27 | // only loaded in 5.1 mode to implement lua_compare
|
---|
28 | static int( *lua_equal ) ( lua_State *L, int idx1, int idx2 ) = nullptr;
|
---|
29 | static int( *lua_lessthan ) ( lua_State *L, int idx1, int idx2 ) = nullptr;
|
---|
30 | #endif
|
---|
31 |
|
---|
32 |
|
---|
33 | #if defined( NV_LUA_DYNAMIC )
|
---|
34 |
|
---|
35 | #include "nv/core/library.hh"
|
---|
36 |
|
---|
37 | #if NV_LUA_VERSION == NV_LUA_52
|
---|
38 | # undef luaL_loadfile
|
---|
39 | # undef luaL_loadbuffer
|
---|
40 | # undef luaL_prepbuffer
|
---|
41 | # undef lua_tonumber
|
---|
42 | # undef lua_tointeger
|
---|
43 | # undef lua_tounsigned
|
---|
44 | # undef lua_call
|
---|
45 | # undef lua_pcall
|
---|
46 | # undef lua_yield
|
---|
47 | #endif
|
---|
48 |
|
---|
49 | #define NV_LUA_FUN( rtype, fname, fparams ) rtype (*fname) fparams = nullptr;
|
---|
50 | #if NV_LUA_VERSION == NV_LUA_52
|
---|
51 | # define NV_LUA_FUN_51( rtype, fname, fparams )
|
---|
52 | # define NV_LUA_FUN_52 NV_LUA_FUN
|
---|
53 | #elif NV_LUA_VERSION == NV_LUA_51
|
---|
54 | # define NV_LUA_FUN_51 NV_LUA_FUN
|
---|
55 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
56 | #else
|
---|
57 | # define NV_LUA_FUN_51( rtype, fname, fparams )
|
---|
58 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
59 | #endif
|
---|
60 |
|
---|
61 | #include <nv/lib/detail/lua_functions.inc>
|
---|
62 |
|
---|
63 | #undef NV_LUA_FUN
|
---|
64 | #undef NV_LUA_FUN_51
|
---|
65 | #undef NV_LUA_FUN_52
|
---|
66 |
|
---|
67 | #if NV_LUA_VERSION == NV_LUA_5C
|
---|
68 | # define NV_LUA_COMPAT_FUN( rt, fn, fp,u1,u2,u3,u4,u5 ) rt (*fn) fp = nullptr;
|
---|
69 | # include <nv/lib/detail/lua_functions_compat.inc>
|
---|
70 | # undef NV_LUA_COMPAT_FUN
|
---|
71 |
|
---|
72 | # define NV_LUA_COMPAT_FUN( u1,u2,u3,rt2,fn2,fp2,u4,u5 ) static rt2 (*fn2##_compat) fp2 = nullptr;
|
---|
73 | # include <nv/lib/detail/lua_functions_compat.inc>
|
---|
74 | # undef NV_LUA_COMPAT_FUN
|
---|
75 |
|
---|
76 | # define NV_LUA_COMPAT_FUN( rt, fn, fp, rt2, fn2, fp2,arg,ret ) \
|
---|
77 | static rt call_##fn2##_compat fp { ret fn2##_compat arg; }
|
---|
78 | # include <nv/lib/detail/lua_functions_compat.inc>
|
---|
79 | # undef NV_LUA_COMPAT_FUN
|
---|
80 |
|
---|
81 | #endif
|
---|
82 |
|
---|
83 | #endif
|
---|
84 |
|
---|
85 | #if NV_LUA_VERSION == NV_LUA_5C
|
---|
86 | int LUA_UPVALUEINDEX = 0;
|
---|
87 | int LUA_REGISTRYINDEX = 0;
|
---|
88 | int LUA_VERSION_NUM = 0;
|
---|
89 | # define LUAI_MAXSTACK_52 1000000
|
---|
90 | # define LUAI_FIRSTPSEUDOIDX_52 (-LUAI_MAXSTACK_52 - 1000)
|
---|
91 | # define LUA_REGISTRYINDEX_52 LUAI_FIRSTPSEUDOIDX_52
|
---|
92 | # define LUA_GLOBALSINDEX_51 (-10002)
|
---|
93 | # define LUA_GLOBALSINDEX_52 2
|
---|
94 | # define LUA_REGISTRYINDEX_51 (-10000)
|
---|
95 |
|
---|
96 | static int lua_absindex_51( lua_State *L, int idx )
|
---|
97 | {
|
---|
98 | return ( idx > 0 ? idx : idx + lua_gettop( L ) + 1 );
|
---|
99 | };
|
---|
100 |
|
---|
101 | static void lua_getglobal_51( lua_State *L, const char *var )
|
---|
102 | {
|
---|
103 | lua_getfield( L, LUA_GLOBALSINDEX_51, var );
|
---|
104 | };
|
---|
105 |
|
---|
106 | static void lua_setglobal_51( lua_State *L, const char *var )
|
---|
107 | {
|
---|
108 | lua_setfield( L, LUA_GLOBALSINDEX_51, var );
|
---|
109 | };
|
---|
110 |
|
---|
111 | static void luaL_requiref_51( lua_State *L, const char *modname, lua_CFunction openf, int glb )
|
---|
112 | {
|
---|
113 | lua_pushcfunction( L, openf );
|
---|
114 | lua_pushstring( L, modname );
|
---|
115 | lua_call( L, 1, 1 );
|
---|
116 | if ( glb != 0 )
|
---|
117 | {
|
---|
118 | lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
|
---|
119 | lua_pushvalue( L, -2 );
|
---|
120 | lua_setfield( L, -2, modname );
|
---|
121 | lua_pop( L, 1 );
|
---|
122 | }
|
---|
123 | }
|
---|
124 |
|
---|
125 | static void luaL_setmetatable_51( lua_State *L, const char *tname )
|
---|
126 | {
|
---|
127 | luaL_getmetatable( L, tname );
|
---|
128 | lua_setmetatable( L, -2 );
|
---|
129 | }
|
---|
130 |
|
---|
131 | static void *luaL_testudata_51( lua_State *L, int ud, const char *tname )
|
---|
132 | {
|
---|
133 | void *p = lua_touserdata( L, ud );
|
---|
134 | if ( p != NULL )
|
---|
135 | {
|
---|
136 | if ( lua_getmetatable( L, ud ) )
|
---|
137 | {
|
---|
138 | luaL_getmetatable( L, tname );
|
---|
139 | if ( !lua_rawequal( L, -1, -2 ) )
|
---|
140 | p = NULL;
|
---|
141 | lua_pop( L, 2 );
|
---|
142 | return p;
|
---|
143 | }
|
---|
144 | }
|
---|
145 | return NULL;
|
---|
146 | }
|
---|
147 |
|
---|
148 | static const lua_Number *lua_version_51( lua_State* )
|
---|
149 | {
|
---|
150 | static const lua_Number version = lua_Number( LUA_VERSION_NUM );
|
---|
151 | return &version;
|
---|
152 | }
|
---|
153 |
|
---|
154 | static void lua_copy_51( lua_State *L, int fromidx, int toidx )
|
---|
155 | {
|
---|
156 | toidx = lua_absindex( L, toidx );
|
---|
157 | lua_pushvalue( L, fromidx );
|
---|
158 | lua_replace( L, toidx );
|
---|
159 | }
|
---|
160 |
|
---|
161 | static int lua_compare_51( lua_State *L, int idx1, int idx2, int op )
|
---|
162 | {
|
---|
163 | switch ( op )
|
---|
164 | {
|
---|
165 | case LUA_OPEQ: return lua_equal( L, idx1, idx2 );
|
---|
166 | case LUA_OPLT: return lua_lessthan( L, idx1, idx2 );
|
---|
167 | case LUA_OPLE: return lua_lessthan( L, idx1, idx2 ) || lua_equal( L, idx1, idx2 );
|
---|
168 | default:
|
---|
169 | return 0;
|
---|
170 | }
|
---|
171 | }
|
---|
172 |
|
---|
173 | static void lua_rawgetp_51( lua_State *L, int idx, const void *p )
|
---|
174 | {
|
---|
175 | idx = lua_absindex( L, idx );
|
---|
176 | void* pp = const_cast<void *>( p ); // EVIL
|
---|
177 | lua_pushlightuserdata( L, pp );
|
---|
178 | lua_rawget( L, idx );
|
---|
179 | }
|
---|
180 |
|
---|
181 | static void lua_rawsetp_51( lua_State *L, int idx, const void *p )
|
---|
182 | {
|
---|
183 | idx = lua_absindex( L, idx );
|
---|
184 | void* pp = const_cast<void *>( p ); // EVIL
|
---|
185 | lua_pushlightuserdata( L, pp );
|
---|
186 | lua_insert( L, -1 );
|
---|
187 | lua_rawset( L, idx );
|
---|
188 | }
|
---|
189 |
|
---|
190 | static int luaL_getsubtable_51( lua_State *L, int idx, const char *fname )
|
---|
191 | {
|
---|
192 | lua_getfield( L, idx, fname );
|
---|
193 | if ( lua_istable( L, -1 ) ) return 1;
|
---|
194 | else
|
---|
195 | {
|
---|
196 | idx = lua_absindex( L, idx );
|
---|
197 | lua_pop( L, 1 );
|
---|
198 | lua_newtable( L );
|
---|
199 | lua_pushvalue( L, -1 );
|
---|
200 | lua_setfield( L, idx, fname );
|
---|
201 | return 0;
|
---|
202 | }
|
---|
203 | }
|
---|
204 |
|
---|
205 | static void luaL_setfuncs_51( lua_State *L, const luaL_Reg *l, int nup )
|
---|
206 | {
|
---|
207 | luaL_checkstack( L, nup, "too many upvalues" );
|
---|
208 | for ( ; l->name != NULL; l++ )
|
---|
209 | {
|
---|
210 | for ( int i = 0; i < nup; i++ )
|
---|
211 | {
|
---|
212 | lua_pushvalue( L, -nup );
|
---|
213 | }
|
---|
214 | lua_pushcclosure( L, l->func, nup );
|
---|
215 | lua_setfield( L, -( nup + 2 ), l->name );
|
---|
216 | }
|
---|
217 | lua_pop( L, nup );
|
---|
218 | }
|
---|
219 |
|
---|
220 | static void lua_pushglobaltable_51( lua_State* L )
|
---|
221 | {
|
---|
222 | lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
|
---|
223 | }
|
---|
224 |
|
---|
225 | static void lua_pushglobaltable_52( lua_State* L )
|
---|
226 | {
|
---|
227 | lua_rawgeti( L, LUA_REGISTRYINDEX_52, LUA_GLOBALSINDEX_52 );
|
---|
228 | }
|
---|
229 |
|
---|
230 |
|
---|
231 | #endif
|
---|
232 |
|
---|
233 | #if defined( NV_LUA_DYNAMIC )
|
---|
234 |
|
---|
235 | bool nv::load_lua_library( const char* path )
|
---|
236 | {
|
---|
237 | static nv::library lua_library;
|
---|
238 | if ( lua_library.is_open() ) return true;
|
---|
239 | #if NV_LUA_VERSION == NV_LUA_5C
|
---|
240 | if ( path == nullptr )
|
---|
241 | {
|
---|
242 | if (!lua_library.try_open( NV_LUA_PATH_JIT ) &&
|
---|
243 | !lua_library.try_open( NV_LUA_PATH_52 ) )
|
---|
244 | {
|
---|
245 | lua_library.open( NV_LUA_PATH_51 );
|
---|
246 | }
|
---|
247 | }
|
---|
248 | else
|
---|
249 | #else
|
---|
250 | lua_library.open( path );
|
---|
251 | #endif
|
---|
252 |
|
---|
253 | # define NV_LUA_FUN( rtype, fname, fparams ) void_assign( fname, lua_library.get(#fname) );
|
---|
254 | # if NV_LUA_VERSION == NV_LUA_52
|
---|
255 | # define NV_LUA_FUN_51( rtype, fname, fparams )
|
---|
256 | # define NV_LUA_FUN_52 NV_LUA_FUN
|
---|
257 | # elif NV_LUA_VERSION == NV_LUA_51
|
---|
258 | # define NV_LUA_FUN_51 NV_LUA_FUN
|
---|
259 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
260 | # else
|
---|
261 | # define NV_LUA_FUN_51( rtype, fname, fparams )
|
---|
262 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
263 | # endif
|
---|
264 |
|
---|
265 | # include <nv/lib/detail/lua_functions.inc>
|
---|
266 |
|
---|
267 | # undef NV_LUA_FUN
|
---|
268 | # undef NV_LUA_FUN_51
|
---|
269 | # undef NV_LUA_FUN_52
|
---|
270 |
|
---|
271 | #if NV_LUA_VERSION == NV_LUA_5C
|
---|
272 | # define NV_LUA_LOAD( fname ) void_assign( fname, lua_library.get(#fname) );
|
---|
273 | # define NV_LUA_LOAD_AS( fname,fname2 ) void_assign( fname, lua_library.get(#fname2) );
|
---|
274 | bool version_52 = lua_library.try_get("luaL_checkversion_") != nullptr;
|
---|
275 | if (version_52)
|
---|
276 | {
|
---|
277 | # define NV_LUA_COMPAT_FUN( u1, fn, u2, u3, fn2, u5, u6, u7 ) \
|
---|
278 | void_assign( fn2##_compat, lua_library.get(#fn2) ); \
|
---|
279 | fn = call_##fn2##_compat;
|
---|
280 | # include <nv/lib/detail/lua_functions_compat.inc>
|
---|
281 | # undef NV_LUA_COMPAT_FUN
|
---|
282 | NV_LUA_LOAD( lua_rawlen );
|
---|
283 | NV_LUA_LOAD( lua_absindex );
|
---|
284 | NV_LUA_LOAD( lua_getglobal );
|
---|
285 | NV_LUA_LOAD( lua_setglobal );
|
---|
286 | NV_LUA_LOAD( luaL_setmetatable );
|
---|
287 | NV_LUA_LOAD( luaL_testudata );
|
---|
288 | NV_LUA_LOAD( lua_version );
|
---|
289 | NV_LUA_LOAD( lua_copy );
|
---|
290 | NV_LUA_LOAD( lua_compare );
|
---|
291 | NV_LUA_LOAD( lua_rawgetp );
|
---|
292 | NV_LUA_LOAD( lua_rawsetp );
|
---|
293 | NV_LUA_LOAD( luaL_setfuncs );
|
---|
294 | NV_LUA_LOAD( luaL_getsubtable );
|
---|
295 | NV_LUA_LOAD( luaL_requiref );
|
---|
296 |
|
---|
297 | lua_pushglobaltable = lua_pushglobaltable_52;
|
---|
298 |
|
---|
299 | LUA_UPVALUEINDEX = LUA_REGISTRYINDEX_52;
|
---|
300 | LUA_REGISTRYINDEX = LUA_REGISTRYINDEX_52;
|
---|
301 | LUA_VERSION_NUM = 502;
|
---|
302 | }
|
---|
303 | else
|
---|
304 | {
|
---|
305 | # define NV_LUA_COMPAT_FUN( u1, fn, u2, u3, u4, u5, u6, u7 ) \
|
---|
306 | void_assign(fn, lua_library.get(#fn) );
|
---|
307 | # include <nv/lib/detail/lua_functions_compat.inc>
|
---|
308 | # undef NV_LUA_COMPAT_FUN
|
---|
309 | NV_LUA_LOAD_AS( lua_rawlen, lua_objlen )
|
---|
310 | lua_absindex = lua_absindex_51;
|
---|
311 | lua_getglobal = lua_getglobal_51;
|
---|
312 | lua_setglobal = lua_setglobal_51;
|
---|
313 | luaL_setmetatable = luaL_setmetatable_51;
|
---|
314 | luaL_testudata = luaL_testudata_51;
|
---|
315 | lua_version = lua_version_51;
|
---|
316 | lua_copy = lua_copy_51;
|
---|
317 | lua_rawgetp = lua_rawgetp_51;
|
---|
318 | lua_rawsetp = lua_rawsetp_51;
|
---|
319 | lua_pushglobaltable = lua_pushglobaltable_51;
|
---|
320 | luaL_setfuncs = luaL_setfuncs_51;
|
---|
321 | luaL_getsubtable = luaL_getsubtable_51;
|
---|
322 | luaL_requiref = luaL_requiref_51;
|
---|
323 |
|
---|
324 | NV_LUA_LOAD( lua_lessthan );
|
---|
325 | NV_LUA_LOAD( lua_equal );
|
---|
326 | lua_compare = lua_compare_51;
|
---|
327 | LUA_UPVALUEINDEX = LUA_GLOBALSINDEX_51;
|
---|
328 | LUA_REGISTRYINDEX = LUA_REGISTRYINDEX_51;
|
---|
329 | LUA_VERSION_NUM = 501;
|
---|
330 | }
|
---|
331 | # undef NV_LUA_LOAD
|
---|
332 | #endif
|
---|
333 |
|
---|
334 | return true;
|
---|
335 | }
|
---|
336 |
|
---|
337 | #else
|
---|
338 |
|
---|
339 | bool nv::load_lua_library( const char* path )
|
---|
340 | {
|
---|
341 | lua_rawlen = lua_objlen;
|
---|
342 | lua_absindex = lua_absindex_51;
|
---|
343 | lua_getglobal = lua_getglobal_51;
|
---|
344 | lua_setglobal = lua_setglobal_51;
|
---|
345 | luaL_setmetatable = luaL_setmetatable_51;
|
---|
346 | luaL_testudata = luaL_testudata_51;
|
---|
347 | lua_version = lua_version_51;
|
---|
348 | lua_copy = lua_copy_51;
|
---|
349 | lua_rawgetp = lua_rawgetp_51;
|
---|
350 | lua_rawsetp = lua_rawsetp_51;
|
---|
351 | lua_pushglobaltable = lua_pushglobaltable_51;
|
---|
352 | luaL_setfuncs = luaL_setfuncs_51;
|
---|
353 | luaL_getsubtable = luaL_getsubtable_51;
|
---|
354 | luaL_requiref = luaL_requiref_51;
|
---|
355 |
|
---|
356 | NV_LUA_LOAD( lua_lessthan );
|
---|
357 | NV_LUA_LOAD( lua_equal );
|
---|
358 | lua_compare = lua_compare_51;
|
---|
359 | LUA_UPVALUEINDEX = LUA_GLOBALSINDEX_51;
|
---|
360 | LUA_REGISTRYINDEX = LUA_REGISTRYINDEX_51;
|
---|
361 | LUA_VERSION_NUM = 501;
|
---|
362 | return true;
|
---|
363 | }
|
---|
364 |
|
---|
365 | #endif
|
---|