[395] | 1 | // Copyright (C) 2012-2015 ChaosForge Ltd
|
---|
[5] | 2 | // http://chaosforge.org/
|
---|
| 3 | //
|
---|
[395] | 4 | // This file is part of Nova libraries.
|
---|
| 5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
[5] | 6 |
|
---|
| 7 | #include "nv/lib/lua.hh"
|
---|
| 8 |
|
---|
[489] | 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 |
|
---|
[5] | 33 | #if defined( NV_LUA_DYNAMIC )
|
---|
| 34 |
|
---|
[319] | 35 | #include "nv/core/library.hh"
|
---|
[5] | 36 |
|
---|
[164] | 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
|
---|
[5] | 48 |
|
---|
[164] | 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
|
---|
[165] | 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 )
|
---|
[164] | 56 | #else
|
---|
[165] | 57 | # define NV_LUA_FUN_51( rtype, fname, fparams )
|
---|
| 58 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
[164] | 59 | #endif
|
---|
[5] | 60 |
|
---|
[164] | 61 | #include <nv/lib/detail/lua_functions.inc>
|
---|
[5] | 62 |
|
---|
[164] | 63 | #undef NV_LUA_FUN
|
---|
| 64 | #undef NV_LUA_FUN_51
|
---|
| 65 | #undef NV_LUA_FUN_52
|
---|
[5] | 66 |
|
---|
[166] | 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 ) \
|
---|
[198] | 77 | static rt call_##fn2##_compat fp { ret fn2##_compat arg; }
|
---|
[166] | 78 | # include <nv/lib/detail/lua_functions_compat.inc>
|
---|
| 79 | # undef NV_LUA_COMPAT_FUN
|
---|
| 80 |
|
---|
[489] | 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;
|
---|
[166] | 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)
|
---|
[173] | 93 | # define LUA_GLOBALSINDEX_52 2
|
---|
[166] | 94 | # define LUA_REGISTRYINDEX_51 (-10000)
|
---|
| 95 |
|
---|
[489] | 96 | static int lua_absindex_51( lua_State *L, int idx )
|
---|
[166] | 97 | {
|
---|
[489] | 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 )
|
---|
[166] | 117 | {
|
---|
| 118 | lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
|
---|
[489] | 119 | lua_pushvalue( L, -2 );
|
---|
| 120 | lua_setfield( L, -2, modname );
|
---|
| 121 | lua_pop( L, 1 );
|
---|
[166] | 122 | }
|
---|
| 123 | }
|
---|
| 124 |
|
---|
[489] | 125 | static void luaL_setmetatable_51( lua_State *L, const char *tname )
|
---|
[166] | 126 | {
|
---|
[489] | 127 | luaL_getmetatable( L, tname );
|
---|
| 128 | lua_setmetatable( L, -2 );
|
---|
[166] | 129 | }
|
---|
| 130 |
|
---|
[489] | 131 | static void *luaL_testudata_51( lua_State *L, int ud, const char *tname )
|
---|
[166] | 132 | {
|
---|
[489] | 133 | void *p = lua_touserdata( L, ud );
|
---|
| 134 | if ( p != NULL )
|
---|
| 135 | {
|
---|
| 136 | if ( lua_getmetatable( L, ud ) )
|
---|
[166] | 137 | {
|
---|
[489] | 138 | luaL_getmetatable( L, tname );
|
---|
| 139 | if ( !lua_rawequal( L, -1, -2 ) )
|
---|
| 140 | p = NULL;
|
---|
| 141 | lua_pop( L, 2 );
|
---|
[166] | 142 | return p;
|
---|
| 143 | }
|
---|
| 144 | }
|
---|
| 145 | return NULL;
|
---|
| 146 | }
|
---|
| 147 |
|
---|
[489] | 148 | static const lua_Number *lua_version_51( lua_State* )
|
---|
[166] | 149 | {
|
---|
[406] | 150 | static const lua_Number version = lua_Number( LUA_VERSION_NUM );
|
---|
[166] | 151 | return &version;
|
---|
| 152 | }
|
---|
| 153 |
|
---|
[489] | 154 | static void lua_copy_51( lua_State *L, int fromidx, int toidx )
|
---|
[166] | 155 | {
|
---|
| 156 | toidx = lua_absindex( L, toidx );
|
---|
| 157 | lua_pushvalue( L, fromidx );
|
---|
| 158 | lua_replace( L, toidx );
|
---|
| 159 | }
|
---|
| 160 |
|
---|
[489] | 161 | static int lua_compare_51( lua_State *L, int idx1, int idx2, int op )
|
---|
[166] | 162 | {
|
---|
[489] | 163 | switch ( op )
|
---|
[166] | 164 | {
|
---|
[489] | 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 );
|
---|
[172] | 168 | default:
|
---|
[166] | 169 | return 0;
|
---|
| 170 | }
|
---|
| 171 | }
|
---|
| 172 |
|
---|
[489] | 173 | static void lua_rawgetp_51( lua_State *L, int idx, const void *p )
|
---|
[166] | 174 | {
|
---|
| 175 | idx = lua_absindex( L, idx );
|
---|
[489] | 176 | void* pp = const_cast<void *>( p ); // EVIL
|
---|
[166] | 177 | lua_pushlightuserdata( L, pp );
|
---|
| 178 | lua_rawget( L, idx );
|
---|
| 179 | }
|
---|
| 180 |
|
---|
[489] | 181 | static void lua_rawsetp_51( lua_State *L, int idx, const void *p )
|
---|
[166] | 182 | {
|
---|
| 183 | idx = lua_absindex( L, idx );
|
---|
[489] | 184 | void* pp = const_cast<void *>( p ); // EVIL
|
---|
[166] | 185 | lua_pushlightuserdata( L, pp );
|
---|
| 186 | lua_insert( L, -1 );
|
---|
| 187 | lua_rawset( L, idx );
|
---|
| 188 | }
|
---|
| 189 |
|
---|
[489] | 190 | static int luaL_getsubtable_51( lua_State *L, int idx, const char *fname )
|
---|
[166] | 191 | {
|
---|
[489] | 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;
|
---|
[166] | 202 | }
|
---|
| 203 | }
|
---|
| 204 |
|
---|
[489] | 205 | static void luaL_setfuncs_51( lua_State *L, const luaL_Reg *l, int nup )
|
---|
[166] | 206 | {
|
---|
[489] | 207 | luaL_checkstack( L, nup, "too many upvalues" );
|
---|
| 208 | for ( ; l->name != NULL; l++ )
|
---|
[166] | 209 | {
|
---|
[489] | 210 | for ( int i = 0; i < nup; i++ )
|
---|
[166] | 211 | {
|
---|
[489] | 212 | lua_pushvalue( L, -nup );
|
---|
[166] | 213 | }
|
---|
[489] | 214 | lua_pushcclosure( L, l->func, nup );
|
---|
| 215 | lua_setfield( L, -( nup + 2 ), l->name );
|
---|
[166] | 216 | }
|
---|
[489] | 217 | lua_pop( L, nup );
|
---|
[166] | 218 | }
|
---|
| 219 |
|
---|
[489] | 220 | static void lua_pushglobaltable_51( lua_State* L )
|
---|
[166] | 221 | {
|
---|
| 222 | lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
|
---|
| 223 | }
|
---|
| 224 |
|
---|
[489] | 225 | static void lua_pushglobaltable_52( lua_State* L )
|
---|
[173] | 226 | {
|
---|
| 227 | lua_rawgeti( L, LUA_REGISTRYINDEX_52, LUA_GLOBALSINDEX_52 );
|
---|
| 228 | }
|
---|
| 229 |
|
---|
[489] | 230 |
|
---|
[166] | 231 | #endif
|
---|
| 232 |
|
---|
[489] | 233 | #if defined( NV_LUA_DYNAMIC )
|
---|
| 234 |
|
---|
[5] | 235 | bool nv::load_lua_library( const char* path )
|
---|
| 236 | {
|
---|
[109] | 237 | static nv::library lua_library;
|
---|
| 238 | if ( lua_library.is_open() ) return true;
|
---|
[166] | 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
|
---|
[5] | 252 |
|
---|
[406] | 253 | # define NV_LUA_FUN( rtype, fname, fparams ) void_assign( fname, lua_library.get(#fname) );
|
---|
[164] | 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
|
---|
[165] | 257 | # elif NV_LUA_VERSION == NV_LUA_51
|
---|
[164] | 258 | # define NV_LUA_FUN_51 NV_LUA_FUN
|
---|
| 259 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
[165] | 260 | # else
|
---|
| 261 | # define NV_LUA_FUN_51( rtype, fname, fparams )
|
---|
| 262 | # define NV_LUA_FUN_52( rtype, fname, fparams )
|
---|
[164] | 263 | # endif
|
---|
[109] | 264 |
|
---|
[165] | 265 | # include <nv/lib/detail/lua_functions.inc>
|
---|
[5] | 266 |
|
---|
[165] | 267 | # undef NV_LUA_FUN
|
---|
| 268 | # undef NV_LUA_FUN_51
|
---|
| 269 | # undef NV_LUA_FUN_52
|
---|
[166] | 270 |
|
---|
| 271 | #if NV_LUA_VERSION == NV_LUA_5C
|
---|
[406] | 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) );
|
---|
[166] | 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 ) \
|
---|
[406] | 278 | void_assign( fn2##_compat, lua_library.get(#fn2) ); \
|
---|
[166] | 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 );
|
---|
[173] | 295 | NV_LUA_LOAD( luaL_requiref );
|
---|
[166] | 296 |
|
---|
[173] | 297 | lua_pushglobaltable = lua_pushglobaltable_52;
|
---|
| 298 |
|
---|
[172] | 299 | LUA_UPVALUEINDEX = LUA_REGISTRYINDEX_52;
|
---|
[166] | 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 ) \
|
---|
[406] | 306 | void_assign(fn, lua_library.get(#fn) );
|
---|
[166] | 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;
|
---|
[173] | 322 | luaL_requiref = luaL_requiref_51;
|
---|
[166] | 323 |
|
---|
| 324 | NV_LUA_LOAD( lua_lessthan );
|
---|
| 325 | NV_LUA_LOAD( lua_equal );
|
---|
| 326 | lua_compare = lua_compare_51;
|
---|
[172] | 327 | LUA_UPVALUEINDEX = LUA_GLOBALSINDEX_51;
|
---|
[166] | 328 | LUA_REGISTRYINDEX = LUA_REGISTRYINDEX_51;
|
---|
| 329 | LUA_VERSION_NUM = 501;
|
---|
| 330 | }
|
---|
| 331 | # undef NV_LUA_LOAD
|
---|
| 332 | #endif
|
---|
| 333 |
|
---|
[5] | 334 | return true;
|
---|
| 335 | }
|
---|
| 336 |
|
---|
[489] | 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 |
|
---|
[5] | 365 | #endif
|
---|