From 617654ed50e39412cc04922874364daa47966678 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Tue, 14 Aug 2012 22:01:15 +0200 Subject: code updated to build against Lua 5.1 and Lua 5.2 --- CHANGES | 4 ++++ docs/index.html | 8 +++++--- src/keeper.c | 2 +- src/lanes.c | 33 ++++++++++++++++++++------------- src/tools.c | 14 ++++++++------ src/tools.h | 27 ++++++++++++++++++++++----- 6 files changed, 60 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index b2882e7..30f73c2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ CHANGES: +CHANGE 44: BGe 13-Aug-2012 + * lanes code updated to build against Lua 5.1 and Lua 5.2 + * removed the search for MSVCR80.DLL when building for MinGW32 since it no longer seems to be necessary + CHANGE 43: BGe 09-Aug-2012 * fix possible crash at application shutdown when a race condition causes linda objects to be collected after the keeper states are cleaned up. diff --git a/docs/index.html b/docs/index.html index f082156..4e37fe6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -55,8 +55,8 @@


Copyright © 2007-12 Asko Kauppi, Benoit Germain. All rights reserved. -
Lua Lanes is published under the same MIT license as Lua 5.1. -

This document was revised on 09-Jul-12, and applies to version 3.1.5 +
Lua Lanes is published under the same MIT license as Lua 5.1 and 5.2. +

This document was revised on 13-Aug-12, and applies to version 3.1.6

@@ -74,6 +74,8 @@ Lanes is included into your software by the regular require "lanes" method. No C side programming is needed; all APIs are Lua side, and most existing extension modules should work seamlessly together with the multiple lanes. +

+ Starting with version 3.1.6, Lanes should build and run identically with either Lua 5.1 or Lua 5.2.

See comparison of Lua Lanes with other Lua multithreading solutions.

@@ -281,7 +283,7 @@ also in the new lanes. "base" or "" root level names, print, assert, unpack etc. - "coroutine"coroutine.* namespace (part of base in Lua 5.1) + "coroutine"coroutine.* namespace (part of base in Lua 5.1 and 5.2) "debug"debug.* namespace "io"io.* namespace "math"math.* namespace diff --git a/src/keeper.c b/src/keeper.c index 2629485..444a98e 100644 --- a/src/keeper.c +++ b/src/keeper.c @@ -116,7 +116,7 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create) lua_setglobal( K, "decoda_name"); // use package.loaders[2] to find keeper microcode - lua_getfield( K, LUA_GLOBALSINDEX, "package"); // package + lua_getglobal( K, "package"); // package lua_getfield( K, -1, "loaders"); // package package.loaders lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] lua_pushliteral( K, "lanes-keeper"); // package package.loaders package.loaders[2] "lanes-keeper" diff --git a/src/lanes.c b/src/lanes.c index 360990a..84f23e3 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -51,7 +51,7 @@ * ... */ -char const* VERSION = "3.1.5"; +char const* VERSION = "3.1.6"; /* =============================================================================== @@ -928,7 +928,7 @@ LUAG_FUNC( set_finalizer ) // push_registry_table( L, FINALIZER_REG_KEY, TRUE /*do create if none*/ ); - lua_pushinteger( L, lua_objlen(L,-1)+1 ); + lua_pushinteger( L, lua_rawlen(L,-1)+1 ); lua_pushvalue( L, 1 ); // copy of the function lua_settable( L, -3 ); @@ -966,7 +966,8 @@ static int run_finalizers( lua_State *L, int lua_rc ) // [-1]: { func [, ...] } // - for( n= (unsigned int)lua_objlen(L,-1); n>0; n-- ) { + for( n = (unsigned int)lua_rawlen( L, -1); n > 0; -- n) + { unsigned args= 0; lua_pushinteger( L,n ); lua_gettable( L, -2 ); @@ -1686,6 +1687,7 @@ LUAG_FUNC( thread_new ) if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); STACK_GROW( L, 2); + STACK_GROW( L2, 3); ASSERT_L( lua_gettop(L2) == 0); @@ -1769,13 +1771,15 @@ LUAG_FUNC( thread_new ) luaL_error( L, "Expected table, got %s", luaL_typename(L,glob)); lua_pushnil( L); + lua_pushglobaltable( L2); // Lua 5.2 wants us to push the globals table on the stack while( lua_next( L, glob)) { luaG_inter_copy( L, L2, 2); // moves the key/value pair to the L2 stack - // assign it in the globals table - lua_rawset( L2, LUA_GLOBALSINDEX); + // assign it in L2's globals table + lua_rawset( L2, -3); lua_pop( L, 1); } + lua_pop( L2, 1); STACK_END(L2, 0) STACK_END(L, 0) @@ -1845,7 +1849,7 @@ LUAG_FUNC( thread_new ) // Clear environment for the userdata // lua_newtable( L); - lua_setfenv( L, -2); + lua_setuservalue( L, -2); // Place 's' in registry, for 'cancel_test()' (even if 'cs'==0 we still // do cancel tests at pending send/receive). @@ -2134,7 +2138,7 @@ LUAG_FUNC( thread_index) // first, check that we don't already have an environment that holds the requested value { // If key is found in the environment, return it - lua_getfenv( L, UD); + lua_getuservalue( L, UD); lua_pushvalue( L, KEY); lua_rawget( L, ENV); if( !lua_isnil( L, -1)) @@ -2324,7 +2328,7 @@ LUAG_FUNC( wakeup_conv ) /*---=== Module linkage ===--- */ -static const struct luaL_reg lanes_functions [] = { +static const struct luaL_Reg lanes_functions [] = { {"linda", LG_linda}, {"now_secs", LG_now_secs}, {"wakeup_conv", LG_wakeup_conv}, @@ -2485,7 +2489,8 @@ LUAG_FUNC( configure ) // remove configure() (this function) from the module interface lua_pushnil( L); lua_setfield( L, -2, "configure"); - luaL_register(L, NULL, lanes_functions); + // add functions to the module's table + luaG_registerlibfuncs(L, lanes_functions); // metatable for threads // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join } @@ -2495,10 +2500,10 @@ LUAG_FUNC( configure ) lua_setfield( L, -2, "__gc"); lua_pushcfunction( L, LG_thread_index); lua_setfield( L, -2, "__index"); - lua_getfield( L, LUA_GLOBALSINDEX, "error"); + lua_getglobal( L, "error"); ASSERT_L( lua_isfunction( L, -1)); lua_setfield( L, -2, "cached_error"); - lua_getfield( L, LUA_GLOBALSINDEX, "tostring"); + lua_getglobal( L, "tostring"); ASSERT_L( lua_isfunction( L, -1)); lua_setfield( L, -2, "cached_tostring"); lua_pushcfunction( L, LG_thread_join); @@ -2526,10 +2531,12 @@ LUAG_FUNC( configure ) // register all native functions found in that module in the transferable functions database // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) populate_func_lookup_table( L, -1, name); + lua_pop( L, 1); // record all existing C/JIT-fast functions - populate_func_lookup_table( L, LUA_GLOBALSINDEX, NULL); + lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack + populate_func_lookup_table( L, -1, NULL); + lua_pop( L, 1); // done with globals table, pop it // Return nothing - lua_pop( L, 1); return 0; } diff --git a/src/tools.c b/src/tools.c index 65c70bf..c03433a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -171,7 +171,7 @@ FuncSubType luaG_getfuncsubtype( lua_State *L, int _i) } { int mustpush = 0, dumpres; - if( STACK_ABS( L, _i) != lua_gettop( L)) + if( lua_absindex( L, _i) != lua_gettop( L)) { lua_pushvalue( L, _i); mustpush = 1; @@ -376,7 +376,7 @@ static void populate_func_lookup_table_recur( lua_State *L, int _ctx_base, int _ void populate_func_lookup_table( lua_State *L, int _i, char const *_name) { int const ctx_base = lua_gettop( L) + 1; - int const in_base = STACK_ABS( L, _i); + int const in_base = lua_absindex( L, _i); int const start_depth = _name ? 1 : 0; //printf( "%p: populate_func_lookup_table('%s')\n", L, _name ? _name : "NULL"); STACK_GROW( L, 3); @@ -458,7 +458,9 @@ lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) } } // after opening base, register the functions it exported in our name<->function database - populate_func_lookup_table( L, LUA_GLOBALSINDEX, NULL); + lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack + populate_func_lookup_table( L, -1, NULL); + lua_pop( L, 1); STACK_MID( L, 0); if( libs) { @@ -594,7 +596,7 @@ luaG_IdFunction get_idfunc( lua_State *L, int index ) { luaG_IdFunction ret; - index = STACK_ABS( L, index); + index = lua_absindex( L, index); STACK_GROW(L,1); @@ -1006,7 +1008,7 @@ uint_t get_mt_id( lua_State *L, int i ) { static uint_t last_id= 0; uint_t id; - i = STACK_ABS( L, i); + i = lua_absindex( L, i); STACK_GROW(L,3); @@ -1296,7 +1298,7 @@ int luaG_nameof( lua_State* L) // push a table whose contents are strings that, when concatenated, produce unique name lua_newtable( L); // o nil {c} {fqn} // this is where we start the search - lua_pushvalue( L, LUA_GLOBALSINDEX); // o nil {c} {fqn} _G + lua_pushglobaltable( L); // o nil {c} {fqn} _G (void) discover_object_name_recur( L, 6666, 0); lua_pop( L, 3); // o "result" lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" diff --git a/src/tools.h b/src/tools.h index b8dc362..43582c5 100644 --- a/src/tools.h +++ b/src/tools.h @@ -4,16 +4,33 @@ #ifndef TOOLS_H #define TOOLS_H -#include "lua.h" +#include "lauxlib.h" #include "threading.h" // MUTEX_T #include -// Note: The < LUA_REGISTRYINDEX test is to leave registry/global/upvalue indices untouched -// -#define /*int*/ STACK_ABS(L,n) \ - ( ((n) >= 0 || (n) <= LUA_REGISTRYINDEX) ? (n) : lua_gettop(L) +(n) +1 ) +// M$ compiler doesn't support 'inline' keyword in C files... +#if defined( _MSC_VER) +#define inline __inline +#endif + +// code is now using Lua 5.2 API +// add Lua 5.2 API when building for Lua 5.1 +#if LUA_VERSION_NUM == 501 +#define lua_absindex( L, idx) (((idx) >= 0 || (idx) <= LUA_REGISTRYINDEX) ? (idx) : lua_gettop(L) + (idx) +1) +#define lua_pushglobaltable(L) lua_pushvalue( L, LUA_GLOBALSINDEX) +#define lua_setuservalue lua_setfenv +#define lua_getuservalue lua_getfenv +#define lua_rawlen lua_objlen +#define luaG_registerlibfuncs( L, _funcs) luaL_register( L, NULL, _funcs) +#endif // LUA_VERSION_NUM == 501 + +// wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way +#if LUA_VERSION_NUM == 502 +#define lua_equal( L, a, b) lua_compare( L, a, b, LUA_OPEQ) +#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0) +#endif // LUA_VERSION_NUM == 502 #ifdef NDEBUG #define _ASSERT_L(lua,c) /*nothing*/ -- cgit v1.2.3-55-g6feb