Unverified Commit eaac369d authored by Johny Mattsson's avatar Johny Mattsson Committed by GitHub
Browse files

LFS support for ESP32 NodeMCU (#2801)

* Port LFS from ESP8266 to ESP32
parent 7cb61a27
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include C_HEADER_MATH #include <math.h>
#include C_HEADER_STRING #include <string.h>
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h" #include "ldo.h"
...@@ -105,8 +105,9 @@ static Node *mainposition (const Table *t, const TValue *key) { ...@@ -105,8 +105,9 @@ static Node *mainposition (const Table *t, const TValue *key) {
return hashstr(t, rawtsvalue(key)); return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key)); return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
case LUA_TROTABLE: case LUA_TROTABLE:
return hashpointer(t, rvalue(key));
case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION: case LUA_TLIGHTFUNCTION:
return hashpointer(t, pvalue(key)); return hashpointer(t, pvalue(key));
default: default:
...@@ -444,6 +445,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { ...@@ -444,6 +445,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int oldasize = t->sizearray; int oldasize = t->sizearray;
if (nasize > oldasize) /* array part must grow? */ if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize); setarrayvector(L, t, nasize);
if (t->node != dummynode || nhsize>0)
resize_hashpart(L, t, nhsize); resize_hashpart(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */ if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize; t->sizearray = nasize;
...@@ -578,7 +580,7 @@ const TValue *luaH_getnum (Table *t, int key) { ...@@ -578,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 = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject; return res ? res : luaO_nilobject;
} }
...@@ -598,13 +600,9 @@ const TValue *luaH_getstr (Table *t, TString *key) { ...@@ -598,13 +600,9 @@ 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;
} }
...@@ -741,19 +739,15 @@ int luaH_getn (Table *t) { ...@@ -741,19 +739,15 @@ int luaH_getn (Table *t) {
/* same thing for rotables */ /* same thing for rotables */
int luaH_getn_ro (void *t) { int luaH_getn_ro (void *t) {
int i = 1, len=0; return 0; // Integer Keys are not currently supported for ROTables
while(luaR_findentry(t, NULL, i ++, NULL))
len ++;
return len;
} }
#if defined(LUA_DEBUG) int luaH_isdummy (Node *n) { return n == dummynode; }
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) { Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key); return mainposition(t, key);
} }
#endif
int luaH_isdummy (Node *n) { return n == dummynode; }
#endif
...@@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); ...@@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key); LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t); LUAI_FUNC int luaH_getn (Table *t);
LUAI_FUNC int luaH_getn_ro (void *t); LUAI_FUNC int luaH_getn_ro (void *t);
LUAI_FUNC int luaH_isdummy (Node *n);
#if defined(LUA_DEBUG) #if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n);
#endif #endif
#endif #endif
...@@ -266,22 +266,18 @@ static int sort (lua_State *L) { ...@@ -266,22 +266,18 @@ static int sort (lua_State *L) {
/* }====================================================== */ /* }====================================================== */
#undef MIN_OPT_LEVEL LROT_PUBLIC_BEGIN(tab_funcs)
#define MIN_OPT_LEVEL 1 LROT_FUNCENTRY( concat, tconcat )
#include "lrodefs.h" LROT_FUNCENTRY( foreach, foreach )
const LUA_REG_TYPE tab_funcs[] = { LROT_FUNCENTRY( foreachi, foreachi )
{LSTRKEY("concat"), LFUNCVAL(tconcat)}, LROT_FUNCENTRY( getn, getn )
{LSTRKEY("foreach"), LFUNCVAL(foreach)}, LROT_FUNCENTRY( maxn, maxn )
{LSTRKEY("foreachi"), LFUNCVAL(foreachi)}, LROT_FUNCENTRY( insert, tinsert )
{LSTRKEY("getn"), LFUNCVAL(getn)}, LROT_FUNCENTRY( remove, tremove )
{LSTRKEY("maxn"), LFUNCVAL(maxn)}, LROT_FUNCENTRY( setn, setn )
{LSTRKEY("insert"), LFUNCVAL(tinsert)}, LROT_FUNCENTRY( sort, sort )
{LSTRKEY("remove"), LFUNCVAL(tremove)}, LROT_END(tab_funcs, NULL, 0)
{LSTRKEY("setn"), LFUNCVAL(setn)},
{LSTRKEY("sort"), LFUNCVAL(sort)},
{LNILKEY, LNILVAL}
};
LUALIB_API int luaopen_table (lua_State *L) { LUALIB_API int luaopen_table (lua_State *L) {
LREGISTER(L, LUA_TABLIBNAME, tab_funcs); return 1;
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
#include "lgc.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h" #include "ltable.h"
#include "ltm.h" #include "ltm.h"
...@@ -39,7 +40,7 @@ void luaT_init (lua_State *L) { ...@@ -39,7 +40,7 @@ void luaT_init (lua_State *L) {
int i; int i;
for (i=0; i<TM_N; i++) { for (i=0; i<TM_N; i++) {
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
luaS_fix(G(L)->tmname[i]); /* never collect these names */ stringfix(G(L)->tmname[i]); /* never collect these names */
} }
} }
...@@ -49,14 +50,22 @@ void luaT_init (lua_State *L) { ...@@ -49,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 (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? */ if (ttisnil(tm)) { /* no tag method? */
if (!luaR_isrotable(events))
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 @@ ...@@ -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,10 +36,8 @@ typedef enum { ...@@ -36,10 +36,8 @@ 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)
......
...@@ -9,12 +9,10 @@ ...@@ -9,12 +9,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "flash_fs.h"
#include "user_version.h" #include "user_version.h"
#include "driver/console.h" #include "driver/console.h"
#include "esp_system.h" #include "esp_system.h"
#include "platform.h" #include "platform.h"
#include "c_stdlib.h"
#define lua_c #define lua_c
...@@ -23,52 +21,13 @@ ...@@ -23,52 +21,13 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "legc.h" #include "legc.h"
#include "lflash.h"
lua_State *globalL = NULL; lua_State *globalL = NULL;
lua_Load gLoad; lua_Load gLoad;
static const char *progname = LUA_PROGNAME; static const char *progname = LUA_PROGNAME;
#if 0
static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void laction (int i) {
// signal(i, SIG_DFL);
/* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage (void) {
#if defined(LUA_USE_STDIO)
fprintf(stderr,
#else
luai_writestringerror(
#endif
"usage: %s [options] [script [args]].\n"
"Available options are:\n"
" -e stat execute string " LUA_QL("stat") "\n"
" -l name require library " LUA_QL("name") "\n"
" -m limit set memory limit. (units are in Kbytes)\n"
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -v show version information\n"
" -- stop handling options\n"
" - execute stdin and stop handling options\n"
,
progname);
#if defined(LUA_USE_STDIO)
fflush(stderr);
#endif
}
#endif
static void l_message (const char *pname, const char *msg) { static void l_message (const char *pname, const char *msg) {
#if defined(LUA_USE_STDIO) #if defined(LUA_USE_STDIO)
if (pname) fprintf(stderr, "%s: ", pname); if (pname) fprintf(stderr, "%s: ", pname);
...@@ -128,14 +87,15 @@ static int docall (lua_State *L, int narg, int clear) { ...@@ -128,14 +87,15 @@ static int docall (lua_State *L, int narg, int clear) {
static void print_version (lua_State *L) { static void print_version (lua_State *L) {
lua_pushliteral (L, NODE_VERSION " build " BUILD_DATE " powered by " LUA_RELEASE); lua_pushliteral (L, "\n" NODE_VERSION " build " BUILD_DATE " powered by " LUA_RELEASE " on SDK ");
lua_pushstring (L, SDK_VERSION);
lua_concat (L, 2);
const char *msg = lua_tostring (L, -1); const char *msg = lua_tostring (L, -1);
l_message (NULL, msg); l_message (NULL, msg);
lua_pop (L, 1); lua_pop (L, 1);
} }
#if 0
static int getargs (lua_State *L, char **argv, int n) { static int getargs (lua_State *L, char **argv, int n) {
int narg; int narg;
int i; int i;
...@@ -153,16 +113,39 @@ static int getargs (lua_State *L, char **argv, int n) { ...@@ -153,16 +113,39 @@ static int getargs (lua_State *L, char **argv, int n) {
return narg; return narg;
} }
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name) || docall(L, 0, 1);
return report(L, status);
}
#else
static int dofsfile (lua_State *L, const char *name) { static int dofsfile (lua_State *L, const char *name) {
int status = luaL_loadfsfile(L, name) || docall(L, 0, 1); int status = luaL_loadfsfile(L, name) || docall(L, 0, 1);
return report(L, status); return report(L, status);
} }
#endif
static int dolfsfile (lua_State *L, const char *name) {
int status = 1;
const char *code_fmt = "if node.flashindex('%s') then node.flashindex('%s')() end";
char *module_name = strdup(name);
unsigned name_len = strlen(name);
unsigned code_length = strlen(code_fmt) + name_len*2 + 1;
char *code_buf = malloc(code_length);
if (code_buf && module_name) {
char *dot = strrchr(module_name, '.');
if (dot) {
if (strstr(module_name, ".lua") == dot)
*dot = 0;
}
snprintf(code_buf, code_length, code_fmt, module_name, module_name);
status = luaL_dostring(L, code_buf);
if (status)
lua_pushfstring(L, "Failed to load %s from LFS", module_name);
} else {
lua_pushstring(L, "Failed to allocate memory");
}
if (module_name)
free(module_name);
if (code_buf)
free(code_buf);
return report(L, status);
}
static int dostring (lua_State *L, const char *s, const char *name) { static int dostring (lua_State *L, const char *s, const char *name) {
int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
...@@ -199,92 +182,6 @@ static int incomplete (lua_State *L, int status) { ...@@ -199,92 +182,6 @@ static int incomplete (lua_State *L, int status) {
return 0; /* else... */ return 0; /* else... */
} }
#if 0
static int pushline (lua_State *L, int firstline) {
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
if (lua_readline(L, b, prmt) == 0)
return 0; /* no input */
l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[l-1] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* first line starts with `=' ? */
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
else
lua_pushstring(L, b);
lua_freeline(L, b);
return 1;
}
static int loadline (lua_State *L) {
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
for (;;) { /* repeat until gets a complete line */
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
if (!incomplete(L, status)) break; /* cannot try to add lines? */
if (!pushline(L, 0)) /* no more input? */
return -1;
lua_pushliteral(L, "\n"); /* add a new line... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
lua_saveline(L, 1);
lua_remove(L, 1); /* remove line */
return status;
}
static void dotty (lua_State *L) {
int status;
const char *oldprogname = progname;
progname = NULL;
while ((status = loadline(L)) != -1) {
if (status == 0) status = docall(L, 0, 0);
report(L, status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
#if defined(LUA_USE_STDIO)
fputs("\n", stdout);
fflush(stdout);
#else
luai_writeline();
#endif
progname = oldprogname;
}
static int handle_script (lua_State *L, char **argv, int n) {
int status;
const char *fname;
int narg = getargs(L, argv, n); /* collect arguments */
lua_setglobal(L, "arg");
fname = argv[n];
if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
fname = NULL; /* stdin */
status = luaL_loadfile(L, fname);
lua_insert(L, -(narg+1));
if (status == 0)
status = docall(L, narg, 0);
else
lua_pop(L, narg);
return report(L, status);
}
#endif
/* check that argument has no extra characters at the end */ /* check that argument has no extra characters at the end */
#define notail(x) {if ((x)[2] != '\0') return -1;} #define notail(x) {if ((x)[2] != '\0') return -1;}
...@@ -362,17 +259,21 @@ static int runargs (lua_State *L, char **argv, int n) { ...@@ -362,17 +259,21 @@ static int runargs (lua_State *L, char **argv, int n) {
} }
#ifndef LUA_INIT_STRING
#define LUA_INIT_STRING "@init.lua"
#endif
static int handle_luainit (lua_State *L) { static int handle_luainit (lua_State *L) {
const char *init = c_getenv(LUA_INIT); const char *init = LUA_INIT_STRING;
if (init == NULL) return 0; /* status OK */ if (init[0] == '@') {
else if (init[0] == '@') #if CONFIG_LUA_EMBEDDED_FLASH_STORE > 0
#if 0 int status = dolfsfile(L, init+1);
return dofile(L, init+1); if (status == 0)
#else return status;
#endif
return dofsfile(L, init+1); return dofsfile(L, init+1);
#endif } else
else return dostring(L, init, LUA_INIT);
return dostring(L, init, "=" LUA_INIT);
} }
...@@ -395,40 +296,18 @@ static int pmain (lua_State *L) { ...@@ -395,40 +296,18 @@ static int pmain (lua_State *L) {
lua_gc(L, LUA_GCRESTART, 0); lua_gc(L, LUA_GCRESTART, 0);
print_version(L); print_version(L);
s->status = handle_luainit(L); s->status = handle_luainit(L);
#if 0
if (s->status != 0) return 0;
#endif
script = collectargs(argv, &has_i, &has_v, &has_e); script = collectargs(argv, &has_i, &has_v, &has_e);
if (script < 0) { /* invalid args? */ if (script < 0) { /* invalid args? */
#if 0
print_usage();
#endif
s->status = 1; s->status = 1;
return 0; return 0;
} }
// if (has_v) print_version();
s->status = runargs(L, argv, (script > 0) ? script : s->argc); s->status = runargs(L, argv, (script > 0) ? script : s->argc);
if (s->status != 0) return 0; if (s->status != 0) return 0;
#if 0
if (script)
s->status = handle_script(L, argv, script);
if (s->status != 0) return 0;
if (has_i)
dotty(L);
else if (script == 0 && !has_e && !has_v) {
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
#endif
return 0; return 0;
} }
static void dojob(lua_Load *load); static void dojob(lua_Load *load);
static bool readline(lua_Load *load); static bool readline(lua_Load *load);
char line_buffer[LUA_MAXINPUT];
#ifdef LUA_RPC #ifdef LUA_RPC
int main (int argc, char **argv) { int main (int argc, char **argv) {
...@@ -444,30 +323,47 @@ int lua_main (int argc, char **argv) { ...@@ -444,30 +323,47 @@ int lua_main (int argc, char **argv) {
} }
s.argc = argc; s.argc = argc;
s.argv = argv; s.argv = argv;
status = lua_cpcall(L, &pmain, &s); status = lua_cpcall(L, &pmain, &s);
report(L, status); report(L, status);
gLoad.L = L; gLoad.L = L;
gLoad.firstline = 1; gLoad.firstline = 1;
gLoad.done = 0; gLoad.done = 0;
gLoad.line = line_buffer; gLoad.line = malloc(LUA_MAXINPUT);
gLoad.len = LUA_MAXINPUT; gLoad.len = LUA_MAXINPUT;
gLoad.line_position = 0; gLoad.line_position = 0;
gLoad.prmt = get_prompt(L, 1); gLoad.prmt = get_prompt(L, 1);
dojob(&gLoad); dojob(&gLoad);
NODE_DBG("Heap size::%d.\n",system_get_free_heap_size()); NODE_DBG("Heap size:%d.\n",system_get_free_heap_size());
legc_set_mode( L, EGC_ALWAYS, 4096 ); legc_set_mode( L, EGC_ALWAYS, 4096 );
// legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 ); // legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 );
// lua_close(L); // lua_close(L);
return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
} }
int lua_put_line(const char *s, size_t l) {
if (s == NULL || ++l > LUA_MAXINPUT || gLoad.line_position > 0)
return 0;
memcpy(gLoad.line, s, l);
gLoad.line[l] = '\0';
gLoad.line_position = l;
gLoad.done = 1;
NODE_DBG("Get command: %s\n", gLoad.line);
return 1;
}
void lua_handle_input (bool force) void lua_handle_input (bool force)
{ {
if (gLoad.L && (force || readline (&gLoad))) while (gLoad.L && (force || readline (&gLoad))) {
NODE_DBG("Handle Input: first=%u, pos=%u, len=%u, actual=%u, line=%s\n", gLoad.firstline,
gLoad.line_position, gLoad.len, strlen(gLoad.line), gLoad.line);
dojob (&gLoad); dojob (&gLoad);
force = false;
}
} }
void donejob(lua_Load *load){ void donejob(lua_Load *load){
...@@ -475,7 +371,7 @@ void donejob(lua_Load *load){ ...@@ -475,7 +371,7 @@ void donejob(lua_Load *load){
} }
static void dojob(lua_Load *load){ static void dojob(lua_Load *load){
size_t l; size_t l, rs;
int status; int status;
char *b = load->line; char *b = load->line;
lua_State *L = load->L; lua_State *L = load->L;
......
...@@ -166,7 +166,6 @@ LUA_API void (lua_pushnil) (lua_State *L); ...@@ -166,7 +166,6 @@ LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushrolstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushstring) (lua_State *L, const char *s); LUA_API void (lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp); va_list argp);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include "sdkconfig.h"
/* /*
** ================================================================== ** ==================================================================
...@@ -32,6 +33,11 @@ ...@@ -32,6 +33,11 @@
#define LUA_WIN #define LUA_WIN
#endif #endif
#if defined(LUA_CROSS_COMPILER) && !defined(_MSC_VER) && !defined(__MINGW32__)
#define LUA_USE_LINUX
#endif
#if defined(LUA_USE_LINUX) #if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX #define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ #define LUA_USE_DLOPEN /* needs an extra library: -ldl */
...@@ -53,7 +59,7 @@ ...@@ -53,7 +59,7 @@
#if defined(LUA_USE_POSIX) #if defined(LUA_USE_POSIX)
#define LUA_USE_MKSTEMP #define LUA_USE_MKSTEMP
#define LUA_USE_ISATTY #define LUA_USE_ISATTY
#define LUA_USE_POPEN //#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP #define LUA_USE_ULONGJMP
#endif #endif
...@@ -161,7 +167,7 @@ ...@@ -161,7 +167,7 @@
#define LUA_INTEGER ptrdiff_t #define LUA_INTEGER ptrdiff_t
#else #else
#if !defined LUA_INTEGRAL_LONGLONG #if !defined LUA_INTEGRAL_LONGLONG
#define LUA_INTEGER long #define LUA_INTEGER int
#else #else
#define LUA_INTEGER long long #define LUA_INTEGER long long
#endif // #if !defined LUA_INTEGRAL_LONGLONG #endif // #if !defined LUA_INTEGRAL_LONGLONG
...@@ -251,11 +257,7 @@ ...@@ -251,11 +257,7 @@
#define lua_stdin_is_tty() isatty(0) #define lua_stdin_is_tty() isatty(0)
#elif defined(LUA_WIN) #elif defined(LUA_WIN)
#include <io.h> #include <io.h>
#ifdef LUA_CROSS_COMPILER
#include <stdio.h>
else
#include <stdio.h> #include <stdio.h>
#endif
#define lua_stdin_is_tty() _isatty(_fileno(stdin)) #define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else #else
...@@ -481,7 +483,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -481,7 +483,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
/* 16-bit ints */ /* 16-bit ints */
#define LUAI_UINT32 unsigned long #define LUAI_UINT32 unsigned long
#define LUAI_INT32 long #define LUAI_INT32 long
#define LUAI_MAXINT32 LONG_MAX #define LUAI_MAXINT32 INT_MAX
#define LUAI_UMEM unsigned long #define LUAI_UMEM unsigned long
#define LUAI_MEM long #define LUAI_MEM long
#endif #endif
...@@ -550,7 +552,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -550,7 +552,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
** For example: If set to 4K a call to string.gsub will need more than ** For example: If set to 4K a call to string.gsub will need more than
** 5k C stack space. ** 5k C stack space.
*/ */
#define LUAL_BUFFERSIZE 1024 #define LUAL_BUFFERSIZE 256
/* }================================================================== */ /* }================================================================== */
...@@ -601,8 +603,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -601,8 +603,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
*/ */
#if defined LUA_NUMBER_INTEGRAL #if defined LUA_NUMBER_INTEGRAL
#if !defined LUA_INTEGRAL_LONGLONG #if !defined LUA_INTEGRAL_LONGLONG
#define LUA_NUMBER_SCAN "%ld" #define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%ld" #define LUA_NUMBER_FMT "%d"
#else #else
#define LUA_NUMBER_SCAN "%lld" #define LUA_NUMBER_SCAN "%lld"
#define LUA_NUMBER_FMT "%lld" #define LUA_NUMBER_FMT "%lld"
...@@ -745,18 +747,18 @@ union luai_Cast { double l_d; long l_l; }; ...@@ -745,18 +747,18 @@ union luai_Cast { double l_d; long l_l; };
{ if ((c)->status == 0) (c)->status = -1; } { if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */ #define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP) #else
#if defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */ /* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1) #define LONGJMP(a,b) _longjmp(a,b)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } #define SETJMP(a) _setjmp(a)
#define luai_jmpbuf jmp_buf
#else #else
/* default handling with long jumps */ #define LONGJMP(a,b) longjmp(a,b)
#define LUAI_THROW(L,c) longjmp((c)->b, 1) #define SETJMP(a) setjmp(a)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } #endif
#define LUAI_THROW(L,c) LONGJMP((c)->b, 1)
#define LUAI_TRY(L,c,a) if (SETJMP((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf #define luai_jmpbuf jmp_buf
#endif #endif
...@@ -891,15 +893,8 @@ union luai_Cast { double l_d; long l_l; }; ...@@ -891,15 +893,8 @@ union luai_Cast { double l_d; long l_l; };
** without modifying the main part of the file. ** without modifying the main part of the file.
*/ */
/* If you define the next macro you'll get the ability to set rotables as #if defined(LUA_USE_POPEN)
metatables for tables/userdata/types (but the VM might run slower) #error "Pipes not supported NodeMCU firmware"
*/
#if (LUA_OPTIMIZE_MEMORY == 2) && !defined(LUA_CROSS_COMPILER)
#define LUA_META_ROTABLES
#endif
#if LUA_OPTIMIZE_MEMORY == 2 && defined(LUA_USE_POPEN)
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)"
#endif #endif
#endif #endif
...@@ -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"
...@@ -172,7 +172,7 @@ static TString* LoadString(LoadState* S) ...@@ -172,7 +172,7 @@ static TString* LoadString(LoadState* S)
} else { } else {
s = (char*)luaZ_get_crt_address(S->Z); s = (char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,size); LoadBlock(S,NULL,size);
return luaS_newrolstr(S->L,s,size-1); return luaS_newlstr(S->L,s,size-1);
} }
} }
} }
...@@ -280,7 +280,7 @@ static Proto* LoadFunction(LoadState* S, TString* p) ...@@ -280,7 +280,7 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto* f; Proto* f;
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
f=luaF_newproto(S->L); f=luaF_newproto(S->L);
if (luaZ_direct_mode(S->Z)) proto_readonly(f); if (luaZ_direct_mode(S->Z)) l_setbit((f)->marked, READONLYBIT);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p; f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S); f->linedefined=LoadInt(S);
......
...@@ -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_MATH #include <math.h>
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h" #include "ldo.h"
...@@ -130,11 +130,21 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { ...@@ -130,11 +130,21 @@ 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);
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); setobj2s(L, val, res);
return; return;
} }
...@@ -142,6 +152,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { ...@@ -142,6 +152,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
} }
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) { ...@@ -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);
...@@ -292,8 +305,9 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { ...@@ -292,8 +305,9 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TNIL: return 1; case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(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_TLIGHTUSERDATA:
case LUA_TROTABLE: case LUA_TROTABLE:
return rvalue(t1) == rvalue(t2);
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: {
...@@ -320,7 +334,7 @@ void luaV_concat (lua_State *L, int total, int last) { ...@@ -320,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) */
......
...@@ -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 "llimits.h" #include "llimits.h"
#include "lmem.h" #include "lmem.h"
......
all: build
ifeq ($V,)
Q:=@
endif
LUAC_CFLAGS:= -I$(COMPONENT_PATH)/../uzlib -I$(COMPONENT_PATH)/../lua -I$(BUILD_DIR_BASE)/include -I$(COMPONENT_PATH)/../base_nodemcu/include -O2 -g -Wall -Wextra
LUAC_LDFLAGS:= -ldl -lm
LUAC_DEFINES += -DLUA_CROSS_COMPILER -DLUA_USE_STDIO
ifneq ($(CONFIG_LUA_OPTIMIZE_DEBUG),)
LUAC_DEFINES += -DLUA_OPTIMIZE_DEBUG=$(CONFIG_LUA_OPTIMIZE_DEBUG)
endif
vpath %.c $(COMPONENT_PATH) $(COMPONENT_PATH)/../lua $(COMPONENT_PATH)/../uzlib $(COMPONENT_PATH)/../base_nodemcu
LUAC_LUACSRC:= \
luac.c lflashimg.c loslib.c print.c liolib.c
LUAC_LUASRC:= $(addprefix $(COMPONENT_PATH)/../lua/, \
lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c \
ldo.c ldump.c lfunc.c lgc.c llex.c \
lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c lparser.c \
lrotable.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c \
)
LUAC_UZSRC:= $(addprefix $(COMPONENT_PATH)/../uzlib/, \
uzlib_deflate.c crc32.c \
)
LUAC_NODEMCUSRC:= $(addprefix $(COMPONENT_PATH)/../base_nodemcu/, \
linit.c \
)
LUAC_BUILD_DIR:=$(BUILD_DIR_BASE)/luac_cross
LUAC_OBJS:=$(LUAC_LUACSRC:%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_OBJS+=$(LUAC_LUASRC:$(COMPONENT_PATH)/../lua/%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_OBJS+=$(LUAC_UZSRC:$(COMPONENT_PATH)/../uzlib/%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_OBJS+=$(LUAC_NODEMCUSRC:$(COMPONENT_PATH)/../base_nodemcu/%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_DEPS:=$(LUAC_OBJS:%.o=%.d)
LUAC_CROSS:=$(LUAC_BUILD_DIR)/luac.cross
$(LUAC_BUILD_DIR):
@mkdir -p "$@"
$(LUAC_BUILD_DIR)/%.o: | $(LUAC_BUILD_DIR)
@echo '[hostcc] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) "$<" -c -o "$@"
$(LUAC_BUILD_DIR)/%.d: SHELL=/bin/bash
$(LUAC_BUILD_DIR)/%.d: %.c | $(LUAC_BUILD_DIR)
@echo '[ dep] $<'
@rm -f "$@"
$Qset -eo pipefail; $(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) -M "$<" | sed 's,\($*\.o\)[ :]*,$(LUAC_BUILD_DIR)/\1 $@ : ,g' > "$@.tmp"; mv "$@.tmp" "$@"
build: $(LUAC_DEPS) $(LUAC_CROSS)
$(LUAC_CROSS): $(LUAC_OBJS)
@echo '[ link] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_CFLAGS) $^ $(LUAC_LDFLAGS) -o "$@"
ifneq ($(MAKECMDGOALS),clean)
-include $(LUAC_DEPS)
endif
COMPONENT_OWNBUILDTARGET:=build
COMPONENT_ADD_LDFLAGS:=
build:
$(MAKE) -f $(COMPONENT_PATH)/Makefile HOSTCC=$(HOSTCC) BUILD_DIR_BASE=$(BUILD_DIR_BASE) V=$V COMPONENT_PATH=$(COMPONENT_PATH) CONFIG_LUA_OPTIMIZE_DEBUG=$(CONFIG_LUA_OPTIMIZE_DEBUG)
ar cr lib$(COMPONENT_NAME).a # work around IDF regression
/***--
** lflashimg.c
** Dump a compiled Proto hiearchy to a RO (FLash) image file
** See Copyright Notice in lua.h
*/
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lflashimg_c
#define LUA_CORE
#include "lobject.h"
#include "lstring.h"
#include "lflash.h"
#include "uzlib.h"
//#define LOCAL_DEBUG
#if INT_MAX != 2147483647
# error "luac.cross requires C toolchain with 4 byte word size"
#endif
#define WORDSIZE ((int) sizeof(int))
#define ALIGN(s) (((s)+(WORDSIZE-1)) & (-(signed) WORDSIZE))
#define WORDSHIFT 2
typedef unsigned int uint;
#define FLASH_WORDS(t) (sizeof(t)/sizeof(FlashAddr))
/*
*
* This dumper is a variant of the standard ldump, in that instead of producing a
* binary loader format that lundump can load, it produces an image file that can be
* directly mapped or copied into addressable memory. The typical application is on
* small memory IoT devices which support programmable flash storage such as the
* ESP8266. A 64 Kb LFS image has 16Kb words and will enable all program-related
* storage to be accessed directly from flash, leaving the RAM for true R/W
* application data.
*
* The start address of the Lua Flash Store (LFS) is build-dependent, and the cross
* compiler '-a' option allows the developer to fix the LFS at a defined flash memory
* address. Alternatively and by default the cross compilation adopts a position
* independent image format, which permits the on-device image loader to load the LFS
* image at an appropriate base within the flash address space. As all objects in the
* LFS can be treated as multiples of 4-byte words, also all address fields are both
* word aligned, and any address references within the LFS are also word-aligned.
*
* This version adds gzip compression of the generated LFS image for more efficient
* over-the-air (OTA) transfer, so the method of tagging address words has been
* replaced by a scheme which achieves better compression: an additional bitmap
* has been added to the image, with each bit corresponding to a word in the image
* and set if the corresponding work is an address. The addresses are stored as
* signed relative word offsets.
*
* The unloader is documented in lflash.c Note that his relocation process is
* skipped for absolute addressed images (which are identified by the
* FLASH_SIG_ABSOLUTE bit setting in the flash signature).
*
* The flash image has a standard header detailed in lflash.h
*
* Note that luac.cross may be compiled on any little-endian machine with 32 or 64 bit
* word length so Flash addresses can't be handled as standard C pointers as size_t
* and int may not have the same size. Hence addresses with the must be declared as
* the FlashAddr type rather than typed C pointers and must be accessed through macros.
*
* Also note that image built with a given LUA_PACK_TVALUES / LUA_NUNBER_INTEGRAL
* combination must be loaded into a corresponding firmware build. Hence these
* configuration options are also included in the FLash Signature.
*
* The Flash image is assembled up by first building the RO stringtable containing
* all strings used in the compiled proto hierarchy. This is followed by the Protos.
*
* The storage is allocated bottom up using a serial allocator and the algortihm for
* building the image essentially does a bottom-uo serial enumeration so that any
* referenced storage has already been allocated in the image, and therefore (with the
* exception of the Flash Header) all pointer references are backwards.
*
* As addresses are 4 byte on the target and either 4 or (typically) 8 bytes on the
* host so any structures containing address fields (TStrings, TValues, Protos, other
* address vectors) need repacking.
*/
typedef struct flashts { /* This is the fixed 32-bit equivalent of TString */
FlashAddr next;
lu_byte tt;
lu_byte marked;
int hash;
int len;
} FlashTS;
#ifndef LUA_MAX_FLASH_SIZE
#define LUA_MAX_FLASH_SIZE 0x10000 //in words
#endif
static uint curOffset = 0;
/*
* The flashAddrTag is a bit array, one bit per flashImage word denoting
* whether the corresponding word is a relative address. The defines
* are access methods for this bit array.
*/
static uint flashImage[LUA_MAX_FLASH_SIZE + LUA_MAX_FLASH_SIZE/32];
static uint *flashAddrTag = flashImage + LUA_MAX_FLASH_SIZE;
#define _TW(v) (v)>>5
#define _TB(v) (1<<((v)&0x1F))
#define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v)
#define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0)
#ifdef _MSC_VER
extern void __declspec( noreturn ) fatal( const char* message );
#else
extern void __attribute__((noreturn)) fatal(const char* message);
#endif
#ifdef LOCAL_DEBUG
#define DBG_PRINT(...) printf(__VA_ARGS__)
#else
#define DBG_PRINT(...) ((void)0)
#endif
/*
* Serial allocator. Throw a luac-style out of memory error is allocaiton fails.
*/
static void *flashAlloc(lua_State* L, size_t n) {
void *p = (void *)(flashImage + curOffset);
curOffset += ALIGN(n)>>WORDSHIFT;
if (curOffset > LUA_MAX_FLASH_SIZE) {
fatal("Out of Flash memory");
}
return p;
}
/*
* Convert an absolute address pointing inside the flash image to offset form.
* This macro form also takes the lvalue destination so that this can be tagged
* as a relocatable address.
*/
#define toFlashAddr(l, pd, s) _toFlashAddr(l, &(pd), s)
static void _toFlashAddr(lua_State* L, FlashAddr *a, void *p) {
uint doffset = cast(char *, a) - cast(char *,flashImage);
lua_assert(!(doffset & (WORDSIZE-1))); // check word aligned
doffset >>= WORDSHIFT; // and convert to a word offset
lua_assert(doffset <= curOffset);
if (p) {
uint poffset = cast(char *, p) - cast(char *,flashImage);
lua_assert(!(poffset & (WORDSIZE-1)));
poffset >>= WORDSHIFT;
lua_assert(poffset <= curOffset);
flashImage[doffset] = poffset; // Set the pointer to the offset
setFlashAddrTag(doffset); // And tag as an address
} /* else leave clear */ // Special case for NULL pointer
}
/*
* Convert an image address in offset form back to (host) absolute form
*/
static void *fromFashAddr(FlashAddr a) {
return a ? cast(void *, flashImage + a) : NULL;
}
/*
* Add a TS found in the Proto Load to the table at the ToS
*/
static void addTS(lua_State *L, TString *ts) {
lua_assert(ts->tsv.tt==LUA_TSTRING);
lua_pushnil(L);
setsvalue(L, L->top-1, ts);
lua_pushinteger(L, 1);
lua_rawset(L, -3);
DBG_PRINT("Adding string: %s\n",getstr(ts));
}
/*
* Enumerate all of the Protos in the Proto hiearchy and scan contents to collect
* all referenced strings in a Lua Array at ToS.
*/
static void scanProtoStrings(lua_State *L, const Proto* f) {
/* Table at L->Top[-1] is used to collect the strings */
int i;
if (f->source)
addTS(L, f->source);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo)
addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo)));
#endif
for (i = 0; i < f->sizek; i++) {
if (ttisstring(f->k + i))
addTS(L, rawtsvalue(f->k + i));
}
for (i = 0; i < f->sizeupvalues; i++) addTS(L, f->upvalues[i]);
for (i = 0; i < f->sizelocvars; i++) addTS(L, f->locvars[i].varname);
for (i = 0; i < f->sizep; i++) scanProtoStrings(L, f->p[i]);
}
/*
* Use the collected strings table to build the new ROstrt in the Flash Image
*
* The input is an array of {"SomeString" = 1, ...} on the ToS.
* The output is an array of {"SomeString" = FlashOffset("SomeString"), ...} on ToS
*/
static void createROstrt(lua_State *L, FlashHeader *fh) {
/* Table at L->Top[-1] on input is hash used to collect the strings */
/* Count the number of strings. Can't use objlen as this is a hash */
fh->nROuse = 0;
lua_pushnil(L); /* first key */
while (lua_next(L, -2) != 0) {
fh->nROuse++;
DBG_PRINT("Found: %s\n",getstr(rawtsvalue(L->top-2)));
lua_pop(L, 1); // dump the value
}
fh->nROsize = 2<<luaO_log2(fh->nROuse);
FlashAddr *hashTab = flashAlloc(L, fh->nROsize * WORDSIZE);
toFlashAddr(L, fh->pROhash, hashTab);
/* Now iterate over the strings to be added to the RO string table and build it */
lua_newtable(L); // add output table
lua_pushnil(L); // First key
while (lua_next(L, -3) != 0) { // replaces key, pushes value
TString *ts = rawtsvalue(L->top - 2); // key.ts
const char *p = getstr(ts); // C string of key
uint hash = ts->tsv.hash; // hash of key
size_t len = ts->tsv.len; // and length
DBG_PRINT("2nd pass: %s\n",p);
FlashAddr *e = hashTab + lmod(hash, fh->nROsize);
FlashTS *last = cast(FlashTS *, fromFashAddr(*e));
FlashTS *fts = cast(FlashTS *, flashAlloc(L, sizeof(FlashTS)));
toFlashAddr(L, *e, fts); // add reference to TS to lookup vector
toFlashAddr(L, fts->next, last); // and chain to previous entry if any
fts->tt = LUA_TSTRING; // Set as String
fts->marked = bitmask(LFSBIT); // LFS string with no Whitebits set
fts->hash = hash; // add hash
fts->len = len; // and length
memcpy(flashAlloc(L, len+1), p, len+1); // copy string
// include the trailing null char
lua_pop(L, 1); // Junk the value
lua_pushvalue(L, -1); // Dup the key as rawset dumps its copy
lua_pushinteger(L, cast(FlashAddr*,fts)-flashImage); // Value is new TS offset.
lua_rawset(L, -4); // Add to new table
}
/* At this point the old hash is done to derefence for GC */
lua_remove(L, -2);
}
/*
* Convert a TString reference in the host G(L)->strt entry into the corresponding
* TString address in the flashImage using the lookup table at ToS
*/
static void *resolveTString(lua_State* L, TString *s) {
if (!s)
return NULL;
lua_pushnil(L);
setsvalue(L, L->top-1, s);
lua_rawget(L, -2);
lua_assert(!lua_isnil(L, -1));
void *ts = fromFashAddr(lua_tointeger(L, -1));
lua_pop(L, 1);
return ts;
}
/*
* In order to simplify repacking of structures from the host format to that target
* format, this simple copy routine is data-driven by a simple format specifier.
* n Number of consecutive records to be processed
* fmt A string of A, I, S, V specifiers spanning the record.
* src Source of record
* returns Address of destination record
*/
#if defined(LUA_PACK_TVALUES)
#define TARGET_TV_SIZE (sizeof(lua_Number)+sizeof(lu_int32))
#else
#define TARGET_TV_SIZE (2*sizeof(lua_Number))
#endif
static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* ToS is the string address mapping table */
if (n == 0)
return NULL;
int i, recsize;
void *newts;
/* A bit of a botch because fmt is either "V" or a string of WORDSIZE specifiers */
/* The size 8 / 12 / 16 bytes for integer builds, packed TV and default TVs resp */
if (fmt[0]=='V') {
lua_assert(fmt[1] == 0); /* V formats must be singetons */
recsize = TARGET_TV_SIZE;
} else {
recsize = WORDSIZE * strlen(fmt);
}
uint *d = cast(uint *, flashAlloc(L, n * recsize));
uint *dest = d;
uint *s = cast(uint *, src);
for (i = 0; i < n; i++) {
const char *p = fmt;
while (*p) {
/* All input address types (A,S,V) are aligned to size_t boundaries */
if (*p != 'I' && ((size_t)s)&(sizeof(size_t)-1))
s++;
switch (*p++) {
case 'A':
toFlashAddr(L, *d, *cast(void**, s));
s += FLASH_WORDS(size_t);
d++;
break;
case 'I':
*d++ = *s++;
break;
case 'H':
*d++ = (*s++) & 0;
break;
case 'S':
newts = resolveTString(L, *cast(TString **, s));
toFlashAddr(L, *d, newts);
s += FLASH_WORDS(size_t);
d++;
break;
case 'V':
/* This code has to work for both Integer and Float build variants */
memset(d, 0, TARGET_TV_SIZE);
TValue *sv = cast(TValue *, s);
/* The value is 0, 4 or 8 bytes depending on type */
if (ttisstring(sv)) {
toFlashAddr(L, *d, resolveTString(L, rawtsvalue(sv)));
} else if (ttisnumber(sv)) {
*cast(lua_Number*,d) = *cast(lua_Number*,s);
} else if (!ttisnil(sv)){
/* all other types are 4 byte */
lua_assert(!iscollectable(sv));
*cast(uint *,d) = *cast(uint *,s);
}
*cast(int *,cast(lua_Number*,d)+1) = ttype(sv);
s += FLASH_WORDS(TValue);
d += TARGET_TV_SIZE/WORDSIZE;
break;
default:
lua_assert (0);
}
}
}
return dest;
}
/* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIIAI"
#endif
/*
* Do the actual prototype copy.
*/
static void *functionToFlash(lua_State* L, const Proto* orig) {
Proto f;
int i;
memcpy (&f, orig, sizeof(Proto));
f.gclist = NULL;
f.next = NULL;
l_setbit(f.marked, LFSBIT); /* OK to set the LFSBIT on a stack-cloned copy */
if (f.sizep) { /* clone included Protos */
Proto **p = luaM_newvector(L, f.sizep, Proto *);
for (i=0; i<f.sizep; i++)
p[i] = cast(Proto *, functionToFlash(L, f.p[i]));
f.p = cast(Proto **, flashCopy(L, f.sizep, "A", p));
luaM_freearray(L, p, f.sizep, Proto *);
}
f.k = cast(TValue *, flashCopy(L, f.sizek, "V", f.k));
f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code));
#ifdef LUA_OPTIMIZE_DEBUG
if (f.packedlineinfo) {
TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo));
f.packedlineinfo = cast(unsigned char *, resolveTString(L, ts)) + sizeof (FlashTS);
}
#else
f.lineinfo = cast(int *, flashCopy(L, f.sizelineinfo, "I", f.lineinfo));
#endif
f.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
}
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip,
lu_int32 address, lu_int32 maxSize) {
// parameter strip is ignored for now
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
int i, status;
lua_newtable(L);
scanProtoStrings(L, main);
createROstrt(L, fh);
toFlashAddr(L, fh->mainProto, functionToFlash(L, main));
fh->flash_sig = FLASH_SIG + (address ? FLASH_SIG_ABSOLUTE : 0);
fh->flash_size = curOffset*WORDSIZE;
if (fh->flash_size>maxSize) {
fatal ("The image is too large for specfied LFS size");
}
if (address) { /* in absolute mode convert addresses to mapped address */
for (i = 0 ; i < curOffset; i++)
if (getFlashAddrTag(i))
flashImage[i] = 4*flashImage[i] + address;
lua_unlock(L);
status = w(L, flashImage, fh->flash_size, data);
} else { /* compressed PI mode */
/*
* In image mode, shift the relocation bitmap down directly above
* the used flashimage. This consolidated array is then gzipped.
*/
uint oLen;
uint8_t *oBuf;
int bmLen = sizeof(uint)*((curOffset+31)/32); /* 32 flags to a word */
memmove(flashImage+curOffset, flashAddrTag, bmLen);
status = uzlib_compress (&oBuf, &oLen,
(const uint8_t *)flashImage, bmLen+fh->flash_size);
if (status != UZLIB_OK) {
fatal("Out of memory during image compression");
}
lua_unlock(L);
#if 0
status = w(L, flashImage, bmLen+fh->flash_size, data);
#else
status = w(L, oBuf, oLen, data);
free(oBuf);
#endif
}
lua_lock(L);
return status;
}
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "luac_cross.h" #include "luac_cross.h"
#include C_HEADER_ERRNO #include <errno.h>
#include C_HEADER_LOCALE #include <locale.h>
#include C_HEADER_STDLIB #include <stdlib.h>
#include C_HEADER_STRING #include <string.h>
#include C_HEADER_TIME #include <time.h>
#define loslib_c #define loslib_c
#define LUA_LIB #define LUA_LIB
...@@ -218,33 +218,34 @@ static int os_setlocale (lua_State *L) { ...@@ -218,33 +218,34 @@ static int os_setlocale (lua_State *L) {
static int os_exit (lua_State *L) { static int os_exit (lua_State *L) {
c_exit(luaL_optint(L, 1, EXIT_SUCCESS)); exit(luaL_optint(L, 1, EXIT_SUCCESS));
} }
#undef MIN_OPT_LEVEL #undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1 #define MIN_OPT_LEVEL 1
#include "lrodefs.h" #include "lrotable.h"
const LUA_REG_TYPE syslib[] = { LROT_PUBLIC_BEGIN(oslib)
{LSTRKEY("clock"), LFUNCVAL(os_clock)}, LROT_FUNCENTRY(clock, os_clock)
{LSTRKEY("date"), LFUNCVAL(os_date)}, LROT_FUNCENTRY(date, os_date)
#if !defined LUA_NUMBER_INTEGRAL #if !defined LUA_NUMBER_INTEGRAL
{LSTRKEY("difftime"), LFUNCVAL(os_difftime)}, LROT_FUNCENTRY(difftime, os_difftime)
#endif #endif
{LSTRKEY("execute"), LFUNCVAL(os_execute)}, LROT_FUNCENTRY(execute, os_execute)
{LSTRKEY("exit"), LFUNCVAL(os_exit)}, LROT_FUNCENTRY(exit, os_exit)
{LSTRKEY("getenv"), LFUNCVAL(os_getenv)}, LROT_FUNCENTRY(getenv, os_getenv)
{LSTRKEY("remove"), LFUNCVAL(os_remove)}, LROT_FUNCENTRY(remove, os_remove)
{LSTRKEY("rename"), LFUNCVAL(os_rename)}, LROT_FUNCENTRY(rename, os_rename)
{LSTRKEY("setlocale"), LFUNCVAL(os_setlocale)}, LROT_FUNCENTRY(setlocale, os_setlocale)
{LSTRKEY("time"), LFUNCVAL(os_time)}, LROT_FUNCENTRY(time, os_time)
{LSTRKEY("tmpname"), LFUNCVAL(os_tmpname)}, LROT_FUNCENTRY(tmpname, os_tmpname)
{LNILKEY, LNILVAL} LROT_END(oslib, NULL, 0)
};
/* }====================================================== */ /* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) { LUALIB_API int luaopen_os (lua_State *L) {
LREGISTER(L, LUA_OSLIBNAME, syslib); //LREGISTER(L, LUA_OSLIBNAME, oslib); // <------------- ???
return 0;
} }
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "luac_cross.h" #include "luac_cross.h"
#include C_HEADER_CTYPE #include <ctype.h>
#include C_HEADER_STDIO #include <stdio.h>
#define luac_c #define luac_c
#define LUA_CORE #define LUA_CORE
......
...@@ -60,18 +60,16 @@ static int read_hall_sensor( lua_State *L ) ...@@ -60,18 +60,16 @@ static int read_hall_sensor( lua_State *L )
} }
// Module function map // Module function map
static const LUA_REG_TYPE adc_map[] = LROT_BEGIN(adc)
{ LROT_FUNCENTRY( setwidth, adc_set_width )
{ LSTRKEY( "setwidth" ), LFUNCVAL( adc_set_width ) }, LROT_FUNCENTRY( setup, adc_setup )
{ LSTRKEY( "setup" ), LFUNCVAL( adc_setup ) }, LROT_FUNCENTRY( read, adc_read )
{ LSTRKEY( "read" ), LFUNCVAL( adc_read ) }, LROT_FUNCENTRY( read_hall_sensor, read_hall_sensor )
{ LSTRKEY( "read_hall_sensor" ), LFUNCVAL( read_hall_sensor ) }, LROT_NUMENTRY ( ATTEN_0db, PLATFORM_ADC_ATTEN_0db )
{ LSTRKEY( "ATTEN_0db" ), LNUMVAL( PLATFORM_ADC_ATTEN_0db ) }, LROT_NUMENTRY ( ATTEN_2_5db, PLATFORM_ADC_ATTEN_2_5db )
{ LSTRKEY( "ATTEN_2_5db" ), LNUMVAL( PLATFORM_ADC_ATTEN_2_5db ) }, LROT_NUMENTRY ( ATTEN_6db, PLATFORM_ADC_ATTEN_6db )
{ LSTRKEY( "ATTEN_6db" ), LNUMVAL( PLATFORM_ADC_ATTEN_6db ) }, LROT_NUMENTRY ( ATTEN_11db, PLATFORM_ADC_ATTEN_11db )
{ LSTRKEY( "ATTEN_11db" ), LNUMVAL( PLATFORM_ADC_ATTEN_11db ) }, LROT_NUMENTRY ( ADC1, 1 )
{ LSTRKEY( "ADC1" ), LNUMVAL( 1 ) }, LROT_END(adc, NULL, 0)
{ LNILKEY, LNILVAL }
};
NODEMCU_MODULE(ADC, "adc", adc_map, NULL); NODEMCU_MODULE(ADC, "adc", adc, NULL);
...@@ -119,20 +119,19 @@ static int bit_clear( lua_State* L ) ...@@ -119,20 +119,19 @@ static int bit_clear( lua_State* L )
return 1; return 1;
} }
static const LUA_REG_TYPE bit_map[] = { LROT_BEGIN(bit)
{ LSTRKEY( "bnot" ), LFUNCVAL( bit_bnot ) }, LROT_FUNCENTRY( bnot, bit_bnot )
{ LSTRKEY( "band" ), LFUNCVAL( bit_band ) }, LROT_FUNCENTRY( band, bit_band )
{ LSTRKEY( "bor" ), LFUNCVAL( bit_bor ) }, LROT_FUNCENTRY( bor, bit_bor )
{ LSTRKEY( "bxor" ), LFUNCVAL( bit_bxor ) }, LROT_FUNCENTRY( bxor, bit_bxor )
{ LSTRKEY( "lshift" ), LFUNCVAL( bit_lshift ) }, LROT_FUNCENTRY( lshift, bit_lshift )
{ LSTRKEY( "rshift" ), LFUNCVAL( bit_rshift ) }, LROT_FUNCENTRY( rshift, bit_rshift )
{ LSTRKEY( "arshift" ), LFUNCVAL( bit_arshift ) }, LROT_FUNCENTRY( arshift, bit_arshift )
{ LSTRKEY( "bit" ), LFUNCVAL( bit_bit ) }, LROT_FUNCENTRY( bit, bit_bit )
{ LSTRKEY( "set" ), LFUNCVAL( bit_set ) }, LROT_FUNCENTRY( set, bit_set )
{ LSTRKEY( "clear" ), LFUNCVAL( bit_clear ) }, LROT_FUNCENTRY( clear, bit_clear )
{ LSTRKEY( "isset" ), LFUNCVAL( bit_isset ) }, LROT_FUNCENTRY( isset, bit_isset )
{ LSTRKEY( "isclear" ), LFUNCVAL( bit_isclear ) }, LROT_FUNCENTRY( isclear, bit_isclear )
{ LNILKEY, LNILVAL} LROT_END(bit, NULL, 0)
};
NODEMCU_MODULE(BIT, "bit", bit, NULL);
NODEMCU_MODULE(BIT, "bit", bit_map, NULL);
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