source: trunk/src/lib/lua.cc @ 509

Last change on this file since 509 was 489, checked in by epyon, 9 years ago
File size: 10.4 KB
Line 
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
10size_t( *lua_rawlen )        ( lua_State *L, int idx ) = nullptr;
11int( *lua_absindex )      ( lua_State *L, int idx ) = nullptr;
12void( *lua_getglobal )     ( lua_State *L, const char *var ) = nullptr;
13void( *lua_setglobal )     ( lua_State *L, const char *var ) = nullptr;
14void( *luaL_requiref )     ( lua_State *L, const char *modname, lua_CFunction openf, int glb ) = nullptr;
15void( *luaL_setmetatable ) ( lua_State *L, const char *tname ) = nullptr;
16void*  ( *luaL_testudata )    ( lua_State *L, int ud, const char *tname ) = nullptr;
17void( *lua_copy )          ( lua_State *L, int fromidx, int toidx ) = nullptr;
18int( *lua_compare )       ( lua_State *L, int idx1, int idx2, int op ) = nullptr;
19void( *lua_rawgetp )       ( lua_State *L, int idx, const void *p ) = nullptr;
20void( *lua_rawsetp )       ( lua_State *L, int idx, const void *p ) = nullptr;
21void( *lua_pushglobaltable )( lua_State* L ) = nullptr;
22void( *luaL_setfuncs )     ( lua_State *L, const luaL_Reg *l, int nup ) = nullptr;
23int( *luaL_getsubtable )  ( lua_State *L, int idx, const char *fname ) = nullptr;
24
25const lua_Number* ( *lua_version ) ( lua_State *L ) = nullptr;
26
27// only loaded in 5.1 mode to implement lua_compare
28static int( *lua_equal )        ( lua_State *L, int idx1, int idx2 ) = nullptr;
29static 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
86int LUA_UPVALUEINDEX = 0;
87int LUA_REGISTRYINDEX = 0;
88int 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
96static int lua_absindex_51( lua_State *L, int idx )
97{
98        return ( idx > 0 ? idx : idx + lua_gettop( L ) + 1 );
99};
100
101static void lua_getglobal_51( lua_State *L, const char *var )
102{
103        lua_getfield( L, LUA_GLOBALSINDEX_51, var );
104};
105
106static void lua_setglobal_51( lua_State *L, const char *var )
107{
108        lua_setfield( L, LUA_GLOBALSINDEX_51, var );
109};
110
111static 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
125static void luaL_setmetatable_51( lua_State *L, const char *tname )
126{
127        luaL_getmetatable( L, tname );
128        lua_setmetatable( L, -2 );
129}
130
131static 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
148static 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
154static 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
161static 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
173static 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
181static 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
190static 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
205static 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
220static void lua_pushglobaltable_51( lua_State* L )
221{
222        lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
223}
224
225static 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
235bool 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
339bool 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
Note: See TracBrowser for help on using the repository browser.