@@ -28,7 +28,7 @@
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"

#include "lrotable.h"


const char lua_ident[] =
@@ -61,12 +61,13 @@ static TValue *index2adr (lua_State *L, int idx) {
case LUA_REGISTRYINDEX: return registry(L);
case LUA_ENVIRONINDEX: {
Closure *func = curr_func(L);
sethvalue(L, &L->env, func->c.env);
sethvalue(L, &L->env, func ? func->c.env : hvalue(gt(L)));
return &L->env;
}
case LUA_GLOBALSINDEX: return gt(L);
default: {
Closure *func = curr_func(L);
if (!func) return cast(TValue *, luaO_nilobject);
idx = LUA_GLOBALSINDEX - idx;
return (idx <= func->c.nupvalues)
? &func->c.upvalue[idx-1]
@@ -81,7 +82,7 @@ static Table *getcurrenv (lua_State *L) {
return hvalue(gt(L)); /* use global table as environment */
else {
Closure *func = curr_func(L);
return func->c.env;
return func ? func->c.env : hvalue(gt(L));
}
}

@@ -211,13 +212,17 @@ LUA_API void lua_replace (lua_State *L, int idx) {
api_checkvalidindex(L, o);
if (idx == LUA_ENVIRONINDEX) {
Closure *func = curr_func(L);
api_check(L, ttistable(L->top - 1));
func->c.env = hvalue(L->top - 1);
luaC_barrier(L, func, L->top - 1);
if (!func)
luaG_runerror(L, "attempt to set environment on lightfunction");
else {
api_check(L, ttistable(L->top - 1));
func->c.env = hvalue(L->top - 1);
luaC_barrier(L, func, L->top - 1);
}
}
else {
setobj(L, o, L->top - 1);
if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
if (curr_func(L) && idx < LUA_GLOBALSINDEX) /* function upvalue? */
luaC_barrier(L, curr_func(L), L->top - 1);
}
L->top--;
@@ -364,6 +369,7 @@ LUA_API size_t lua_objlen (lua_State *L, int idx) {
case LUA_TSTRING: return tsvalue(o)->len;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
case LUA_TROTABLE: return luaH_getn_ro(rvalue(o));
case LUA_TNUMBER: {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
@@ -407,6 +413,9 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx);
case LUA_TROTABLE:
case LUA_TLIGHTFUNCTION:
return pvalue(o);
default: return NULL;
}
}
@@ -515,6 +524,20 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_unlock(L);
}

LUA_API void lua_pushrotable (lua_State *L, void *p) {
lua_lock(L);
setrvalue(L->top, p);
api_incr_top(L);
lua_unlock(L);
}

LUA_API void lua_pushlightfunction(lua_State *L, void *p) {
lua_lock(L);
setfvalue(L->top, p);
api_incr_top(L);
lua_unlock(L);
}


LUA_API int lua_pushthread (lua_State *L) {
lua_lock(L);
@@ -556,10 +579,12 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {

LUA_API void lua_rawget (lua_State *L, int idx) {
StkId t;
const TValue *res;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
api_check(L, ttistable(t) || ttisrotable(t));
res = ttistable(t) ? luaH_get(hvalue(t), L->top - 1) : luaH_get_ro(rvalue(t), L->top - 1);
setobj2s(L, L->top - 1, res);
lua_unlock(L);
}

@@ -568,8 +593,8 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
o = index2adr(L, idx);
api_check(L, ttistable(o));
setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
api_check(L, ttistable(o) || ttisrotable(o));
setobj2s(L, L->top, ttistable(o) ? luaH_getnum(hvalue(o), n) : luaH_getnum_ro(rvalue(o), n))
api_incr_top(L);
lua_unlock(L);
}
@@ -597,14 +622,20 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
case LUA_TUSERDATA:
mt = uvalue(obj)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(obj));
break;
default:
mt = G(L)->mt[ttype(obj)];
break;
}
if (mt == NULL)
res = 0;
else {
sethvalue(L, L->top, mt);
if(luaR_isrotable(mt))
setrvalue(L->top, mt)
else
sethvalue(L, L->top, mt)
api_incr_top(L);
res = 1;
}
@@ -697,26 +728,32 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
TValue *obj;
Table *mt;
int isrometa = 0;
lua_lock(L);
api_checknelems(L, 1);
obj = index2adr(L, objindex);
api_checkvalidindex(L, obj);
if (ttisnil(L->top - 1))
mt = NULL;
else {
api_check(L, ttistable(L->top - 1));
mt = hvalue(L->top - 1);
api_check(L, ttistable(L->top - 1) || ttisrotable(L->top - 1));
if (ttistable(L->top - 1))
mt = hvalue(L->top - 1);
else {
mt = (Table*)rvalue(L->top - 1);
isrometa = 1;
}
}
switch (ttype(obj)) {
case LUA_TTABLE: {
hvalue(obj)->metatable = mt;
if (mt)
if (mt && !isrometa)
luaC_objbarriert(L, hvalue(obj), mt);
break;
}
case LUA_TUSERDATA: {
uvalue(obj)->metatable = mt;
if (mt)
if (mt && !isrometa)
luaC_objbarrier(L, rawuvalue(obj), mt);
break;
}
@@ -975,8 +1012,8 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
more = luaH_next(L, hvalue(t), L->top - 1);
api_check(L, ttistable(t) || ttisrotable(t));
more = ttistable(t) ? luaH_next(L, hvalue(t), L->top - 1) : luaH_next_ro(L, rvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
}
@@ -22,6 +22,8 @@

#include "lua.h"

#include "lrotable.h"

#include "lauxlib.h"


@@ -32,6 +34,9 @@
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)

// Parameters for luaI_openlib
#define LUA_USECCLOSURES 0
#define LUA_USELIGHTFUNCTIONS 1

/*
** {======================================================
@@ -120,6 +125,16 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
return 1;
}

LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) {
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_pushrotable(L, p);
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1;
}

LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
@@ -148,6 +163,22 @@ LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
tag_error(L, narg, t);
}

LUALIB_API void luaL_checkanyfunction (lua_State *L, int narg) {
if (lua_type(L, narg) != LUA_TFUNCTION && lua_type(L, narg) != LUA_TLIGHTFUNCTION) {
const char *msg = lua_pushfstring(L, "function or lightfunction expected, got %s",
luaL_typename(L, narg));
luaL_argerror(L, narg, msg);
}
}

LUALIB_API void luaL_checkanytable (lua_State *L, int narg) {
if (lua_type(L, narg) != LUA_TTABLE && lua_type(L, narg) != LUA_TROTABLE) {
const char *msg = lua_pushfstring(L, "table or rotable expected, got %s",
luaL_typename(L, narg));
luaL_argerror(L, narg, msg);
}
}


LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE)
@@ -228,9 +259,17 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {

LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l) {
luaI_openlib(L, libname, l, 0);
luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES);
}

LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname,
const luaL_Reg *l) {
#if LUA_OPTIMIZE_MEMORY > 0
luaI_openlib(L, libname, l, 0, LUA_USELIGHTFUNCTIONS);
#else
luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES);
#endif
}

static int libsize (const luaL_Reg *l) {
int size = 0;
@@ -240,7 +279,7 @@ static int libsize (const luaL_Reg *l) {


LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
const luaL_Reg *l, int nup) {
const luaL_Reg *l, int nup, int ftype) {
if (libname) {
int size = libsize(l);
/* check whether lib already exists */
@@ -261,7 +300,10 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
int i;
for (i=0; i<nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup);
if (ftype == LUA_USELIGHTFUNCTIONS)
lua_pushlightfunction(L, l->func);
else
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name);
}
lua_pop(L, nup); /* remove upvalues */
@@ -363,14 +405,22 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
/* If looking for a global variable, check the rotables too */
void *ptable = luaR_findglobal(fname, e - fname);
if (ptable) {
lua_pop(L, 1);
lua_pushrotable(L, ptable);
}
}
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, e - fname);
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
else if (!lua_istable(L, -1)) { /* field has a non-table value? */
else if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
@@ -40,9 +40,11 @@ typedef struct luaL_Reg {


LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
const luaL_Reg *l, int nup, int ftype);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
@@ -61,8 +63,11 @@ LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API void (luaL_checkanyfunction) (lua_State *L, int narg);
LUALIB_API void (luaL_checkanytable) (lua_State *L, int narg);

LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, void *p);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);

LUALIB_API void (luaL_where) (lua_State *L, int lvl);
@@ -18,6 +18,7 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"



@@ -104,7 +105,7 @@ static int luaB_getmetatable (lua_State *L) {
static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE || t == LUA_TROTABLE, 2,
"nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable"))
luaL_error(L, "cannot change a protected metatable");
@@ -167,7 +168,7 @@ static int luaB_rawequal (lua_State *L) {


static int luaB_rawget (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanytable(L, 1);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
@@ -224,7 +225,7 @@ static int luaB_type (lua_State *L) {


static int luaB_next (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanytable(L, 1);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
@@ -236,7 +237,7 @@ static int luaB_next (lua_State *L) {


static int luaB_pairs (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanytable(L, 1);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */
@@ -246,7 +247,7 @@ static int luaB_pairs (lua_State *L) {

static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanytable(L, 1);
i++; /* next value */
lua_pushinteger(L, i);
lua_rawgeti(L, 1, i);
@@ -255,7 +256,7 @@ static int ipairsaux (lua_State *L) {


static int luaB_ipairs (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanytable(L, 1);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */
@@ -443,32 +444,70 @@ static int luaB_newproxy (lua_State *L) {
return 1;
}

#define LUA_BASELIB_FUNCLIST\
{LSTRKEY("assert"), LFUNCVAL(luaB_assert)},\
{LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)},\
{LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)},\
{LSTRKEY("error"), LFUNCVAL(luaB_error)},\
{LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)},\
{LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)},\
{LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)},\
{LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)},\
{LSTRKEY("load"), LFUNCVAL(luaB_load)},\
{LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)},\
{LSTRKEY("next"), LFUNCVAL(luaB_next)},\
{LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)},\
{LSTRKEY("print"), LFUNCVAL(luaB_print)},\
{LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)},\
{LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)},\
{LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)},\
{LSTRKEY("select"), LFUNCVAL(luaB_select)},\
{LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)},\
{LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)},\
{LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)},\
{LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)},\
{LSTRKEY("type"), LFUNCVAL(luaB_type)},\
{LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)},\
{LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall)}

#if LUA_OPTIMIZE_MEMORY == 2
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE base_funcs_list[] = {
LUA_BASELIB_FUNCLIST,
{LNILKEY, LNILVAL}
};
#endif


static int luaB_index(lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 2
int fres;
if ((fres = luaR_findfunction(L, base_funcs_list)) != 0)
return fres;
#endif
const char *keyname = luaL_checkstring(L, 2);
if (!strcmp(keyname, "_VERSION")) {
lua_pushliteral(L, LUA_VERSION);
return 1;
}
void *res = luaR_findglobal(keyname, strlen(keyname));
if (!res)
return 0;
else {
lua_pushrotable(L, res);
return 1;
}
}

static const luaL_Reg base_funcs[] = {
{"assert", luaB_assert},
{"collectgarbage", luaB_collectgarbage},
{"dofile", luaB_dofile},
{"error", luaB_error},
{"gcinfo", luaB_gcinfo},
{"getfenv", luaB_getfenv},
{"getmetatable", luaB_getmetatable},
{"loadfile", luaB_loadfile},
{"load", luaB_load},
{"loadstring", luaB_loadstring},
{"next", luaB_next},
{"pcall", luaB_pcall},
{"print", luaB_print},
{"rawequal", luaB_rawequal},
{"rawget", luaB_rawget},
{"rawset", luaB_rawset},
{"select", luaB_select},
{"setfenv", luaB_setfenv},
{"setmetatable", luaB_setmetatable},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
{"unpack", luaB_unpack},
{"xpcall", luaB_xpcall},
#if LUA_OPTIMIZE_MEMORY != 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 0
#include "lrodefs.h"
LUA_BASELIB_FUNCLIST,
#endif
{"__index", luaB_index},
{NULL, NULL}
};

@@ -601,15 +640,17 @@ static int luaB_corunning (lua_State *L) {
return 1;
}


static const luaL_Reg co_funcs[] = {
{"create", luaB_cocreate},
{"resume", luaB_coresume},
{"running", luaB_corunning},
{"status", luaB_costatus},
{"wrap", luaB_cowrap},
{"yield", luaB_yield},
{NULL, NULL}
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE co_funcs[] = {
{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)},
{LSTRKEY("resume"), LFUNCVAL(luaB_coresume)},
{LSTRKEY("running"), LFUNCVAL(luaB_corunning)},
{LSTRKEY("status"), LFUNCVAL(luaB_costatus)},
{LSTRKEY("wrap"), LFUNCVAL(luaB_cowrap)},
{LSTRKEY("yield"), LFUNCVAL(luaB_yield)},
{LNILKEY, LNILVAL}
};

/* }====================================================== */
@@ -628,9 +669,14 @@ static void base_open (lua_State *L) {
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
/* open lib into global table */
luaL_register(L, "_G", base_funcs);
luaL_register_light(L, "_G", base_funcs);
#if LUA_OPTIMIZE_MEMORY > 0
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
#else
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
#endif
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
auxopen(L, "pairs", luaB_pairs, luaB_next);
@@ -647,7 +693,10 @@ static void base_open (lua_State *L) {

LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
#if LUA_OPTIMIZE_MEMORY == 0
luaL_register(L, LUA_COLIBNAME, co_funcs);
return 2;
#else
return 1;
#endif
}

@@ -16,6 +16,7 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"



@@ -106,7 +107,7 @@ static int db_getinfo (lua_State *L) {
return 1;
}
}
else if (lua_isfunction(L, arg+1)) {
else if (lua_isfunction(L, arg+1) || lua_islightfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
@@ -264,7 +265,7 @@ static int db_sethook (lua_State *L) {
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
luaL_checkanyfunction(L, arg+1);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
@@ -370,28 +371,26 @@ static int db_errorfb (lua_State *L) {
return 1;
}


static const luaL_Reg dblib[] = {
{"debug", db_debug},
{"getfenv", db_getfenv},
{"gethook", db_gethook},
{"getinfo", db_getinfo},
{"getlocal", db_getlocal},
{"getregistry", db_getregistry},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
{"setfenv", db_setfenv},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
{"traceback", db_errorfb},
{NULL, NULL}
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE dblib[] = {
{LSTRKEY("debug"), LFUNCVAL(db_debug)},
{LSTRKEY("getfenv"), LFUNCVAL(db_getfenv)},
{LSTRKEY("gethook"), LFUNCVAL(db_gethook)},
{LSTRKEY("getinfo"), LFUNCVAL(db_getinfo)},
{LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)},
{LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)},
{LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)},
{LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)},
{LSTRKEY("setfenv"), LFUNCVAL(db_setfenv)},
{LSTRKEY("sethook"), LFUNCVAL(db_sethook)},
{LSTRKEY("setlocal"), LFUNCVAL(db_setlocal)},
{LSTRKEY("setmetatable"), LFUNCVAL(db_setmetatable)},
{LSTRKEY("setupvalue"), LFUNCVAL(db_setupvalue)},
{LSTRKEY("traceback"), LFUNCVAL(db_errorfb)},
{LNILKEY, LNILVAL}
};


LUALIB_API int luaopen_debug (lua_State *L) {
luaL_register(L, LUA_DBLIBNAME, dblib);
return 1;
LREGISTER(L, LUA_DBLIBNAME, dblib);
}

@@ -147,8 +147,8 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
}


static void funcinfo (lua_Debug *ar, Closure *cl) {
if (cl->c.isC) {
static void funcinfo (lua_Debug *ar, Closure *cl, void *plight) {
if (plight || cl->c.isC) {
ar->source = "=[C]";
ar->linedefined = -1;
ar->lastlinedefined = -1;
@@ -191,24 +191,24 @@ static void collectvalidlines (lua_State *L, Closure *f) {


static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
Closure *f, void *plight, CallInfo *ci) {
int status = 1;
if (f == NULL) {
if (plight == NULL && f == NULL) {
info_tailcall(ar);
return status;
}
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(ar, f);
funcinfo(ar, f, plight);
break;
}
case 'l': {
ar->currentline = (ci) ? currentline(L, ci) : -1;
break;
}
case 'u': {
ar->nups = f->c.nupvalues;
ar->nups = f ? f->c.nupvalues : 0;
break;
}
case 'n': {
@@ -233,23 +233,34 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status;
Closure *f = NULL;
CallInfo *ci = NULL;
void *plight = NULL;
lua_lock(L);
if (*what == '>') {
StkId func = L->top - 1;
luai_apicheck(L, ttisfunction(func));
luai_apicheck(L, ttisfunction(func) || ttislightfunction(func));
what++; /* skip the '>' */
f = clvalue(func);
if (ttisfunction(func))
f = clvalue(func);
else
plight = fvalue(func);
L->top--; /* pop function */
}
else if (ar->i_ci != 0) { /* no tail call? */
ci = L->base_ci + ar->i_ci;
lua_assert(ttisfunction(ci->func));
f = clvalue(ci->func);
lua_assert(ttisfunction(ci->func) || ttislightfunction(ci->func));
if (ttisfunction(ci->func))
f = clvalue(ci->func);
else
plight = fvalue(ci->func);
}
status = auxgetinfo(L, what, ar, f, ci);
status = auxgetinfo(L, what, ar, f, plight, ci);
if (strchr(what, 'f')) {
if (f == NULL) setnilvalue(L->top);
else setclvalue(L, L->top, f);
if (f != NULL)
setclvalue(L, L->top, f)
else if (plight != NULL)
setfvalue(L->top, plight)
else
setnilvalue(L->top);
incr_top(L);
}
if (strchr(what, 'L'))
@@ -618,7 +629,7 @@ static void addinfo (lua_State *L, const char *msg) {
void luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
if (!ttisfunction(errfunc) && !ttislightfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
incr_top(L);
@@ -262,14 +262,15 @@ static StkId tryfuncTM (lua_State *L, StkId func) {


int luaD_precall (lua_State *L, StkId func, int nresults) {
LClosure *cl;
ptrdiff_t funcr;
if (!ttisfunction(func)) /* `func' is not a function? */
LClosure *cl = NULL;
if (!ttisfunction(func) && !ttislightfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
cl = &clvalue(func)->l;
if (ttisfunction(func))
cl = &clvalue(func)->l;
L->ci->savedpc = L->savedpc;
if (!cl->isC) { /* Lua function? prepare its call */
if (cl && !cl->isC) { /* Lua function? prepare its call */
CallInfo *ci;
StkId st, base;
Proto *p = cl->p;
@@ -316,7 +317,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*curr_func(L)->c.f)(L); /* do the actual call */
if (ttisfunction(func))
n = (*curr_func(L)->c.f)(L); /* do the actual call */
else
n = ((lua_CFunction)fvalue(func))(L); /* do the actual call */
lua_lock(L);
if (n < 0) /* yielding? */
return PCRYIELD;
@@ -21,7 +21,7 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"

#include "lrotable.h"

#define GCSTEPSIZE 1024u
#define GCSWEEPMAX 40
@@ -76,7 +76,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
case LUA_TUSERDATA: {
Table *mt = gco2u(o)->metatable;
gray2black(o); /* udata are never gray */
if (mt) markobject(g, mt);
if (mt && !luaR_isrotable(mt)) markobject(g, mt);
markobject(g, gco2u(o)->env);
return;
}
@@ -160,7 +160,7 @@ static int traversetable (global_State *g, Table *h) {
int weakkey = 0;
int weakvalue = 0;
const TValue *mode;
if (h->metatable)
if (h->metatable && !luaR_isrotable(h->metatable))
markobject(g, h->metatable);
mode = gfasttm(g, h->metatable, TM_MODE);
if (mode && ttisstring(mode)) { /* is there a weak mode? */
@@ -493,7 +493,7 @@ void luaC_freeall (lua_State *L) {
static void markmt (global_State *g) {
int i;
for (i=0; i<NUM_TAGS; i++)
if (g->mt[i]) markobject(g, g->mt[i]);
if (g->mt[i] && !luaR_isrotable(g->mt[i])) markobject(g, g->mt[i]);
}


@@ -4,13 +4,16 @@
** See Copyright Notice in lua.h
*/


#define linit_c
#define LUA_LIB

#include "lua.h"

#include "lualib.h"
#include "lauxlib.h"
#include "lrotable.h"
#include "luaconf.h"

#ifndef LUA_CROSS_COMPILER
#include "platform_conf.h"
@@ -19,17 +22,48 @@
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
// {LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
// {LUA_DBLIBNAME, luaopen_debug},
#ifdef LUA_PLATFORM_LIBS
LUA_PLATFORM_LIBS,
{LUA_STRLIBNAME, luaopen_string},
#if LUA_OPTIMIZE_MEMORY == 0
{LUA_MATHLIBNAME, luaopen_math},
{LUA_TABLIBNAME, luaopen_table},
{LUA_DBLIBNAME, luaopen_debug},
#endif
#ifdef LUA_PLATFORM_LIBS_REG
LUA_PLATFORM_LIBS_REG,
#endif
#if defined(LUA_PLATFORM_LIBS_ROM) && LUA_OPTIMIZE_MEMORY != 2
#define _ROM( name, openf, table ) { name, openf },
LUA_PLATFORM_LIBS_ROM
#endif
{NULL, NULL}
};

extern const luaR_entry strlib[];
extern const luaR_entry syslib[];
extern const luaR_entry tab_funcs[];
extern const luaR_entry dblib[];
extern const luaR_entry co_funcs[];
#if defined(LUA_PLATFORM_LIBS_ROM) && LUA_OPTIMIZE_MEMORY == 2
#undef _ROM
#define _ROM( name, openf, table ) extern const luaR_entry table[];
LUA_PLATFORM_LIBS_ROM;
#endif
const luaR_table lua_rotable[] =
{
#if LUA_OPTIMIZE_MEMORY > 0
{LUA_STRLIBNAME, strlib},
{LUA_TABLIBNAME, tab_funcs},
{LUA_DBLIBNAME, dblib},
{LUA_COLIBNAME, co_funcs},
#if defined(LUA_PLATFORM_LIBS_ROM) && LUA_OPTIMIZE_MEMORY == 2
#undef _ROM
#define _ROM( name, openf, table ) { name, table },
LUA_PLATFORM_LIBS_ROM
#endif
#endif
{NULL, NULL}
};

LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
@@ -39,4 +73,3 @@ LUALIB_API void luaL_openlibs (lua_State *L) {
lua_call(L, 1, 0);
}
}

@@ -17,15 +17,24 @@

#include "lauxlib.h"
#include "lualib.h"

#include "lrotable.h"


#define IO_INPUT 1
#define IO_OUTPUT 2
#define IO_STDERR 0

#if LUA_OPTIMIZE_MEMORY != 2
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_ENVIRONINDEX, f)
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_ENVIRONINDEX, f)
#else
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX, liolib_keys[f])
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[f])
#endif

static const char *const fnames[] = {"input", "output"};

/* "Pseudo-random" keys for the registry */
static const int liolib_keys[] = {(int)&luaL_callmeta, (int)&luaL_typerror, (int)&luaL_argerror};

static int pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
@@ -92,6 +101,7 @@ static FILE **newfile (lua_State *L) {
}


#if LUA_OPTIMIZE_MEMORY != 2
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
@@ -122,18 +132,31 @@ static int io_fclose (lua_State *L) {
*p = NULL;
return pushresult(L, ok, NULL);
}

#endif

static int aux_close (lua_State *L) {
#if LUA_OPTIMIZE_MEMORY != 2
lua_getfenv(L, 1);
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
#else
FILE **p = tofilep(L);
if(*p == stdin || *p == stdout || *p == stderr)
{
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
int ok = (fclose(*p) == 0);
*p = NULL;
return pushresult(L, ok, NULL);
#endif
}


static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
LUA_IO_GETFIELD(IO_OUTPUT);
tofile(L); /* make sure argument is a file */
return aux_close(L);
}
@@ -189,7 +212,7 @@ static int io_tmpfile (lua_State *L) {

static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
LUA_IO_GETFIELD(findex);
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
@@ -210,10 +233,10 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
LUA_IO_SETFIELD(f);
}
/* return current value */
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
LUA_IO_GETFIELD(f);
return 1;
}

@@ -248,7 +271,7 @@ static int f_lines (lua_State *L) {
static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
LUA_IO_GETFIELD(IO_INPUT);
return f_lines(L);
}
else {
@@ -473,81 +496,119 @@ static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}


static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
{"input", io_input},
{"lines", io_lines},
{"open", io_open},
{"output", io_output},
{"popen", io_popen},
{"read", io_read},
{"tmpfile", io_tmpfile},
{"type", io_type},
{"write", io_write},
{NULL, NULL}
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
#if LUA_OPTIMIZE_MEMORY == 2
const LUA_REG_TYPE iolib_funcs[] = {
#else
const LUA_REG_TYPE iolib[] = {
#endif
{LSTRKEY("close"), LFUNCVAL(io_close)},
{LSTRKEY("flush"), LFUNCVAL(io_flush)},
{LSTRKEY("input"), LFUNCVAL(io_input)},
{LSTRKEY("lines"), LFUNCVAL(io_lines)},
{LSTRKEY("open"), LFUNCVAL(io_open)},
{LSTRKEY("output"), LFUNCVAL(io_output)},
{LSTRKEY("popen"), LFUNCVAL(io_popen)},
{LSTRKEY("read"), LFUNCVAL(io_read)},
{LSTRKEY("tmpfile"), LFUNCVAL(io_tmpfile)},
{LSTRKEY("type"), LFUNCVAL(io_type)},
{LSTRKEY("write"), LFUNCVAL(io_write)},
{LNILKEY, LNILVAL}
};


static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
{"__gc", io_gc},
{"__tostring", io_tostring},
#if LUA_OPTIMIZE_MEMORY == 2
static int luaL_index(lua_State *L)
{
return luaR_findfunction(L, iolib_funcs);
}

const luaL_Reg iolib[] = {
{"__index", luaL_index},
{NULL, NULL}
};

#endif

#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE flib[] = {
{LSTRKEY("close"), LFUNCVAL(io_close)},
{LSTRKEY("flush"), LFUNCVAL(f_flush)},
{LSTRKEY("lines"), LFUNCVAL(f_lines)},
{LSTRKEY("read"), LFUNCVAL(f_read)},
{LSTRKEY("seek"), LFUNCVAL(f_seek)},
{LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)},
{LSTRKEY("write"), LFUNCVAL(f_write)},
{LSTRKEY("__gc"), LFUNCVAL(io_gc)},
{LSTRKEY("__tostring"), LFUNCVAL(io_tostring)},
#if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("__index"), LROVAL(flib)},
#endif
{LNILKEY, LNILVAL}
};

static void createmeta (lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 0
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_register(L, NULL, flib); /* file methods */
#else
luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */
#endif
}


static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
#if LUA_OPTIMIZE_MEMORY != 2
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_pushvalue(L, -2); /* copy environment */
lua_setfenv(L, -2); /* set it */
lua_setfield(L, -3, fname);
#else
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[k]);
lua_setfield(L, -2, fname);
#endif
}


#if LUA_OPTIMIZE_MEMORY != 2
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
lua_pushcfunction(L, cls);
lua_setfield(L, -2, "__close");
}

#endif

LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
#if LUA_OPTIMIZE_MEMORY != 2
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv(L, io_fclose);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
#else
luaL_register_light(L, LUA_IOLIBNAME, iolib);
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
#endif
/* create (and set) default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
createstdfile(L, stderr, IO_STDERR, "stderr");
#if LUA_OPTIMIZE_MEMORY != 2
lua_pop(L, 1); /* pop environment for default files */
lua_getfield(L, -1, "popen");
newfenv(L, io_pclose); /* create environment for 'popen' */
lua_setfenv(L, -2); /* set fenv for 'popen' */
lua_pop(L, 1); /* pop 'popen' */
#endif
return 1;
}

@@ -15,7 +15,7 @@

#include "lauxlib.h"
#include "lualib.h"

#include "lrotable.h"

#undef PI
#define PI (3.14159265358979323846)
@@ -211,37 +211,45 @@ static int math_randomseed (lua_State *L) {
return 0;
}


static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
{"asin", math_asin},
{"atan2", math_atan2},
{"atan", math_atan},
{"ceil", math_ceil},
{"cosh", math_cosh},
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
{"floor", math_floor},
{"fmod", math_fmod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"log10", math_log10},
{"log", math_log},
{"max", math_max},
{"min", math_min},
{"modf", math_modf},
{"pow", math_pow},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
{"sinh", math_sinh},
{"sin", math_sin},
{"sqrt", math_sqrt},
{"tanh", math_tanh},
{"tan", math_tan},
{NULL, NULL}
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE math_map[] = {
{LSTRKEY("abs"), LFUNCVAL(math_abs)},
{LSTRKEY("acos"), LFUNCVAL(math_acos)},
{LSTRKEY("asin"), LFUNCVAL(math_asin)},
{LSTRKEY("atan2"), LFUNCVAL(math_atan2)},
{LSTRKEY("atan"), LFUNCVAL(math_atan)},
{LSTRKEY("ceil"), LFUNCVAL(math_ceil)},
{LSTRKEY("cosh"), LFUNCVAL(math_cosh)},
{LSTRKEY("cos"), LFUNCVAL(math_cos)},
{LSTRKEY("deg"), LFUNCVAL(math_deg)},
{LSTRKEY("exp"), LFUNCVAL(math_exp)},
{LSTRKEY("floor"), LFUNCVAL(math_floor)},
{LSTRKEY("fmod"), LFUNCVAL(math_fmod)},
#if LUA_OPTIMIZE_MEMORY > 0 && defined(LUA_COMPAT_MOD)
{LSTRKEY("mod"), LFUNCVAL(math_fmod)},
#endif
{LSTRKEY("frexp"), LFUNCVAL(math_frexp)},
{LSTRKEY("ldexp"), LFUNCVAL(math_ldexp)},
{LSTRKEY("log10"), LFUNCVAL(math_log10)},
{LSTRKEY("log"), LFUNCVAL(math_log)},
{LSTRKEY("max"), LFUNCVAL(math_max)},
{LSTRKEY("min"), LFUNCVAL(math_min)},
{LSTRKEY("modf"), LFUNCVAL(math_modf)},
{LSTRKEY("pow"), LFUNCVAL(math_pow)},
{LSTRKEY("rad"), LFUNCVAL(math_rad)},
{LSTRKEY("random"), LFUNCVAL(math_random)},
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)},
{LSTRKEY("sinh"), LFUNCVAL(math_sinh)},
{LSTRKEY("sin"), LFUNCVAL(math_sin)},
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)},
{LSTRKEY("tanh"), LFUNCVAL(math_tanh)},
{LSTRKEY("tan"), LFUNCVAL(math_tan)},
#if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("pi"), LNUMVAL(PI)},
{LSTRKEY("huge"), LNUMVAL(HUGE_VAL)},
#endif
{LNILKEY, LNILVAL}
};


@@ -250,16 +258,20 @@ static const luaL_Reg mathlib[] = {
*/
LUALIB_API int luaopen_math (lua_State *L) {
#if !defined LUA_NUMBER_INTEGRAL
luaL_register(L, LUA_MATHLIBNAME, mathlib);
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register(L, LUA_MATHLIBNAME, math_map);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
#if defined(LUA_COMPAT_MOD)
lua_getfield(L, -1, "fmod");
lua_setfield(L, -2, "mod");
return 1;
#endif // #if defined(LUA_COMPAT_MOD)
return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
#else // #if !defined LUA_NUMBER_INTEGRAL
return 0;
#endif // #if !defined LUA_NUMBER_INTEGRAL
@@ -20,7 +20,7 @@

#include "lauxlib.h"
#include "lualib.h"

#include "lrotable.h"

/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@@ -459,6 +459,12 @@ static int ll_require (lua_State *L) {
luaL_error(L, "loop or previous error loading module " LUA_QS, name);
return 1; /* package is already loaded */
}
/* Is this a readonly table? */
void *res = luaR_findglobal(name, strlen(name));
if (res) {
lua_pushrotable(L, res);
return 1;
}
/* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
if (!lua_istable(L, -1))
@@ -543,6 +549,8 @@ static void modinit (lua_State *L, const char *modname) {

static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
if (luaR_findglobal(modname, strlen(modname)))
return 0;
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
@@ -623,15 +631,25 @@ static const luaL_Reg ll_funcs[] = {
static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL};

#if LUA_OPTIMIZE_MEMORY > 0
const luaR_entry lmt[] = {
{LRO_STRKEY("__gc"), LRO_FUNCVAL(gctm)},
{LRO_NILKEY, LRO_NILVAL}
};
#endif

LUALIB_API int luaopen_package (lua_State *L) {
int i;
/* create new type _LOADLIB */
#if LUA_OPTIMIZE_MEMORY == 0
luaL_newmetatable(L, "_LOADLIB");
lua_pushcfunction(L, gctm);
lua_pushlightfunction(L, gctm);
lua_setfield(L, -2, "__gc");
#else
luaL_rometatable(L, "_LOADLIB", (void*)lmt);
#endif
/* create `package' table */
luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
luaL_register_light(L, LUA_LOADLIBNAME, pk_funcs);
#if defined(LUA_COMPAT_LOADLIB)
lua_getfield(L, -1, "loadlib");
lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
@@ -79,6 +79,8 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
case LUA_TROTABLE:
case LUA_TLIGHTFUNCTION:
return pvalue(t1) == pvalue(t2);
default:
lua_assert(iscollectable(t1));
@@ -74,7 +74,6 @@ typedef struct lua_TValue {
TValuefields;
} TValue;


/* Macros to test type */
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
@@ -85,11 +84,15 @@ typedef struct lua_TValue {
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
#define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)

/* Macros to access values */
#define ttype(o) ((o)->tt)
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
#define rvalue(o) check_exp(ttisrotable(o), (o)->value.p)
#define fvalue(o) check_exp(ttislightfunction(o), (o)->value.p)
#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv)
@@ -121,6 +124,12 @@ typedef struct lua_TValue {

#define setpvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }

#define setrvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TROTABLE; }

#define setfvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTFUNCTION; }

#define setbvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
@@ -312,7 +321,7 @@ typedef union Closure {
} Closure;


#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
#define iscfunction(o) ((ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)||(ttype(o)==LUA_TLIGHTFUNCTION))
#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)


@@ -348,7 +357,6 @@ typedef struct Table {
} Table;



/*
** `module' operation for hashing (size is always a power of 2)
*/
@@ -18,6 +18,7 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"


static int os_pushresult (lua_State *L, int i, const char *filename) {
@@ -218,29 +219,29 @@ static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
}

static const luaL_Reg syslib[] = {
{"clock", os_clock},
{"date", os_date},
#if !defined LUA_NUMBER_INTEGRAL
{"difftime", os_difftime},
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE syslib[] = {
{LSTRKEY("clock"), LFUNCVAL(os_clock)},
{LSTRKEY("date"), LFUNCVAL(os_date)},
#if !defined LUA_NUMBER_INTEGRAL
{LSTRKEY("difftime"), LFUNCVAL(os_difftime)},
#endif
{"execute", os_execute},
{"exit", os_exit},
{"getenv", os_getenv},
{"remove", os_remove},
{"rename", os_rename},
{"setlocale", os_setlocale},
{"time", os_time},
{"tmpname", os_tmpname},
{NULL, NULL}
{LSTRKEY("execute"), LFUNCVAL(os_execute)},
{LSTRKEY("exit"), LFUNCVAL(os_exit)},
{LSTRKEY("getenv"), LFUNCVAL(os_getenv)},
{LSTRKEY("remove"), LFUNCVAL(os_remove)},
{LSTRKEY("rename"), LFUNCVAL(os_rename)},
{LSTRKEY("setlocale"), LFUNCVAL(os_setlocale)},
{LSTRKEY("time"), LFUNCVAL(os_time)},
{LSTRKEY("tmpname"), LFUNCVAL(os_tmpname)},
{LNILKEY, LNILVAL}
};

/* }====================================================== */



LUALIB_API int luaopen_os (lua_State *L) {
luaL_register(L, LUA_OSLIBNAME, syslib);
return 1;
LREGISTER(L, LUA_OSLIBNAME, syslib);
}

@@ -0,0 +1,34 @@
/* Read-only tables helper */

#undef LUA_REG_TYPE
#undef LSTRKEY
#undef LNILKEY
#undef LNUMKEY
#undef LFUNCVAL
#undef LNUMVAL
#undef LROVAL
#undef LNILVAL
#undef LREGISTER

#if (MIN_OPT_LEVEL > 0) && (LUA_OPTIMIZE_MEMORY >= MIN_OPT_LEVEL)
#define LUA_REG_TYPE luaR_entry
#define LSTRKEY LRO_STRKEY
#define LNUMKEY LRO_NUMKEY
#define LNILKEY LRO_NILKEY
#define LFUNCVAL LRO_FUNCVAL
#define LNUMVAL LRO_NUMVAL
#define LROVAL LRO_ROVAL
#define LNILVAL LRO_NILVAL
#define LREGISTER(L, name, table)\
return 0
#else
#define LUA_REG_TYPE luaL_reg
#define LSTRKEY(x) x
#define LNILKEY NULL
#define LFUNCVAL(x) x
#define LNILVAL NULL
#define LREGISTER(L, name, table)\
luaL_register(L, name, table);\
return 1
#endif

@@ -0,0 +1,134 @@
/* Read-only tables for Lua */

#include <string.h>
#include "lrotable.h"
#include "lua.h"
#include "lauxlib.h"
#include "lstring.h"
#include "lobject.h"
#include "lapi.h"

/* Local defines */
#define LUAR_FINDFUNCTION 0
#define LUAR_FINDVALUE 1

/* Externally defined read-only table array */
extern const luaR_table lua_rotable[];

/* Find a global "read only table" in the constant lua_rotable array */
void* luaR_findglobal(const char *name, unsigned len) {
unsigned i;

if (strlen(name) > LUA_MAX_ROTABLE_NAME)
return NULL;
for (i=0; lua_rotable[i].name; i ++)
if (*lua_rotable[i].name != '\0' && strlen(lua_rotable[i].name) == len && !strncmp(lua_rotable[i].name, name, len)) {
return (void*)(lua_rotable[i].pentries);
}
return NULL;
}

/* Find an entry in a rotable and return it */
static const TValue* luaR_auxfind(const luaR_entry *pentry, const char *strkey, luaR_numkey numkey, unsigned *ppos) {
const TValue *res = NULL;
unsigned i = 0;

if (pentry == NULL)
return NULL;
while(pentry->key.type != LUA_TNIL) {
if ((strkey && (pentry->key.type == LUA_TSTRING) && (!strcmp(pentry->key.strkey, strkey))) ||
(!strkey && (pentry->key.type == LUA_TNUMBER) && ((luaR_numkey)pentry->key.numkey == numkey))) {
res = &pentry->value;
break;
}
i ++; pentry ++;
}
if (res && ppos)
*ppos = i;
return res;
}

int luaR_findfunction(lua_State *L, const luaR_entry *ptable) {
const TValue *res = NULL;
const char *key = luaL_checkstring(L, 2);

res = luaR_auxfind(ptable, key, 0, NULL);
if (res && ttislightfunction(res)) {
luaA_pushobject(L, res);
return 1;
}
else
return 0;
}

/* Find an entry in a rotable and return its type
If "strkey" is not NULL, the function will look for a string key,
otherwise it will look for a number key */
const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos) {
return luaR_auxfind((const luaR_entry*)data, strkey, numkey, ppos);
}

/* Find the metatable of a given table */
void* luaR_getmeta(void *data) {
#ifdef LUA_META_ROTABLES
const TValue *res = luaR_auxfind((const luaR_entry*)data, "__metatable", 0, NULL);
return res && ttisrotable(res) ? rvalue(res) : NULL;
#else
return NULL;
#endif
}

static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos, TValue *key, TValue *val) {
setnilvalue(key);
setnilvalue(val);
if (pentries[pos].key.type != LUA_TNIL) {
/* Found an entry */
if (pentries[pos].key.type == LUA_TSTRING)
setsvalue(L, key, luaS_new(L, pentries[pos].key.strkey))
else
setnvalue(key, (lua_Number)pentries[pos].key.numkey)
setobj2s(L, val, &pentries[pos].value);
}
}
/* next (used for iteration) */
void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) {
const luaR_entry* pentries = (const luaR_entry*)data;
char strkey[LUA_MAX_ROTABLE_NAME + 1], *pstrkey = NULL;
luaR_numkey numkey = 0;
unsigned keypos;

/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
luaR_next_helper(L, pentries, 0, key, val);
else if (ttisstring(key) || ttisnumber(key)) {
/* Find the previoud key again */
if (ttisstring(key)) {
luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME);
pstrkey = strkey;
} else
numkey = (luaR_numkey)nvalue(key);
luaR_findentry(data, pstrkey, numkey, &keypos);
/* Advance to next key */
keypos ++;
luaR_next_helper(L, pentries, keypos, key, val);
}
}

/* Convert a Lua string to a C string */
void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
if (src->tsv.len+1 > maxsize)
dest[0] = '\0';
else {
memcpy(dest, getstr(src), src->tsv.len);
dest[src->tsv.len] = '\0';
}
}

/* Return 1 if the given pointer is a rotable */
#ifdef LUA_META_ROTABLES
extern char stext[];
extern char etext[];
int luaR_isrotable(void *p) {
return stext <= ( char* )p && ( char* )p <= etext;
}
#endif
@@ -0,0 +1,64 @@
/* Read-only tables for Lua */

#ifndef lrotable_h
#define lrotable_h

#include "lua.h"
#include "llimits.h"
#include "lobject.h"
#include "luaconf.h"

/* Macros one can use to define rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = ( void* )v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}

#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}

/* Maximum length of a rotable name */
#define LUA_MAX_ROTABLE_NAME 16

/* Type of a numeric key in a rotable */
typedef int luaR_numkey;

/* The next structure defines the type of a key */
typedef struct
{
int type;
union
{
const char* strkey;
luaR_numkey numkey;
};
} luaR_key;

/* An entry in the read only table */
typedef struct
{
const luaR_key key;
const TValue value;
} luaR_entry;

/* A rotable */
typedef struct
{
const char *name;
const luaR_entry *pentries;
} luaR_table;

void* luaR_findglobal(const char *key, unsigned len);
int luaR_findfunction(lua_State *L, const luaR_entry *ptable);
const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos);
void luaR_getcstr(char *dest, const TString *src, size_t maxsize);
void luaR_next(lua_State *L, void *data, TValue *key, TValue *val);
void* luaR_getmeta(void *data);
#ifdef LUA_META_ROTABLES
int luaR_isrotable(void *p);
#else
#define luaR_isrotable(p) (0)
#endif

#endif
@@ -56,9 +56,9 @@ typedef struct CallInfo {



#define curr_func(L) (clvalue(L->ci->func))
#define ci_func(ci) (clvalue((ci)->func))
#define f_isLua(ci) (!ci_func(ci)->c.isC)
#define curr_func(L) (ttisfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define ci_func(ci) (ttisfunction((ci)->func) ? clvalue((ci)->func) : NULL)
#define f_isLua(ci) (!ttislightfunction((ci)->func) && !ci_func(ci)->c.isC)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))


@@ -161,7 +161,6 @@ union GCObject {
/* macro to convert any Lua object into a GCObject */
#define obj2gco(v) (cast(GCObject *, (v)))


LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);

@@ -18,7 +18,7 @@

#include "lauxlib.h"
#include "lualib.h"

#include "lrotable.h"

/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
@@ -580,12 +580,12 @@ static int gmatch (lua_State *L) {
return 1;
}


#if LUA_OPTIMIZE_MEMORY == 0 || !defined(LUA_COMPAT_GFIND)
static int gfind_nodef (lua_State *L) {
return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
LUA_QL("string.gmatch"));
}

#endif

static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
const char *e) {
@@ -618,7 +618,8 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
add_s(ms, b, s, e);
return;
}
case LUA_TFUNCTION: {
case LUA_TFUNCTION:
case LUA_TLIGHTFUNCTION: {
int n;
lua_pushvalue(L, 3);
n = push_captures(ms, s, e);
@@ -652,8 +653,9 @@ static int str_gsub (lua_State *L) {
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
"string/function/table expected");
tr == LUA_TFUNCTION || tr == LUA_TTABLE ||
tr == LUA_TLIGHTFUNCTION, 3,
"string/function/table/lightfunction expected");
luaL_buffinit(L, &b);
ms.L = L;
ms.src_init = src;
@@ -823,27 +825,36 @@ static int str_format (lua_State *L) {
return 1;
}


static const luaL_Reg strlib[] = {
{"byte", str_byte},
{"char", str_char},
{"dump", str_dump},
{"find", str_find},
{"format", str_format},
{"gfind", gfind_nodef},
{"gmatch", gmatch},
{"gsub", str_gsub},
{"len", str_len},
{"lower", str_lower},
{"match", str_match},
{"rep", str_rep},
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
{NULL, NULL}
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE strlib[] = {
{LSTRKEY("byte"), LFUNCVAL(str_byte)},
{LSTRKEY("char"), LFUNCVAL(str_char)},
{LSTRKEY("dump"), LFUNCVAL(str_dump)},
{LSTRKEY("find"), LFUNCVAL(str_find)},
{LSTRKEY("format"), LFUNCVAL(str_format)},
#if LUA_OPTIMIZE_MEMORY > 0 && defined(LUA_COMPAT_GFIND)
{LSTRKEY("gfind"), LFUNCVAL(gmatch)},
#else
{LSTRKEY("gfind"), LFUNCVAL(gfind_nodef)},
#endif
{LSTRKEY("gmatch"), LFUNCVAL(gmatch)},
{LSTRKEY("gsub"), LFUNCVAL(str_gsub)},
{LSTRKEY("len"), LFUNCVAL(str_len)},
{LSTRKEY("lower"), LFUNCVAL(str_lower)},
{LSTRKEY("match"), LFUNCVAL(str_match)},
{LSTRKEY("rep"), LFUNCVAL(str_rep)},
{LSTRKEY("reverse"), LFUNCVAL(str_reverse)},
{LSTRKEY("sub"), LFUNCVAL(str_sub)},
{LSTRKEY("upper"), LFUNCVAL(str_upper)},
#if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("__index"), LROVAL(strlib)},
#endif
{LNILKEY, LNILVAL}
};


#if LUA_OPTIMIZE_MEMORY != 2
static void createmetatable (lua_State *L) {
lua_createtable(L, 0, 1); /* create metatable for strings */
lua_pushliteral(L, ""); /* dummy string */
@@ -854,18 +865,26 @@ static void createmetatable (lua_State *L) {
lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
lua_pop(L, 1); /* pop metatable */
}

#endif

/*
** Open string library
*/
LUALIB_API int luaopen_string (lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 0
luaL_register(L, LUA_STRLIBNAME, strlib);
#if defined(LUA_COMPAT_GFIND)
lua_getfield(L, -1, "gmatch");
lua_setfield(L, -2, "gfind");
#endif
createmetatable(L);
return 1;
#else
lua_pushliteral(L,"");
lua_pushrotable(L, (void*)strlib);
lua_setmetatable(L, -2);
lua_pop(L,1);
return 0;
#endif
}

@@ -33,7 +33,7 @@
#include "lobject.h"
#include "lstate.h"
#include "ltable.h"

#include "lrotable.h"

/*
** max size of array part is 2^MAXBITS
@@ -106,6 +106,8 @@ static Node *mainposition (const Table *t, const TValue *key) {
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
case LUA_TROTABLE:
case LUA_TLIGHTFUNCTION:
return hashpointer(t, pvalue(key));
default:
return hashpointer(t, gcvalue(key));
@@ -179,6 +181,12 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
}


int luaH_next_ro (lua_State *L, void *t, StkId key) {
luaR_next(L, t, key, key+1);
return ttisnil(key) ? 0 : 1;
}


/*
** {=============================================================
** Rehash
@@ -448,6 +456,12 @@ const TValue *luaH_getnum (Table *t, int key) {
}
}

/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
const TValue *res = luaR_findentry(t, NULL, key, NULL);
return res ? res : luaO_nilobject;
}


/*
** search function for strings
@@ -462,6 +476,17 @@ const TValue *luaH_getstr (Table *t, TString *key) {
return luaO_nilobject;
}

/* same thing for rotables */
const TValue *luaH_getstr_ro (void *t, TString *key) {
char keyname[LUA_MAX_ROTABLE_NAME + 1];
const TValue *res;
if (!t)
return luaO_nilobject;
luaR_getcstr(keyname, key, LUA_MAX_ROTABLE_NAME);
res = luaR_findentry(t, keyname, 0, NULL);
return res ? res : luaO_nilobject;
}


/*
** main search function
@@ -490,6 +515,25 @@ const TValue *luaH_get (Table *t, const TValue *key) {
}
}

/* same thing for rotables */
const TValue *luaH_get_ro (void *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr_ro(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum_ro(t, k); /* use specialized version */
/* else go through */
}
default: {
return luaO_nilobject;
}
}
}


TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
@@ -575,7 +619,14 @@ int luaH_getn (Table *t) {
else return unbound_search(t, j);
}


/* same thing for rotables */
int luaH_getn_ro (void *t) {
int i = 1, len=0;

while(luaR_findentry(t, NULL, i ++, NULL))
len ++;
return len;
}

#if defined(LUA_DEBUG)

@@ -19,17 +19,21 @@


LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
LUAI_FUNC const TValue *luaH_getnum_ro (void *t, int key);
LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_getstr_ro (void *t, TString *key);
LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC const TValue *luaH_get_ro (void *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);

LUAI_FUNC int luaH_getn_ro (void *t);

#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
@@ -14,6 +14,7 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"


#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
@@ -22,7 +23,7 @@
static int foreachi (lua_State *L) {
int i;
int n = aux_getn(L, 1);
luaL_checktype(L, 2, LUA_TFUNCTION);
luaL_checkanyfunction(L, 2);
for (i=1; i <= n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */
@@ -38,7 +39,7 @@ static int foreachi (lua_State *L) {

static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktype(L, 2, LUA_TFUNCTION);
luaL_checkanyfunction(L, 2);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pushvalue(L, 2); /* function */
@@ -266,22 +267,21 @@ static int sort (lua_State *L) {
/* }====================================================== */


static const luaL_Reg tab_funcs[] = {
{"concat", tconcat},
{"foreach", foreach},
{"foreachi", foreachi},
{"getn", getn},
{"maxn", maxn},
{"insert", tinsert},
{"remove", tremove},
{"setn", setn},
{"sort", sort},
{NULL, NULL}
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE tab_funcs[] = {
{LSTRKEY("concat"), LFUNCVAL(tconcat)},
{LSTRKEY("foreach"), LFUNCVAL(foreach)},
{LSTRKEY("foreachi"), LFUNCVAL(foreachi)},
{LSTRKEY("getn"), LFUNCVAL(getn)},
{LSTRKEY("maxn"), LFUNCVAL(maxn)},
{LSTRKEY("insert"), LFUNCVAL(tinsert)},
{LSTRKEY("remove"), LFUNCVAL(tremove)},
{LSTRKEY("setn"), LFUNCVAL(setn)},
{LSTRKEY("sort"), LFUNCVAL(sort)},
{LNILKEY, LNILVAL}
};


LUALIB_API int luaopen_table (lua_State *L) {
luaL_register(L, LUA_TABLIBNAME, tab_funcs);
return 1;
LREGISTER(L, LUA_TABLIBNAME, tab_funcs);
}

@@ -17,11 +17,12 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lrotable.h"



const char *const luaT_typenames[] = {
"nil", "boolean", "userdata", "number",
"nil", "boolean", "romtable", "lightfunction", "userdata", "number",
"string", "table", "function", "userdata", "thread",
"proto", "upval"
};
@@ -48,10 +49,11 @@ void luaT_init (lua_State *L) {
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm = luaH_getstr(events, ename);
const TValue *tm = luaR_isrotable(events) ? luaH_getstr_ro(events, ename) : luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
if (!luaR_isrotable(events))
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
else return tm;
@@ -64,12 +66,19 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(o));
break;
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
mt = G(L)->mt[ttype(o)];
}
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
if (!mt)
return luaO_nilobject;
else if (luaR_isrotable(mt))
return luaH_getstr_ro(mt, G(L)->tmname[event]);
else
return luaH_getstr(mt, G(L)->tmname[event]);
}

@@ -39,7 +39,7 @@ typedef enum {


#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
!luaR_isrotable(et) && ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))

#define fasttm(l,et,e) gfasttm(G(l), et, e)

@@ -77,12 +77,12 @@ static int traceback (lua_State *L) {
if (!lua_isstring(L, 1)) /* 'message' not a string? */
return 1; /* keep it intact */
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) {
lua_pop(L, 1);
return 1;
}
lua_getfield(L, -1, "traceback");
if (!lua_isfunction(L, -1)) {
if (!lua_isfunction(L, -1) && !lua_islightfunction(L, -1)) {
lua_pop(L, 2);
return 1;
}
@@ -73,15 +73,15 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);

#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8


#define LUA_TROTABLE 2
#define LUA_TLIGHTFUNCTION 3
#define LUA_TLIGHTUSERDATA 4
#define LUA_TNUMBER 5
#define LUA_TSTRING 6
#define LUA_TTABLE 7
#define LUA_TFUNCTION 8
#define LUA_TUSERDATA 9
#define LUA_TTHREAD 10

/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
@@ -168,6 +168,8 @@ LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API void (lua_pushlightfunction) (lua_State *L, void *p);
LUA_API void (lua_pushrotable) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);


@@ -262,7 +264,9 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_strlen(L,i) lua_objlen(L, (i))

#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_islightfunction(L,n) (lua_type(L, (n)) == LUA_TLIGHTFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_isrotable(L,n) (lua_type(L, (n)) == LUA_TROTABLE)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
@@ -814,6 +814,8 @@ union luai_Cast { double l_d; long l_l; };

#endif



/* =================================================================== */

/*
@@ -826,4 +828,13 @@ typedef short int16_t;
typedef long int32_t;
#endif

/* If you define the next macro you'll get the ability to set rotables as
metatables for tables/userdata/types (but the VM might run slower)
*/
#define LUA_META_ROTABLES

#if LUA_OPTIMIZE_MEMORY == 2 && LUA_USE_POPEN
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)"
#endif

#endif
@@ -25,7 +25,7 @@
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"

#include "lrotable.h"


/* limit for table tag-method chains (to avoid loops) */
@@ -128,19 +128,19 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */
void *h = ttistable(t) ? hvalue(t) : rvalue(t);
const TValue *res = ttistable(t) ? luaH_get((Table*)h, key) : luaH_get_ro(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
(tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)h, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm)) {
luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) {
callTMres(L, val, tm, t, key);
return;
}
@@ -274,7 +274,10 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TLIGHTUSERDATA:
case LUA_TROTABLE:
case LUA_TLIGHTFUNCTION:
return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
@@ -529,8 +532,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
case OP_LEN: {
const TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE: {
setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
case LUA_TTABLE:
case LUA_TROTABLE: {
setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb))));
break;
}
case LUA_TSTRING: {
@@ -39,12 +39,6 @@ LUALIB_API int ( luaopen_net )( lua_State *L );
#define AUXLIB_CPU "cpu"
LUALIB_API int ( luaopen_cpu )( lua_State* L );

#define AUXLIB_MOD "mod"
LUALIB_API int ( luaopen_mod )( lua_State* L );

#define AUXLIB_DISP "disp"
LUALIB_API int ( luaopen_disp )( lua_State* L );

// Helper macros

#define MOD_CHECK_ID( mod, id )\
@@ -9,6 +9,7 @@
#include <limits.h>
#include "auxmods.h"
#include "type.h"
#include "lrotable.h"

/* FIXME: Assume size_t is an unsigned lua_Integer */
typedef size_t lua_UInteger;
@@ -123,23 +124,24 @@ static int bit_clear( lua_State* L )
return 1;
}

static const struct luaL_reg bitlib[] = {
{"bnot", bit_bnot},
{"band", bit_band},
{"bor", bit_bor},
{"bxor", bit_bxor},
{"lshift", bit_lshift},
{"rshift", bit_rshift},
{"arshift", bit_arshift},
{"bit", bit_bit},
{"set", bit_set},
{"clear", bit_clear},
{"isset", bit_isset},
{"isclear", bit_isclear},
{NULL, NULL}
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE bit_map[] = {
{ LSTRKEY( "bnot" ), LFUNCVAL( bit_bnot ) },
{ LSTRKEY( "band" ), LFUNCVAL( bit_band ) },
{ LSTRKEY( "bor" ), LFUNCVAL( bit_bor ) },
{ LSTRKEY( "bxor" ), LFUNCVAL( bit_bxor ) },
{ LSTRKEY( "lshift" ), LFUNCVAL( bit_lshift ) },
{ LSTRKEY( "rshift" ), LFUNCVAL( bit_rshift ) },
{ LSTRKEY( "arshift" ), LFUNCVAL( bit_arshift ) },
{ LSTRKEY( "bit" ), LFUNCVAL( bit_bit ) },
{ LSTRKEY( "set" ), LFUNCVAL( bit_set ) },
{ LSTRKEY( "clear" ), LFUNCVAL( bit_clear ) },
{ LSTRKEY( "isset" ), LFUNCVAL( bit_isset ) },
{ LSTRKEY( "isclear" ), LFUNCVAL( bit_isclear ) },
{ LNILKEY, LNILVAL}
};

LUALIB_API int luaopen_bit (lua_State *L) {
luaL_register(L, "bit", bitlib);
return 1;
LREGISTER( L, "bit", bit_map );
}
@@ -5,6 +5,7 @@
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
#include <string.h>

#define _C( x ) { #x, x }
@@ -95,11 +96,10 @@ typedef struct
u32 val;
} cpu_const_t;

#ifdef PLATFORM_CPU_CONSTANTS
static const cpu_const_t cpu_constants[] =
{
#ifdef PLATFORM_CPU_CONSTANTS
PLATFORM_CPU_CONSTANTS,
#endif
{ NULL, 0 }
};

@@ -119,38 +119,45 @@ static int cpu_mt_index( lua_State *L )
}
return 0;
}

// Metatable data
static const luaL_reg cpu_mt_map[] =
{
{ "__index", cpu_mt_index },
{ NULL, NULL }
};
#endif

// Module function map
static const luaL_reg cpu_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE cpu_map[] =
{
{ "w32", cpu_w32 },
{ "r32", cpu_r32 },
{ "w16", cpu_w16 },
{ "r16", cpu_r16 },
{ "w8", cpu_w8 },
{ "r8", cpu_r8 },
{ "cli", cpu_cli },
{ "sei", cpu_sei },
{ "clock", cpu_clock },
{ NULL, NULL }
{ LSTRKEY( "w32" ), LFUNCVAL( cpu_w32 ) },
{ LSTRKEY( "r32" ), LFUNCVAL( cpu_r32 ) },
{ LSTRKEY( "w16" ), LFUNCVAL( cpu_w16 ) },
{ LSTRKEY( "r16" ), LFUNCVAL( cpu_r16 ) },
{ LSTRKEY( "w8" ), LFUNCVAL( cpu_w8 ) },
{ LSTRKEY( "r8" ), LFUNCVAL( cpu_r8 ) },
{ LSTRKEY( "cli" ), LFUNCVAL( cpu_cli ) },
{ LSTRKEY( "sei" ), LFUNCVAL( cpu_sei ) },
{ LSTRKEY( "clock" ), LFUNCVAL( cpu_clock ) },
#if defined( PLATFORM_CPU_CONSTANTS ) && LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "__metatable" ), LROVAL( cpu_map ) },
#endif
#ifdef PLATFORM_CPU_CONSTANTS
{ LSTRKEY( "__index" ), LFUNCVAL( cpu_mt_index ) },
#endif
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_cpu( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
// Register methods
luaL_register( L, AUXLIB_CPU, cpu_map );

// Create and set metatable
lua_newtable( L );
luaL_register( L, NULL, cpu_mt_map );
lua_setmetatable( L, -2 );
#ifdef PLATFORM_CPU_CONSTANTS
// Set table as its own metatable
lua_pushvalue( L, -1 );
lua_setmetatable( L, -2 );
#endif // #ifdef PLATFORM_CPU_CONSTANTS

return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}

This file was deleted.

@@ -37,6 +37,7 @@
#include "lualib.h"
#include "lauxlib.h"
#include "auxmods.h"
#include "lrotable.h"

static void badcode(lua_State *L, int c)
{
@@ -254,15 +255,16 @@ static int l_pack(lua_State *L) /** pack(f,...) */
return 1;
}

static const luaL_reg pack_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE pack_map[] =
{
{"pack", l_pack},
{"unpack", l_unpack},
{NULL, NULL}
{ LSTRKEY( "pack" ), LFUNCVAL( l_pack ) },
{ LSTRKEY( "unpack" ), LFUNCVAL( l_unpack ) },
{ LNILKEY, LNILVAL }
};

int luaopen_pack( lua_State *L )
{
luaL_register( L, AUXLIB_PACK, pack_map );
return 1;
LREGISTER( L, AUXLIB_PACK, pack_map );
}

This file was deleted.

@@ -9,6 +9,7 @@
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include "lrotable.h"

#include "platform_conf.h"
#ifdef BUILD_UIP
@@ -184,22 +185,31 @@ static int net_lookup( lua_State* L )
}

// Module function map
static const luaL_reg net_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE net_map[] =
{
{ "accept", net_accept },
{ "packip", net_packip },
{ "unpackip", net_unpackip },
{ "connect", net_connect },
{ "socket", net_socket },
{ "close", net_close },
{ "send", net_send },
{ "recv", net_recv },
{ "lookup", net_lookup },
{ NULL, NULL }
{ LSTRKEY( "accept" ), LFUNCVAL( net_accept ) },
{ LSTRKEY( "packip" ), LFUNCVAL( net_packip ) },
{ LSTRKEY( "unpackip" ), LFUNCVAL( net_unpackip ) },
{ LSTRKEY( "connect" ), LFUNCVAL( net_connect ) },
{ LSTRKEY( "socket" ), LFUNCVAL( net_socket ) },
{ LSTRKEY( "close" ), LFUNCVAL( net_close ) },
{ LSTRKEY( "send" ), LFUNCVAL( net_send ) },
{ LSTRKEY( "recv" ), LFUNCVAL( net_recv ) },
{ LSTRKEY( "lookup" ), LFUNCVAL( net_lookup ) },
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "SOCK_STREAM" ), LNUMVAL( ELUA_NET_SOCK_STREAM ) },
{ LSTRKEY( "SOCK_DGRAM" ), LNUMVAL( ELUA_NET_SOCK_DGRAM ) },
#endif
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_net( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register( L, AUXLIB_NET, net_map );

// Module constants
@@ -209,6 +219,7 @@ LUALIB_API int luaopen_net( lua_State *L )
lua_setfield( L, -2, "SOCK_DGRAM" );

return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}

#else // #ifdef BUILD_UIP
@@ -5,6 +5,7 @@
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"

#define MACRO_NAME( x ) MACRO_AGAIN( x )
#define MACRO_AGAIN( x ) #x
@@ -31,16 +32,17 @@ static int pd_board( lua_State* L )
}

// Module function map
static const luaL_reg pd_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE pd_map[] =
{
{ "platform", pd_platform },
{ "cpu", pd_cpu },
{ "board", pd_board },
{ NULL, NULL }
{ LSTRKEY( "platform" ), LFUNCVAL( pd_platform ) },
{ LSTRKEY( "cpu" ), LFUNCVAL( pd_cpu ) },
{ LSTRKEY( "board" ), LFUNCVAL( pd_board ) },
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_pd( lua_State* L )
{
luaL_register( L, AUXLIB_PD, pd_map );
return 1;
LREGISTER( L, AUXLIB_PD, pd_map );
}
@@ -5,6 +5,8 @@
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
#include "platform_conf.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
@@ -211,27 +213,6 @@ static int pio_pin_nopull( lua_State* L )
return pioh_set_pins( L, 1, PLATFORM_IO_PIN_NOPULL );
}

// Module function map
static const luaL_reg pio_map[] =
{
{ "setpin", pio_set_pin_state },
{ "set", pio_set_pin },
{ "get", pio_get_pin },
{ "clear", pio_clear_pin },
{ "input", pio_pin_input },
{ "output", pio_pin_output },
{ "setport", pio_set_port },
{ "getport", pio_get_port },
{ "port_input", pio_port_input },
{ "port_output", pio_port_output },
{ "pullup", pio_pin_pullup },
{ "pulldown", pio_pin_pulldown },
{ "nopull", pio_pin_nopull },
{ "port", pio_port },
{ "pin", pio_pin },
{ NULL, NULL }
};

// __index metafunction for PIO
// Look for all Px or Px_y keys and return their correct value
static int pio_mt_index( lua_State* L )
@@ -243,6 +224,8 @@ static int pio_mt_index( lua_State* L )
return 0;
if( isupper( key[ 1 ] ) ) // PA, PB, ...
{
if( PIO_PREFIX != 'A' )
return 0;
port = key[ 1 ] - 'A';
if( key[ 2 ] == '\0' )
isport = 1;
@@ -252,7 +235,8 @@ static int pio_mt_index( lua_State* L )
}
else // P0, P1, ...
{
// P0, P1, ...
if( PIO_PREFIX != '0' )
return 0;
if( !strchr( key, '_' ) ) // parse port
{
if( sscanf( key + 1, "%d%n", &port, &sz ) != 1 || sz != strlen( key ) - 1 )
@@ -283,21 +267,44 @@ static int pio_mt_index( lua_State* L )
}
}

// Metatable data
static const luaL_reg pio_mt_map[] =
// Module function map
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE pio_map[] =
{
{ "__index", pio_mt_index },
{ NULL, NULL }
{ LSTRKEY( "setpin" ), LFUNCVAL( pio_set_pin_state ) },
{ LSTRKEY( "set" ), LFUNCVAL( pio_set_pin ) },
{ LSTRKEY( "get" ), LFUNCVAL( pio_get_pin ) },
{ LSTRKEY( "clear" ), LFUNCVAL( pio_clear_pin ) },
{ LSTRKEY( "input" ), LFUNCVAL( pio_pin_input ) },
{ LSTRKEY( "output" ), LFUNCVAL( pio_pin_output ) },
{ LSTRKEY( "setport" ), LFUNCVAL( pio_set_port ) },
{ LSTRKEY( "getport" ), LFUNCVAL( pio_get_port ) },
{ LSTRKEY( "port_input" ), LFUNCVAL( pio_port_input ) },
{ LSTRKEY( "port_output" ), LFUNCVAL( pio_port_output ) },
{ LSTRKEY( "pullup" ), LFUNCVAL( pio_pin_pullup ) },
{ LSTRKEY( "pulldown" ), LFUNCVAL( pio_pin_pulldown ) },
{ LSTRKEY( "nopull" ), LFUNCVAL( pio_pin_nopull ) },
{ LSTRKEY( "port" ), LFUNCVAL( pio_port ) },
{ LSTRKEY( "pin" ), LFUNCVAL( pio_pin ) },
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "__metatable" ), LROVAL( pio_map ) },
#endif
{ LSTRKEY( "__index" ), LFUNCVAL( pio_mt_index ) },
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_pio( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register( L, AUXLIB_PIO, pio_map );

// Create and set metatable
lua_newtable( L );
luaL_register( L, NULL, pio_mt_map );
// Set this table as its own metatable
lua_pushvalue( L, -1 );
lua_setmetatable( L, -2 );

return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}
@@ -5,6 +5,7 @@
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"

// Lua: realfrequency = setup( id, frequency, duty )
static int pwm_setup( lua_State* L )
@@ -73,18 +74,19 @@ static int pwm_getclock( lua_State* L )
}

// Module function map
static const luaL_reg pwm_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE pwm_map[] =
{
{ "setup", pwm_setup },
{ "start", pwm_start },
{ "stop", pwm_stop },
{ "setclock", pwm_setclock },
{ "getclock", pwm_getclock },
{ NULL, NULL }
{ LSTRKEY( "setup" ), LFUNCVAL( pwm_setup ) },
{ LSTRKEY( "start" ), LFUNCVAL( pwm_start ) },
{ LSTRKEY( "stop" ), LFUNCVAL( pwm_stop ) },
{ LSTRKEY( "setclock" ), LFUNCVAL( pwm_setclock ) },
{ LSTRKEY( "getclock" ), LFUNCVAL( pwm_getclock ) },
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_pwm( lua_State *L )
{
luaL_register( L, AUXLIB_PWM, pwm_map );
return 1;
LREGISTER( L, AUXLIB_PWM, pwm_map );
}
@@ -5,6 +5,7 @@
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"

// Lua: select( id )
static int spi_select( lua_State* L )
@@ -80,25 +81,35 @@ static int spi_send_recv( lua_State* L )
}

// Module function map
static const luaL_reg spi_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE spi_map[] =
{
{ "setup", spi_setup },
{ "select", spi_select },
{ "unselect", spi_unselect },
{ "send", spi_send },
{ "send_recv", spi_send_recv },
{ NULL, NULL }
{ LSTRKEY( "setup" ), LFUNCVAL( spi_setup ) },
{ LSTRKEY( "select" ), LFUNCVAL( spi_select ) },
{ LSTRKEY( "unselect" ), LFUNCVAL( spi_unselect ) },
{ LSTRKEY( "send" ), LFUNCVAL( spi_send ) },
{ LSTRKEY( "send_recv" ), LFUNCVAL( spi_send_recv ) },
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "MASTER" ), LNUMVAL( PLATFORM_SPI_MASTER ) } ,
{ LSTRKEY( "SLAVE" ), LNUMVAL( PLATFORM_SPI_SLAVE ) },
#endif
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_spi( lua_State *L )
{

#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register( L, AUXLIB_SPI, spi_map );

// Add the MASTER and SLAVE constants (for spi.setup)
lua_pushnumber( L, PLATFORM_SPI_MASTER );
lua_setfield( L, -2, "MASTER" );
lua_pushnumber( L, PLATFORM_SPI_SLAVE );
lua_setfield( L, -2, "SLAVE" );

return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}
@@ -7,6 +7,7 @@
#include "auxmods.h"
#include "term.h"
#include "platform_conf.h"
#include "lrotable.h"
#include <string.h>

// Lua: clrscr()
@@ -209,52 +210,56 @@ static int term_mt_index( lua_State* L )
}

// Module function map
static const luaL_reg term_map[] =
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE term_map[] =
{
{ "clrscr", luaterm_clrscr },
{ "clreol", luaterm_clreol },
{ "gotoxy", luaterm_gotoxy },
{ "up", luaterm_up },
{ "down", luaterm_down },
{ "left", luaterm_left },
{ "right", luaterm_right },
{ "lines", luaterm_lines },
{ "cols", luaterm_cols },
{ "put", luaterm_put },
{ "putstr", luaterm_putstr },
{ "putxy", luaterm_putxy },
{ "putstrxy", luaterm_putstrxy },
{ "cursorx", luaterm_cx },
{ "cursory", luaterm_cy },
{ "getch", luaterm_getch },
{ NULL, NULL }
};

// Metatable data
static const luaL_reg term_mt_map[] =
{
{ "__index", term_mt_index },
{ NULL, NULL }
{ LSTRKEY( "clrscr" ), LFUNCVAL( luaterm_clrscr ) },
{ LSTRKEY( "clreol" ), LFUNCVAL( luaterm_clreol ) },
{ LSTRKEY( "gotoxy" ), LFUNCVAL( luaterm_gotoxy ) },
{ LSTRKEY( "up" ), LFUNCVAL( luaterm_up ) },
{ LSTRKEY( "down" ), LFUNCVAL( luaterm_down ) },
{ LSTRKEY( "left" ), LFUNCVAL( luaterm_left ) },
{ LSTRKEY( "right" ), LFUNCVAL( luaterm_right ) },
{ LSTRKEY( "lines" ), LFUNCVAL( luaterm_lines ) },
{ LSTRKEY( "cols" ), LFUNCVAL( luaterm_cols ) },
{ LSTRKEY( "put" ), LFUNCVAL( luaterm_put ) },
{ LSTRKEY( "putstr" ), LFUNCVAL( luaterm_putstr ) },
{ LSTRKEY( "putxy" ), LFUNCVAL( luaterm_putxy ) },
{ LSTRKEY( "putstrxy" ), LFUNCVAL( luaterm_putstrxy ) },
{ LSTRKEY( "cursorx" ), LFUNCVAL( luaterm_cx ) },
{ LSTRKEY( "cursory" ), LFUNCVAL( luaterm_cy ) },
{ LSTRKEY( "getch" ), LFUNCVAL( luaterm_getch ) },
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "__metatable" ), LROVAL( term_map ) },
{ LSTRKEY( "NOWAIT" ), LNUMVAL( TERM_INPUT_DONT_WAIT ) },
{ LSTRKEY( "WAIT" ), LNUMVAL( TERM_INPUT_WAIT ) },
#endif
{ LSTRKEY( "__index" ), LFUNCVAL( term_mt_index ) },
{ LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_term( lua_State* L )
{
#ifdef BUILD_TERM
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
// Register methods
luaL_register( L, AUXLIB_TERM, term_map );

// Create and set metatable
lua_newtable( L );
luaL_register( L, NULL, term_mt_map );
lua_setmetatable( L, -2 );

// Set this table as itw own metatable
lua_pushvalue( L, -1 );
lua_setmetatable( L, -2 );

// Register the constants for "getch"
lua_pushnumber( L, TERM_INPUT_DONT_WAIT );
lua_setfield( L, -2, "NOWAIT" );
lua_pushnumber( L, TERM_INPUT_WAIT );
lua_setfield( L, -2, "WAIT" );

return 1;
#endif // # if LUA_OPTIMIZE_MEMORY > 0
#else // #ifdef BUILD_TERM
return 0;
#endif // #ifdef BUILD_TERM