Unverified Commit 1990f957 authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Updated ROTables 1st tranch (#2742)

Updated ROTables
parent e0f3dbed
...@@ -138,8 +138,6 @@ DEPENDS_eagle.app.v6 = \ ...@@ -138,8 +138,6 @@ DEPENDS_eagle.app.v6 = \
# -DWLAN_CONFIG_CCX # -DWLAN_CONFIG_CCX
CONFIGURATION_DEFINES = -D__ets__ \ CONFIGURATION_DEFINES = -D__ets__ \
-DICACHE_FLASH \ -DICACHE_FLASH \
-DLUA_OPTIMIZE_MEMORY=2 \
-DMIN_OPT_LEVEL=2 \
-DLWIP_OPEN_SRC \ -DLWIP_OPEN_SRC \
-DPBUF_RSV_FOR_WLAN \ -DPBUF_RSV_FOR_WLAN \
-DEBUF_LWIP \ -DEBUF_LWIP \
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define __MODULE_H__ #define __MODULE_H__
#include "user_modules.h" #include "user_modules.h"
#include "lrodefs.h" #include "lrotable.h"
/* Registering a module within NodeMCU is really easy these days! /* Registering a module within NodeMCU is really easy these days!
* *
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
* *
* Then simply put a line like this at the bottom of your module file: * Then simply put a line like this at the bottom of your module file:
* *
* NODEMCU_MODULE(MYNAME, "myname", myname_map, luaopen_myname); * NODEMCU_MODULE(MYNAME, "myname", myname, luaopen_myname);
* *
* or perhaps * or perhaps
* *
* NODEMCU_MODULE(MYNAME, "myname", myname_map, NULL); * NODEMCU_MODULE(MYNAME, "myname", myname, NULL);
* *
* if you don't need an init function. * if you don't need an init function.
* *
...@@ -67,13 +67,8 @@ ...@@ -67,13 +67,8 @@
*/ */
#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \ #define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
const LOCK_IN_SECTION(libs) \ const LOCK_IN_SECTION(libs) \
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \ luaR_entry MODULE_PASTE_(lua_lib_,cfgname) = { luaname, LRO_FUNCVAL(initfunc) }; \
const LOCK_IN_SECTION(rotable) \ const LOCK_IN_SECTION(rotable) \
luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \ luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= {LSTRKEY(luaname), LROVAL(map)} = {luaname, LRO_ROVAL(map ## _map)}
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
#endif
#endif #endif
...@@ -24,23 +24,17 @@ ...@@ -24,23 +24,17 @@
#define PMSLEEP_ERR(...) #define PMSLEEP_ERR(...)
#endif #endif
#define PMSLEEP_SLEEP_MIN_TIME 50000 #define PMSLEEP_SLEEP_MIN_TIME 50000
#define PMSLEEP_SLEEP_MAX_TIME 268435454 //FPM_MAX_SLEEP_TIME-1 #define PMSLEEP_SLEEP_MAX_TIME 268435454 //FPM_MAX_SLEEP_TIME-1
#define pmSleep_INIT_CFG(X) pmSleep_param_t X = {.sleep_duration=0, .wake_pin=255, \ #define pmSleep_INIT_CFG(X) pmSleep_param_t X = {.sleep_duration=0, .wake_pin=255, \
.preserve_opmode=TRUE, .suspend_cb_ptr=NULL, .resume_cb_ptr=NULL} .preserve_opmode=TRUE, .suspend_cb_ptr=NULL, .resume_cb_ptr=NULL}
#define PMSLEEP_INT_MAP \ #define PMSLEEP_INT_MAP \
{ LSTRKEY( "INT_BOTH" ), LNUMVAL( GPIO_PIN_INTR_ANYEDGE ) }, \ LROT_NUMENTRY( INT_BOTH, GPIO_PIN_INTR_ANYEDGE ) \
{ LSTRKEY( "INT_UP" ), LNUMVAL( GPIO_PIN_INTR_POSEDGE ) }, \ LROT_NUMENTRY( INT_UP, GPIO_PIN_INTR_POSEDGE ) \
{ LSTRKEY( "INT_DOWN" ), LNUMVAL( GPIO_PIN_INTR_NEGEDGE ) }, \ LROT_NUMENTRY( INT_DOWN, GPIO_PIN_INTR_NEGEDGE ) \
{ LSTRKEY( "INT_HIGH" ), LNUMVAL( GPIO_PIN_INTR_HILEVEL ) }, \ LROT_NUMENTRY( INT_HIGH, GPIO_PIN_INTR_HILEVEL ) \
{ LSTRKEY( "INT_LOW" ), LNUMVAL( GPIO_PIN_INTR_LOLEVEL ) } LROT_NUMENTRY( INT_LOW, GPIO_PIN_INTR_LOLEVEL )
typedef struct pmSleep_param{ typedef struct pmSleep_param{
uint32 sleep_duration; uint32 sleep_duration;
......
...@@ -244,7 +244,7 @@ extern void luaL_dbgbreak(void); ...@@ -244,7 +244,7 @@ extern void luaL_dbgbreak(void);
#endif #endif
#endif #endif
#if !defined(LUA_NUMBER_INTEGRAL) && defined (LUA_DWORD_ALIGNED_TVALUES) #if !defined(LUA_NUMBER_INTEGRAL) && !defined (LUA_DWORD_ALIGNED_TVALUES)
#define LUA_PACK_TVALUES #define LUA_PACK_TVALUES
#else #else
#undef LUA_PACK_TVALUES #undef LUA_PACK_TVALUES
......
...@@ -419,11 +419,7 @@ LUALIB_API void (luaL_register) (lua_State *L, const char *libname, ...@@ -419,11 +419,7 @@ LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname, LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname,
const luaL_Reg *l) { const luaL_Reg *l) {
#if LUA_OPTIMIZE_MEMORY > 0
luaI_openlib(L, libname, l, 0, LUA_USELIGHTFUNCTIONS); 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) { static int libsize (const luaL_Reg *l) {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include C_HEADER_STDLIB #include C_HEADER_STDLIB
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrodefs.h" #include "lrotable.h"
...@@ -462,64 +462,59 @@ static int luaB_newproxy (lua_State *L) { ...@@ -462,64 +462,59 @@ static int luaB_newproxy (lua_State *L) {
return 1; return 1;
} }
#include "lrodefs.h" #include "lrotable.h"
extern const luaR_entry lua_rotable_base[]; LROT_EXTERN(lua_rotable_base);
/* /*
* ESP builds use specific linker directives to marshal all ROTable declarations * Separate ROTables are used for the base functions and library ROTables, with
* into a single ROTable in the PSECT ".lua_rotable". * the base functions ROTable declared below. The library ROTable is chained
* from this using its __index meta-method.
* *
* This is not practical on Posix builds using a standard link so for cross * ESP builds use specific linker directives to marshal all the ROTable entries
* compiler builds, separate ROTables are used for the base functions and library * for the library modules into a single ROTable in the PSECT ".lua_rotable".
* ROTables, with the latter chained from the former using its __index meta-method. * This is not practical on Posix builds using a standard GNU link, so the
* In this case all library ROTables are defined in linit.c. * equivalent ROTable for the core libraries defined in linit.c for the cross-
* compiler build.
*/ */
#ifdef LUA_CROSS_COMPILER
#define BASE_ROTABLE base_func_map
#define LOCK_IN_ROTABLE
static const LUA_REG_TYPE base_func_meta[] = {
LROT_TABENTRY(__index, lua_rotable_base),
LROT_END};
#else
#define BASE_ROTABLE lua_rotable_base
#define LOCK_IN_ROTABLE __attribute__((used,unused,section(".lua_rotable")))
#endif
static const LUA_REG_TYPE LOCK_IN_ROTABLE base_func_map[] = { LROT_EXTERN(lua_rotables);
LROT_FUNCENTRY(assert, luaB_assert),
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage), LROT_PUBLIC_BEGIN(base_func_meta)
LROT_FUNCENTRY(dofile, luaB_dofile), LROT_TABENTRY( __index, lua_rotables )
LROT_FUNCENTRY(error, luaB_error), LROT_END(base_func, base_func_meta, LROT_MASK_INDEX)
LROT_FUNCENTRY(gcinfo, luaB_gcinfo),
LROT_FUNCENTRY(getfenv, luaB_getfenv), LROT_PUBLIC_BEGIN(base_func)
LROT_FUNCENTRY(getmetatable, luaB_getmetatable), LROT_FUNCENTRY(assert, luaB_assert)
LROT_FUNCENTRY(loadfile, luaB_loadfile), LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage)
LROT_FUNCENTRY(load, luaB_load), LROT_FUNCENTRY(dofile, luaB_dofile)
LROT_FUNCENTRY(loadstring, luaB_loadstring), LROT_FUNCENTRY(error, luaB_error)
LROT_FUNCENTRY(next, luaB_next), LROT_FUNCENTRY(gcinfo, luaB_gcinfo)
LROT_FUNCENTRY(pcall, luaB_pcall), LROT_FUNCENTRY(getfenv, luaB_getfenv)
LROT_FUNCENTRY(print, luaB_print), LROT_FUNCENTRY(getmetatable, luaB_getmetatable)
LROT_FUNCENTRY(rawequal, luaB_rawequal), LROT_FUNCENTRY(loadfile, luaB_loadfile)
LROT_FUNCENTRY(rawget, luaB_rawget), LROT_FUNCENTRY(load, luaB_load)
LROT_FUNCENTRY(rawset, luaB_rawset), LROT_FUNCENTRY(loadstring, luaB_loadstring)
LROT_FUNCENTRY(select, luaB_select), LROT_FUNCENTRY(next, luaB_next)
LROT_FUNCENTRY(setfenv, luaB_setfenv), LROT_FUNCENTRY(pcall, luaB_pcall)
LROT_FUNCENTRY(setmetatable, luaB_setmetatable), LROT_FUNCENTRY(print, luaB_print)
LROT_FUNCENTRY(tonumber, luaB_tonumber), LROT_FUNCENTRY(rawequal, luaB_rawequal)
LROT_FUNCENTRY(tostring, luaB_tostring), LROT_FUNCENTRY(rawget, luaB_rawget)
LROT_FUNCENTRY(type, luaB_type), LROT_FUNCENTRY(rawset, luaB_rawset)
LROT_FUNCENTRY(unpack, luaB_unpack), LROT_FUNCENTRY(select, luaB_select)
LROT_FUNCENTRY(setfenv, luaB_setfenv)
LROT_FUNCENTRY(setmetatable, luaB_setmetatable)
LROT_FUNCENTRY(tonumber, luaB_tonumber)
LROT_FUNCENTRY(tostring, luaB_tostring)
LROT_FUNCENTRY(type, luaB_type)
LROT_FUNCENTRY(unpack, luaB_unpack)
LROT_FUNCENTRY(xpcall, luaB_xpcall) LROT_FUNCENTRY(xpcall, luaB_xpcall)
#ifdef LUA_CROSS_COMPILER LROT_TABENTRY(__metatable, base_func_meta)
,LROT_TABENTRY(__metatable, base_func_meta), LROT_END(base_func, base_func_meta, LROT_MASK_INDEX)
LROT_END
#endif
};
static const luaL_Reg base_funcs[] = { LROT_BEGIN(G_meta)
{NULL, NULL} LROT_TABENTRY( __index, base_func )
}; LROT_END(G_meta, NULL, 0)
/* /*
...@@ -650,17 +645,14 @@ static int luaB_corunning (lua_State *L) { ...@@ -650,17 +645,14 @@ static int luaB_corunning (lua_State *L) {
return 1; return 1;
} }
#undef MIN_OPT_LEVEL LROT_PUBLIC_BEGIN(co_funcs)
#define MIN_OPT_LEVEL 1 LROT_FUNCENTRY( create, luaB_cocreate )
const LUA_REG_TYPE co_funcs[] = { LROT_FUNCENTRY( resume, luaB_coresume )
{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)}, LROT_FUNCENTRY( running, luaB_corunning )
{LSTRKEY("resume"), LFUNCVAL(luaB_coresume)}, LROT_FUNCENTRY( status, luaB_costatus )
{LSTRKEY("running"), LFUNCVAL(luaB_corunning)}, LROT_FUNCENTRY( wrap, luaB_cowrap )
{LSTRKEY("status"), LFUNCVAL(luaB_costatus)}, LROT_FUNCENTRY( yield, luaB_yield )
{LSTRKEY("wrap"), LFUNCVAL(luaB_cowrap)}, LROT_END (co_funcs, NULL, 0)
{LSTRKEY("yield"), LFUNCVAL(luaB_yield)},
{LNILKEY, LNILVAL}
};
/* }====================================================== */ /* }====================================================== */
...@@ -676,14 +668,12 @@ static void base_open (lua_State *L) { ...@@ -676,14 +668,12 @@ static void base_open (lua_State *L) {
/* set global _G */ /* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G"); lua_setglobal(L, "_G");
/* open lib into global table */ /* open lib into global table */
luaL_register_light(L, "_G", base_funcs); luaL_register_light(L, "_G", &((luaL_Reg) {0}));
#if LUA_OPTIMIZE_MEMORY > 0 lua_pushrotable(L, LROT_TABLEREF(G_meta));
lua_pushvalue(L, -1); lua_setmetatable(L, LUA_GLOBALSINDEX);
lua_setmetatable(L, -2);
lua_pushrotable(L, (void *)BASE_ROTABLE);
lua_setglobal(L, "__index");
#endif
lua_pushliteral(L, LUA_VERSION); lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */
......
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
#include "lualib.h" #include "lualib.h"
#include "lstring.h" #include "lstring.h"
#include "lflash.h" #include "lflash.h"
#include "user_modules.h" #include "lrotable.h"
#include "user_modules.h"
static int db_getregistry (lua_State *L) { static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX); lua_pushvalue(L, LUA_REGISTRYINDEX);
...@@ -417,32 +417,28 @@ static int db_errorfb (lua_State *L) { ...@@ -417,32 +417,28 @@ static int db_errorfb (lua_State *L) {
return 1; return 1;
} }
#undef MIN_OPT_LEVEL LROT_PUBLIC_BEGIN(dblib)
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE dblib[] = {
#ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL #ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL
{LSTRKEY("debug"), LFUNCVAL(db_debug)}, LROT_FUNCENTRY( debug, db_debug )
{LSTRKEY("getfenv"), LFUNCVAL(db_getfenv)}, LROT_FUNCENTRY( getfenv, db_getfenv )
{LSTRKEY("gethook"), LFUNCVAL(db_gethook)}, LROT_FUNCENTRY( gethook, db_gethook )
{LSTRKEY("getinfo"), LFUNCVAL(db_getinfo)}, LROT_FUNCENTRY( getinfo, db_getinfo )
{LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)}, LROT_FUNCENTRY( getlocal, db_getlocal )
#endif #endif
{LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)}, LROT_FUNCENTRY( getregistry, db_getregistry )
{LSTRKEY("getstrings"), LFUNCVAL(db_getstrings)}, LROT_FUNCENTRY( getstrings, db_getstrings )
#ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL #ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL
{LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)}, LROT_FUNCENTRY( getmetatable, db_getmetatable )
{LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)}, LROT_FUNCENTRY( getupvalue, db_getupvalue )
{LSTRKEY("setfenv"), LFUNCVAL(db_setfenv)}, LROT_FUNCENTRY( setfenv, db_setfenv )
{LSTRKEY("sethook"), LFUNCVAL(db_sethook)}, LROT_FUNCENTRY( sethook, db_sethook )
{LSTRKEY("setlocal"), LFUNCVAL(db_setlocal)}, LROT_FUNCENTRY( setlocal, db_setlocal )
{LSTRKEY("setmetatable"), LFUNCVAL(db_setmetatable)}, LROT_FUNCENTRY( setmetatable, db_setmetatable )
{LSTRKEY("setupvalue"), LFUNCVAL(db_setupvalue)}, LROT_FUNCENTRY( setupvalue, db_setupvalue )
#endif #endif
{LSTRKEY("traceback"), LFUNCVAL(db_errorfb)}, LROT_FUNCENTRY( traceback, db_errorfb )
{LNILKEY, LNILVAL} LROT_END(dblib, NULL, 0)
};
LUALIB_API int luaopen_debug (lua_State *L) { LUALIB_API int luaopen_debug (lua_State *L) {
LREGISTER(L, LUA_DBLIBNAME, dblib); return 0;
} }
...@@ -15,45 +15,43 @@ ...@@ -15,45 +15,43 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "luaconf.h" #include "luaconf.h"
#include "module.h" #include "module.h"
#include "lstate.h"
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2) LROT_EXTERN(strlib);
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" LROT_EXTERN(tab_funcs);
LROT_EXTERN(dblib);
LROT_EXTERN(co_funcs);
LROT_EXTERN(math);
#if defined(LUA_CROSS_COMPILER)
LROT_EXTERN(oslib);
LROT_EXTERN(iolib);
#endif #endif
extern const luaR_entry strlib[], tab_funcs[], dblib[],
co_funcs[], math_map[], syslib[];
extern const luaR_entry syslib[], io_funcs[]; // Only used on cross-compile builds
/* /*
* The NodeMCU Lua initalisation has been adapted to use linker-based module * The NodeMCU Lua initalisation has been adapted to use linker-based module
* registration. This uses a PSECT naming convention to allow the lib and rotab * registration. This uses a PSECT naming convention to allow the ROTable and
* entries to be collected by the linker into consoliated tables. The linker * initialisation function entries to be collected by the linker into two
* defines lua_libs_base and lua_rotable_base. * consoliated ROTables. This significantly simplifies adding new modules and
* configuring builds with a small subset of the total modules.
*
* This linker-based approach is not practical for cross compiler builds which
* must link on a range of platforms, and where we don't have control of PSECT
* placement. However unlike the target builds, the luac.cross builds only
* used a small and fixed list of libraries and so in this case the table can
* be defined in this source file, so in this case all library ROTables are
* defined here, avoiding the need for linker magic is avoided on host builds.
* *
* This is not practical on Posix builds which use a standard loader declaration * Note that a separate ROTable is defined in lbaselib.c for the base functions
* so for cross compiler builds, separate ROTables are used for the base functions * and there is a metatable index cascade from _G to this base function table to
* and library ROTables, with the latter chained from the former using its __index * the master rotables table. In the target build, the linker marshals the
* meta-method. In this case all library ROTables are defined here, avoiding the * table, hence the LROT_BREAK() macros which don't 0 terminate the lists.
* need for linker magic is avoided on host builds.
*/ */
#if defined(LUA_CROSS_COMPILER)
#define LUA_ROTABLES lua_rotable_base
#define LUA_LIBS lua_libs_base
#else /* declare Xtensa toolchain linker defined constants */
extern const luaL_Reg lua_libs_base[];
extern const luaR_entry lua_rotable_base[];
#define LUA_ROTABLES lua_rotable_core
#define LUA_LIBS lua_libs_core
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
//MSVC requires us to declare these sections before we refer to them //MSVC requires us to declare these sections before we refer to them
#pragma section(__ROSECNAME(A), read) #pragma section(__ROSECNAME(A), read)
#pragma section(__ROSECNAME(zzzzzzzz), read) #pragma section(__ROSECNAME(zzzzzzzz), read)
#pragma section(__ROSECNAME(libs), read) #pragma section(__ROSECNAME(libs), read)
#pragma section(__ROSECNAME(rotable), read) #pragma section(__ROSECNAME(rotable), read)
//These help us to find the beginning and ending of the RO data. NOTE: linker //These help us to find the beginning and ending of the RO data. NOTE: linker
//magic is used; the section names are lexically sorted, so 'a' and 'z' are //magic is used; the section names are lexically sorted, so 'a' and 'z' are
//important to keep the other sections lexically between these two dummy //important to keep the other sections lexically between these two dummy
...@@ -61,43 +59,57 @@ extern const luaR_entry lua_rotable_base[]; ...@@ -61,43 +59,57 @@ extern const luaR_entry lua_rotable_base[];
const LOCK_IN_SECTION(A) char _ro_start[1] = {0}; const LOCK_IN_SECTION(A) char _ro_start[1] = {0};
const LOCK_IN_SECTION(zzzzzzzz) char _ro_end[1] = {0}; const LOCK_IN_SECTION(zzzzzzzz) char _ro_end[1] = {0};
#endif #endif
static const LOCK_IN_SECTION(libs) luaL_reg LUA_LIBS[] = {
{"", luaopen_base}, LROT_PUBLIC_TABLE(lua_rotables)
{LUA_LOADLIBNAME, luaopen_package},
{LUA_STRLIBNAME, luaopen_string}, LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables)
{LUA_TABLIBNAME, luaopen_table}, LROT_TABENTRY( string, strlib )
{LUA_DBLIBNAME, luaopen_debug} LROT_TABENTRY( table, tab_funcs )
#if defined(LUA_CROSS_COMPILER) LROT_TABENTRY( debug, dblib)
,{LUA_IOLIBNAME, luaopen_io}, LROT_TABENTRY( coroutine, co_funcs )
{NULL, NULL} LROT_TABENTRY( math, math )
LROT_TABENTRY( ROM, lua_rotables )
#ifdef LUA_CROSS_COMPILER
LROT_TABENTRY( os, oslib )
LROT_TABENTRY( io, iolib )
LROT_END(lua_rotables, NULL, 0)
#else
LROT_BREAK(lua_rotables)
#endif #endif
};
#define ENTRY(n,t) {LSTRKEY(n), LRO_ROVAL(t)} LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(libs) lua_libs)
LROT_FUNCENTRY( _, luaopen_base )
LROT_FUNCENTRY( package, luaopen_package )
LROT_FUNCENTRY( string, luaopen_string )
LROT_FUNCENTRY( table, luaopen_table )
LROT_FUNCENTRY( debug, luaopen_debug )
#ifndef LUA_CROSS_COMPILER
LROT_BREAK(lua_rotables)
#else
LROT_FUNCENTRY( io, luaopen_io )
LROT_END( lua_libs, NULL, 0)
#endif
const LOCK_IN_SECTION(rotable) ROTable LUA_ROTABLES[] = { #ifndef LUA_CROSS_COMPILER
ENTRY("ROM", LUA_ROTABLES), extern void luaL_dbgbreak(void);
ENTRY(LUA_STRLIBNAME, strlib),
ENTRY(LUA_TABLIBNAME, tab_funcs),
ENTRY(LUA_DBLIBNAME, dblib),
ENTRY(LUA_COLIBNAME, co_funcs),
ENTRY(LUA_MATHLIBNAME, math_map)
#if defined(LUA_CROSS_COMPILER)
,ENTRY(LUA_OSLIBNAME, syslib),
LROT_END
#endif #endif
};
void luaL_openlibs (lua_State *L) { void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib = lua_libs_base;
lua_pushrotable(L, LROT_TABLEREF(lua_libs));
lua_pushnil(L); /* first key */
/* loop round and open libraries */ /* loop round and open libraries */
for (; lib->name; lib++) { #ifndef LUA_CROSS_COMPILER
if (lib->func) { // luaL_dbgbreak(); // This is a test point for debugging library start ups
lua_pushcfunction(L, lib->func); #endif
lua_pushstring(L, lib->name); while (lua_next(L, -2) != 0) {
lua_call(L, 1, 0); if (lua_islightfunction(L,-1) &&
fvalue(L->top-1)) { // only process function entries
lua_pushvalue(L, -2);
lua_call(L, 1, 0); // call luaopen_XXX(libname)
} else {
lua_pop(L, 1);
} }
} }
lua_pop(L, 1); //cleanup stack
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
#undef PI #undef PI
#define PI (3.14159265358979323846) #define PI (3.14159265358979323846)
...@@ -308,92 +309,57 @@ static int math_randomseed (lua_State *L) { ...@@ -308,92 +309,57 @@ static int math_randomseed (lua_State *L) {
return 0; return 0;
} }
LROT_PUBLIC_BEGIN(math)
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE math_map[] = {
#ifdef LUA_NUMBER_INTEGRAL #ifdef LUA_NUMBER_INTEGRAL
{LSTRKEY("abs"), LFUNCVAL(math_abs)}, LROT_FUNCENTRY( abs, math_abs )
{LSTRKEY("ceil"), LFUNCVAL(math_identity)}, LROT_FUNCENTRY( ceil, math_identity )
{LSTRKEY("floor"), LFUNCVAL(math_identity)}, LROT_FUNCENTRY( floor, math_identity )
{LSTRKEY("max"), LFUNCVAL(math_max)}, LROT_FUNCENTRY( max, math_max )
{LSTRKEY("min"), LFUNCVAL(math_min)}, LROT_FUNCENTRY( min, math_min )
{LSTRKEY("pow"), LFUNCVAL(math_pow)}, LROT_FUNCENTRY( pow, math_pow )
{LSTRKEY("random"), LFUNCVAL(math_random)}, LROT_FUNCENTRY( random, math_random )
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, LROT_FUNCENTRY( randomseed, math_randomseed )
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, LROT_FUNCENTRY( sqrt, math_sqrt )
#if LUA_OPTIMIZE_MEMORY > 0 LROT_NUMENTRY( huge, INT_MAX )
{LSTRKEY("huge"), LNUMVAL(INT_MAX)},
#endif
#else #else
{LSTRKEY("abs"), LFUNCVAL(math_abs)}, LROT_FUNCENTRY( abs, math_abs )
// {LSTRKEY("acos"), LFUNCVAL(math_acos)}, // LROT_FUNCENTRY( acos, math_acos )
// {LSTRKEY("asin"), LFUNCVAL(math_asin)}, // LROT_FUNCENTRY( asin, math_asin )
// {LSTRKEY("atan2"), LFUNCVAL(math_atan2)}, // LROT_FUNCENTRY( atan2, math_atan2 )
// {LSTRKEY("atan"), LFUNCVAL(math_atan)}, // LROT_FUNCENTRY( atan, math_atan )
{LSTRKEY("ceil"), LFUNCVAL(math_ceil)}, LROT_FUNCENTRY( ceil, math_ceil )
// {LSTRKEY("cosh"), LFUNCVAL(math_cosh)}, // LROT_FUNCENTRY( cosh, math_cosh )
// {LSTRKEY("cos"), LFUNCVAL(math_cos)}, // LROT_FUNCENTRY( cos, math_cos )
// {LSTRKEY("deg"), LFUNCVAL(math_deg)}, // LROT_FUNCENTRY( deg, math_deg )
// {LSTRKEY("exp"), LFUNCVAL(math_exp)}, // LROT_FUNCENTRY( exp, math_exp )
{LSTRKEY("floor"), LFUNCVAL(math_floor)}, LROT_FUNCENTRY( floor, math_floor )
// {LSTRKEY("fmod"), LFUNCVAL(math_fmod)}, // LROT_FUNCENTRY( fmod, math_fmod )
#if LUA_OPTIMIZE_MEMORY > 0 && defined(LUA_COMPAT_MOD) // LROT_FUNCENTRY( mod, math_fmod )
// {LSTRKEY("mod"), LFUNCVAL(math_fmod)}, // LROT_FUNCENTRY( frexp, math_frexp )
#endif // LROT_FUNCENTRY( ldexp, math_ldexp )
// {LSTRKEY("frexp"), LFUNCVAL(math_frexp)}, // LROT_FUNCENTRY( log10, math_log10 )
// {LSTRKEY("ldexp"), LFUNCVAL(math_ldexp)}, // LROT_FUNCENTRY( log, math_log )
// {LSTRKEY("log10"), LFUNCVAL(math_log10)}, LROT_FUNCENTRY( max, math_max )
// {LSTRKEY("log"), LFUNCVAL(math_log)}, LROT_FUNCENTRY( min, math_min )
{LSTRKEY("max"), LFUNCVAL(math_max)}, // LROT_FUNCENTRY( modf, math_modf )
{LSTRKEY("min"), LFUNCVAL(math_min)}, LROT_FUNCENTRY( pow, math_pow )
// {LSTRKEY("modf"), LFUNCVAL(math_modf)}, // LROT_FUNCENTRY( rad, math_rad )
{LSTRKEY("pow"), LFUNCVAL(math_pow)}, LROT_FUNCENTRY( random, math_random )
// {LSTRKEY("rad"), LFUNCVAL(math_rad)}, LROT_FUNCENTRY( randomseed, math_randomseed )
{LSTRKEY("random"), LFUNCVAL(math_random)}, // LROT_FUNCENTRY( sinh, math_sinh )
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, // LROT_FUNCENTRY( sin, math_sin )
// {LSTRKEY("sinh"), LFUNCVAL(math_sinh)}, LROT_FUNCENTRY( sqrt, math_sqrt )
// {LSTRKEY("sin"), LFUNCVAL(math_sin)}, // LROT_FUNCENTRY( tanh, math_tanh )
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, // LROT_FUNCENTRY( tan, math_tan )
// {LSTRKEY("tanh"), LFUNCVAL(math_tanh)}, LROT_NUMENTRY( pi, PI )
// {LSTRKEY("tan"), LFUNCVAL(math_tan)}, LROT_NUMENTRY( huge, HUGE_VAL )
#if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("pi"), LNUMVAL(PI)},
{LSTRKEY("huge"), LNUMVAL(HUGE_VAL)},
#endif // #if LUA_OPTIMIZE_MEMORY > 0
#endif // #ifdef LUA_NUMBER_INTEGRAL #endif // #ifdef LUA_NUMBER_INTEGRAL
{LNILKEY, LNILVAL} LROT_END(math, NULL, 0)
};
/* /*
** Open math library ** Open math library
*/ */
#if defined LUA_NUMBER_INTEGRAL
# include "c_limits.h" /* for INT_MAX */
#endif
LUALIB_API int luaopen_math (lua_State *L) { LUALIB_API int luaopen_math (lua_State *L) {
#if LUA_OPTIMIZE_MEMORY > 0
return 0; return 0;
#else
luaL_register(L, LUA_MATHLIBNAME, math_map);
# if defined LUA_NUMBER_INTEGRAL
lua_pushnumber(L, INT_MAX);
lua_setfield(L, -2, "huge");
# else
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");
# endif
# endif
return 1;
#endif
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
/* prefix for open functions in C libraries */ /* prefix for open functions in C libraries */
#define LUA_POF "luaopen_" #define LUA_POF "luaopen_"
...@@ -361,7 +362,9 @@ static const char * findfile (lua_State *L, const char *name, ...@@ -361,7 +362,9 @@ static const char * findfile (lua_State *L, const char *name,
const char *pname) { const char *pname) {
const char *path; const char *path;
name = luaL_gsub(L, name, ".", LUA_DIRSEP); name = luaL_gsub(L, name, ".", LUA_DIRSEP);
lua_getfield(L, LUA_ENVIRONINDEX, pname); lua_getfield(L, LUA_GLOBALSINDEX, "package");
lua_getfield(L, -1, pname);
lua_remove(L, -2);
path = lua_tostring(L, -1); path = lua_tostring(L, -1);
if (path == NULL) if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname); luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
...@@ -447,7 +450,9 @@ static int loader_Croot (lua_State *L) { ...@@ -447,7 +450,9 @@ static int loader_Croot (lua_State *L) {
static int loader_preload (lua_State *L) { static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_ENVIRONINDEX, "preload"); lua_getfield(L, LUA_GLOBALSINDEX, "package");
lua_getfield(L, -1, "preload");
lua_remove(L, -2);
if (!lua_istable(L, -1)) if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.preload") " must be a table"); luaL_error(L, LUA_QL("package.preload") " must be a table");
lua_getfield(L, -1, name); lua_getfield(L, -1, name);
...@@ -480,7 +485,9 @@ static int ll_require (lua_State *L) { ...@@ -480,7 +485,9 @@ static int ll_require (lua_State *L) {
lua_pop(L, 1); lua_pop(L, 1);
} }
/* else must load it; iterate over available loaders */ /* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); lua_getfield(L, LUA_GLOBALSINDEX, "package");
lua_getfield(L, -1, "loaders");
lua_remove(L, -2);
if (!lua_istable(L, -1)) if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.loaders") " must be a table"); luaL_error(L, LUA_QL("package.loaders") " must be a table");
lua_pushliteral(L, ""); /* error message accumulator */ lua_pushliteral(L, ""); /* error message accumulator */
...@@ -650,34 +657,20 @@ static const luaL_Reg ll_funcs[] = { ...@@ -650,34 +657,20 @@ static const luaL_Reg ll_funcs[] = {
static const lua_CFunction loaders[] = static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
#if LUA_OPTIMIZE_MEMORY > 0 LROT_PUBLIC_BEGIN(lmt)
#undef MIN_OPT_LEVEL LROT_FUNCENTRY(__gc,gctm)
#define MIN_OPT_LEVEL 1 LROT_END(lmt,lmt, LROT_MASK_GC)
#include "lrodefs.h"
const LUA_REG_TYPE lmt[] = {
{LRO_STRKEY("__gc"), LRO_FUNCVAL(gctm)},
{LRO_NILKEY, LRO_NILVAL}
};
#endif
LUALIB_API int luaopen_package (lua_State *L) { LUALIB_API int luaopen_package (lua_State *L) {
int i; int i;
/* create new type _LOADLIB */ /* create new type _LOADLIB */
#if LUA_OPTIMIZE_MEMORY == 0 luaL_rometatable(L, "_LOADLIB",LROT_TABLEREF(lmt));
luaL_newmetatable(L, "_LOADLIB");
lua_pushlightfunction(L, gctm);
lua_setfield(L, -2, "__gc");
#else
luaL_rometatable(L, "_LOADLIB", (void*)lmt);
#endif
/* create `package' table */ /* create `package' table */
luaL_register_light(L, LUA_LOADLIBNAME, pk_funcs); luaL_register_light(L, LUA_LOADLIBNAME, pk_funcs);
#if defined(LUA_COMPAT_LOADLIB) #if defined(LUA_COMPAT_LOADLIB)
lua_getfield(L, -1, "loadlib"); lua_getfield(L, -1, "loadlib");
lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
#endif #endif
lua_pushvalue(L, -1);
lua_replace(L, LUA_ENVIRONINDEX);
/* create `loaders' table */ /* create `loaders' table */
lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
/* fill it with pre-defined loaders */ /* fill it with pre-defined loaders */
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#define LNUMVAL LRO_NUMVAL #define LNUMVAL LRO_NUMVAL
#define LROVAL LRO_ROVAL #define LROVAL LRO_ROVAL
#define LNILVAL LRO_NILVAL #define LNILVAL LRO_NILVAL
#define LREGISTER(L, name, table)\ #define LREGISTER(L, name, table) return 0
return 0
#else #else
#define LUA_REG_TYPE luaL_reg #define LUA_REG_TYPE luaL_reg
#define LSTRKEY(x) x #define LSTRKEY(x) x
...@@ -38,10 +37,17 @@ ...@@ -38,10 +37,17 @@
return 1 return 1
#endif #endif
#define LROT_TABENTRY(n,t) {LSTRKEY(#n), LRO_ROVAL(t)} #define LROT_TABLE(t) static const LUA_REG_TYPE t ## _map[];
#define LROT_FUNCENTRY(n,f) {LSTRKEY(#n), LRO_FUNCVAL(f)} #define LROT_TABLEREF(t) ((void *) t ## _map)
#define LROT_NUMENTRY(n,x) {LSTRKEY(#n), LRO_NUMVAL(x)} #define LROT_BEGIN(t) static const LUA_REG_TYPE t ## _map [] = {
#define LROT_END {LNILKEY, LNILVAL} #define LROT_PUBLIC_BEGIN(t) const LUA_REG_TYPE t ## _map[] = {
#define LROT_EXTERN(t) extern const LUA_REG_TYPE t ## _map[]
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t ## _map)},
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
#define LROT_END(t,mt, f) {LRO_NILKEY, LRO_NILVAL} };
#define LREGISTER(L, name, table) return 0
#endif /* lrodefs_h */ #endif /* lrodefs_h */
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#else #else
#define ALIGNED_STRING (__attribute__((aligned(4))) char *) #define ALIGNED_STRING (__attribute__((aligned(4))) char *)
#endif #endif
#define LA_LINES 16 #define LA_LINES 32
#define LA_SLOTS 4 #define LA_SLOTS 4
//#define COLLECT_STATS //#define COLLECT_STATS
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* Note that this hash does a couple of prime multiples and a modulus 2^X * Note that this hash does a couple of prime multiples and a modulus 2^X
* with is all evaluated in H/W, and adequately randomizes the lookup. * with is all evaluated in H/W, and adequately randomizes the lookup.
*/ */
#define HASH(a,b) (519*((size_t)(a)>>4) + 17*((size_t)(b)>>4)) #define HASH(a,b) ((((519*(size_t)(a)))>>4) + ((b) ? (b)->tsv.hash: 0))
static struct { static struct {
unsigned hash; unsigned hash;
...@@ -83,19 +83,18 @@ static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) { ...@@ -83,19 +83,18 @@ static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) {
const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) { const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) {
const luaR_entry *pentry = rotable; const luaR_entry *pentry = rotable;
const char *strkey = key ? getstr(key) : ALIGNED_STRING "__metatable" ; const char *strkey = key ? getstr(key) : ALIGNED_STRING "__metatable" ;
size_t hash = HASH(rotable, key); unsigned hash = HASH(rotable, key);
unsigned i = 0; unsigned i = 0;
int j = lookup_cache(hash, rotable); int j = lookup_cache(hash, rotable);
unsigned l = key ? key->tsv.len : sizeof("__metatable")-1; unsigned l = key ? key->tsv.len : sizeof("__metatable")-1;
if (pentry) { if (pentry) {
if (j >= 0){ if (j >= 0 && !c_strcmp(pentry[j].key, strkey)) {
if ((pentry[j].key.type == LUA_TSTRING) && if (ppos)
!c_strcmp(pentry[j].key.id.strkey, strkey)) { *ppos = j;
if (ppos) //dbg_printf("%3d hit %p %s\n", (hash>>2) & (LA_LINES-1), rotable, strkey);
*ppos = j; return &pentry[j].value;
return &pentry[j].value;
}
} }
/* /*
* The invariants for 1st word comparison are deferred to here since they * The invariants for 1st word comparison are deferred to here since they
...@@ -105,40 +104,22 @@ const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) { ...@@ -105,40 +104,22 @@ const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) {
unsigned name4, mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8); unsigned name4, mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
c_memcpy(&name4, strkey, sizeof(name4)); c_memcpy(&name4, strkey, sizeof(name4));
for(;pentry->key.type != LUA_TNIL; i++, pentry++) { for(;pentry->key != NULL; i++, pentry++) {
if ((pentry->key.type == LUA_TSTRING) && if (((*(unsigned *)pentry->key ^ name4) & mask4) == 0 &&
((*(unsigned *)pentry->key.id.strkey ^ name4) & mask4) == 0 && !c_strcmp(pentry->key, strkey)) {
!c_strcmp(pentry->key.id.strkey, strkey)) { //dbg_printf("%p %s hit after %d probes \n", rotable, strkey, (int)(rotable-pentry));
if (ppos) if (ppos)
*ppos = i; *ppos = i;
if (j==-1) { update_cache(hash, rotable, pentry - rotable);
update_cache(hash, rotable, pentry - rotable); //dbg_printf("%3d %3d %p %s\n", (hash>>2) & (LA_LINES-1), (int)(pentry-rotable), rotable, strkey);
} else if (j != (pentry - rotable)) { return &pentry->value;
j = 0;
}
return &pentry->value;
} }
} }
} }
//dbg_printf("%p %s miss after %d probes \n", rotable, strkey, (int)(rotable-pentry));
return luaO_nilobject; return luaO_nilobject;
} }
const TValue* luaR_findentryN(ROTable *rotable, luaR_numkey numkey, unsigned *ppos) {
unsigned i = 0;
const luaR_entry *pentry = rotable;
if (pentry) {
for ( ;pentry->key.type != LUA_TNIL; i++, pentry++) {
if (pentry->key.type == LUA_TNUMBER && (luaR_numkey) pentry->key.id.numkey == numkey) {
if (ppos)
*ppos = i;
return &pentry->value;
}
}
}
return NULL;
}
/* Find the metatable of a given table */ /* Find the metatable of a given table */
void* luaR_getmeta(ROTable *rotable) { void* luaR_getmeta(ROTable *rotable) {
const TValue *res = luaR_findentry(rotable, NULL, NULL); const TValue *res = luaR_findentry(rotable, NULL, NULL);
...@@ -147,15 +128,13 @@ void* luaR_getmeta(ROTable *rotable) { ...@@ -147,15 +128,13 @@ void* luaR_getmeta(ROTable *rotable) {
static void luaR_next_helper(lua_State *L, ROTable *pentries, int pos, static void luaR_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val) { TValue *key, TValue *val) {
setnilvalue(key); if (pentries[pos].key) {
setnilvalue(val);
if (pentries[pos].key.type != LUA_TNIL) {
/* Found an entry */ /* Found an entry */
if (pentries[pos].key.type == LUA_TSTRING) setsvalue(L, key, luaS_new(L, pentries[pos].key));
setsvalue(L, key, luaS_new(L, pentries[pos].key.id.strkey)) setobj2s(L, val, &pentries[pos].value);
else } else {
setnvalue(key, (lua_Number)pentries[pos].key.id.numkey) setnilvalue(key);
setobj2s(L, val, &pentries[pos].value); setnilvalue(val);
} }
} }
...@@ -167,12 +146,10 @@ void luaR_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val) { ...@@ -167,12 +146,10 @@ void luaR_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val) {
/* Special case: if key is nil, return the first element of the rotable */ /* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key)) if (ttisnil(key))
luaR_next_helper(L, rotable, 0, key, val); luaR_next_helper(L, rotable, 0, key, val);
else if (ttisstring(key) || ttisnumber(key)) { else if (ttisstring(key)) {
/* Find the previous key again */ /* Find the previous key again */
if (ttisstring(key)) { if (ttisstring(key)) {
luaR_findentry(rotable, rawtsvalue(key), &keypos); luaR_findentry(rotable, rawtsvalue(key), &keypos);
} else {
luaR_findentryN(rotable, (luaR_numkey)nvalue(key), &keypos);
} }
/* Advance to next key */ /* Advance to next key */
keypos ++; keypos ++;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "luaconf.h" #include "luaconf.h"
#include "lobject.h" #include "lobject.h"
#include "llimits.h" #include "llimits.h"
#include "lrotable.h"
/* Macros one can use to define rotable entries */ /* Macros one can use to define rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION} #define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
...@@ -14,13 +15,28 @@ ...@@ -14,13 +15,28 @@
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER} #define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE} #define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL} #define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#ifdef LUA_CROSS_COMPILER #ifdef LUA_CROSS_COMPILER
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}} #define LRO_STRKEY(k) k
#else #else
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = (STORE_ATTR char *) k}} #define LRO_STRKEY(k) ((STORE_ATTR char *) k)
#endif #endif
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}} #define LROT_TABLE(t) static const LUA_REG_TYPE t ## _map[];
#define LROT_PUBLIC_TABLE(t) const LUA_REG_TYPE t ## _map[];
#define LROT_TABLEREF(t) ((void *) t ## _map)
#define LROT_BEGIN(t) static const LUA_REG_TYPE t ## _map [] = {
#define LROT_PUBLIC_BEGIN(t) const LUA_REG_TYPE t ## _map[] = {
#define LROT_EXTERN(t) extern const LUA_REG_TYPE t ## _map[]
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t ## _map)},
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
#define LROT_END(t,mt, f) {NULL, LRO_NILVAL} };
#define LROT_BREAK(t) };
#define LUA_REG_TYPE luaR_entry
#define LREGISTER(L, name, table) return 0
/* Maximum length of a rotable name and of a string key*/ /* Maximum length of a rotable name and of a string key*/
#define LUA_MAX_ROTABLE_NAME 32 #define LUA_MAX_ROTABLE_NAME 32
...@@ -28,18 +44,9 @@ ...@@ -28,18 +44,9 @@
/* Type of a numeric key in a rotable */ /* Type of a numeric key in a rotable */
typedef int luaR_numkey; typedef int luaR_numkey;
/* The next structure defines the type of a key */
typedef struct {
int type;
union {
const char* strkey;
luaR_numkey numkey;
} id;
} luaR_key;
/* An entry in the read only table */ /* An entry in the read only table */
typedef struct luaR_entry { typedef struct luaR_entry {
const luaR_key key; const char *key;
const TValue value; const TValue value;
} luaR_entry; } luaR_entry;
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
/* macro to `unsign' a character */ /* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c)) #define uchar(c) ((unsigned char)(c))
static int str_len (lua_State *L) { static int str_len (lua_State *L) {
size_t l; size_t l;
luaL_checklstring(L, 1, &l); luaL_checklstring(L, 1, &l);
...@@ -576,7 +576,7 @@ static int gmatch (lua_State *L) { ...@@ -576,7 +576,7 @@ static int gmatch (lua_State *L) {
return 1; return 1;
} }
#if LUA_OPTIMIZE_MEMORY == 0 || !defined(LUA_COMPAT_GFIND) #ifndef LUA_COMPAT_GFIND
static int gfind_nodef (lua_State *L) { static int gfind_nodef (lua_State *L) {
return luaL_error(L, LUA_QL("string.gfind") " was renamed to " return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
LUA_QL("string.gmatch")); LUA_QL("string.gmatch"));
...@@ -824,67 +824,37 @@ static int str_format (lua_State *L) { ...@@ -824,67 +824,37 @@ static int str_format (lua_State *L) {
return 1; return 1;
} }
#undef MIN_OPT_LEVEL LROT_PUBLIC_BEGIN(strlib)
#define MIN_OPT_LEVEL 1 LROT_FUNCENTRY( byte, str_byte )
#include "lrodefs.h" LROT_FUNCENTRY( char, str_char )
const LUA_REG_TYPE strlib[] = { LROT_FUNCENTRY( dump, str_dump )
{LSTRKEY("byte"), LFUNCVAL(str_byte)}, LROT_FUNCENTRY( find, str_find )
{LSTRKEY("char"), LFUNCVAL(str_char)}, LROT_FUNCENTRY( format, str_format )
{LSTRKEY("dump"), LFUNCVAL(str_dump)}, #ifdef LUA_COMPAT_GFIND
{LSTRKEY("find"), LFUNCVAL(str_find)}, LROT_FUNCENTRY( gfind, gmatch )
{LSTRKEY("format"), LFUNCVAL(str_format)},
#if LUA_OPTIMIZE_MEMORY > 0 && defined(LUA_COMPAT_GFIND)
{LSTRKEY("gfind"), LFUNCVAL(gmatch)},
#else #else
{LSTRKEY("gfind"), LFUNCVAL(gfind_nodef)}, LROT_FUNCENTRY( gfind, 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 */
lua_pushvalue(L, -2);
lua_setmetatable(L, -2); /* set string metatable */
lua_pop(L, 1); /* pop dummy string */
lua_pushvalue(L, -2); /* string library... */
lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
lua_pop(L, 1); /* pop metatable */
}
#endif #endif
LROT_FUNCENTRY( gmatch, gmatch )
LROT_FUNCENTRY( gsub, str_gsub )
LROT_FUNCENTRY( len, str_len )
LROT_FUNCENTRY( lower, str_lower )
LROT_FUNCENTRY( match, str_match )
LROT_FUNCENTRY( rep, str_rep )
LROT_FUNCENTRY( reverse, str_reverse )
LROT_FUNCENTRY( sub, str_sub )
LROT_FUNCENTRY( upper, str_upper )
LROT_TABENTRY( __index, strlib )
LROT_END(strlib, NULL, 0) // OR DO WE NEED LRTO_MASK_INDEX **TODO**
/* /*
** Open string library ** Open string library
*/ */
LUALIB_API int luaopen_string (lua_State *L) { 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_pushliteral(L,"");
lua_pushrotable(L, (void*)strlib); lua_pushrotable(L, LROT_TABLEREF(strlib));
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_pop(L,1); lua_pop(L,1);
return 0; return 0;
#endif
} }
...@@ -580,7 +580,7 @@ const TValue *luaH_getnum (Table *t, int key) { ...@@ -580,7 +580,7 @@ const TValue *luaH_getnum (Table *t, int key) {
/* same thing for rotables */ /* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) { const TValue *luaH_getnum_ro (void *t, int key) {
const TValue *res = luaR_findentryN(t, key, NULL); const TValue *res = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject; return res ? res : luaO_nilobject;
} }
...@@ -739,11 +739,7 @@ int luaH_getn (Table *t) { ...@@ -739,11 +739,7 @@ int luaH_getn (Table *t) {
/* same thing for rotables */ /* same thing for rotables */
int luaH_getn_ro (void *t) { int luaH_getn_ro (void *t) {
int i = 1, len=0; return 0; // Integer Keys are not currently supported for ROTables
while(luaR_findentryN(t, i ++, NULL))
len ++;
return len;
} }
int luaH_isdummy (Node *n) { return n == dummynode; } int luaH_isdummy (Node *n) { return n == dummynode; }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
...@@ -265,22 +266,18 @@ static int sort (lua_State *L) { ...@@ -265,22 +266,18 @@ static int sort (lua_State *L) {
/* }====================================================== */ /* }====================================================== */
#undef MIN_OPT_LEVEL LROT_PUBLIC_BEGIN(tab_funcs)
#define MIN_OPT_LEVEL 1 LROT_FUNCENTRY( concat, tconcat )
#include "lrodefs.h" LROT_FUNCENTRY( foreach, foreach )
const LUA_REG_TYPE tab_funcs[] = { LROT_FUNCENTRY( foreachi, foreachi )
{LSTRKEY("concat"), LFUNCVAL(tconcat)}, LROT_FUNCENTRY( getn, getn )
{LSTRKEY("foreach"), LFUNCVAL(foreach)}, LROT_FUNCENTRY( maxn, maxn )
{LSTRKEY("foreachi"), LFUNCVAL(foreachi)}, LROT_FUNCENTRY( insert, tinsert )
{LSTRKEY("getn"), LFUNCVAL(getn)}, LROT_FUNCENTRY( remove, tremove )
{LSTRKEY("maxn"), LFUNCVAL(maxn)}, LROT_FUNCENTRY( setn, setn )
{LSTRKEY("insert"), LFUNCVAL(tinsert)}, LROT_FUNCENTRY( sort, sort )
{LSTRKEY("remove"), LFUNCVAL(tremove)}, LROT_END(tab_funcs, NULL, 0)
{LSTRKEY("setn"), LFUNCVAL(setn)},
{LSTRKEY("sort"), LFUNCVAL(sort)},
{LNILKEY, LNILVAL}
};
LUALIB_API int luaopen_table (lua_State *L) { LUALIB_API int luaopen_table (lua_State *L) {
LREGISTER(L, LUA_TABLIBNAME, tab_funcs); return 1;
} }
...@@ -13,7 +13,7 @@ LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -ldl -Wl,-Map=mapfile ...@@ -13,7 +13,7 @@ LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -ldl -Wl,-Map=mapfile
CCFLAGS += -Wall CCFLAGS += -Wall
DEFINES += -DLUA_CROSS_COMPILER -DLUA_OPTIMIZE_MEMORY=2 DEFINES += -DLUA_CROSS_COMPILER
TARGET = host TARGET = host
......
...@@ -12,12 +12,12 @@ ...@@ -12,12 +12,12 @@
#define liolib_c #define liolib_c
#define LUA_LIB #define LUA_LIB
#define LUA_OPTIMIZE_MEMORY 2
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
#define IO_INPUT 1 #define IO_INPUT 1
#define IO_OUTPUT 2 #define IO_OUTPUT 2
...@@ -439,36 +439,31 @@ static int f_flush (lua_State *L) { ...@@ -439,36 +439,31 @@ static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL); return pushresult(L, fflush(tofile(L)) == 0, NULL);
} }
#define MIN_OPT_LEVEL 2 LROT_PUBLIC_BEGIN(iolib)
#include "lrodefs.h" LROT_FUNCENTRY( close, io_close )
const LUA_REG_TYPE iolib_funcs[] = { LROT_FUNCENTRY( flush, io_flush )
{LSTRKEY("close"), LFUNCVAL(io_close)}, LROT_FUNCENTRY( input, io_input )
{LSTRKEY("flush"), LFUNCVAL(io_flush)}, LROT_FUNCENTRY( lines, io_lines )
{LSTRKEY("input"), LFUNCVAL(io_input)}, LROT_FUNCENTRY( open, io_open )
{LSTRKEY("lines"), LFUNCVAL(io_lines)}, LROT_FUNCENTRY( output, io_output )
{LSTRKEY("open"), LFUNCVAL(io_open)}, LROT_FUNCENTRY( read, io_read )
{LSTRKEY("output"), LFUNCVAL(io_output)}, LROT_FUNCENTRY( type, io_type )
{LSTRKEY("read"), LFUNCVAL(io_read)}, LROT_FUNCENTRY( write, io_write )
{LSTRKEY("type"), LFUNCVAL(io_type)}, LROT_TABENTRY( __index, iolib )
{LSTRKEY("write"), LFUNCVAL(io_write)}, LROT_END(iolib, NULL, 0)
{LSTRKEY("__index"), LROVAL(iolib_funcs)},
{LNILKEY, LNILVAL} LROT_BEGIN(flib)
}; LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, f_flush )
#include "lrodefs.h" LROT_FUNCENTRY( lines, f_lines )
const LUA_REG_TYPE flib[] = { LROT_FUNCENTRY( read, f_read )
{LSTRKEY("close"), LFUNCVAL(io_close)}, LROT_FUNCENTRY( seek, f_seek )
{LSTRKEY("flush"), LFUNCVAL(f_flush)}, LROT_FUNCENTRY( setvbuf, f_setvbuf )
{LSTRKEY("lines"), LFUNCVAL(f_lines)}, LROT_FUNCENTRY( write, f_write )
{LSTRKEY("read"), LFUNCVAL(f_read)}, LROT_FUNCENTRY( __gc, io_gc )
{LSTRKEY("seek"), LFUNCVAL(f_seek)}, LROT_FUNCENTRY( __tostring, io_tostring )
{LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)}, LROT_TABENTRY( __index, flib )
{LSTRKEY("write"), LFUNCVAL(f_write)}, LROT_END(flib, NULL, LROT_MASK_GC_INDEX)
{LSTRKEY("__gc"), LFUNCVAL(io_gc)},
{LSTRKEY("__tostring"), LFUNCVAL(io_tostring)},
{LSTRKEY("__index"), LROVAL(flib)},
{LNILKEY, LNILVAL}
};
static const luaL_Reg io_base[] = {{NULL, NULL}}; static const luaL_Reg io_base[] = {{NULL, NULL}};
...@@ -481,12 +476,12 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { ...@@ -481,12 +476,12 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
} }
LUALIB_API int luaopen_io(lua_State *L) { LUALIB_API int luaopen_io(lua_State *L) {
luaL_rometatable(L, LUA_FILEHANDLE, (void*) flib); /* create metatable for file handles */ luaL_rometatable(L, LUA_FILEHANDLE, LROT_TABLEREF(flib)); /* create metatable for file handles */
luaL_register_light(L, LUA_IOLIBNAME, io_base); luaL_register_light(L, LUA_IOLIBNAME, io_base);
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_pushliteral(L, "__index"); lua_pushliteral(L, "__index");
lua_pushrotable(L, (void *)iolib_funcs); lua_pushrotable(L, LROT_TABLEREF(iolib));
lua_rawset(L, -3); lua_rawset(L, -3);
/* create (and set) default files */ /* create (and set) default files */
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
static int os_pushresult (lua_State *L, int i, const char *filename) { static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */ int en = errno; /* calls to Lua API may change this value */
...@@ -219,30 +220,25 @@ static int os_exit (lua_State *L) { ...@@ -219,30 +220,25 @@ static int os_exit (lua_State *L) {
c_exit(luaL_optint(L, 1, EXIT_SUCCESS)); c_exit(luaL_optint(L, 1, EXIT_SUCCESS));
} }
#undef MIN_OPT_LEVEL LROT_PUBLIC_BEGIN(oslib)
#define MIN_OPT_LEVEL 1 LROT_FUNCENTRY( clock, os_clock )
#include "lrodefs.h" LROT_FUNCENTRY( date, os_date )
const LUA_REG_TYPE syslib[] = {
{LSTRKEY("clock"), LFUNCVAL(os_clock)},
{LSTRKEY("date"), LFUNCVAL(os_date)},
#if !defined LUA_NUMBER_INTEGRAL #if !defined LUA_NUMBER_INTEGRAL
{LSTRKEY("difftime"), LFUNCVAL(os_difftime)}, LROT_FUNCENTRY( difftime, os_difftime )
#endif #endif
{LSTRKEY("execute"), LFUNCVAL(os_execute)}, LROT_FUNCENTRY( execute, os_execute )
{LSTRKEY("exit"), LFUNCVAL(os_exit)}, LROT_FUNCENTRY( exit, os_exit )
{LSTRKEY("getenv"), LFUNCVAL(os_getenv)}, LROT_FUNCENTRY( getenv, os_getenv )
{LSTRKEY("remove"), LFUNCVAL(os_remove)}, LROT_FUNCENTRY( remove, os_remove )
{LSTRKEY("rename"), LFUNCVAL(os_rename)}, LROT_FUNCENTRY( rename, os_rename )
{LSTRKEY("setlocale"), LFUNCVAL(os_setlocale)}, LROT_FUNCENTRY( setlocale, os_setlocale )
{LSTRKEY("time"), LFUNCVAL(os_time)}, LROT_FUNCENTRY( time, os_time )
{LSTRKEY("tmpname"), LFUNCVAL(os_tmpname)}, LROT_FUNCENTRY( tmpname, os_tmpname )
{LNILKEY, LNILVAL} LROT_END(oslib, NULL, 0)
};
/* }====================================================== */ /* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) { LUALIB_API int luaopen_os (lua_State *L) {
LREGISTER(L, LUA_OSLIBNAME, syslib); return 1;
} }
...@@ -910,8 +910,8 @@ union luai_Cast { double l_d; long l_l; }; ...@@ -910,8 +910,8 @@ union luai_Cast { double l_d; long l_l; };
** without modifying the main part of the file. ** without modifying the main part of the file.
*/ */
#if LUA_OPTIMIZE_MEMORY == 2 && defined(LUA_USE_POPEN) #if defined(LUA_USE_POPEN)
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)" #error "Pipes not supported NodeMCU firmware"
#endif #endif
#endif #endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment