Commit 17df207a authored by Johny Mattsson's avatar Johny Mattsson
Browse files

Port Terry's Lua 5.1 + 5.3 work from the esp8266 branch.

Changes have been kept to a minimum, but a serious chunk of work was
needed to move from 8266isms to IDFisms.

Some things got refactored into components/lua/common, in particular
the LFS location awareness.

As part of this work I also evicted our partition table manipulation
code, as with the current IDF it kept breaking checksums and rendering
things unbootable, which is the opposite of helpful (which was the
original intent behind it).

The uart module got relocated from base_nodemcu to the modules component
properly, after I worked out how to force its inclusion using Kconfig alone.
parent f123d462
......@@ -13,7 +13,6 @@
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
#ifdef LUA_OPTIMIZE_DEBUG
# include "lvm.h"
# define getline(f,pc) (((f)->packedlineinfo) ? luaG_getline((f), pc) : 0)
# define INFO_FILL_BYTE 0x7F
......@@ -23,9 +22,6 @@
# define INFO_DELTA_7BITS 0x7F
# define INFO_MAX_LINECNT 126
# define lineInfoTop(fs) ((fs)->f->packedlineinfo + (fs)->lastlineOffset)
#else
# define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
#endif
#define resethookcount(L) (L->hookcount = L->basehookcount)
......@@ -41,9 +37,7 @@ LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaG_errormsg (lua_State *L);
LUAI_FUNC int luaG_checkcode (const Proto *pt);
LUAI_FUNC int luaG_checkopenop (Instruction i);
#ifdef LUA_OPTIMIZE_DEBUG
LUAI_FUNC int luaG_getline (const Proto *f, int pc);
LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
#endif
#endif
......@@ -8,7 +8,6 @@
#define ldo_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -106,7 +105,7 @@ void luaD_throw (lua_State *L, int errcode) {
lua_unlock(L);
G(L)->panic(L);
}
// exit(EXIT_FAILURE);
// c_exit(EXIT_FAILURE);
}
}
......@@ -254,13 +253,13 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
return base;
}
static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
ptrdiff_t funcr = savestack(L, func);
if (!ttisfunction(tm))
if (!ttisfunction(tm)) {
luaG_typeerror(L, func, "call");
}
/* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
incr_top(L);
......@@ -279,10 +278,10 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
int luaD_precall (lua_State *L, StkId func, int nresults) {
ptrdiff_t funcr;
LClosure *cl = NULL;
if (!ttisfunction(func) && !ttislightfunction(func)) /* `func' is not a function? */
if (!ttisfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
if (ttisfunction(func))
if (!ttislightfunction(func))
cl = &clvalue(func)->l;
L->ci->savedpc = L->savedpc;
if (cl && !cl->isC) { /* Lua function? prepare its call */
......@@ -332,10 +331,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
if (ttisfunction(ci->func))
n = (*curr_func(L)->c.f)(L); /* do the actual call */
else
if (ttislightfunction(ci->func))
n = ((lua_CFunction)fvalue(ci->func))(L); /* do the actual call */
else
n = (*curr_func(L)->c.f)(L); /* do the actual call */
lua_lock(L);
if (n < 0) /* yielding? */
return PCRYIELD;
......@@ -384,7 +383,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L->nCcalls >= LUAI_MAXCCALLS) {
if (L->nCcalls == LUAI_MAXCCALLS)
......
......@@ -6,7 +6,6 @@
#define ldump_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -229,7 +228,6 @@ static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
#ifdef LUA_OPTIMIZE_DEBUG
n = (D->strip || f->packedlineinfo == NULL) ? 0: strlen(cast(char *,f->packedlineinfo))+1;
DumpInt(n,D);
Align4(D);
......@@ -237,15 +235,6 @@ static void DumpDebug(const Proto* f, DumpState* D)
{
DumpBlock(f->packedlineinfo, n, D);
}
#else
n= (D->strip) ? 0 : f->sizelineinfo;
DumpInt(n,D);
Align4(D);
for (i=0; i<n; i++)
{
DumpInt(f->lineinfo[i],D);
}
#endif
n= (D->strip) ? 0 : f->sizelocvars;
DumpInt(n,D);
......
......@@ -5,7 +5,6 @@
#define lflash_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lobject.h"
......@@ -24,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
#include "lfs.h"
/*
* Flash memory is a fixed memory addressable block that is serially allocated by the
* luac build process and the out image can be downloaded into SPIFSS and loaded into
......@@ -72,7 +73,7 @@ struct OUTPUT {
outBlock buffer;
int ndx;
uint32_t crc;
int (*fullBlkCB) (void);
void (*fullBlkCB) (void);
int flashLen;
int flagsLen;
int flagsNdx;
......@@ -80,12 +81,6 @@ struct OUTPUT {
const char *error;
} *out;
#ifdef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
extern const char lua_flash_store_reserved[0];
#endif
#ifdef NODE_DEBUG
extern void printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
void dumpStrt(stringtable *tb, const char *type) {
......@@ -97,9 +92,8 @@ void dumpStrt(stringtable *tb, const char *type) {
for (i=0; i<tb->size; i++)
for(o = tb->hash[i], j=0; o; (o=o->gch.next), j++ ) {
TString *ts =cast(TString *, o);
NODE_DBG("%5d %5d %08x %08x %5d %1s %s\n",
i, j, (size_t) ts, ts->tsv.hash, ts->tsv.len,
ts_isreadonly(ts) ? "R" : " ", getstr(ts));
NODE_DBG("%5d %5d %08x %08x %5d %s\n",
i, j, (size_t) ts, ts->tsv.hash, ts->tsv.len, getstr(ts));
}
}
......@@ -117,17 +111,25 @@ LUA_API void dumpStrings(lua_State *L) {
* writes are suppressed if the global writeToFlash is false. This is used in
* phase I where the pass is used to size the structures in flash.
*/
static void flashSetPosition(uint32_t offset){
static const char *flashPosition(void){
return flashAddr + curOffset;
}
static const char *flashSetPosition(uint32_t offset){
NODE_DBG("flashSetPosition(%04x)\n", offset);
curOffset = offset;
return flashPosition();
}
static void flashBlock(const void* b, size_t size) {
NODE_DBG("flashBlock((%04x),%08x,%04x)\n", curOffset,(unsigned int)b,size);
static const char *flashBlock(const void* b, size_t size) {
const void *cur = flashPosition();
NODE_DBG("flashBlock((%04x),%p,%04x)\n", curOffset,b,size);
lua_assert(ALIGN_BITS(b) == 0 && ALIGN_BITS(size) == 0);
platform_flash_write(b, flashAddrPhys+curOffset, size);
curOffset += size;
return cur;
}
......@@ -142,11 +144,11 @@ static void flashErase(uint32_t start, uint32_t end){
static int loadLFS (lua_State *L);
static int loadLFSgc (lua_State *L);
static int procFirstPass (void);
static void procFirstPass (void);
#endif
/* =====================================================================================
* luaN_init(), luaN_reload_reboot() and luaN_index() are exported via lflash.h.
* luaN_init() is exported via lflash.h.
* The first is the startup hook used in lstate.c and the last two are
* implementations of the node.flash API calls.
*/
......@@ -155,40 +157,15 @@ static int procFirstPass (void);
* Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed
*/
LUAI_FUNC void luaN_init (lua_State *L) {
#ifdef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
flashSize = CONFIG_NODEMCU_EMBEDDED_LFS_SIZE;
flashAddr = lua_flash_store_reserved;
flashAddrPhys = spi_flash_cache2phys(lua_flash_store_reserved);
if (flashAddrPhys == SPI_FLASH_CACHE2PHYS_FAIL) {
NODE_ERR("spi_flash_cache2phys failed\n");
lfs_location_info_t lfs_loc;
if (!lfs_get_location(&lfs_loc))
return;
}
#else
const esp_partition_t *part = esp_partition_find_first(
PLATFORM_PARTITION_TYPE_NODEMCU,
PLATFORM_PARTITION_SUBTYPE_NODEMCU_LFS,
NULL);
if (!part)
return; // Nothing to do if the size is zero
flashSize = part->size; // in bytes
flashAddrPhys = part->address;
flashAddr = spi_flash_phys2cache(flashAddrPhys, SPI_FLASH_MMAP_DATA);
if (!flashAddr) {
spi_flash_mmap_handle_t ignored;
esp_err_t err = spi_flash_mmap(
flashAddrPhys, flashSize, SPI_FLASH_MMAP_DATA,
cast(const void **, &flashAddr), &ignored);
if (err != ESP_OK) {
NODE_ERR("Unable to access LFS partition - is it 64kB aligned as it needs to be?\n");
return;
}
}
#endif
G(L)->LFSsize = flashSize;
flashSector = platform_flash_get_sector_of_address(flashAddrPhys);
FlashHeader *fh = cast(FlashHeader *, flashAddr);
G(L)->LFSsize = flashSize = lfs_loc.size;
flashAddr = lfs_loc.addr_mem;
flashAddrPhys = lfs_loc.addr_phys;
flashSector = platform_flash_get_sector_of_address(lfs_loc.addr_phys);
FlashHeader *fh = cast(FlashHeader *, lfs_loc.addr_mem);
curOffset = 0;
/*
......@@ -204,15 +181,15 @@ LUAI_FUNC void luaN_init (lua_State *L) {
}
if ((fh->flash_sig & (~FLASH_SIG_ABSOLUTE)) != FLASH_SIG ) {
NODE_ERR("Flash sig not correct: %u vs %u\n",
NODE_ERR("LFS sig not correct: 0x%x vs expected 0x%x\n",
fh->flash_sig & (~FLASH_SIG_ABSOLUTE), FLASH_SIG);
return;
}
if (fh->pROhash == ALL_SET ||
((fh->mainProto - cast(FlashAddr, fh)) >= fh->flash_size)) {
NODE_ERR("Flash size check failed: %x vs 0xFFFFFFFF; size: %u\n",
fh->mainProto - cast(FlashAddr, fh), fh->flash_size);
NODE_ERR("Flash size check failed: 0x%08x vs 0xFFFFFFFF; 0x%08x >= 0x%08x\n",
fh->pROhash, fh->mainProto - cast(FlashAddr, fh), fh->flash_size);
return;
}
......@@ -222,23 +199,24 @@ LUAI_FUNC void luaN_init (lua_State *L) {
G(L)->ROpvmain = cast(Proto *,fh->mainProto);
}
/* luaL_lfsreload() is exported via lauxlib.h */
/*
* Library function called by node.flashreload(filename).
*/
LUALIB_API int luaN_reload_reboot (lua_State *L) {
LUALIB_API void luaL_lfsreload (lua_State *L) {
#ifdef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
// Updating the LFS section is disabled for now because any changes to the
// image requires updating its checksum to prevent boot failure.
lua_pushstring(L, "Not allowed to write to LFS section");
return 1;
return;
#else
// luaL_dbgbreak();
const char *fn = lua_tostring(L, 1), *msg = "";
int status;
if (G(L)->LFSsize == 0) {
lua_pushstring(L, "No LFS partition allocated");
return 1;
return;
}
......@@ -270,7 +248,7 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
lua_cpcall(L, &loadLFSgc, NULL);
lua_settop(L, 0);
lua_pushstring(L, msg);
return 1;
return;
}
if (status == 0) {
......@@ -290,62 +268,22 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
NODE_ERR("%s\n", msg);
esp_restart();
return 0;
#endif // CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
}
/*
* If the arg is a valid LFS module name then return the LClosure
* pointing to it. Otherwise return:
* - The Unix time that the LFS was built
* - The base address and length of the LFS
* - An array of the module names in the LFS
*/
LUAI_FUNC int luaN_index (lua_State *L) {
int n = lua_gettop(L);
/* Return nil + the LFS base address if the LFS size > 0 and it isn't loaded */
if (!(G(L)->ROpvmain)) {
lua_settop(L, 0);
lua_pushnil(L);
if (G(L)->LFSsize) {
lua_pushinteger(L, (lua_Integer) flashAddr);
lua_pushinteger(L, flashAddrPhys);
lua_pushinteger(L, G(L)->LFSsize);
return 4;
} else {
return 1;
}
}
/* Push the LClosure of the LFS index function */
Closure *cl = luaF_newLclosure(L, 0, hvalue(gt(L)));
cl->l.p = G(L)->ROpvmain;
lua_settop(L, n+1);
setclvalue(L, L->top-1, cl);
/* Move it infront of the arguments and call the index function */
lua_insert(L, 1);
lua_call(L, n, LUA_MULTRET);
/* Return it if the response if a single value (the function) */
if (lua_gettop(L) == 1)
return 1;
lua_assert(lua_gettop(L) == 2);
/* Otherwise add the base address of the LFS, and its size bewteen the */
/* Unix time and the module list, then return all 4 params. */
lua_pushinteger(L, (lua_Integer) flashAddr);
lua_insert(L, 2);
lua_pushinteger(L, flashAddrPhys);
lua_insert(L, 3);
lua_pushinteger(L, cast(FlashHeader *, flashAddr)->flash_size);
lua_insert(L, 4);
return 5;
LUA_API void lua_getlfsconfig (lua_State *L, intptr_t *config) {
if (!config)
return;
config[0] = (intptr_t) flashAddr; /* LFS region mapped address */
config[1] = flashAddrPhys; /* LFS region base flash address */
config[2] = G(L)->LFSsize; /* LFS region actual size */
config[3] = (G(L)->ROstrt.hash) ? cast(FlashHeader *, flashAddr)->flash_size : 0;
/* LFS region used */
config[4] = 0; /* Not used in Lua 5.1 */
}
#ifndef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
/* =====================================================================================
* The following routines use my uzlib which was based on pfalcon's inflate and
......@@ -440,7 +378,7 @@ static uint8_t recall_byte (uint32_t offset) {
* - Once the flags array is in-buffer this is also captured.
* This logic is slightly complicated by the last buffer is typically short.
*/
int procFirstPass (void) {
void procFirstPass (void) {
int len = (out->ndx % WRITE_BLOCKSIZE) ?
out->ndx % WRITE_BLOCKSIZE : WRITE_BLOCKSIZE;
if (out->ndx <= WRITE_BLOCKSIZE) {
......@@ -475,12 +413,10 @@ int procFirstPass (void) {
memcpy(out->flags + out->flagsNdx, out->block[0]->byte + start, len - start);
out->flagsNdx += (len -start) / WORDSIZE; /* flashLen and len are word aligned */
}
return 1;
}
int procSecondPass (void) {
void procSecondPass (void) {
/*
* The length rules are different for the second pass since this only processes
* upto the flashLen and not the full image. This also works in word units.
......@@ -518,12 +454,10 @@ int procSecondPass (void) {
flashBlock(&out->flash_sig, WORDSIZE);
out->fullBlkCB = NULL;
}
return 1;
}
/*
* loadLFS)() is protected called from luaN_reload_reboot so that it can recover
* loadLFS)() is protected called from luaL_lfsreload so that it can recover
* from out of memory and other thrown errors. loadLFSgc() GCs any resources.
*/
static int loadLFS (lua_State *L) {
......@@ -548,7 +482,7 @@ static int loadLFS (lua_State *L) {
in->len = vfs_size(in->fd);
if (in->len <= 200 || /* size of an empty luac output */
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(uint32_t)) != sizeof(uint32_t))
flash_error("read error on LFS image file");
vfs_lseek(in->fd, 0, VFS_SEEK_SET);
......
......@@ -43,8 +43,5 @@ typedef struct {
} FlashHeader;
LUAI_FUNC void luaN_init (lua_State *L);
LUAI_FUNC int luaN_flashSetup (lua_State *L);
LUAI_FUNC int luaN_reload_reboot (lua_State *L);
LUAI_FUNC int luaN_index (lua_State *L);
#endif
......@@ -6,7 +6,6 @@
#define lfunc_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -126,12 +125,7 @@ Proto *luaF_newproto (lua_State *L) {
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
#ifdef LUA_OPTIMIZE_DEBUG
f->packedlineinfo = NULL;
#else
f->sizelineinfo = 0;
f->lineinfo = NULL;
#endif
f->sizelocvars = 0;
f->locvars = NULL;
f->linedefined = 0;
......@@ -146,15 +140,9 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->k, f->sizek, TValue);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
if (!proto_isreadonly(f)) {
luaM_freearray(L, f->code, f->sizecode, Instruction);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo) {
luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo))+1, unsigned char);
}
#else
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
#endif
luaM_freearray(L, f->code, f->sizecode, Instruction);
if (f->packedlineinfo) {
luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo))+1, unsigned char);
}
luaM_free(L, f);
}
......
......@@ -6,7 +6,6 @@
#define lgc_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -21,14 +20,12 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lrotable.h"
#define GCSTEPSIZE 1024u
#define GCSWEEPMAX 40
#define GCSWEEPCOST 10
#define GCFINALIZECOST 100
#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
#define makewhite(g,x) \
......@@ -55,7 +52,6 @@
#define markobject(g,t) { if (iswhite(obj2gco(t))) \
reallymarkobject(g, obj2gco(t)); }
#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
......@@ -82,7 +78,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
case LUA_TUSERDATA: {
Table *mt = gco2u(o)->metatable;
gray2black(o); /* udata are never gray */
if (mt && !luaR_isrotable(mt)) markobject(g, mt);
if (mt && isrwtable(mt)) markobject(g, mt);
markobject(g, gco2u(o)->env);
return;
}
......@@ -160,7 +156,6 @@ size_t luaC_separateudata (lua_State *L, int all) {
return deadmem;
}
static int traversetable (global_State *g, Table *h) {
int i;
int weakkey = 0;
......@@ -168,7 +163,7 @@ static int traversetable (global_State *g, Table *h) {
const TValue *mode = luaO_nilobject;
if (h->metatable) {
if (!luaR_isrotable(h->metatable))
if (isrwtable(h->metatable))
markobject(g, h->metatable);
mode = gfasttm(g, h->metatable, TM_MODE);
}
......@@ -331,14 +326,8 @@ static l_mem propagatemark (global_State *g) {
sizeof(TValue) * p->sizek +
sizeof(LocVar) * p->sizelocvars +
sizeof(TString *) * p->sizeupvalues +
(proto_isreadonly(p) ? 0 : sizeof(Instruction) * p->sizecode +
#ifdef LUA_OPTIMIZE_DEBUG
(p->packedlineinfo ?
strlen(cast(char *, p->packedlineinfo))+1 :
0));
#else
sizeof(int) * p->sizelineinfo);
#endif
sizeof(Instruction) * p->sizecode +
(p->packedlineinfo ? strlen(cast(char *, p->packedlineinfo))+1 : 0);
}
default: lua_assert(0); return 0;
}
......@@ -522,8 +511,8 @@ void luaC_freeall (lua_State *L) {
static void markmt (global_State *g) {
int i;
for (i=0; i<NUM_TAGS; i++)
if (g->mt[i] && !luaR_isrotable(g->mt[i])) markobject(g, g->mt[i]);
for (i=0; i<LUA_NUMTAGS; i++)
if (g->mt[i] && isrwtable(g->mt[i])) markobject(g, g->mt[i]);
}
......@@ -713,7 +702,7 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
lua_assert(o->gch.tt != LUA_TTABLE);
lua_assert((gettt(o) & LUA_TMASK) != LUA_TTABLE);
/* must keep invariant? */
if (g->gcstate == GCSpropagate)
reallymarkobject(g, v); /* Restore invariant */
......
......@@ -7,7 +7,6 @@
#define llex_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <ctype.h>
......@@ -62,6 +61,7 @@ static void save (LexState *ls, int c) {
void luaX_init (lua_State *L) {
(void)L;
}
......
......@@ -8,8 +8,6 @@
#define llimits_h
//#include <limits.h>
#include "lua.h"
typedef LUAI_UINT32 lu_int32;
......@@ -104,7 +102,7 @@ typedef lu_int32 Instruction;
#ifndef lua_lock
#define lua_lock(L) ((void) 0)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
......@@ -115,7 +113,7 @@ typedef lu_int32 Instruction;
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
*/
#ifndef HARDSTACKTESTS
#define condhardstacktests(x) ((void)0)
#else
......
......@@ -7,7 +7,6 @@
#define lmathlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdlib.h>
......@@ -15,7 +14,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#undef PI
#define PI (3.14159265358979323846)
......@@ -309,7 +307,7 @@ static int math_randomseed (lua_State *L) {
return 0;
}
LROT_PUBLIC_BEGIN(math)
LROT_BEGIN(mathlib, NULL, 0)
#ifdef LUA_NUMBER_INTEGRAL
LROT_FUNCENTRY( abs, math_abs )
LROT_FUNCENTRY( ceil, math_identity )
......@@ -354,7 +352,7 @@ LROT_PUBLIC_BEGIN(math)
LROT_NUMENTRY( pi, PI )
LROT_NUMENTRY( huge, HUGE_VAL )
#endif // #ifdef LUA_NUMBER_INTEGRAL
LROT_END(math, NULL, 0)
LROT_END(mathlib, NULL, 0)
/*
......
......@@ -7,7 +7,6 @@
#define lmem_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
......
......@@ -8,12 +8,6 @@
#define lmem_h
//#ifdef LUA_CROSS_COMPILER
//#include <stddef.h>
//#else
//#include "c_stddef.h"
//#endif
#include "llimits.h"
#include "lua.h"
......
/*
** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
#define lnodemcu_c
#define LUA_CORE
#include "lua.h"
#include <string.h>
#include "lobject.h"
#include "lstate.h"
#include "lauxlib.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lnodemcu.h"
//== NodeMCU lauxlib.h API extensions ========================================//
#ifdef LUA_USE_ESP
#include "task/task.h"
#include "platform.h"
/*
** Error Reporting Task. We can't pass a string parameter to the error reporter
** directly through the task interface the call is wrapped in a C closure with
** the error string as an Upval and this is posted to call the Lua reporter.
*/
static int errhandler_aux (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, "onerror");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
lua_getglobal(L, "print");
}
lua_pushvalue(L, lua_upvalueindex(1));
lua_call(L, 1, 0); /* Using an error handler would cause an infinite loop! */
return 0;
}
/*
** Error handler for luaL_pcallx(), called from the lua_pcall() with a single
** argument -- the thrown error. This plus depth=2 is passed to debug.traceback()
** to convert into an error message which it handles in a separate posted task.
*/
static int errhandler (lua_State *L) {
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
if (lua_isfunction(L, -1)) {
lua_insert(L, 1); /* insert tracback function above error */
lua_pop(L, 1); /* dump the debug table entry */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return 0;
}
/*
** Use in CBs and other C functions to call a Lua function. This includes
** an error handler which will catch any error and then post this to the
** registered reporter function as a separate follow-on task.
*/
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) { // [-narg, +0, v]
int status;
int base = lua_gettop(L) - narg;
lua_pushcfunction(L, errhandler);
lua_insert(L, base); /* put under args */
status = lua_pcall(L, narg, nres, base);
lua_remove(L, base); /* remove traceback function */
if (status != LUA_OK && status != LUA_ERRRUN) {
lua_gc(L, LUA_GCCOLLECT, 0); /* call onerror directly if handler failed */
lua_pushliteral(L, "out of memory");
lua_pushcclosure(L, errhandler_aux, 1); /* report EOM as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return status;
}
static task_handle_t task_handle = 0;
/*
** Task callback handler. Uses luaN_call to do a protected call with full traceback
*/
static void do_task (task_param_t task_fn_ref, task_prio_t prio) {
lua_State* L = lua_getstate();
if (prio < 0|| prio > 2)
luaL_error(L, "invalid posk task");
/* Pop the CB func from the Reg */
//dbg_printf("calling Reg[%u]\n", task_fn_ref);
lua_rawgeti(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
luaL_checkfunction(L, -1);
luaL_unref(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
lua_pushinteger(L, prio);
luaL_pcallx(L, 1, 0);
}
/*
** Schedule a Lua function for task execution
*/
LUALIB_API int luaL_posttask( lua_State* L, int prio ) { // [-1, +0, -]
if (!task_handle)
task_handle = task_get_id(do_task);
if (!lua_isfunction(L, -1) || prio < LUA_TASK_LOW|| prio > LUA_TASK_HIGH)
luaL_error(L, "invalid posk task");
//void *cl = clvalue(L->top-1);
int task_fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
//dbg_printf("posting Reg[%u]=%p\n",task_fn_ref,cl);
if(!task_post(prio, task_handle, (task_param_t)task_fn_ref)) {
luaL_unref(L, LUA_REGISTRYINDEX, task_fn_ref);
luaL_error(L, "Task queue overflow. Task not posted");
}
return task_fn_ref;
}
#else
LUALIB_API int luaL_posttask( lua_State* L, int prio ) {
(void)L; (void)prio;
return 0;
} /* Dummy stub on host */
#endif
#ifdef LUA_USE_ESP
/*
* Return an LFS function
*/
LUALIB_API int luaL_pushlfsmodule (lua_State *L) {
if (lua_pushlfsindex(L) == LUA_TNIL) {
lua_remove(L,-2); /* dump the name to balance the stack */
return 0; /* return nil if LFS not loaded */
}
lua_insert(L, -2);
lua_call(L, 1, 1);
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
lua_pushnil(L); /* replace DTS by nil */
}
return 1;
}
/*
* Return an array of functions in LFS
*/
LUALIB_API int luaL_pushlfsmodules (lua_State *L) {
if (lua_pushlfsindex(L) == LUA_TNIL)
return 0; /* return nil if LFS not loaded */
lua_call(L, 0, 2);
lua_remove(L, -2); /* remove DTS leaving array */
return 1;
}
/*
* Return the Unix timestamp of the LFS image creation
*/
LUALIB_API int luaL_pushlfsdts (lua_State *L) {
if (lua_pushlfsindex(L) == LUA_TNIL)
return 0; /* return nil if LFS not loaded */
lua_call(L, 0, 1);
return 1;
}
#endif
//== NodeMCU lua.h API extensions ============================================//
LUA_API int lua_freeheap (void) {
#ifdef LUA_USE_HOST
return MAX_INT;
#else
return (int)esp_get_free_heap_size();
#endif
}
#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
LUA_API int lua_pushstringsarray(lua_State *L, int opt) {
stringtable *tb = NULL;
int i, j;
lua_lock(L);
if (opt == 0)
tb = &G(L)->strt;
#ifdef LUA_USE_ESP
else if (opt == 1 && G(L)->ROstrt.hash)
tb = &G(L)->ROstrt;
#endif
if (tb == NULL) {
setnilvalue(L->top);
api_incr_top(L);
lua_unlock(L);
return 0;
}
Table *t = luaH_new(L, tb->nuse, 0);
sethvalue(L, L->top, t);
api_incr_top(L);
luaC_checkGC(L);
lua_unlock(L);
for (i = 0, j = 1; i < tb->size; i++) {
GCObject *o;
for(o = tb->hash[i]; o; o = o->gch.next) {
TValue v;
setsvalue(L, &v, o);
setobj2s(L, luaH_setnum(L, hvalue(L->top-1), j++), &v);
}
}
return 1;
}
LUA_API void lua_createrotable (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt) {
int i, j;
lu_byte flags = ~0;
const char *plast = (char *)"_";
for (i = 0; e[i].key; i++) {
if (e[i].key[0] == '_' && strcmp(e[i].key,plast)) {
plast = e[i].key;
lua_pushstring(L,e[i].key);
for (j=0; j<TM_EQ; j++){
if(rawtsvalue(L->top-1)==G(L)->tmname[i]) {
flags |= cast_byte(1u<<i);
break;
}
}
lua_pop(L,1);
}
}
t->next = (GCObject *)1;
t->tt = LUA_TROTABLE;
t->marked = LROT_MARKED;
t->flags = flags;
t->lsizenode = i;
t->metatable = cast(Table *, mt);
t->entry = cast(ROTable_entry *, e);
}
#ifdef LUA_USE_ESP
#include "lfunc.h"
/* Push the LClosure of the LFS index function */
LUA_API int lua_pushlfsindex (lua_State *L) {
lua_lock(L);
Proto *p = G(L)->ROpvmain;
if (p) {
Closure *cl = luaF_newLclosure(L, 0, hvalue(gt(L)));
cl->l.p = p;
setclvalue(L, L->top, cl);
} else {
setnilvalue(L->top);
}
api_incr_top(L);
lua_unlock(L);
return p ? LUA_TFUNCTION : LUA_TNIL;
}
#endif
/*
* NodeMCU extensions to Lua 5.1 for readonly Flash memory support
*/
#ifndef lnodemcu_h
#define lnodemcu_h
#include "lua.h"
#include "lobject.h"
#include "llimits.h"
#include "ltm.h"
#ifdef LUA_USE_HOST
#define LRO_STRKEY(k) k
#define LOCK_IN_SECTION(s)
#else
#define LRO_STRKEY(k) ((__attribute__((aligned(4))) const char *) k)
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
#endif
/* Macros used to declare rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = cast(void*,v)}, LUA_TLIGHTUSERDATA}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_INTVAL(v) LRO_NUMVAL(v)
#define LRO_FLOATVAL(v) LRO_NUMVAL(v)
#define LRO_ROVAL(v) {{.gc = cast(GCObject *, &(v ## _ROTable))}, LUA_TROTABLE}
#define LROT_MARKED 0 //<<<<<<<<<< *** TBD *** >>>>>>>>>>>
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA(x)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_INTENTRY(n,x) LROT_NUMENTRY(n,x)
#define LROT_FLOATENTRY(n,x) LROT_NUMENTRY(n,x)
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t)},
#define LROT_TABLE(rt) const ROTable rt ## _ROTable
#define LROT_ENTRYREF(rt) (rt ##_entries)
#define LROT_TABLEREF(rt) (&rt ##_ROTable)
#define LROT_BEGIN(rt,mt,f) LROT_TABLE(rt); \
static ROTable_entry rt ## _entries[] = {
#define LROT_ENTRIES_IN_SECTION(rt,s) \
static ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
#define LROT_END(rt,mt,f) {NULL, LRO_NILVAL} }; \
const ROTable rt ## _ROTable = { \
(GCObject *)1, LUA_TROTABLE, LROT_MARKED, \
cast(lu_byte, ~(f)), (sizeof(rt ## _entries)/sizeof(ROTable_entry)) - 1, \
cast(Table *, mt), cast(ROTable_entry *, rt ## _entries) };
#define LROT_BREAK(rt) };
#define LROT_MASK(m) cast(lu_byte, 1<<TM_ ## m)
/*
* These are statically coded can be any combination of the fast index tags
* listed in ltm.h: EQ, GC, INDEX, LEN, MODE, NEWINDEX or combined by anding
* GC+INDEX is the only common combination used, hence the combinaton macro
*/
#define LROT_MASK_EQ LROT_MASK(EQ)
#define LROT_MASK_GC LROT_MASK(GC)
#define LROT_MASK_INDEX LROT_MASK(INDEX)
#define LROT_MASK_LEN LROT_MASK(LEN)
#define LROT_MASK_MODE LROT_MASK(MODE)
#define LROT_MASK_NEWINDEX LROT_MASK(NEWINDEX)
#define LROT_MASK_GC_INDEX (LROT_MASK_GC | LROT_MASK_INDEX)
#define LUA_MAX_ROTABLE_NAME 32 /* Maximum length of a rotable name and of a string key*/
#ifdef LUA_CORE
#endif
#endif
......@@ -11,7 +11,6 @@
#define loadlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdlib.h>
......@@ -24,7 +23,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
......@@ -394,11 +392,7 @@ static int loader_Lua (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path");
if (filename == NULL) return 1; /* library not found in this path */
#ifdef LUA_CROSS_COMPILER
if (luaL_loadfile(L, filename) != 0)
#else
if (luaL_loadfsfile(L, filename) != 0)
#endif
loaderror(L, filename);
return 1; /* library loaded successfully */
}
......@@ -479,7 +473,7 @@ static int ll_require (lua_State *L) {
}
/* Is this a readonly table? */
lua_getfield(L, LUA_GLOBALSINDEX, name);
if(lua_isrotable(L,-1)) {
if(lua_istable(L,-1)) {
return 1;
} else {
lua_pop(L, 1);
......@@ -572,7 +566,7 @@ static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
/* Is this a readonly table? */
lua_getfield(L, LUA_GLOBALSINDEX, modname);
if(lua_isrotable(L,-1)) {
if(lua_istable(L,-1)) {
return 0;
} else {
lua_pop(L, 1);
......@@ -658,9 +652,9 @@ static const luaL_Reg ll_funcs[] = {
static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
LROT_PUBLIC_BEGIN(lmt)
LROT_FUNCENTRY(__gc,gctm)
LROT_END(lmt,lmt, LROT_MASK_GC)
LROT_BEGIN(lmt, NULL, LROT_MASK_GC)
LROT_FUNCENTRY( __gc, gctm )
LROT_END(lmt, NULL, LROT_MASK_GC)
LUALIB_API int luaopen_package (lua_State *L) {
int i;
......
/*
** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
** Some generic functions over Lua objects
......@@ -7,7 +8,6 @@
#define lobject_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
......@@ -25,7 +25,6 @@
#else
#include <limits.h>
#endif
const TValue luaO_nilobject_ = {LUA_TVALUE_NIL};
......@@ -54,7 +53,23 @@ int luaO_fb2int (int x) {
int luaO_log2 (unsigned int x) {
#ifdef LUA_CROSS_COMPILER
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = -1;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
#else
return 31 - __builtin_clz(x);
#endif
}
......@@ -70,7 +85,7 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
case LUA_TLIGHTUSERDATA:
return pvalue(t1) == pvalue(t2);
case LUA_TROTABLE:
return rvalue(t1) == rvalue(t2);
return hvalue(t1) == hvalue(t2);
case LUA_TLIGHTFUNCTION:
return fvalue(t1) == fvalue(t2);
default:
......@@ -85,11 +100,11 @@ int luaO_str2d (const char *s, lua_Number *result) {
*result = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* conversion failed */
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
#if defined(LUA_CROSS_COMPILER)
#if defined(LUA_CROSS_COMPILER)
{
long lres = strtoul(s, &endptr, 16);
#if LONG_MAX != 2147483647L
if (lres & ~0xffffffffL)
#if INT_MAX != 2147483647L
if (lres & ~0xffffffffL)
*result = cast_num(-1);
else if (lres & 0x80000000L)
*result = cast_num(lres | ~0x7fffffffL);
......
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