Optimise ROTable accesses and interface (#2505)
- Optimise ROTable accesses and interface This includes some refinements to the ROTable cache which remove the linker cludges on the CROSS_COMPILE builds. Also keyhole tweaks to some of the Lua VM code to implrove runtimes. I also noticed some compile time warnings during the build; the change to uz_unzip.c doesn't impact the compiled code, but does remove the compiler warnings.
This commit is contained in:
parent
ff44b2f015
commit
5f67de8d48
|
@ -57,18 +57,8 @@
|
||||||
const LOCK_IN_SECTION(libs) \
|
const LOCK_IN_SECTION(libs) \
|
||||||
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
|
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
|
||||||
const LOCK_IN_SECTION(rotable) \
|
const LOCK_IN_SECTION(rotable) \
|
||||||
luaR_table 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))) \
|
||||||
= { luaname, map }
|
= {LSTRKEY(luaname), LROVAL(map)}
|
||||||
|
|
||||||
|
|
||||||
/* System module registration support, not using LUA_USE_MODULES_XYZ. */
|
|
||||||
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
|
|
||||||
const LOCK_IN_SECTION(libs) \
|
|
||||||
luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
|
|
||||||
|
|
||||||
#define BUILTIN_LIB(name, luaname, map) \
|
|
||||||
const LOCK_IN_SECTION(rotable) \
|
|
||||||
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
|
|
||||||
|
|
||||||
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
|
#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)"
|
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#define lauxlib_c
|
#define lauxlib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "lrotable.h"
|
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
|
@ -555,14 +553,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
|
||||||
if (e == NULL) e = fname + c_strlen(fname);
|
if (e == NULL) e = fname + c_strlen(fname);
|
||||||
lua_pushlstring(L, fname, e - fname);
|
lua_pushlstring(L, fname, e - fname);
|
||||||
lua_rawget(L, -2);
|
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? */
|
if (lua_isnil(L, -1)) { /* no such field? */
|
||||||
lua_pop(L, 1); /* remove this nil */
|
lua_pop(L, 1); /* remove this nil */
|
||||||
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
|
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
|
||||||
|
|
|
@ -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 "lrotable.h"
|
#include "lrodefs.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -462,71 +462,62 @@ static int luaB_newproxy (lua_State *L) {
|
||||||
return 1;
|
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
|
|
||||||
#undef MIN_OPT_LEVEL
|
|
||||||
#define MIN_OPT_LEVEL 2
|
|
||||||
#include "lrodefs.h"
|
#include "lrodefs.h"
|
||||||
const LUA_REG_TYPE base_funcs_list[] = {
|
|
||||||
LUA_BASELIB_FUNCLIST,
|
extern const luaR_entry lua_rotable_base[];
|
||||||
{LNILKEY, LNILVAL}
|
|
||||||
};
|
/*
|
||||||
|
* ESP builds use specific linker directives to marshal all ROTable declarations
|
||||||
|
* into a single ROTable in the PSECT ".lua_rotable".
|
||||||
|
*
|
||||||
|
* This is not practical on Posix builds using a standard link so for cross
|
||||||
|
* compiler builds, separate ROTables are used for the base functions and library
|
||||||
|
* ROTables, with the latter chained from the former using its __index meta-method.
|
||||||
|
* In this case all library ROTables are defined in linit.c.
|
||||||
|
*/
|
||||||
|
#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
|
#endif
|
||||||
|
|
||||||
|
static const LUA_REG_TYPE LOCK_IN_ROTABLE base_func_map[] = {
|
||||||
static int luaB_index(lua_State *L) {
|
LROT_FUNCENTRY(assert, luaB_assert),
|
||||||
#if LUA_OPTIMIZE_MEMORY == 2
|
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage),
|
||||||
int fres;
|
LROT_FUNCENTRY(dofile, luaB_dofile),
|
||||||
if ((fres = luaR_findfunction(L, base_funcs_list)) != 0)
|
LROT_FUNCENTRY(error, luaB_error),
|
||||||
return fres;
|
LROT_FUNCENTRY(gcinfo, luaB_gcinfo),
|
||||||
#endif
|
LROT_FUNCENTRY(getfenv, luaB_getfenv),
|
||||||
const char *keyname = luaL_checkstring(L, 2);
|
LROT_FUNCENTRY(getmetatable, luaB_getmetatable),
|
||||||
if (!c_strcmp(keyname, "_VERSION")) {
|
LROT_FUNCENTRY(loadfile, luaB_loadfile),
|
||||||
lua_pushliteral(L, LUA_VERSION);
|
LROT_FUNCENTRY(load, luaB_load),
|
||||||
return 1;
|
LROT_FUNCENTRY(loadstring, luaB_loadstring),
|
||||||
}
|
LROT_FUNCENTRY(next, luaB_next),
|
||||||
void *res = luaR_findglobal(keyname, c_strlen(keyname));
|
LROT_FUNCENTRY(pcall, luaB_pcall),
|
||||||
if (!res)
|
LROT_FUNCENTRY(print, luaB_print),
|
||||||
return 0;
|
LROT_FUNCENTRY(rawequal, luaB_rawequal),
|
||||||
else {
|
LROT_FUNCENTRY(rawget, luaB_rawget),
|
||||||
lua_pushrotable(L, res);
|
LROT_FUNCENTRY(rawset, luaB_rawset),
|
||||||
return 1;
|
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)
|
||||||
|
#ifdef LUA_CROSS_COMPILER
|
||||||
|
,LROT_TABENTRY(__metatable, base_func_meta),
|
||||||
|
LROT_END
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static const luaL_Reg base_funcs[] = {
|
static const luaL_Reg base_funcs[] = {
|
||||||
#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}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -661,7 +652,6 @@ static int luaB_corunning (lua_State *L) {
|
||||||
|
|
||||||
#undef MIN_OPT_LEVEL
|
#undef MIN_OPT_LEVEL
|
||||||
#define MIN_OPT_LEVEL 1
|
#define MIN_OPT_LEVEL 1
|
||||||
#include "lrodefs.h"
|
|
||||||
const LUA_REG_TYPE co_funcs[] = {
|
const LUA_REG_TYPE co_funcs[] = {
|
||||||
{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)},
|
{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)},
|
||||||
{LSTRKEY("resume"), LFUNCVAL(luaB_coresume)},
|
{LSTRKEY("resume"), LFUNCVAL(luaB_coresume)},
|
||||||
|
@ -682,7 +672,6 @@ static void auxopen (lua_State *L, const char *name,
|
||||||
lua_setfield(L, -2, name);
|
lua_setfield(L, -2, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void base_open (lua_State *L) {
|
static void base_open (lua_State *L) {
|
||||||
/* set global _G */
|
/* set global _G */
|
||||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||||
|
@ -691,11 +680,12 @@ static void base_open (lua_State *L) {
|
||||||
luaL_register_light(L, "_G", base_funcs);
|
luaL_register_light(L, "_G", base_funcs);
|
||||||
#if LUA_OPTIMIZE_MEMORY > 0
|
#if LUA_OPTIMIZE_MEMORY > 0
|
||||||
lua_pushvalue(L, -1);
|
lua_pushvalue(L, -1);
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
#else
|
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 */
|
||||||
#endif
|
|
||||||
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
|
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
|
||||||
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
|
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
|
||||||
auxopen(L, "pairs", luaB_pairs, luaB_next);
|
auxopen(L, "pairs", luaB_pairs, luaB_next);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
#include "lrotable.h"
|
|
||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
#include "lflash.h"
|
#include "lflash.h"
|
||||||
#include "user_modules.h"
|
#include "user_modules.h"
|
||||||
|
|
|
@ -168,10 +168,14 @@ static int traversetable (global_State *g, Table *h) {
|
||||||
int i;
|
int i;
|
||||||
int weakkey = 0;
|
int weakkey = 0;
|
||||||
int weakvalue = 0;
|
int weakvalue = 0;
|
||||||
const TValue *mode;
|
const TValue *mode = luaO_nilobject;
|
||||||
if (h->metatable && !luaR_isrotable(h->metatable))
|
|
||||||
markobject(g, h->metatable);
|
if (h->metatable) {
|
||||||
mode = gfasttm(g, h->metatable, TM_MODE);
|
if (!luaR_isrotable(h->metatable))
|
||||||
|
markobject(g, h->metatable);
|
||||||
|
mode = gfasttm(g, h->metatable, TM_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
if (mode && ttisstring(mode)) { /* is there a weak mode? */
|
if (mode && ttisstring(mode)) { /* is there a weak mode? */
|
||||||
weakkey = (c_strchr(svalue(mode), 'k') != NULL);
|
weakkey = (c_strchr(svalue(mode), 'k') != NULL);
|
||||||
weakvalue = (c_strchr(svalue(mode), 'v') != NULL);
|
weakvalue = (c_strchr(svalue(mode), 'v') != NULL);
|
||||||
|
|
|
@ -15,60 +15,71 @@
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "luaconf.h"
|
#include "luaconf.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#if defined(LUA_CROSS_COMPILER)
|
|
||||||
BUILTIN_LIB( start_list, NULL, NULL);
|
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
|
||||||
BUILTIN_LIB_INIT( start_list, NULL, NULL);
|
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const luaR_entry strlib[], tab_funcs[], dblib[],
|
extern const luaR_entry strlib[], tab_funcs[], dblib[],
|
||||||
co_funcs[], math_map[], syslib[];
|
co_funcs[], math_map[], syslib[];
|
||||||
|
extern const luaR_entry syslib[], io_funcs[]; // Only used on cross-compile builds
|
||||||
|
|
||||||
BUILTIN_LIB_INIT( BASE, "", luaopen_base);
|
/*
|
||||||
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);
|
* 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
|
||||||
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
|
* entries to be collected by the linker into consoliated tables. The linker
|
||||||
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
|
* defines lua_libs_base and lua_rotable_base.
|
||||||
|
*
|
||||||
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
|
* This is not practical on Posix builds which use a standard loader declaration
|
||||||
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
|
* so for cross compiler builds, separate ROTables are used for the base functions
|
||||||
|
* and library ROTables, with the latter chained from the former using its __index
|
||||||
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
|
* meta-method. In this case all library ROTables are defined here, avoiding the
|
||||||
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
|
* need for linker magic is avoided on host builds.
|
||||||
|
*/
|
||||||
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
|
|
||||||
|
|
||||||
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
|
|
||||||
|
|
||||||
#if defined(LUA_CROSS_COMPILER)
|
#if defined(LUA_CROSS_COMPILER)
|
||||||
extern const luaR_entry syslib[], iolib[];
|
#define LUA_ROTABLES lua_rotable_base
|
||||||
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
|
#define LUA_LIBS lua_libs_base
|
||||||
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
|
#else /* declare Xtensa toolchain linker defined constants */
|
||||||
BUILTIN_LIB( end_list, NULL, NULL);
|
|
||||||
BUILTIN_LIB_INIT( end_list, NULL, NULL);
|
|
||||||
/*
|
|
||||||
* These base addresses are internal to this module for cross compile builds
|
|
||||||
* This also exploits feature of the GCC code generator that the variables are
|
|
||||||
* emitted in either normal OR reverse order within PSECT.
|
|
||||||
*/
|
|
||||||
#define isascending(n) ((&(n ## _end_list)-&(n ## _start_list))>0)
|
|
||||||
static const luaL_Reg *lua_libs;
|
|
||||||
const luaR_table *lua_rotable;
|
|
||||||
#else
|
|
||||||
/* These base addresses are Xtensa toolchain linker constants for Firmware builds */
|
|
||||||
extern const luaL_Reg lua_libs_base[];
|
extern const luaL_Reg lua_libs_base[];
|
||||||
extern const luaR_table lua_rotable_base[];
|
extern const luaR_entry lua_rotable_base[];
|
||||||
static const luaL_Reg *lua_libs = lua_libs_base;
|
#define LUA_ROTABLES lua_rotable_core
|
||||||
const luaR_table *lua_rotable = lua_rotable_base;
|
#define LUA_LIBS lua_libs_core
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const LOCK_IN_SECTION(libs) luaL_reg LUA_LIBS[] = {
|
||||||
|
{"", luaopen_base},
|
||||||
|
{LUA_LOADLIBNAME, luaopen_package},
|
||||||
|
{LUA_STRLIBNAME, luaopen_string},
|
||||||
|
{LUA_TABLIBNAME, luaopen_table},
|
||||||
|
{LUA_DBLIBNAME, luaopen_debug}
|
||||||
|
#if defined(LUA_CROSS_COMPILER)
|
||||||
|
,{LUA_IOLIBNAME, luaopen_io},
|
||||||
|
{NULL, NULL}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ENTRY(n,t) {LSTRKEY(n), LRO_ROVAL(t)}
|
||||||
|
|
||||||
|
const LOCK_IN_SECTION(rotable) ROTable LUA_ROTABLES[] = {
|
||||||
|
ENTRY("ROM", LUA_ROTABLES),
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
void luaL_openlibs (lua_State *L) {
|
void luaL_openlibs (lua_State *L) {
|
||||||
#if defined(LUA_CROSS_COMPILER)
|
const luaL_Reg *lib = lua_libs_base;
|
||||||
lua_libs = (isascending(lua_lib) ? &lua_lib_start_list : &lua_lib_end_list) + 1;
|
|
||||||
lua_rotable = (isascending(lua_rotable) ? &lua_rotable_start_list : &lua_rotable_end_list) + 1;
|
/* loop round and open libraries */
|
||||||
#endif
|
|
||||||
const luaL_Reg *lib = lua_libs;
|
|
||||||
for (; lib->name; lib++) {
|
for (; lib->name; lib++) {
|
||||||
if (lib->func)
|
if (lib->func) {
|
||||||
{
|
|
||||||
lua_pushcfunction(L, lib->func);
|
lua_pushcfunction(L, lib->func);
|
||||||
lua_pushstring(L, lib->name);
|
lua_pushstring(L, lib->name);
|
||||||
lua_call(L, 1, 0);
|
lua_call(L, 1, 0);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#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)
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
#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_"
|
||||||
|
@ -474,10 +473,11 @@ static int ll_require (lua_State *L) {
|
||||||
return 1; /* package is already loaded */
|
return 1; /* package is already loaded */
|
||||||
}
|
}
|
||||||
/* Is this a readonly table? */
|
/* Is this a readonly table? */
|
||||||
void *res = luaR_findglobal(name, c_strlen(name));
|
lua_getfield(L, LUA_GLOBALSINDEX, name);
|
||||||
if (res) {
|
if(lua_isrotable(L,-1)) {
|
||||||
lua_pushrotable(L, res);
|
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
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_ENVIRONINDEX, "loaders");
|
||||||
|
@ -563,8 +563,13 @@ static void modinit (lua_State *L, const char *modname) {
|
||||||
|
|
||||||
static int ll_module (lua_State *L) {
|
static int ll_module (lua_State *L) {
|
||||||
const char *modname = luaL_checkstring(L, 1);
|
const char *modname = luaL_checkstring(L, 1);
|
||||||
if (luaR_findglobal(modname, c_strlen(modname)))
|
/* Is this a readonly table? */
|
||||||
|
lua_getfield(L, LUA_GLOBALSINDEX, modname);
|
||||||
|
if(lua_isrotable(L,-1)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
|
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
|
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
|
||||||
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
|
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
|
||||||
|
|
|
@ -405,6 +405,7 @@ typedef struct Table {
|
||||||
int sizearray; /* size of `array' array */
|
int sizearray; /* size of `array' array */
|
||||||
} Table;
|
} Table;
|
||||||
|
|
||||||
|
typedef const struct luaR_entry ROTable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** `module' operation for hashing (size is always a power of 2)
|
** `module' operation for hashing (size is always a power of 2)
|
||||||
|
|
|
@ -38,5 +38,10 @@
|
||||||
return 1
|
return 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LROT_TABENTRY(n,t) {LSTRKEY(#n), LRO_ROVAL(t)}
|
||||||
|
#define LROT_FUNCENTRY(n,f) {LSTRKEY(#n), LRO_FUNCVAL(f)}
|
||||||
|
#define LROT_NUMENTRY(n,x) {LSTRKEY(#n), LRO_NUMVAL(x)}
|
||||||
|
#define LROT_END {LNILKEY, LNILVAL}
|
||||||
|
|
||||||
#endif /* lrodefs_h */
|
#endif /* lrodefs_h */
|
||||||
|
|
||||||
|
|
|
@ -9,77 +9,139 @@
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lapi.h"
|
#include "lapi.h"
|
||||||
|
|
||||||
/* Local defines */
|
#define ALIGNED_STRING (__attribute__((aligned(4))) char *)
|
||||||
#define LUAR_FINDFUNCTION 0
|
#define LA_LINES 16
|
||||||
#define LUAR_FINDVALUE 1
|
#define LA_SLOTS 4
|
||||||
|
//#define COLLECT_STATS
|
||||||
|
|
||||||
/* Externally defined read-only table array */
|
/*
|
||||||
extern const luaR_table *lua_rotable;
|
* All keyed ROtable access passes through luaR_findentry(). ROTables
|
||||||
|
* are simply a list of <key><TValue value> pairs. The existing algo
|
||||||
|
* did a linear scan of this vector of pairs looking for a match.
|
||||||
|
*
|
||||||
|
* A N×M lookaside cache has been added, with a simple hash on the key's
|
||||||
|
* TString addr and the ROTable addr to identify one of N lines. Each
|
||||||
|
* line has M slots which are scanned. This is all done in RAM and is
|
||||||
|
* perhaps 20x faster than the corresponding random Flash accesses which
|
||||||
|
* will cause flash faults.
|
||||||
|
*
|
||||||
|
* If a match is found and the table addresses match, then this entry is
|
||||||
|
* probed first. In practice the hit-rate here is over 99% so the code
|
||||||
|
* rarely fails back to doing the linear scan in ROM.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#define HASH(a,b) (519*((size_t)(a)>>4) + 17*((size_t)(b)>>4))
|
||||||
|
|
||||||
/* Find a global "read only table" in the constant lua_rotable array */
|
static struct {
|
||||||
void* luaR_findglobal(const char *name, unsigned len) {
|
unsigned hash;
|
||||||
unsigned i;
|
unsigned addr:24;
|
||||||
|
unsigned ndx:8;
|
||||||
|
} cache[LA_LINES][LA_SLOTS];
|
||||||
|
|
||||||
if (c_strlen(name) > LUA_MAX_ROTABLE_NAME)
|
#ifdef COLLECT_STATS
|
||||||
return NULL;
|
unsigned cache_stats[3];
|
||||||
for (i=0; lua_rotable[i].name; i ++)
|
#define COUNT(i) cache_stats[i]++
|
||||||
if (*lua_rotable[i].name != '\0' && c_strlen(lua_rotable[i].name) == len && !c_strncmp(lua_rotable[i].name, name, len)) {
|
#else
|
||||||
return (void*)(lua_rotable[i].pentries);
|
#define COUNT(i)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int lookup_cache(unsigned hash, ROTable *rotable) {
|
||||||
|
int i = (hash>>2) & (LA_LINES-1), j;
|
||||||
|
|
||||||
|
for (j = 0; j<LA_SLOTS; j++) {
|
||||||
|
if (cache[i][j].hash == hash &&
|
||||||
|
((size_t)rotable & 0xffffffu) == cache[i][j].addr) {
|
||||||
|
COUNT(0);
|
||||||
|
return cache[i][j].ndx;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
COUNT(1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) {
|
||||||
|
int i = (hash)>>2 & (LA_LINES-1), j;
|
||||||
|
COUNT(2);
|
||||||
|
if (ndx>0xffu)
|
||||||
|
return;
|
||||||
|
for (j = LA_SLOTS-1; j>0; j--)
|
||||||
|
cache[i][j] = cache[i][j-1];
|
||||||
|
cache[i][0].hash = hash;
|
||||||
|
cache[i][0].addr = (size_t) rotable;
|
||||||
|
cache[i][0].ndx = ndx;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Find a string key entry in a rotable and return it. Note that this internally
|
||||||
|
* uses a null key to denote a metatable search.
|
||||||
|
*/
|
||||||
|
const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) {
|
||||||
|
const luaR_entry *pentry = rotable;
|
||||||
|
const char *strkey = key ? getstr(key) : ALIGNED_STRING "__metatable" ;
|
||||||
|
size_t hash = HASH(rotable, key);
|
||||||
|
unsigned i = 0;
|
||||||
|
int j = lookup_cache(hash, rotable);
|
||||||
|
|
||||||
|
if (pentry) {
|
||||||
|
if (j >= 0){
|
||||||
|
if ((pentry[j].key.type == LUA_TSTRING) &&
|
||||||
|
!c_strcmp(pentry[j].key.id.strkey, strkey)) {
|
||||||
|
if (ppos)
|
||||||
|
*ppos = j;
|
||||||
|
return &pentry[j].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* The invariants for 1st word comparison are deferred to here since they
|
||||||
|
* aren't needed if there is a cache hit. Note that the termination null
|
||||||
|
* is included so a "on\0" has a mask of 0xFFFFFF and "a\0" has 0xFFFF.
|
||||||
|
*/
|
||||||
|
unsigned name4 = *(unsigned *)strkey;
|
||||||
|
unsigned l = key ? key->tsv.len : sizeof("__metatable")-1;
|
||||||
|
unsigned mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
|
||||||
|
for(;pentry->key.type != LUA_TNIL; i++, pentry++) {
|
||||||
|
if ((pentry->key.type == LUA_TSTRING) &&
|
||||||
|
((*(unsigned *)pentry->key.id.strkey ^ name4) & mask4) == 0 &&
|
||||||
|
!c_strcmp(pentry->key.id.strkey, strkey)) {
|
||||||
|
if (ppos)
|
||||||
|
*ppos = i;
|
||||||
|
if (j==-1) {
|
||||||
|
update_cache(hash, rotable, pentry - rotable);
|
||||||
|
} else if (j != (pentry - rotable)) {
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
return &pentry->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
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) && (!c_strcmp(pentry->key.id.strkey, strkey))) ||
|
|
||||||
(!strkey && (pentry->key.type == LUA_TNUMBER) && ((luaR_numkey)pentry->key.id.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 */
|
/* Find the metatable of a given table */
|
||||||
void* luaR_getmeta(void *data) {
|
void* luaR_getmeta(ROTable *rotable) {
|
||||||
#ifdef LUA_META_ROTABLES
|
const TValue *res = luaR_findentry(rotable, NULL, NULL);
|
||||||
const TValue *res = luaR_auxfind((const luaR_entry*)data, "__metatable", 0, NULL);
|
|
||||||
return res && ttisrotable(res) ? rvalue(res) : 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) {
|
static void luaR_next_helper(lua_State *L, ROTable *pentries, int pos,
|
||||||
|
TValue *key, TValue *val) {
|
||||||
setnilvalue(key);
|
setnilvalue(key);
|
||||||
setnilvalue(val);
|
setnilvalue(val);
|
||||||
if (pentries[pos].key.type != LUA_TNIL) {
|
if (pentries[pos].key.type != LUA_TNIL) {
|
||||||
|
@ -91,56 +153,24 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos,
|
||||||
setobj2s(L, val, &pentries[pos].value);
|
setobj2s(L, val, &pentries[pos].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* next (used for iteration) */
|
/* next (used for iteration) */
|
||||||
void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) {
|
void luaR_next(lua_State *L, ROTable *rotable, 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;
|
unsigned keypos;
|
||||||
|
|
||||||
/* 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, pentries, 0, key, val);
|
luaR_next_helper(L, rotable, 0, key, val);
|
||||||
else if (ttisstring(key) || ttisnumber(key)) {
|
else if (ttisstring(key) || ttisnumber(key)) {
|
||||||
/* Find the previoud key again */
|
/* Find the previous key again */
|
||||||
if (ttisstring(key)) {
|
if (ttisstring(key)) {
|
||||||
luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME);
|
luaR_findentry(rotable, rawtsvalue(key), &keypos);
|
||||||
pstrkey = strkey;
|
} else {
|
||||||
} else
|
luaR_findentryN(rotable, (luaR_numkey)nvalue(key), &keypos);
|
||||||
numkey = (luaR_numkey)nvalue(key);
|
}
|
||||||
luaR_findentry(data, pstrkey, numkey, &keypos);
|
|
||||||
/* Advance to next key */
|
/* Advance to next key */
|
||||||
keypos ++;
|
keypos ++;
|
||||||
luaR_next_helper(L, pentries, keypos, key, val);
|
luaR_next_helper(L, rotable, 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 {
|
|
||||||
c_memcpy(dest, getstr(src), src->tsv.len);
|
|
||||||
dest[src->tsv.len] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LUA_META_ROTABLES
|
|
||||||
/* Set in RO check depending on platform */
|
|
||||||
#if defined(LUA_CROSS_COMPILER) && defined(__CYGWIN__)
|
|
||||||
extern char __end__[];
|
|
||||||
#define IN_RO_AREA(p) ((p) < __end__)
|
|
||||||
#elif defined(LUA_CROSS_COMPILER)
|
|
||||||
extern char _edata[];
|
|
||||||
#define IN_RO_AREA(p) ((p) < _edata)
|
|
||||||
#else /* xtensa tool chain for ESP target */
|
|
||||||
extern char _irom0_text_start[];
|
|
||||||
extern char _irom0_text_end[];
|
|
||||||
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return 1 if the given pointer is a rotable */
|
|
||||||
int luaR_isrotable(void *p) {
|
|
||||||
return IN_RO_AREA((char *)p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -14,7 +14,11 @@
|
||||||
#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
|
||||||
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
|
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
|
||||||
|
#else
|
||||||
|
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = (STORE_ATTR char *) k}}
|
||||||
|
#endif
|
||||||
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
|
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
|
||||||
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
|
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
|
||||||
|
|
||||||
|
@ -25,40 +29,58 @@
|
||||||
typedef int luaR_numkey;
|
typedef int luaR_numkey;
|
||||||
|
|
||||||
/* The next structure defines the type of a key */
|
/* The next structure defines the type of a key */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int type;
|
int type;
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
const char* strkey;
|
const char* strkey;
|
||||||
luaR_numkey numkey;
|
luaR_numkey numkey;
|
||||||
} id;
|
} id;
|
||||||
} luaR_key;
|
} luaR_key;
|
||||||
|
|
||||||
/* An entry in the read only table */
|
/* An entry in the read only table */
|
||||||
typedef struct
|
typedef struct luaR_entry {
|
||||||
{
|
|
||||||
const luaR_key key;
|
const luaR_key key;
|
||||||
const TValue value;
|
const TValue value;
|
||||||
} luaR_entry;
|
} luaR_entry;
|
||||||
|
|
||||||
/* A rotable */
|
/*
|
||||||
typedef struct
|
* The current ROTable implmentation is a vector of luaR_entry terminated by a
|
||||||
{
|
* nil record. The convention is to use ROtable * to refer to the entire vector
|
||||||
const char *name;
|
* as a logical ROTable.
|
||||||
const luaR_entry *pentries;
|
*/
|
||||||
} luaR_table;
|
typedef const struct luaR_entry ROTable;
|
||||||
|
|
||||||
void* luaR_findglobal(const char *key, unsigned len);
|
const TValue* luaR_findentry(ROTable *tab, TString *key, unsigned *ppos);
|
||||||
int luaR_findfunction(lua_State *L, const luaR_entry *ptable);
|
const TValue* luaR_findentryN(ROTable *tab, luaR_numkey numkey, unsigned *ppos);
|
||||||
const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos);
|
void luaR_next(lua_State *L, ROTable *tab, TValue *key, TValue *val);
|
||||||
void luaR_getcstr(char *dest, const TString *src, size_t maxsize);
|
void* luaR_getmeta(ROTable *tab);
|
||||||
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);
|
int luaR_isrotable(void *p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set inRO check depending on platform. Note that this implementation needs
|
||||||
|
* to work on both the host (luac.cross) and ESP targets. The luac.cross
|
||||||
|
* VM is used for the -e option, and is primarily used to be able to debug
|
||||||
|
* VM changes on the more developer-friendly hot gdb environment.
|
||||||
|
*/
|
||||||
|
#if defined(LUA_CROSS_COMPILER)
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
#define _RODATA_END __end__
|
||||||
#else
|
#else
|
||||||
#define luaR_isrotable(p) (0)
|
#define _RODATA_END _edata
|
||||||
#endif
|
#endif
|
||||||
|
extern const char _RODATA_END[];
|
||||||
|
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
|
||||||
|
|
||||||
|
#else /* xtensa tool chain for ESP target */
|
||||||
|
|
||||||
|
extern const char _irom0_text_start[];
|
||||||
|
extern const char _irom0_text_end[];
|
||||||
|
#define IN_RODATA_AREA(p) (((const char *)(p)) >= _irom0_text_start && ((const char *)(p)) <= _irom0_text_end)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Return 1 if the given pointer is a rotable */
|
||||||
|
#define luaR_isrotable(p) IN_RODATA_AREA(p)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,16 +80,12 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUA_CROSS_COMPILER
|
static int lua_is_ptr_in_ro_area(const char *p) {
|
||||||
#define IN_RO_AREA(p) (0)
|
#ifdef LUA_CROSS_COMPILER
|
||||||
#else /* xtensa tool chain for ESP */
|
return 0; // TStrings are never in RO in luac.cross
|
||||||
extern char _irom0_text_start[];
|
#else
|
||||||
extern char _irom0_text_end[];
|
return IN_RODATA_AREA(p);
|
||||||
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int lua_is_ptr_in_ro_area(const char *p) {
|
|
||||||
return IN_RO_AREA(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#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))
|
||||||
|
|
|
@ -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_findentry(t, NULL, key, NULL);
|
const TValue *res = luaR_findentryN(t, key, NULL);
|
||||||
return res ? res : luaO_nilobject;
|
return res ? res : luaO_nilobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,14 +599,10 @@ const TValue *luaH_getstr (Table *t, TString *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* same thing for rotables */
|
/* same thing for rotables */
|
||||||
const TValue *luaH_getstr_ro (void *t, TString *key) {
|
const TValue *luaH_getstr_ro (void *t, TString *key) {
|
||||||
char keyname[LUA_MAX_ROTABLE_NAME + 1];
|
if (!t || key->tsv.len>LUA_MAX_ROTABLE_NAME)
|
||||||
const TValue *res;
|
|
||||||
if (!t)
|
|
||||||
return luaO_nilobject;
|
return luaO_nilobject;
|
||||||
luaR_getcstr(keyname, key, LUA_MAX_ROTABLE_NAME);
|
return luaR_findentry(t, key, NULL);
|
||||||
res = luaR_findentry(t, keyname, 0, NULL);
|
|
||||||
return res ? res : luaO_nilobject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -745,7 +741,7 @@ int luaH_getn (Table *t) {
|
||||||
int luaH_getn_ro (void *t) {
|
int luaH_getn_ro (void *t) {
|
||||||
int i = 1, len=0;
|
int i = 1, len=0;
|
||||||
|
|
||||||
while(luaR_findentry(t, NULL, i ++, NULL))
|
while(luaR_findentryN(t, i ++, NULL))
|
||||||
len ++;
|
len ++;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#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))
|
||||||
|
|
|
@ -50,14 +50,22 @@ void luaT_init (lua_State *L) {
|
||||||
** tag methods
|
** tag methods
|
||||||
*/
|
*/
|
||||||
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
|
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
|
||||||
const TValue *tm = luaR_isrotable(events) ? luaH_getstr_ro(events, ename) : luaH_getstr(events, ename);
|
const TValue *tm;
|
||||||
lua_assert(event <= TM_EQ);
|
lua_assert(event <= TM_EQ);
|
||||||
if (ttisnil(tm)) { /* no tag method? */
|
|
||||||
if (!luaR_isrotable(events))
|
if (luaR_isrotable(events)) {
|
||||||
|
tm = luaH_getstr_ro(events, ename);
|
||||||
|
if (ttisnil(tm)) { /* no tag method? */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tm = luaH_getstr(events, ename);
|
||||||
|
if (ttisnil(tm)) { /* no tag method? */
|
||||||
events->flags |= cast_byte(1u<<event); /* cache this fact */
|
events->flags |= cast_byte(1u<<event); /* cache this fact */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else return tm;
|
}
|
||||||
|
return tm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
|
#include "lrotable.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WARNING: if you change the order of this enumeration,
|
* WARNING: if you change the order of this enumeration,
|
||||||
|
@ -36,12 +36,10 @@ typedef enum {
|
||||||
TM_N /* number of elements in the enum */
|
TM_N /* number of elements in the enum */
|
||||||
} TMS;
|
} TMS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
|
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
|
||||||
!luaR_isrotable(et) && ((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)
|
#define fasttm(l,et,e) gfasttm(G(l), et, e)
|
||||||
|
|
||||||
LUAI_DATA const char *const luaT_typenames[];
|
LUAI_DATA const char *const luaT_typenames[];
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ TARGET = host
|
||||||
ifeq ($(FLAVOR),debug)
|
ifeq ($(FLAVOR),debug)
|
||||||
CCFLAGS += -O0 -g
|
CCFLAGS += -O0 -g
|
||||||
TARGET_LDFLAGS += -O0 -g
|
TARGET_LDFLAGS += -O0 -g
|
||||||
|
DEFINES += -DLUA_DEBUG_BUILD
|
||||||
else
|
else
|
||||||
FLAVOR = release
|
FLAVOR = release
|
||||||
CCFLAGS += -O2
|
CCFLAGS += -O2
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#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
|
||||||
|
@ -28,7 +27,11 @@
|
||||||
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
|
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
|
||||||
|
|
||||||
/* "Pseudo-random" keys for the registry */
|
/* "Pseudo-random" keys for the registry */
|
||||||
static const size_t liolib_keys[] = {(size_t)&luaL_callmeta, (size_t)&luaL_typerror, (size_t)&luaL_argerror};
|
static const size_t liolib_keys[] = {
|
||||||
|
(size_t)&luaL_callmeta,
|
||||||
|
(size_t)&luaL_typerror,
|
||||||
|
(size_t)&luaL_argerror
|
||||||
|
};
|
||||||
|
|
||||||
static const char *const fnames[] = {"input", "output"};
|
static const char *const fnames[] = {"input", "output"};
|
||||||
|
|
||||||
|
@ -452,20 +455,6 @@ const LUA_REG_TYPE iolib_funcs[] = {
|
||||||
{LNILKEY, LNILVAL}
|
{LNILKEY, LNILVAL}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Note that IO objects use a RAM metatable created to allow extensibility */
|
|
||||||
|
|
||||||
static int io_index(lua_State *L)
|
|
||||||
{
|
|
||||||
return luaR_findfunction(L, iolib_funcs);
|
|
||||||
}
|
|
||||||
|
|
||||||
const luaL_Reg iolib[] = {
|
|
||||||
{"__index", io_index},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef MIN_OPT_LEVEL
|
|
||||||
#define MIN_OPT_LEVEL 1
|
|
||||||
#include "lrodefs.h"
|
#include "lrodefs.h"
|
||||||
const LUA_REG_TYPE flib[] = {
|
const LUA_REG_TYPE flib[] = {
|
||||||
{LSTRKEY("close"), LFUNCVAL(io_close)},
|
{LSTRKEY("close"), LFUNCVAL(io_close)},
|
||||||
|
@ -481,6 +470,7 @@ const LUA_REG_TYPE flib[] = {
|
||||||
{LNILKEY, LNILVAL}
|
{LNILKEY, LNILVAL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg io_base[] = {{NULL, NULL}};
|
||||||
|
|
||||||
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
|
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
|
||||||
*newfile(L) = f;
|
*newfile(L) = f;
|
||||||
|
@ -490,14 +480,18 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
|
||||||
lua_setfield(L, -2, fname);
|
lua_setfield(L, -2, 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, (void*) flib); /* create metatable for file handles */
|
||||||
luaL_register_light(L, LUA_IOLIBNAME, iolib);
|
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_pushrotable(L, (void *)iolib_funcs);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
|
||||||
/* create (and set) default files */
|
/* create (and set) default files */
|
||||||
createstdfile(L, stdin, IO_INPUT, "stdin");
|
createstdfile(L, stdin, IO_INPUT, "stdin");
|
||||||
createstdfile(L, stdout, IO_OUTPUT, "stdout");
|
createstdfile(L, stdout, IO_OUTPUT, "stdout");
|
||||||
createstdfile(L, stderr, 0, "stderr");
|
createstdfile(L, stderr, IO_STDERR, "stderr");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#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 */
|
||||||
|
|
|
@ -896,13 +896,6 @@ 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 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)
|
|
||||||
*/
|
|
||||||
#if (LUA_OPTIMIZE_MEMORY == 2)
|
|
||||||
#define LUA_META_ROTABLES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LUA_OPTIMIZE_MEMORY == 2 && defined(LUA_USE_POPEN)
|
#if LUA_OPTIMIZE_MEMORY == 2 && defined(LUA_USE_POPEN)
|
||||||
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)"
|
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -130,18 +130,29 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
||||||
TValue temp;
|
TValue temp;
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
const TValue *tm;
|
const TValue *tm;
|
||||||
if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */
|
|
||||||
void *h = ttistable(t) ? hvalue(t) : rvalue(t);
|
if (ttistable(t)) { /* `t' is a table? */
|
||||||
const TValue *res = ttistable(t) ? luaH_get((Table*)h, key) : luaH_get_ro(h, key); /* do a primitive get */
|
Table *h = hvalue(t);
|
||||||
|
const TValue *res = luaH_get(h, key); /* do a primitive get */
|
||||||
if (!ttisnil(res) || /* result is no nil? */
|
if (!ttisnil(res) || /* result is no nil? */
|
||||||
(tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
|
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
|
||||||
setobj2s(L, val, res);
|
setobj2s(L, val, res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* else will try the tag method */
|
||||||
|
} else if (ttisrotable(t)) { /* `t' is a table? */
|
||||||
|
void *h = rvalue(t);
|
||||||
|
const TValue *res = luaH_get_ro(h, key); /* do a primitive get */
|
||||||
|
if (!ttisnil(res) || /* result is no nil? */
|
||||||
|
(tm = fasttm(L, (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
|
||||||
|
setobj2s(L, val, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* else will try the tag method */
|
/* else will try the tag method */
|
||||||
}
|
}
|
||||||
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
|
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
|
||||||
luaG_typeerror(L, t, "index");
|
luaG_typeerror(L, t, "index");
|
||||||
|
|
||||||
if (ttisfunction(tm) || ttislightfunction(tm)) {
|
if (ttisfunction(tm) || ttislightfunction(tm)) {
|
||||||
callTMres(L, val, tm, t, key);
|
callTMres(L, val, tm, t, key);
|
||||||
return;
|
return;
|
||||||
|
@ -161,25 +172,27 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
||||||
L->top++;
|
L->top++;
|
||||||
fixedstack(L);
|
fixedstack(L);
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
const TValue *tm;
|
const TValue *tm = NULL;
|
||||||
if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */
|
if (ttistable(t)) { /* `t' is a table? */
|
||||||
void *h = ttistable(t) ? hvalue(t) : rvalue(t);
|
Table *h = hvalue(t);
|
||||||
TValue *oldval = ttistable(t) ? luaH_set(L, (Table*)h, key) : NULL; /* do a primitive set */
|
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
|
||||||
if ((oldval && !ttisnil(oldval)) || /* result is no nil? */
|
if ((!ttisnil(oldval)) || /* result is no nil? */
|
||||||
(tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */
|
(tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) {
|
||||||
if(oldval) {
|
L->top--;
|
||||||
L->top--;
|
unfixedstack(L);
|
||||||
unfixedstack(L);
|
setobj2t(L, oldval, val);
|
||||||
setobj2t(L, oldval, val);
|
((Table *)h)->flags = 0;
|
||||||
((Table *)h)->flags = 0;
|
luaC_barriert(L, (Table*)h, val);
|
||||||
luaC_barriert(L, (Table*)h, val);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else will try the tag method */
|
/* else will try the tag method */
|
||||||
}
|
}
|
||||||
|
else if (ttisrotable(t)) {
|
||||||
|
luaG_runerror(L, "invalid write to ROM variable");
|
||||||
|
}
|
||||||
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
|
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
|
||||||
luaG_typeerror(L, t, "index");
|
luaG_typeerror(L, t, "index");
|
||||||
|
|
||||||
if (ttisfunction(tm) || ttislightfunction(tm)) {
|
if (ttisfunction(tm) || ttislightfunction(tm)) {
|
||||||
L->top--;
|
L->top--;
|
||||||
unfixedstack(L);
|
unfixedstack(L);
|
||||||
|
@ -294,7 +307,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
|
||||||
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
|
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
|
||||||
case LUA_TROTABLE:
|
case LUA_TROTABLE:
|
||||||
return rvalue(t1) == rvalue(t2);
|
return rvalue(t1) == rvalue(t2);
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
case LUA_TLIGHTFUNCTION:
|
case LUA_TLIGHTFUNCTION:
|
||||||
return pvalue(t1) == pvalue(t2);
|
return pvalue(t1) == pvalue(t2);
|
||||||
case LUA_TUSERDATA: {
|
case LUA_TUSERDATA: {
|
||||||
|
@ -321,7 +334,7 @@ void luaV_concat (lua_State *L, int total, int last) {
|
||||||
if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit;
|
if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit;
|
||||||
do {
|
do {
|
||||||
/* Any call which does a memory allocation may trim the stack,
|
/* Any call which does a memory allocation may trim the stack,
|
||||||
invalidating top unless the stack is fixed duri ng the allocation */
|
invalidating top unless the stack is fixed during the allocation */
|
||||||
StkId top = L->base + last + 1;
|
StkId top = L->base + last + 1;
|
||||||
fixedstack(L);
|
fixedstack(L);
|
||||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||||
|
@ -570,7 +583,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
||||||
case OP_LEN: {
|
case OP_LEN: {
|
||||||
const TValue *rb = RB(i);
|
const TValue *rb = RB(i);
|
||||||
switch (ttype(rb)) {
|
switch (ttype(rb)) {
|
||||||
case LUA_TTABLE:
|
case LUA_TTABLE:
|
||||||
case LUA_TROTABLE: {
|
case LUA_TROTABLE: {
|
||||||
setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb))));
|
setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb))));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -570,9 +570,9 @@ static int packet_map_lookup(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now search the packet function map
|
// Now search the packet function map
|
||||||
const TValue *res = luaR_findentry((void *) packet_function_map, field, 0, NULL);
|
lua_pushrotable(L, (void *)packet_function_map);
|
||||||
if (res) {
|
lua_getfield(L, -1, field);
|
||||||
luaA_pushobject(L, res);
|
if (!lua_isnil(L, -1)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,20 +131,20 @@ int main(int argc, char *argv[]) {
|
||||||
assert(sizeof(unsigned int) == 4);
|
assert(sizeof(unsigned int) == 4);
|
||||||
|
|
||||||
/* allocate and zero the in and out Blocks */
|
/* allocate and zero the in and out Blocks */
|
||||||
assert(in = uz_malloc(sizeof(*in)));
|
assert((in = uz_malloc(sizeof(*in))) != NULL);
|
||||||
assert(out = uz_malloc(sizeof(*out)));
|
assert((out = uz_malloc(sizeof(*out))) != NULL);
|
||||||
|
|
||||||
memset(in, 0, sizeof(*in));
|
memset(in, 0, sizeof(*in));
|
||||||
memset(out, 0, sizeof(*out));
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
/* open input files and probe end to read the expanded length */
|
/* open input files and probe end to read the expanded length */
|
||||||
assert((in->fin = fopen(inFile, "rb")));
|
assert((in->fin = fopen(inFile, "rb")) != NULL);
|
||||||
fseek(in->fin, -4, SEEK_END);
|
fseek(in->fin, -4, SEEK_END);
|
||||||
assert(fread((uchar*)&(out->len), 1, 4, in->fin) == 4);
|
assert(fread((uchar*)&(out->len), 1, 4, in->fin) == 4);
|
||||||
in->len = ftell(in->fin);
|
in->len = ftell(in->fin);
|
||||||
fseek(in->fin, 0, SEEK_SET);
|
fseek(in->fin, 0, SEEK_SET);
|
||||||
|
|
||||||
assert((out->fout = fopen(outFile, "wb")));
|
assert((out->fout = fopen(outFile, "wb")) != NULL);
|
||||||
|
|
||||||
printf ("Inflating in=%s out=%s\n", inFile, outFile);
|
printf ("Inflating in=%s out=%s\n", inFile, outFile);
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ int main(int argc, char *argv[]) {
|
||||||
n = (out->len > DICTIONARY_WINDOW) ? WRITE_BLOCKS :
|
n = (out->len > DICTIONARY_WINDOW) ? WRITE_BLOCKS :
|
||||||
1 + (out->len-1) / WRITE_BLOCKSIZE;
|
1 + (out->len-1) / WRITE_BLOCKSIZE;
|
||||||
for(i = WRITE_BLOCKS - n + 1; i <= WRITE_BLOCKS; i++)
|
for(i = WRITE_BLOCKS - n + 1; i <= WRITE_BLOCKS; i++)
|
||||||
assert(out->block[i % WRITE_BLOCKS] = uz_malloc(sizeof(outBlock)));
|
assert((out->block[i % WRITE_BLOCKS] = uz_malloc(sizeof(outBlock))) != NULL);
|
||||||
|
|
||||||
out->breakNdx = (out->len < WRITE_BLOCKSIZE) ? out->len : WRITE_BLOCKSIZE;
|
out->breakNdx = (out->len < WRITE_BLOCKSIZE) ? out->len : WRITE_BLOCKSIZE;
|
||||||
out->fullBlkCB = processOutRec;
|
out->fullBlkCB = processOutRec;
|
||||||
|
|
Loading…
Reference in New Issue