Changeset 166 for trunk


Ignore:
Timestamp:
07/17/13 03:28:22 (12 years ago)
Author:
epyon
Message:
  • library - try_open and try_get functions added for non-throwing access
  • lua - compatibility layer mode added - the whole system can bind to lua 5.1, 5.2 or LuaJIT as a *RUNTIME* choice
Location:
trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/lib/detail/lua_functions.inc

    r164 r166  
    127127NV_LUA_FUN_52( void  ,lua_upvaluejoin,(lua_State *L, int fidx1, int n1, int fidx2, int n2) );
    128128NV_LUA_FUN( int,lua_sethook,(lua_State *L, lua_Hook func, int mask, int count) );
    129 NV_LUA_FUN( lua_Hook,lua_gethook,(lua_State *L) );
     129NV_LUA_FUN_52( lua_Hook,lua_gethook,(lua_State *L) );
    130130NV_LUA_FUN( int,lua_gethookmask,(lua_State *L) );
    131131NV_LUA_FUN( int,lua_gethookcount,(lua_State *L) );
    132132
     133#if NV_LUA_VERSION != NV_LUA_5C
    133134/* buffer API */
    134135NV_LUA_FUN( void,luaL_buffinit, (lua_State *L, luaL_Buffer *B) );
     
    141142NV_LUA_FUN_52( void,luaL_pushresultsize,(luaL_Buffer *B, size_t sz) );
    142143NV_LUA_FUN_52( char *,luaL_buffinitsize,(lua_State *L, luaL_Buffer *B, size_t sz) );
     144#endif
    143145
    144146/* lualib API */
  • trunk/nv/lib/lua.hh

    r165 r166  
    3838//#define NV_LUA_SHARED
    3939
    40 #define NV_LUA_51     0
    41 #define NV_LUA_52     1
     40#define NV_LUA_5C     0
     41#define NV_LUA_51     1
     42#define NV_LUA_52     2
     43
     44#if NV_PLATFORM == NV_WINDOWS
     45#       define NV_LUA_PATH_51  "lua51.dll"
     46#       define NV_LUA_PATH_52  "lua52.dll"
     47#       define NV_LUA_PATH_JIT "luajit.dll"
     48#elif NV_PLATFORM == NV_APPLE
     49#       define NV_LUA_PATH_51  "lua5.1.dylib"
     50#       define NV_LUA_PATH_52  "lua5.2.dylib"
     51#       define NV_LUA_PATH_JIT "luajit.dylib"
     52#else
     53#       define NV_LUA_PATH_51  "lua5.1.so"
     54#       define NV_LUA_PATH_52  "lua5.2.so"
     55#       define NV_LUA_PATH_JIT "luajit.so"
     56#endif
     57
    4258
    4359#if !defined(NV_LUA_VERSION)
    44 #       define NV_LUA_VERSION NV_LUA_52
    45 #endif
     60#       define NV_LUA_VERSION     NV_LUA_5C
     61#endif
     62
    4663#if defined(NV_LUA_JIT)
    47 #       define NV_LUA_VERSION NV_LUA_51
    48 #endif
    49 
    50 #if NV_LUA_VERSION == NV_LUA_52
    51 #       if NV_PLATFORM == NV_WINDOWS
    52 #               define NV_LUA_PATH "lua52.dll"
    53 #       elif NV_PLATFORM == NV_APPLE
    54 #               define NV_LUA_PATH "lua5.2.dylib"
    55 #       else
    56 #               define NV_LUA_PATH "lua5.2.so"
     64#       if NV_LUA_VERSION == NV_LUA_52
     65#               error "LuaJIT requested with version 5.2!"
    5766#       endif
     67#endif
     68
     69#if NV_LUA_VERSION == NV_LUA_52
     70#       define NV_LUA_PATH NV_LUA_PATH_52
    5871#elif NV_LUA_VERSION == NV_LUA_51
    59 #       if NV_PLATFORM == NV_WINDOWS
    60 #               define NV_LUA_PATH "lua51.dll"
    61 #       elif NV_PLATFORM == NV_APPLE
    62 #               define NV_LUA_PATH "lua5.1.dylib"
    63 #       else
    64 #               define NV_LUA_PATH "lua5.1.so"
    65 #       endif
     72#       define NV_LUA_PATH NV_LUA_PATH_51
     73#elif NV_LUA_VERSION == NV_LUA_5C
     74#       define NV_LUA_PATH nullptr
    6675#else
    6776#       error "Unrecognized NV_LUA_VERSION!"
     
    6978
    7079#if defined(NV_LUA_JIT)
    71 #       if NV_PLATFORM == NV_WINDOWS
    72 #               define NV_LUA_PATH "luajit.dll"
    73 #       elif NV_PLATFORM == NV_APPLE
    74 #               define NV_LUA_PATH "luajit.dylib"
    75 #       else
    76 #               define NV_LUA_PATH "luajit.so"
    77 #       endif
     80#       define NV_LUA_PATH NV_LUA_PATH_JIT
    7881#endif
    7982
     
    9699#define LUA_UNSIGNED unsigned int
    97100
    98 #define LUAI_MAXSTACK           1000000
    99 #define LUAI_FIRSTPSEUDOIDX     (-LUAI_MAXSTACK - 1000)
    100101#define LUA_IDSIZE 60
    101102
     
    106107#       define LUA_VERSION_NUM          502
    107108#       define LUA_VERSION_RELEASE      "1"
    108 #else
    109 #       define LUA_VERSION_MAJOR        "5"
     109#elif NV_LUA_VERSION == NV_LUA_51
    110110#       define LUA_VERSION_MINOR        "1"
    111111#       define LUA_VERSION_NUM          501
    112112#       define LUA_VERSION_RELEASE      "4"
     113#else
     114#       define LUA_VERSION_MINOR        "?"
     115#       define LUA_VERSION_RELEASE      "?"
    113116#endif
    114117
     
    124127
    125128#if NV_LUA_VERSION == NV_LUA_52
     129#       define LUAI_MAXSTACK            1000000
     130#       define LUAI_FIRSTPSEUDOIDX      (-LUAI_MAXSTACK - 1000)
    126131#       define LUA_REGISTRYINDEX        LUAI_FIRSTPSEUDOIDX
    127132#       define lua_upvalueindex(i)      (LUA_REGISTRYINDEX - (i))
     
    177182} luaL_Reg;
    178183
     184/* TODO: make compat version - two buffers, decision at load time */
    179185#if NV_LUA_VERSION == NV_LUA_52
    180186typedef struct luaL_Buffer {
     
    333339#undef NV_LUA_FUN_51
    334340#undef NV_LUA_FUN_52
     341
     342#if NV_LUA_VERSION == NV_LUA_5C
     343#       define NV_LUA_COMPAT_FUN( rtype, fname, fparams,u1,u2,u3,u4,u5 ) extern rtype (*fname) fparams
     344#       include <nv/lib/detail/lua_functions_compat.inc>
     345#       undef NV_LUA_COMPAT_FUN
     346extern size_t (*lua_rawlen)        (lua_State *L, int idx);
     347extern int    (*lua_absindex)      (lua_State *L, int idx);
     348extern void   (*lua_getglobal)     (lua_State *L, const char *var);
     349extern void   (*lua_setglobal)     (lua_State *L, const char *var);
     350extern void   (*luaL_requiref)     (lua_State *L, const char *modname, lua_CFunction openf, int glb);
     351extern void   (*luaL_setmetatable) (lua_State *L, const char *tname);
     352extern void*  (*luaL_testudata)    (lua_State *L, int ud, const char *tname);
     353extern void   (*lua_copy)          (lua_State *L, int fromidx, int toidx);
     354#       define LUA_OPEQ 0
     355#       define LUA_OPLT 1
     356#       define LUA_OPLE 2
     357extern int    (*lua_compare)       (lua_State *L, int idx1, int idx2, int op);
     358extern void   (*lua_rawgetp)       (lua_State *L, int idx, const void *p);
     359extern void   (*lua_rawsetp)       (lua_State *L, int idx, const void *p);
     360extern void   (*lua_pushglobaltable)(lua_State* L);
     361extern void   (*luaL_setfuncs)     (lua_State *L, const luaL_Reg *l, int nup);
     362extern int    (*luaL_getsubtable)  (lua_State *L, int idx, const char *fname);
     363
     364extern const lua_Number* (*lua_version) (lua_State *L);
     365extern int LUA_REGISTRYINDEX;
     366extern int LUA_VERSION_NUM;
     367#define lua_tounsigned(L,idx) (lua_Number)lua_tointeger(L,idx)
     368#define lua_pushunsigned(L,u) lua_pushinteger(L,(lua_Integer)u)
     369#define lua_objlen lua_rawlen
     370#endif
    335371
    336372/* Macros */
     
    395431#else
    396432#endif
    397 
    398433}
    399434
  • trunk/nv/library.hh

    r109 r166  
    3434                /**
    3535                 * Opens the library
     36                 *
     37                 * Throws library_error on failure
    3638                 */
    3739                void open( const std::string& name );
     40
     41                /**
     42                 * Tries to open the library
     43                 *
     44                 * returns true if succeeded, false otherwise
     45                 */
     46                bool try_open( const std::string& name );
    3847
    3948                /**
     
    4958                /**
    5059                 * Get symbol from library
     60                 *
     61                 * Throws on symbol not found
    5162                 */
    5263                void* get( const std::string& symbol );
     64
     65                /**
     66                 * Get symbol from library
     67                 *
     68                 * Returns null if symbol not found
     69                 */
     70                void* try_get( const std::string& symbol );
    5371
    5472                /**
     
    7290                 * Opens the library and prepares it for getting symbols.
    7391                 * Needs to be done before any get call.
     92                 *
     93                 * returns true on success, false otherwise
    7494                 */
    75                 void open();
     95                bool open();
    7696
    7797                /**
  • trunk/src/lib/lua.cc

    r165 r166  
    4141#undef NV_LUA_FUN_52
    4242
     43#if NV_LUA_VERSION == NV_LUA_5C
     44#       define NV_LUA_COMPAT_FUN( rt, fn, fp,u1,u2,u3,u4,u5 ) rt (*fn) fp = nullptr;
     45#       include <nv/lib/detail/lua_functions_compat.inc>
     46#       undef NV_LUA_COMPAT_FUN
     47int LUA_REGISTRYINDEX = 0;
     48int LUA_VERSION_NUM   = 0;
     49size_t (*lua_rawlen)        (lua_State *L, int idx) = nullptr;
     50int    (*lua_absindex)      (lua_State *L, int idx) = nullptr;
     51void   (*lua_getglobal)     (lua_State *L, const char *var) = nullptr;
     52void   (*lua_setglobal)     (lua_State *L, const char *var) = nullptr;
     53void   (*luaL_requiref)     (lua_State *L, const char *modname, lua_CFunction openf, int glb) = nullptr;
     54void   (*luaL_setmetatable) (lua_State *L, const char *tname) = nullptr;
     55void*  (*luaL_testudata)    (lua_State *L, int ud, const char *tname) = nullptr;
     56void   (*lua_copy)          (lua_State *L, int fromidx, int toidx) = nullptr;
     57int    (*lua_compare)       (lua_State *L, int idx1, int idx2, int op) = nullptr;
     58void   (*lua_rawgetp)       (lua_State *L, int idx, const void *p) = nullptr;
     59void   (*lua_rawsetp)       (lua_State *L, int idx, const void *p) = nullptr;
     60void   (*lua_pushglobaltable)(lua_State* L) = nullptr;
     61void   (*luaL_setfuncs)     (lua_State *L, const luaL_Reg *l, int nup) = nullptr;
     62int    (*luaL_getsubtable)  (lua_State *L, int idx, const char *fname) = nullptr;
     63
     64const lua_Number* (*lua_version) (lua_State *L) = nullptr;
     65
     66// only loaded in 5.1 mode to implement lua_compare
     67int    (*lua_equal)        (lua_State *L, int idx1, int idx2) = nullptr;
     68int    (*lua_lessthan)     (lua_State *L, int idx1, int idx2) = nullptr;
     69
     70
     71#       define NV_LUA_COMPAT_FUN( u1,u2,u3,rt2,fn2,fp2,u4,u5 ) static rt2 (*fn2##_compat) fp2 = nullptr;
     72#       include <nv/lib/detail/lua_functions_compat.inc>
     73#       undef NV_LUA_COMPAT_FUN
     74
     75#       define NV_LUA_COMPAT_FUN( rt, fn, fp, rt2, fn2, fp2,arg,ret ) \
     76                rt call_##fn2##_compat fp { ret fn2##_compat arg; }
     77#       include <nv/lib/detail/lua_functions_compat.inc>
     78#       undef NV_LUA_COMPAT_FUN
     79
     80#       define LUAI_MAXSTACK_52             1000000
     81#       define LUAI_FIRSTPSEUDOIDX_52   (-LUAI_MAXSTACK_52 - 1000)
     82#       define LUA_REGISTRYINDEX_52         LUAI_FIRSTPSEUDOIDX_52
     83#       define LUA_GLOBALSINDEX_51      (-10002)
     84#       define LUA_REGISTRYINDEX_51     (-10000)
     85#       define lua_upvalueindex_51(i)   (LUA_GLOBALSINDEX_51-(i))
     86#       define lua_upvalueindex_52(i)   (LUA_REGISTRYINDEX_52-(i))
     87
     88int lua_absindex_51 (lua_State *L, int idx) { return (idx > 0 ? idx : idx + lua_gettop(L) + 1); };
     89void lua_getglobal_51 (lua_State *L, const char *var) { lua_getfield(L, LUA_GLOBALSINDEX_51, var ); };
     90void lua_setglobal_51 (lua_State *L, const char *var) { lua_setfield(L, LUA_GLOBALSINDEX_51, var ); };
     91void luaL_requiref_51 (lua_State *L, const char *modname, lua_CFunction openf, int glb)
     92{
     93        lua_pushcfunction(L, openf);
     94        lua_pushstring(L, modname);
     95        lua_call(L, 1, 1);
     96        if (glb != 0)
     97        {
     98                lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
     99                lua_pushvalue(L, -2);
     100                lua_setfield(L, -2, modname);
     101                lua_pop(L, 1);
     102        }
     103}
     104
     105void luaL_setmetatable_51 (lua_State *L, const char *tname)
     106{
     107        luaL_getmetatable(L, tname);
     108        lua_setmetatable(L, -2);
     109}
     110
     111void *luaL_testudata_51 (lua_State *L, int ud, const char *tname)
     112{
     113        void *p = lua_touserdata(L, ud);
     114        if (p != NULL)
     115        { 
     116                if (lua_getmetatable(L, ud))
     117                {
     118                        luaL_getmetatable(L, tname);
     119                        if ( !lua_rawequal(L, -1, -2))
     120                                p = NULL; 
     121                        lua_pop(L, 2);
     122                        return p;
     123                }
     124        }
     125        return NULL;
     126}
     127
     128const lua_Number *lua_version_51 (lua_State*)
     129{
     130        static const lua_Number version = (lua_Number)LUA_VERSION_NUM;
     131        return &version;
     132}
     133
     134void lua_copy_51 (lua_State *L, int fromidx, int toidx)
     135{
     136        toidx = lua_absindex( L, toidx );
     137        lua_pushvalue( L, fromidx );
     138        lua_replace( L, toidx );
     139}
     140
     141int lua_compare_51(lua_State *L, int idx1, int idx2, int op)
     142{
     143        switch (op)
     144        {
     145        case LUA_OPEQ : return lua_equal( L, idx1, idx2 );
     146        case LUA_OPLT : return lua_lessthan( L, idx1, idx2 );
     147        case LUA_OPLE : return lua_lessthan( L, idx1, idx2 ) || lua_equal( L, idx1, idx2 );
     148        default:
     149                return 0;
     150        }
     151}
     152
     153void lua_rawgetp_51(lua_State *L, int idx, const void *p)
     154{
     155        idx = lua_absindex( L, idx );
     156        void* pp = const_cast<void *>(p); // EVIL
     157        lua_pushlightuserdata( L, pp );
     158        lua_rawget( L, idx );
     159}
     160
     161void lua_rawsetp_51(lua_State *L, int idx, const void *p)
     162{
     163        idx = lua_absindex( L, idx );
     164        void* pp = const_cast<void *>(p); // EVIL
     165        lua_pushlightuserdata( L, pp );
     166        lua_insert( L, -1 );
     167        lua_rawset( L, idx );
     168}
     169
     170int luaL_getsubtable_51(lua_State *L, int idx, const char *fname)
     171{
     172        lua_getfield(L, idx, fname);
     173        if ( lua_istable(L, -1) ) return 1;
     174        else {
     175                idx = lua_absindex(L, idx);
     176                lua_pop(L, 1);
     177                lua_newtable(L);
     178                lua_pushvalue(L, -1);
     179                lua_setfield(L, idx, fname);
     180                return 0;
     181        }
     182}
     183
     184void luaL_setfuncs_51(lua_State *L, const luaL_Reg *l, int nup)
     185{
     186        luaL_checkstack(L, nup, "too many upvalues");
     187        for (; l->name != NULL; l++)
     188        {
     189                for (int i = 0; i < nup; i++)
     190                {
     191                        lua_pushvalue(L, -nup);
     192                }
     193                lua_pushcclosure(L, l->func, nup);
     194                lua_setfield(L, -(nup + 2), l->name);
     195        }
     196        lua_pop(L, nup);
     197}
     198
     199void lua_pushglobaltable_51(lua_State* L)
     200{
     201        lua_pushvalue( L, LUA_GLOBALSINDEX_51 );
     202}
     203
     204#endif
     205
    43206bool nv::load_lua_library( const char* path )
    44207{
    45208        static nv::library lua_library;
    46209        if ( lua_library.is_open() ) return true;
    47         lua_library.open( path );
     210#if NV_LUA_VERSION == NV_LUA_5C
     211        if ( path == nullptr )
     212        {
     213                if (!lua_library.try_open( NV_LUA_PATH_JIT ) &&
     214                        !lua_library.try_open( NV_LUA_PATH_52 ) )
     215                {
     216                        lua_library.open( NV_LUA_PATH_51 );
     217                }
     218        }
     219        else
     220#else
     221                lua_library.open( path );
     222#endif
    48223
    49224#       define NV_LUA_FUN( rtype, fname, fparams ) *(void **) (&fname) = lua_library.get(#fname);
     
    64239#       undef NV_LUA_FUN_51
    65240#       undef NV_LUA_FUN_52
     241
     242#if NV_LUA_VERSION == NV_LUA_5C
     243#       define NV_LUA_LOAD( fname ) *(void **) (&fname) = lua_library.get(#fname);
     244#       define NV_LUA_LOAD_AS( fname,fname2 ) *(void **) (&fname) = lua_library.get(#fname2);
     245        bool version_52 = lua_library.try_get("luaL_checkversion_") != nullptr;
     246        if (version_52)
     247        {
     248#       define NV_LUA_COMPAT_FUN( u1, fn, u2, u3, fn2, u5, u6, u7 ) \
     249        *(void **) (&(fn2##_compat)) = lua_library.get(#fn2); \
     250        fn = call_##fn2##_compat;
     251#       include <nv/lib/detail/lua_functions_compat.inc>
     252#       undef NV_LUA_COMPAT_FUN
     253                NV_LUA_LOAD( lua_rawlen );
     254                NV_LUA_LOAD( lua_absindex );
     255                NV_LUA_LOAD( lua_getglobal );
     256                NV_LUA_LOAD( lua_setglobal );
     257                NV_LUA_LOAD( luaL_setmetatable );
     258                NV_LUA_LOAD( luaL_testudata );
     259                NV_LUA_LOAD( lua_version );
     260                NV_LUA_LOAD( lua_copy );
     261                NV_LUA_LOAD( lua_compare );
     262                NV_LUA_LOAD( lua_rawgetp );
     263                NV_LUA_LOAD( lua_rawsetp );
     264                NV_LUA_LOAD( lua_pushglobaltable );
     265                NV_LUA_LOAD( luaL_setfuncs );
     266                NV_LUA_LOAD( luaL_getsubtable );
     267
     268                LUA_REGISTRYINDEX = LUA_REGISTRYINDEX_52;
     269                LUA_VERSION_NUM   = 502;
     270        }
     271        else
     272        {
     273#       define NV_LUA_COMPAT_FUN( u1, fn, u2, u3, u4, u5, u6, u7 ) \
     274                *(void **) (&fn) = lua_library.get(#fn);
     275#       include <nv/lib/detail/lua_functions_compat.inc>
     276#       undef NV_LUA_COMPAT_FUN
     277                NV_LUA_LOAD_AS( lua_rawlen, lua_objlen )
     278                lua_absindex        = lua_absindex_51;
     279                lua_getglobal       = lua_getglobal_51;
     280                lua_setglobal       = lua_setglobal_51;
     281                luaL_setmetatable   = luaL_setmetatable_51;
     282                luaL_testudata      = luaL_testudata_51;
     283                lua_version         = lua_version_51;
     284                lua_copy            = lua_copy_51;
     285                lua_rawgetp         = lua_rawgetp_51;
     286                lua_rawsetp         = lua_rawsetp_51;
     287                lua_pushglobaltable = lua_pushglobaltable_51;
     288                luaL_setfuncs       = luaL_setfuncs_51;
     289                luaL_getsubtable    = luaL_getsubtable_51;
     290
     291                NV_LUA_LOAD( lua_lessthan );
     292                NV_LUA_LOAD( lua_equal );
     293                lua_compare       = lua_compare_51;
     294                LUA_REGISTRYINDEX = LUA_REGISTRYINDEX_51;
     295                LUA_VERSION_NUM   = 501;
     296        }
     297#       undef NV_LUA_LOAD
     298#endif
     299
    66300        return true;
    67301}
  • trunk/src/library.cc

    r121 r166  
    4444{
    4545        m_name = name;
    46         open();
     46        if ( !open() )
     47        {
     48                m_handle = nullptr;
     49                NV_THROW( library_error, "Can't load library!", name );
     50        }
     51}
     52
     53bool nv::library::try_open( const std::string& name )
     54{
     55        m_name = name;
     56        if ( !open() )
     57        {
     58                m_handle = nullptr;
     59                return false;
     60        }
     61        return true;
    4762}
    4863
     
    5267}
    5368
    54 void library::open()
     69bool library::open( )
    5570{
    5671    if ( m_handle != NULL )
    5772    {
    58         return;
     73        return true;
    5974    }
    6075    NV_LOG( LOG_NOTICE, "library : loading '" + m_name + "'..." );
     
    7388    if ( m_handle == NULL )
    7489    {
    75         NV_THROW( library_error, "Can't load library!", name );
     90                NV_LOG( LOG_NOTICE, "library : '" + name + "' failed to open." );
     91                return false;
    7692    }
    7793    NV_LOG( LOG_NOTICE, "library : '" + name + "' loaded." );
     94        return true;
    7895}
    7996
     
    86103    }
    87104        return result;
     105}
     106
     107void* nv::library::try_get( const std::string& symbol )
     108{
     109        return (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
    88110}
    89111
Note: See TracChangeset for help on using the changeset viewer.