Unverified Commit 310faf7f authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Merge pull request #2886 from nodemcu/dev

Next master drop
parents 68c425c0 a08e74d9
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#ifdef LUA_FLASH_STORE
#include "lobject.h" #include "lobject.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lstate.h" #include "lstate.h"
...@@ -18,10 +17,10 @@ ...@@ -18,10 +17,10 @@
#include "vfs.h" #include "vfs.h"
#include "uzlib.h" #include "uzlib.h"
#include "c_fcntl.h" #include <fcntl.h>
#include "c_stdio.h" #include <stdio.h>
#include "c_stdlib.h" #include <stdlib.h>
#include "c_string.h" #include <string.h>
/* /*
* Flash memory is a fixed memory addressable block that is serially allocated by the * Flash memory is a fixed memory addressable block that is serially allocated by the
...@@ -31,6 +30,7 @@ ...@@ -31,6 +30,7 @@
*/ */
static char *flashAddr; static char *flashAddr;
static uint32_t flashSize;
static uint32_t flashAddrPhys; static uint32_t flashAddrPhys;
static uint32_t flashSector; static uint32_t flashSector;
static uint32_t curOffset; static uint32_t curOffset;
...@@ -38,9 +38,8 @@ static uint32_t curOffset; ...@@ -38,9 +38,8 @@ static uint32_t curOffset;
#define ALIGN(s) (((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t)))) #define ALIGN(s) (((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t))))
#define ALIGN_BITS(s) (((uint32_t)s) & (sizeof(size_t)-1)) #define ALIGN_BITS(s) (((uint32_t)s) & (sizeof(size_t)-1))
#define ALL_SET (~0) #define ALL_SET (~0)
#define FLASH_SIZE LUA_FLASH_STORE
#define FLASH_PAGE_SIZE INTERNAL_FLASH_SECTOR_SIZE #define FLASH_PAGE_SIZE INTERNAL_FLASH_SECTOR_SIZE
#define FLASH_PAGES (FLASH_SIZE/FLASH_PAGE_SIZE) #define FLASH_PAGES (flashSize/FLASH_PAGE_SIZE)
#define READ_BLOCKSIZE 1024 #define READ_BLOCKSIZE 1024
#define WRITE_BLOCKSIZE 2048 #define WRITE_BLOCKSIZE 2048
#define DICTIONARY_WINDOW 16384 #define DICTIONARY_WINDOW 16384
...@@ -49,8 +48,6 @@ static uint32_t curOffset; ...@@ -49,8 +48,6 @@ static uint32_t curOffset;
#define WRITE_BLOCKS ((DICTIONARY_WINDOW/WRITE_BLOCKSIZE)+1) #define WRITE_BLOCKS ((DICTIONARY_WINDOW/WRITE_BLOCKSIZE)+1)
#define WRITE_BLOCK_WORDS (WRITE_BLOCKSIZE/WORDSIZE) #define WRITE_BLOCK_WORDS (WRITE_BLOCKSIZE/WORDSIZE)
char flash_region_base[FLASH_SIZE] ICACHE_FLASH_RESERVED_ATTR;
struct INPUT { struct INPUT {
int fd; int fd;
int len; int len;
...@@ -152,11 +149,16 @@ static void flashErase(uint32_t start, uint32_t end){ ...@@ -152,11 +149,16 @@ static void flashErase(uint32_t start, uint32_t end){
* Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed * Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed
*/ */
LUAI_FUNC void luaN_init (lua_State *L) { LUAI_FUNC void luaN_init (lua_State *L) {
curOffset = 0;
flashAddr = flash_region_base; flashSize = platform_flash_get_partition (NODEMCU_LFS0_PARTITION, &flashAddrPhys);
flashAddrPhys = platform_flash_mapped2phys((uint32_t)flashAddr); if (flashSize == 0) {
return; // Nothing to do if the size is zero
}
G(L)->LFSsize = flashSize;
flashAddr = cast(char *, platform_flash_phys2mapped(flashAddrPhys));
flashSector = platform_flash_get_sector_of_address(flashAddrPhys); flashSector = platform_flash_get_sector_of_address(flashAddrPhys);
FlashHeader *fh = cast(FlashHeader *, flashAddr); FlashHeader *fh = cast(FlashHeader *, flashAddr);
curOffset = 0;
/* /*
* For the LFS to be valid, its signature has to be correct for this build * For the LFS to be valid, its signature has to be correct for this build
...@@ -201,6 +203,13 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) { ...@@ -201,6 +203,13 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
// luaL_dbgbreak(); // luaL_dbgbreak();
const char *fn = lua_tostring(L, 1), *msg = ""; const char *fn = lua_tostring(L, 1), *msg = "";
int status; int status;
if (G(L)->LFSsize == 0) {
lua_pushstring(L, "No LFS partition allocated");
return 1;
}
/* /*
* Do a protected call of loadLFS. * Do a protected call of loadLFS.
* *
...@@ -264,13 +273,18 @@ LUAI_FUNC int luaN_index (lua_State *L) { ...@@ -264,13 +273,18 @@ LUAI_FUNC int luaN_index (lua_State *L) {
int i; int i;
int n = lua_gettop(L); int n = lua_gettop(L);
/* Return nil + the LFS base address if the LFS isn't loaded */ /* Return nil + the LFS base address if the LFS size > 0 and it isn't loaded */
if(!(G(L)->ROpvmain)) { if (!(G(L)->ROpvmain)) {
lua_settop(L, 0); lua_settop(L, 0);
lua_pushnil(L); lua_pushnil(L);
if (G(L)->LFSsize) {
lua_pushinteger(L, (lua_Integer) flashAddr); lua_pushinteger(L, (lua_Integer) flashAddr);
lua_pushinteger(L, flashAddrPhys); lua_pushinteger(L, flashAddrPhys);
return 3; lua_pushinteger(L, G(L)->LFSsize);
return 4;
} else {
return 1;
}
} }
/* Push the LClosure of the LFS index function */ /* Push the LClosure of the LFS index function */
...@@ -374,13 +388,13 @@ static void put_byte (uint8_t value) { ...@@ -374,13 +388,13 @@ static void put_byte (uint8_t value) {
} }
static uint8_t recall_byte (uint offset) { static uint8_t recall_byte (unsigned offset) {
if(offset > DICTIONARY_WINDOW || offset >= out->ndx) if(offset > DICTIONARY_WINDOW || offset >= out->ndx)
flash_error("invalid dictionary offset on inflate"); flash_error("invalid dictionary offset on inflate");
/* ndx starts at 1. Need relative to 0 */ /* ndx starts at 1. Need relative to 0 */
uint n = out->ndx - offset; unsigned n = out->ndx - offset;
uint pos = n % WRITE_BLOCKSIZE; unsigned pos = n % WRITE_BLOCKSIZE;
uint blockNo = out->ndx / WRITE_BLOCKSIZE - n / WRITE_BLOCKSIZE; unsigned blockNo = out->ndx / WRITE_BLOCKSIZE - n / WRITE_BLOCKSIZE;
return out->block[blockNo]->byte[pos]; return out->block[blockNo]->byte[pos];
} }
...@@ -409,13 +423,13 @@ int procFirstPass (void) { ...@@ -409,13 +423,13 @@ int procFirstPass (void) {
flash_error("Incorrect LFS build type"); flash_error("Incorrect LFS build type");
if ((fh->flash_sig & ~FLASH_SIG_ABSOLUTE) != FLASH_SIG) if ((fh->flash_sig & ~FLASH_SIG_ABSOLUTE) != FLASH_SIG)
flash_error("incorrect LFS header signature"); flash_error("incorrect LFS header signature");
if (fh->flash_size > FLASH_SIZE) if (fh->flash_size > flashSize)
flash_error("LFS Image too big for configured LFS region"); flash_error("LFS Image too big for configured LFS region");
if ((fh->flash_size & 0x3) || if ((fh->flash_size & 0x3) ||
fh->flash_size > FLASH_SIZE || fh->flash_size > flashSize ||
out->flagsLen != 1 + (out->flashLen/WORDSIZE - 1) / BITS_PER_WORD) out->flagsLen != 1 + (out->flashLen/WORDSIZE - 1) / BITS_PER_WORD)
flash_error("LFS length mismatch"); flash_error("LFS length mismatch");
out->flags = luaM_newvector(out->L, out->flagsLen, uint); out->flags = luaM_newvector(out->L, out->flagsLen, unsigned);
} }
/* update running CRC */ /* update running CRC */
...@@ -498,7 +512,7 @@ static int loadLFS (lua_State *L) { ...@@ -498,7 +512,7 @@ static int loadLFS (lua_State *L) {
in->len = vfs_size(in->fd); in->len = vfs_size(in->fd);
if (in->len <= 200 || /* size of an empty luac output */ if (in->len <= 200 || /* size of an empty luac output */
vfs_lseek(in->fd, in->len-4, VFS_SEEK_SET) != in->len-4 || vfs_lseek(in->fd, in->len-4, VFS_SEEK_SET) != in->len-4 ||
vfs_read(in->fd, &out->len, sizeof(uint)) != sizeof(uint)) vfs_read(in->fd, &out->len, sizeof(unsigned)) != sizeof(unsigned))
flash_error("read error on LFS image file"); flash_error("read error on LFS image file");
vfs_lseek(in->fd, 0, VFS_SEEK_SET); vfs_lseek(in->fd, 0, VFS_SEEK_SET);
...@@ -557,4 +571,3 @@ static int loadLFSgc (lua_State *L) { ...@@ -557,4 +571,3 @@ static int loadLFSgc (lua_State *L) {
} }
return 0; return 0;
} }
#endif
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
#if defined(LUA_FLASH_STORE) && !defined(lflash_h) #ifndef lflash_h
#define lflash_h #define lflash_h
#include "lobject.h" #include "lobject.h"
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STRING #include <string.h>
#include "lfunc.h" #include "lfunc.h"
#include "lgc.h" #include "lgc.h"
...@@ -150,7 +150,7 @@ void luaF_freeproto (lua_State *L, Proto *f) { ...@@ -150,7 +150,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->code, f->sizecode, Instruction); luaM_freearray(L, f->code, f->sizecode, Instruction);
#ifdef LUA_OPTIMIZE_DEBUG #ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo) { if (f->packedlineinfo) {
luaM_freearray(L, f->packedlineinfo, c_strlen(cast(char *, f->packedlineinfo))+1, unsigned char); luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo))+1, unsigned char);
} }
#else #else
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STRING #include <string.h>
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h" #include "ldo.h"
...@@ -28,10 +28,6 @@ ...@@ -28,10 +28,6 @@
#define GCSWEEPCOST 10 #define GCSWEEPCOST 10
#define GCFINALIZECOST 100 #define GCFINALIZECOST 100
#if READONLYMASK != (1<<READONLYBIT) || (defined(LUA_FLASH_STORE) && LFSMASK != (1<<LFSBIT))
#error "lgc.h and object.h out of sync on READONLYMASK / LFSMASK"
#endif
#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) #define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
#define makewhite(g,x) \ #define makewhite(g,x) \
...@@ -177,8 +173,8 @@ static int traversetable (global_State *g, Table *h) { ...@@ -177,8 +173,8 @@ static int traversetable (global_State *g, Table *h) {
} }
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 = (strchr(svalue(mode), 'k') != NULL);
weakvalue = (c_strchr(svalue(mode), 'v') != NULL); weakvalue = (strchr(svalue(mode), 'v') != NULL);
if (weakkey || weakvalue) { /* is really weak? */ if (weakkey || weakvalue) { /* is really weak? */
h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
h->marked |= cast_byte((weakkey << KEYWEAKBIT) | h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
...@@ -337,7 +333,7 @@ static l_mem propagatemark (global_State *g) { ...@@ -337,7 +333,7 @@ static l_mem propagatemark (global_State *g) {
(proto_isreadonly(p) ? 0 : sizeof(Instruction) * p->sizecode + (proto_isreadonly(p) ? 0 : sizeof(Instruction) * p->sizecode +
#ifdef LUA_OPTIMIZE_DEBUG #ifdef LUA_OPTIMIZE_DEBUG
(p->packedlineinfo ? (p->packedlineinfo ?
c_strlen(cast(char *, p->packedlineinfo))+1 : strlen(cast(char *, p->packedlineinfo))+1 :
0)); 0));
#else #else
sizeof(int) * p->sizelineinfo); sizeof(int) * p->sizelineinfo);
......
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
#define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT) #define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT)
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT) #define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
#define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT) #define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT)
#ifdef LUA_FLASH_STORE #ifndef LUA_CROSS_COMPILER
#define isLFSobject(x) testbit(getmarked(x), LFSBIT) #define isLFSobject(x) testbit(getmarked(x), LFSBIT)
#define stringfix(s) if (!test2bits(getmarked(&(s)->tsv), FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);} #define stringfix(s) if (!test2bits(getmarked(&(s)->tsv), FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#else #else
......
...@@ -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
} }
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_CTYPE #include <ctype.h>
#include C_HEADER_LOCALE #include <locale.h>
#include C_HEADER_STRING #include <string.h>
#include "ldo.h" #include "ldo.h"
#include "llex.h" #include "llex.h"
...@@ -154,7 +154,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { ...@@ -154,7 +154,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
static int check_next (LexState *ls, const char *set) { static int check_next (LexState *ls, const char *set) {
if (!c_strchr(set, ls->current)) if (!strchr(set, ls->current))
return 0; return 0;
save_and_next(ls); save_and_next(ls);
return 1; return 1;
...@@ -422,7 +422,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { ...@@ -422,7 +422,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
/* look for reserved word */ /* look for reserved word */
save(ls, '\0'); save(ls, '\0');
for (i = 0; i < NUM_RESERVED; i++) for (i = 0; i < NUM_RESERVED; i++)
if (!c_strcmp(luaX_tokens[i], luaZ_buffer(ls->buff))) if (!strcmp(luaX_tokens[i], luaZ_buffer(ls->buff)))
return i + FIRST_RESERVED; return i + FIRST_RESERVED;
ts = luaX_newstring(ls, luaZ_buffer(ls->buff), ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff) - 1); luaZ_bufflen(ls->buff) - 1);
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
#define llimits_h #define llimits_h
//#include "c_limits.h"
#include "lua.h" #include "lua.h"
typedef LUAI_UINT32 lu_int32; typedef LUAI_UINT32 lu_int32;
......
...@@ -10,11 +10,12 @@ ...@@ -10,11 +10,12 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STDLIB #include <stdlib.h>
#include C_HEADER_MATH #include <math.h>
#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
} }
...@@ -8,12 +8,6 @@ ...@@ -8,12 +8,6 @@
#define lmem_h #define lmem_h
//#ifdef LUA_CROSS_COMPILER
//#include <stddef.h>
//#else
//#include "c_stddef.h"
//#endif
#include "llimits.h" #include "llimits.h"
#include "lua.h" #include "lua.h"
......
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STDLIB #include <stdlib.h>
#include C_HEADER_STRING #include <string.h>
#include C_HEADER_FCNTL #include <fcntl.h>
#ifndef LUA_CROSS_COMPILER #ifndef LUA_CROSS_COMPILER
#include "vfs.h" #include "vfs.h"
...@@ -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_"
...@@ -102,7 +103,7 @@ static void setprogdir (lua_State *L) { ...@@ -102,7 +103,7 @@ static void setprogdir (lua_State *L) {
char *lb; char *lb;
DWORD nsize = sizeof(buff)/sizeof(char); DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = c_strrchr(buff, '\\')) == NULL) if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName"); luaL_error(L, "unable to get ModuleFileName");
else { else {
*lb = '\0'; *lb = '\0';
...@@ -332,9 +333,9 @@ static int ll_loadlib (lua_State *L) { ...@@ -332,9 +333,9 @@ static int ll_loadlib (lua_State *L) {
*/ */
#ifdef LUA_CROSS_COMPILER #ifdef LUA_CROSS_COMPILER
static int readable (const char *filename) { static int readable (const char *filename) {
FILE *f = c_fopen(filename, "r"); /* try to open file */ FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL) return 0; /* open failed */ if (f == NULL) return 0; /* open failed */
c_fclose(f); fclose(f);
return 1; return 1;
} }
#else #else
...@@ -350,8 +351,8 @@ static const char * pushnexttemplate (lua_State *L, const char *path) { ...@@ -350,8 +351,8 @@ static const char * pushnexttemplate (lua_State *L, const char *path) {
const char *l; const char *l;
while (*path == *LUA_PATHSEP) path++; /* skip separators */ while (*path == *LUA_PATHSEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */ if (*path == '\0') return NULL; /* no more templates */
l = c_strchr(path, *LUA_PATHSEP); /* find next separator */ l = strchr(path, *LUA_PATHSEP); /* find next separator */
if (l == NULL) l = path + c_strlen(path); if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */ lua_pushlstring(L, path, l - path); /* template */
return l; return l;
} }
...@@ -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);
...@@ -403,7 +406,7 @@ static int loader_Lua (lua_State *L) { ...@@ -403,7 +406,7 @@ static int loader_Lua (lua_State *L) {
static const char *mkfuncname (lua_State *L, const char *modname) { static const char *mkfuncname (lua_State *L, const char *modname) {
const char *funcname; const char *funcname;
const char *mark = c_strchr(modname, *LUA_IGMARK); const char *mark = strchr(modname, *LUA_IGMARK);
if (mark) modname = mark + 1; if (mark) modname = mark + 1;
funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
funcname = lua_pushfstring(L, POF"%s", funcname); funcname = lua_pushfstring(L, POF"%s", funcname);
...@@ -428,7 +431,7 @@ static int loader_Croot (lua_State *L) { ...@@ -428,7 +431,7 @@ static int loader_Croot (lua_State *L) {
const char *funcname; const char *funcname;
const char *filename; const char *filename;
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
const char *p = c_strchr(name, '.'); const char *p = strchr(name, '.');
int stat; int stat;
if (p == NULL) return 0; /* is root */ if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name); lua_pushlstring(L, name, p - name);
...@@ -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 */
...@@ -552,7 +559,7 @@ static void modinit (lua_State *L, const char *modname) { ...@@ -552,7 +559,7 @@ static void modinit (lua_State *L, const char *modname) {
lua_setfield(L, -2, "_M"); /* module._M = module */ lua_setfield(L, -2, "_M"); /* module._M = module */
lua_pushstring(L, modname); lua_pushstring(L, modname);
lua_setfield(L, -2, "_NAME"); lua_setfield(L, -2, "_NAME");
dot = c_strrchr(modname, '.'); /* look for last dot in module name */ dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL) dot = modname; if (dot == NULL) dot = modname;
else dot++; else dot++;
/* set _PACKAGE as package name (full module name minus last part) */ /* set _PACKAGE as package name (full module name minus last part) */
...@@ -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 */
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STDIO #include <stdio.h>
#include C_HEADER_STRING #include <string.h>
#include C_HEADER_STDLIB #include <stdlib.h>
#include "ldo.h" #include "ldo.h"
#include "lmem.h" #include "lmem.h"
...@@ -116,7 +116,7 @@ int luaO_str2d (const char *s, lua_Number *result) { ...@@ -116,7 +116,7 @@ int luaO_str2d (const char *s, lua_Number *result) {
*result = cast_num(lres); *result = cast_num(lres);
} }
#else #else
*result = cast_num(c_strtoul(s, &endptr, 16)); *result = cast_num(strtoul(s, &endptr, 16));
#endif #endif
if (*endptr == '\0') return 1; /* most common case */ if (*endptr == '\0') return 1; /* most common case */
while (isspace(cast(unsigned char, *endptr))) endptr++; while (isspace(cast(unsigned char, *endptr))) endptr++;
...@@ -137,7 +137,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { ...@@ -137,7 +137,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 1; int n = 1;
pushstr(L, ""); pushstr(L, "");
for (;;) { for (;;) {
const char *e = c_strchr(fmt, '%'); const char *e = strchr(fmt, '%');
if (e == NULL) break; if (e == NULL) break;
setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
incr_top(L); incr_top(L);
...@@ -167,7 +167,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { ...@@ -167,7 +167,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
} }
case 'p': { case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
c_sprintf(buff, "%p", va_arg(argp, void *)); sprintf(buff, "%p", va_arg(argp, void *));
pushstr(L, buff); pushstr(L, buff);
break; break;
} }
...@@ -206,7 +206,7 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { ...@@ -206,7 +206,7 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
void luaO_chunkid (char *out, const char *source, size_t bufflen) { void luaO_chunkid (char *out, const char *source, size_t bufflen) {
if (*source == '=') { if (*source == '=') {
c_strncpy(out, source+1, bufflen); /* remove first char */ strncpy(out, source+1, bufflen); /* remove first char */
out[bufflen-1] = '\0'; /* ensures null termination */ out[bufflen-1] = '\0'; /* ensures null termination */
} }
else { /* out = "source", or "...source" */ else { /* out = "source", or "...source" */
...@@ -214,26 +214,26 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) { ...@@ -214,26 +214,26 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) {
size_t l; size_t l;
source++; /* skip the `@' */ source++; /* skip the `@' */
bufflen -= sizeof(" '...' "); bufflen -= sizeof(" '...' ");
l = c_strlen(source); l = strlen(source);
c_strcpy(out, ""); strcpy(out, "");
if (l > bufflen) { if (l > bufflen) {
source += (l-bufflen); /* get last part of file name */ source += (l-bufflen); /* get last part of file name */
c_strcat(out, "..."); strcat(out, "...");
} }
c_strcat(out, source); strcat(out, source);
} }
else { /* out = [string "string"] */ else { /* out = [string "string"] */
size_t len = c_strcspn(source, "\n\r"); /* stop at first newline */ size_t len = strcspn(source, "\n\r"); /* stop at first newline */
bufflen -= sizeof(" [string \"...\"] "); bufflen -= sizeof(" [string \"...\"] ");
if (len > bufflen) len = bufflen; if (len > bufflen) len = bufflen;
c_strcpy(out, "[string \""); strcpy(out, "[string \"");
if (source[len] != '\0') { /* must truncate? */ if (source[len] != '\0') { /* must truncate? */
c_strncat(out, source, len); strncat(out, source, len);
c_strcat(out, "..."); strcat(out, "...");
} }
else else
c_strcat(out, source); strcat(out, source);
c_strcat(out, "\"]"); strcat(out, "\"]");
} }
} }
} }
...@@ -8,11 +8,7 @@ ...@@ -8,11 +8,7 @@
#ifndef lobject_h #ifndef lobject_h
#define lobject_h #define lobject_h
#ifdef LUA_CROSS_COMPILER
#include <stdarg.h> #include <stdarg.h>
#else
#include "c_stdarg.h"
#endif
#include "llimits.h" #include "llimits.h"
#include "lua.h" #include "lua.h"
...@@ -24,9 +20,7 @@ ...@@ -24,9 +20,7 @@
#define NUM_TAGS (LAST_TAG+1) #define NUM_TAGS (LAST_TAG+1)
#define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */ #define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
#ifdef LUA_FLASH_STORE
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */ #define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
#endif
/* /*
** Extra tags for non-values ** Extra tags for non-values
*/ */
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STRING #include <string.h>
#include "lcode.h" #include "lcode.h"
#include "ldebug.h" #include "ldebug.h"
......
...@@ -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 */
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STRING #include <string.h>
#include "lrotable.h" #include "lrotable.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lstring.h" #include "lstring.h"
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
#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,13 +37,15 @@ ...@@ -36,13 +37,15 @@
* 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) (unsigned)((((519*(size_t)(a)))>>4) + ((b) ? (b)->tsv.hash: 0))
static struct { typedef struct {
unsigned hash; unsigned hash;
unsigned addr:24; unsigned addr:24;
unsigned ndx:8; unsigned ndx:8;
} cache[LA_LINES][LA_SLOTS]; } cache_line_t;
static cache_line_t cache [LA_LINES][LA_SLOTS];
#ifdef COLLECT_STATS #ifdef COLLECT_STATS
unsigned cache_stats[3]; unsigned cache_stats[3];
...@@ -55,10 +58,10 @@ static int lookup_cache(unsigned hash, ROTable *rotable) { ...@@ -55,10 +58,10 @@ static int lookup_cache(unsigned hash, ROTable *rotable) {
int i = (hash>>2) & (LA_LINES-1), j; int i = (hash>>2) & (LA_LINES-1), j;
for (j = 0; j<LA_SLOTS; j++) { for (j = 0; j<LA_SLOTS; j++) {
if (cache[i][j].hash == hash && cache_line_t cl = cache[i][j];
((size_t)rotable & 0xffffffu) == cache[i][j].addr) { if (cl.hash == hash && ((size_t)rotable & 0xffffffu) == cl.addr) {
COUNT(0); COUNT(0);
return cache[i][j].ndx; return cl.ndx;
} }
} }
COUNT(1); COUNT(1);
...@@ -67,14 +70,21 @@ static int lookup_cache(unsigned hash, ROTable *rotable) { ...@@ -67,14 +70,21 @@ static int lookup_cache(unsigned hash, ROTable *rotable) {
static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) { static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) {
int i = (hash)>>2 & (LA_LINES-1), j; int i = (hash)>>2 & (LA_LINES-1), j;
#ifndef _MSC_VER
cache_line_t cl = {hash, (size_t) rotable, ndx};
#else
cache_line_t cl; // MSC doesn't allow non-scalar initialisers, which
cl.hash = hash; // is a pity because xtensa gcc generates optimum
cl.addr = (size_t) rotable; // code using them.
cl.ndx = ndx;
#endif
COUNT(2); COUNT(2);
if (ndx>0xffu) if (ndx>0xffu)
return; return;
for (j = LA_SLOTS-1; j>0; j--) for (j = LA_SLOTS-1; j>0; j--)
cache[i][j] = cache[i][j-1]; cache[i][j] = cache[i][j-1];
cache[i][0].hash = hash; cache[i][0] = cl;
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 * Find a string key entry in a rotable and return it. Note that this internally
...@@ -83,62 +93,43 @@ static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) { ...@@ -83,62 +93,43 @@ 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 && !strcmp(pentry[j].key, strkey)) {
if ((pentry[j].key.type == LUA_TSTRING) &&
!c_strcmp(pentry[j].key.id.strkey, strkey)) {
if (ppos) if (ppos)
*ppos = j; *ppos = j;
//dbg_printf("%3d hit %p %s\n", (hash>>2) & (LA_LINES-1), rotable, strkey);
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
* aren't needed if there is a cache hit. Note that the termination null * 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. * is included so a "on\0" has a mask of 0xFFFFFF and "a\0" has 0xFFFF.
*/ */
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)); 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 && !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);
} else if (j != (pentry - rotable)) { //dbg_printf("%3d %3d %p %s\n", (hash>>2) & (LA_LINES-1), (int)(pentry-rotable), rotable, strkey);
j = 0;
}
return &pentry->value; 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 +138,13 @@ void* luaR_getmeta(ROTable *rotable) { ...@@ -147,15 +138,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))
else
setnvalue(key, (lua_Number)pentries[pos].key.id.numkey)
setobj2s(L, val, &pentries[pos].value); setobj2s(L, val, &pentries[pos].value);
} else {
setnilvalue(key);
setnilvalue(val);
} }
} }
...@@ -167,12 +156,10 @@ void luaR_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val) { ...@@ -167,12 +156,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;
......
...@@ -73,7 +73,7 @@ static void f_luaopen (lua_State *L, void *ud) { ...@@ -73,7 +73,7 @@ static void f_luaopen (lua_State *L, void *ud) {
sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER) #ifndef LUA_CROSS_COMPILER
luaN_init(L); /* optionally map RO string table */ luaN_init(L); /* optionally map RO string table */
#endif #endif
luaT_init(L); luaT_init(L);
...@@ -196,11 +196,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { ...@@ -196,11 +196,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
#else #else
g->memlimit = 0; g->memlimit = 0;
#endif #endif
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER) #ifndef LUA_CROSS_COMPILER
g->ROstrt.size = 0; g->ROstrt.size = 0;
g->ROstrt.nuse = 0; g->ROstrt.nuse = 0;
g->ROstrt.hash = NULL; g->ROstrt.hash = NULL;
g->ROpvmain = NULL; g->ROpvmain = NULL;
g->LFSsize = 0;
#endif #endif
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
......
...@@ -94,9 +94,10 @@ typedef struct global_State { ...@@ -94,9 +94,10 @@ typedef struct global_State {
UpVal uvhead; /* head of double-linked list of all open upvalues */ UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */ struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */ TString *tmname[TM_N]; /* array with tag-method names */
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER) #ifndef LUA_CROSS_COMPILER
stringtable ROstrt; /* Flash-based hash table for RO strings */ stringtable ROstrt; /* Flash-based hash table for RO strings */
Proto *ROpvmain; /* Flash-based Proto main */ Proto *ROpvmain; /* Flash-based Proto main */
int LFSsize; /* Size of Lua Flash Store */
#endif #endif
} global_State; } global_State;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_STRING #include <string.h>
#include "lmem.h" #include "lmem.h"
#include "lobject.h" #include "lobject.h"
...@@ -67,7 +67,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, ...@@ -67,7 +67,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
ts->tsv.marked = luaC_white(G(L)); ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING; ts->tsv.tt = LUA_TSTRING;
if (!readonly) { if (!readonly) {
c_memcpy(ts+1, str, l*sizeof(char)); memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else { } else {
*(char **)(ts+1) = (char *)str; *(char **)(ts+1) = (char *)str;
...@@ -106,13 +106,13 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { ...@@ -106,13 +106,13 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
o != NULL; o != NULL;
o = o->gch.next) { o = o->gch.next) {
TString *ts = rawgco2ts(o); TString *ts = rawgco2ts(o);
if (ts->tsv.len == l && (c_memcmp(str, getstr(ts), l) == 0)) { if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
/* string may be dead */ /* string may be dead */
if (isdead(G(L), o)) changewhite(o); if (isdead(G(L), o)) changewhite(o);
return ts; return ts;
} }
} }
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER) #ifndef LUA_CROSS_COMPILER
/* /*
* The RAM strt is searched first since RAM access is faster tham Flash access. * The RAM strt is searched first since RAM access is faster tham Flash access.
* If a miss, then search the RO string table. * If a miss, then search the RO string table.
...@@ -131,7 +131,7 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { ...@@ -131,7 +131,7 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
/* New additions to the RAM strt are tagged as readonly if the string address /* New additions to the RAM strt are tagged as readonly if the string address
* is in the CTEXT segment (target only, not luac.cross) */ * is in the CTEXT segment (target only, not luac.cross) */
int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) && int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) &&
l == c_strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING); l == strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
return newlstr(L, str, l, h, readonly); /* not found */ return newlstr(L, str, l, h, readonly); /* not found */
} }
......
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