Add support for Lua 5.2

master
Robert G. Jakabosky 14 years ago
parent 2a68693f07
commit 58b5d127c9

@ -10,6 +10,54 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
/* some Lua 5.0 compatibility support. */
#if !defined(lua_pushliteral)
#define lua_pushliteral(L, s) lua_pushstring(L, "" s, (sizeof(s)/sizeof(char))-1)
#endif
#if !defined(LUA_VERSION_NUM)
#define lua_pushinteger(L, n) lua_pushnumber(L, (lua_Number)n)
#define luaL_Reg luaL_reg
#endif
/* some Lua 5.1 compatibility support. */
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM == 501)
/*
** Adapted from Lua 5.2.0
*/
static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name != NULL; l++) { /* fill the table with given functions */
int i;
for (i = 0; i < nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushstring(L, l->name);
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
lua_settable(L, -(nup + 3));
}
lua_pop(L, nup); /* remove upvalues */
}
#define lua_load_no_mode(L, reader, data, source) \
lua_load(L, reader, data, source)
#define lua_rawlen(L, idx) lua_objlen(L, idx)
#endif
#if LUA_VERSION_NUM == 502
#define lua_load_no_mode(L, reader, data, source) \
lua_load(L, reader, data, source, NULL)
static int luaL_typerror (lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg);
}
#endif
#define REG_PACKAGE_IS_CONSTRUCTOR 0 #define REG_PACKAGE_IS_CONSTRUCTOR 0
#define REG_MODULES_AS_GLOBALS 0 #define REG_MODULES_AS_GLOBALS 0
#define REG_OBJECTS_AS_GLOBALS 0 #define REG_OBJECTS_AS_GLOBALS 0
@ -189,9 +237,9 @@ typedef struct reg_impl {
typedef struct reg_sub_module { typedef struct reg_sub_module {
obj_type *type; obj_type *type;
module_reg_type req_type; module_reg_type req_type;
const luaL_reg *pub_funcs; const luaL_Reg *pub_funcs;
const luaL_reg *methods; const luaL_Reg *methods;
const luaL_reg *metas; const luaL_Reg *metas;
const obj_base *bases; const obj_base *bases;
const obj_field *fields; const obj_field *fields;
const obj_const *constants; const obj_const *constants;
@ -326,7 +374,7 @@ static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name,
lua_settable(L, priv_table); lua_settable(L, priv_table);
ffi_exports++; ffi_exports++;
} }
err = lua_load(L, nobj_lua_Reader, &state, ffi_mod_name); err = lua_load_no_mode(L, nobj_lua_Reader, &state, ffi_mod_name);
if(0 == err) { if(0 == err) {
lua_pushvalue(L, -2); /* dup C module's table. */ lua_pushvalue(L, -2); /* dup C module's table. */
lua_pushvalue(L, priv_table); /* move priv_table to top of stack. */ lua_pushvalue(L, priv_table); /* move priv_table to top of stack. */
@ -531,6 +579,12 @@ static void obj_type_register_implements(lua_State *L, const reg_impl *impls) {
#define REG_MODULES_AS_GLOBALS 0 #define REG_MODULES_AS_GLOBALS 0
#endif #endif
/* For Lua 5.2 don't register modules as globals. */
#if LUA_VERSION_NUM == 502
#undef REG_MODULES_AS_GLOBALS
#define REG_MODULES_AS_GLOBALS 0
#endif
#ifndef REG_OBJECTS_AS_GLOBALS #ifndef REG_OBJECTS_AS_GLOBALS
#define REG_OBJECTS_AS_GLOBALS 0 #define REG_OBJECTS_AS_GLOBALS 0
#endif #endif
@ -591,7 +645,7 @@ static FUNC_UNUSED obj_udata *obj_udata_toobj(lua_State *L, int _index) {
luaL_typerror(L, _index, "userdata"); /* is not a userdata value. */ luaL_typerror(L, _index, "userdata"); /* is not a userdata value. */
} }
/* verify userdata size. */ /* verify userdata size. */
len = lua_objlen(L, _index); len = lua_rawlen(L, _index);
if(len != sizeof(obj_udata)) { if(len != sizeof(obj_udata)) {
/* This shouldn't be possible */ /* This shouldn't be possible */
luaL_error(L, "invalid userdata size: size=%d, expected=%d", len, sizeof(obj_udata)); luaL_error(L, "invalid userdata size: size=%d, expected=%d", len, sizeof(obj_udata));
@ -1007,9 +1061,9 @@ static FUNC_UNUSED void *obj_simple_udata_luapush(lua_State *L, void *obj, int s
/* default simple object equal method. */ /* default simple object equal method. */
static FUNC_UNUSED int obj_simple_udata_default_equal(lua_State *L) { static FUNC_UNUSED int obj_simple_udata_default_equal(lua_State *L) {
void *ud1 = obj_simple_udata_toobj(L, 1); void *ud1 = obj_simple_udata_toobj(L, 1);
size_t len1 = lua_objlen(L, 1); size_t len1 = lua_rawlen(L, 1);
void *ud2 = obj_simple_udata_toobj(L, 2); void *ud2 = obj_simple_udata_toobj(L, 2);
size_t len2 = lua_objlen(L, 2); size_t len2 = lua_rawlen(L, 2);
if(len1 == len2) { if(len1 == len2) {
lua_pushboolean(L, (memcmp(ud1, ud2, len1) == 0)); lua_pushboolean(L, (memcmp(ud1, ud2, len1) == 0));
@ -1088,12 +1142,12 @@ static void obj_type_register_constants(lua_State *L, const obj_const *constants
} }
static void obj_type_register_package(lua_State *L, const reg_sub_module *type_reg) { static void obj_type_register_package(lua_State *L, const reg_sub_module *type_reg) {
const luaL_reg *reg_list = type_reg->pub_funcs; const luaL_Reg *reg_list = type_reg->pub_funcs;
/* create public functions table. */ /* create public functions table. */
if(reg_list != NULL && reg_list[0].name != NULL) { if(reg_list != NULL && reg_list[0].name != NULL) {
/* register functions */ /* register functions */
luaL_register(L, NULL, reg_list); luaL_setfuncs(L, reg_list, 0);
} }
obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts); obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts);
@ -1102,23 +1156,23 @@ static void obj_type_register_package(lua_State *L, const reg_sub_module *type_r
} }
static void obj_type_register_meta(lua_State *L, const reg_sub_module *type_reg) { static void obj_type_register_meta(lua_State *L, const reg_sub_module *type_reg) {
const luaL_reg *reg_list; const luaL_Reg *reg_list;
/* create public functions table. */ /* create public functions table. */
reg_list = type_reg->pub_funcs; reg_list = type_reg->pub_funcs;
if(reg_list != NULL && reg_list[0].name != NULL) { if(reg_list != NULL && reg_list[0].name != NULL) {
/* register functions */ /* register functions */
luaL_register(L, NULL, reg_list); luaL_setfuncs(L, reg_list, 0);
} }
obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts); obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts);
/* register methods. */ /* register methods. */
luaL_register(L, NULL, type_reg->methods); luaL_setfuncs(L, type_reg->methods, 0);
/* create metatable table. */ /* create metatable table. */
lua_newtable(L); lua_newtable(L);
luaL_register(L, NULL, type_reg->metas); /* fill metatable */ luaL_setfuncs(L, type_reg->metas, 0); /* fill metatable */
/* setmetatable on meta-object. */ /* setmetatable on meta-object. */
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
@ -1126,7 +1180,7 @@ static void obj_type_register_meta(lua_State *L, const reg_sub_module *type_reg)
} }
static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int priv_table) { static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int priv_table) {
const luaL_reg *reg_list; const luaL_Reg *reg_list;
obj_type *type = type_reg->type; obj_type *type = type_reg->type;
const obj_base *base = type_reg->bases; const obj_base *base = type_reg->bases;
@ -1143,7 +1197,7 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int
reg_list = type_reg->pub_funcs; reg_list = type_reg->pub_funcs;
if(reg_list != NULL && reg_list[0].name != NULL) { if(reg_list != NULL && reg_list[0].name != NULL) {
/* register "constructors" as to object's public API */ /* register "constructors" as to object's public API */
luaL_register(L, NULL, reg_list); /* fill public API table. */ luaL_setfuncs(L, reg_list, 0); /* fill public API table. */
/* make public API table callable as the default constructor. */ /* make public API table callable as the default constructor. */
lua_newtable(L); /* create metatable */ lua_newtable(L); /* create metatable */
@ -1173,7 +1227,7 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int
#endif #endif
} }
luaL_register(L, NULL, type_reg->methods); /* fill methods table. */ luaL_setfuncs(L, type_reg->methods, 0); /* fill methods table. */
luaL_newmetatable(L, type->name); /* create metatable */ luaL_newmetatable(L, type->name); /* create metatable */
lua_pushliteral(L, ".name"); lua_pushliteral(L, ".name");
@ -1191,7 +1245,7 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int
lua_pushvalue(L, -2); /* dup metatable. */ lua_pushvalue(L, -2); /* dup metatable. */
lua_rawset(L, priv_table); /* priv_table["<object_name>"] = metatable */ lua_rawset(L, priv_table); /* priv_table["<object_name>"] = metatable */
luaL_register(L, NULL, type_reg->metas); /* fill metatable */ luaL_setfuncs(L, type_reg->metas, 0); /* fill metatable */
/* add obj_bases to metatable. */ /* add obj_bases to metatable. */
while(base->id >= 0) { while(base->id >= 0) {
@ -1348,7 +1402,7 @@ typedef struct Lua_LLThread {
#define ERROR_LEN 1024 #define ERROR_LEN 1024
/****************************************************************************** /******************************************************************************
* traceback() function from Lua 5.1.x source. * traceback() function from Lua 5.1/5.2 source.
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
@ -1370,10 +1424,12 @@ typedef struct Lua_LLThread {
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/ ******************************************************************************/
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM == 501)
/* from Lua 5.1 */
static int traceback (lua_State *L) { static int traceback (lua_State *L) {
if (!lua_isstring(L, 1)) /* 'message' not a string? */ if (!lua_isstring(L, 1)) /* 'message' not a string? */
return 1; /* keep it intact */ return 1; /* keep it intact */
lua_getfield(L, LUA_GLOBALSINDEX, "debug"); lua_getglobal(L, "debug");
if (!lua_istable(L, -1)) { if (!lua_istable(L, -1)) {
lua_pop(L, 1); lua_pop(L, 1);
return 1; return 1;
@ -1388,6 +1444,19 @@ static int traceback (lua_State *L) {
lua_call(L, 2, 1); /* call debug.traceback */ lua_call(L, 2, 1); /* call debug.traceback */
return 1; return 1;
} }
#else
/* from Lua 5.2 */
static int traceback (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg)
luaL_traceback(L, L, msg, 1);
else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */
if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */
lua_pushliteral(L, "(no error message)");
}
return 1;
}
#endif
static Lua_LLThread_child *llthread_child_new() { static Lua_LLThread_child *llthread_child_new() {
Lua_LLThread_child *this; Lua_LLThread_child *this;
@ -1831,17 +1900,17 @@ static int llthreads__new__func(lua_State *L) {
static const luaL_reg obj_Lua_LLThread_pub_funcs[] = { static const luaL_Reg obj_Lua_LLThread_pub_funcs[] = {
{NULL, NULL} {NULL, NULL}
}; };
static const luaL_reg obj_Lua_LLThread_methods[] = { static const luaL_Reg obj_Lua_LLThread_methods[] = {
{"start", Lua_LLThread__start__meth}, {"start", Lua_LLThread__start__meth},
{"join", Lua_LLThread__join__meth}, {"join", Lua_LLThread__join__meth},
{NULL, NULL} {NULL, NULL}
}; };
static const luaL_reg obj_Lua_LLThread_metas[] = { static const luaL_Reg obj_Lua_LLThread_metas[] = {
{"__gc", Lua_LLThread__delete__meth}, {"__gc", Lua_LLThread__delete__meth},
{"__tostring", obj_udata_default_tostring}, {"__tostring", obj_udata_default_tostring},
{"__eq", obj_udata_default_equal}, {"__eq", obj_udata_default_equal},
@ -1864,7 +1933,7 @@ static const reg_impl obj_Lua_LLThread_implements[] = {
{NULL, NULL} {NULL, NULL}
}; };
static const luaL_reg llthreads_function[] = { static const luaL_Reg llthreads_function[] = {
{"new", llthreads__new__func}, {"new", llthreads__new__func},
{NULL, NULL} {NULL, NULL}
}; };
@ -1941,7 +2010,7 @@ LUA_NOBJ_API int luaopen_llthreads(lua_State *L) {
luaL_register(L, "llthreads", llthreads_function); luaL_register(L, "llthreads", llthreads_function);
#else #else
lua_newtable(L); lua_newtable(L);
luaL_register(L, NULL, llthreads_function); luaL_setfuncs(L, llthreads_function, 0);
#endif #endif
/* register module constants. */ /* register module constants. */

@ -59,7 +59,7 @@ typedef struct Lua_LLThread {
#define ERROR_LEN 1024 #define ERROR_LEN 1024
/****************************************************************************** /******************************************************************************
* traceback() function from Lua 5.1.x source. * traceback() function from Lua 5.1/5.2 source.
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
@ -81,10 +81,12 @@ typedef struct Lua_LLThread {
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/ ******************************************************************************/
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM == 501)
/* from Lua 5.1 */
static int traceback (lua_State *L) { static int traceback (lua_State *L) {
if (!lua_isstring(L, 1)) /* 'message' not a string? */ if (!lua_isstring(L, 1)) /* 'message' not a string? */
return 1; /* keep it intact */ return 1; /* keep it intact */
lua_getfield(L, LUA_GLOBALSINDEX, "debug"); lua_getglobal(L, "debug");
if (!lua_istable(L, -1)) { if (!lua_istable(L, -1)) {
lua_pop(L, 1); lua_pop(L, 1);
return 1; return 1;
@ -99,6 +101,19 @@ static int traceback (lua_State *L) {
lua_call(L, 2, 1); /* call debug.traceback */ lua_call(L, 2, 1); /* call debug.traceback */
return 1; return 1;
} }
#else
/* from Lua 5.2 */
static int traceback (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg)
luaL_traceback(L, L, msg, 1);
else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */
if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */
lua_pushliteral(L, "(no error message)");
}
return 1;
}
#endif
static Lua_LLThread_child *llthread_child_new() { static Lua_LLThread_child *llthread_child_new() {
Lua_LLThread_child *this; Lua_LLThread_child *this;

Loading…
Cancel
Save