Browse Source

Lua 5.1 / 5.3 alignment and document (#3193)

Terry Ellison 3 years ago
parent
commit
a92da3c33c
76 changed files with 914 additions and 651 deletions
  1. 2 0
      .gitignore
  2. 0 1
      app/coap/coap.h
  3. 0 1
      app/coap/endpoints.c
  4. 2 2
      app/http/httpclient.c
  5. 2 1
      app/include/user_config.h
  6. 110 34
      app/lua/lapi.c
  7. 1 1
      app/lua/lauxlib.c
  8. 16 5
      app/lua/lauxlib.h
  9. 0 1
      app/lua/lbaselib.c
  10. 0 13
      app/lua/lcode.c
  11. 8 29
      app/lua/ldblib.c
  12. 12 25
      app/lua/ldebug.c
  13. 0 6
      app/lua/ldebug.h
  14. 0 10
      app/lua/ldump.c
  15. 15 55
      app/lua/lflash.c
  16. 0 3
      app/lua/lflash.h
  17. 0 9
      app/lua/lfunc.c
  18. 1 5
      app/lua/lgc.c
  19. 1 1
      app/lua/linit.c
  20. 0 1
      app/lua/lmathlib.c
  21. 115 3
      app/lua/lnodemcu.c
  22. 2 3
      app/lua/loadlib.c
  23. 4 11
      app/lua/lobject.h
  24. 3 22
      app/lua/lparser.c
  25. 0 2
      app/lua/lparser.h
  26. 2 1
      app/lua/lstate.c
  27. 2 1
      app/lua/lstate.h
  28. 11 4
      app/lua/lstrlib.c
  29. 0 5
      app/lua/ltable.h
  30. 0 1
      app/lua/ltablib.c
  31. 1 1
      app/lua/ltm.c
  32. 31 25
      app/lua/lua.h
  33. 1 1
      app/lua/luac_cross/Makefile
  34. 0 10
      app/lua/luac_cross/lflashimg.c
  35. 2 2
      app/lua/luac_cross/mingw32-Makefile.mak
  36. 0 6
      app/lua/lundump.c
  37. 3 3
      app/lua/lvm.c
  38. 1 0
      app/lua/lvm.h
  39. 26 0
      app/lua53/lapi.c
  40. 3 55
      app/lua53/lauxlib.c
  41. 11 3
      app/lua53/lauxlib.h
  42. 0 1
      app/lua53/lbaselib.c
  43. 0 1
      app/lua53/lcorolib.c
  44. 8 10
      app/lua53/ldblib.c
  45. 33 0
      app/lua53/ldump.c
  46. 11 0
      app/lua53/lgc.c
  47. 1 3
      app/lua53/linit.c
  48. 2 3
      app/lua53/lmathlib.c
  49. 168 101
      app/lua53/lnodemcu.c
  50. 3 3
      app/lua53/lnodemcu.h
  51. 0 1
      app/lua53/loadlib.c
  52. 0 6
      app/lua53/lobject.h
  53. 9 1
      app/lua53/lparser.c
  54. 2 1
      app/lua53/lstate.c
  55. 7 4
      app/lua53/lstate.h
  56. 9 6
      app/lua53/lstrlib.c
  57. 1 1
      app/lua53/ltable.c
  58. 0 1
      app/lua53/ltablib.c
  59. 14 3
      app/lua53/lua.c
  60. 12 9
      app/lua53/lua.h
  61. 1 0
      app/lua53/lundump.h
  62. 1 2
      app/lua53/lutf8lib.c
  63. 104 62
      app/modules/node.c
  64. 0 1
      app/modules/sjson.c
  65. 6 6
      app/platform/platform.c
  66. 0 1
      app/websocket/websocketclient.c
  67. 2 2
      app/websocket/websocketclient.h
  68. 3 27
      docs/flash.md
  69. 16 0
      docs/lfs.md
  70. 6 0
      docs/lua53.md
  71. 71 28
      docs/modules/node.md
  72. 13 0
      docs/nodemcu-lrm.md
  73. 10 0
      docs/nodemcu-pil.md
  74. 6 2
      mkdocs.yml
  75. 2 1
      msvc/luac-cross/luac-cross.vcxproj
  76. 5 2
      msvc/luac-cross/luac-cross.vcxproj.filters

+ 2 - 0
.gitignore

@@ -1,4 +1,6 @@
 .gdb_history
+app/lua/.std
+app/lua53/.std
 sdk/
 cache/
 .ccache/

+ 0 - 1
app/coap/coap.h

@@ -7,7 +7,6 @@ extern "C" {
 
 #include <stdint.h>
 #include <stddef.h>
-#include "lualib.h"
 #include "lauxlib.h"
 
 #define MAXOPT 16

+ 0 - 1
app/coap/endpoints.c

@@ -5,7 +5,6 @@
 
 #include "lua.h"
 #include "lauxlib.h"
-#include "lualib.h"
 
 #include "os_type.h"
 #include "user_interface.h"

+ 2 - 2
app/http/httpclient.c

@@ -14,12 +14,12 @@
 
 #include "osapi.h"
 #include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
 #include "user_interface.h"
 #include "espconn.h"
 #include "mem.h"
-#include "limits.h"
 #include "httpclient.h"
-#include "stdlib.h"
 #include "pm/swtimer.h"
 
 #define REDIRECTION_FOLLOW_MAX 20

+ 2 - 1
app/include/user_config.h

@@ -247,7 +247,8 @@
 
 #define LUA_TASK_PRIO             USER_TASK_PRIO_0
 #define LUA_PROCESS_LINE_SIG      2
-#define LUA_OPTIMIZE_DEBUG        2
+// LUAI_OPTIMIZE_DEBUG 0 = Keep all debug; 1 = keep line number info; 2 = remove all debug
+#define LUAI_OPTIMIZE_DEBUG       1
 #define READLINE_INTERVAL        80
 #define STRBUF_DEFAULT_INCREMENT  3
 #define LUA_USE_BUILTIN_DEBUG_MINIMAL // for debug.getregistry() and debug.traceback()

+ 110 - 34
app/lua/lapi.c

@@ -152,6 +152,16 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
 */
 
 
+/*
+** convert an acceptable stack index into an absolute index
+*/
+LUA_API int lua_absindex (lua_State *L, int idx) {
+  return (idx > 0 || idx <= LUA_REGISTRYINDEX)
+         ? idx
+         : cast_int(L->top - L->base) - 1 + idx;
+}
+
+
 LUA_API int lua_gettop (lua_State *L) {
   return cast_int(L->top - L->base);
 }
@@ -241,7 +251,7 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
 
 LUA_API int lua_type (lua_State *L, int idx) {
   StkId o = index2adr(L, idx);
-  return (o == luaO_nilobject) ? LUA_TNONE : basettype(o);
+  return (o == luaO_nilobject) ? LUA_TNONE : ttnov(o);
 }
 
 
@@ -253,7 +263,7 @@ LUA_API int lua_fulltype (lua_State *L, int idx) {
 
 LUA_API const char *lua_typename (lua_State *L, int t) {
   UNUSED(L);
-  return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
+  return (t == LUA_TNONE || t >= LUA_NUMTAGS) ? "no value" : luaT_typenames[t];
 }
 
 
@@ -290,32 +300,25 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
 }
 
 
-LUA_API int lua_equal (lua_State *L, int index1, int index2) {
-  StkId o1, o2;
-  int i;
-  lua_lock(L);  /* may call tag method */
-  o1 = index2adr(L, index1);
-  o2 = index2adr(L, index2);
-  i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
-  lua_unlock(L);
-  return i;
-}
-
-
-LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
+LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
   StkId o1, o2;
-  int i;
+  int i = 0;
   lua_lock(L);  /* may call tag method */
   o1 = index2adr(L, index1);
   o2 = index2adr(L, index2);
-  i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
-       : luaV_lessthan(L, o1, o2);
+  if (o1 != luaO_nilobject && o2 != luaO_nilobject) {
+    switch (op) {
+      case LUA_OPEQ: i = luaV_equalval(L, o1, o2); break;
+      case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
+      case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
+      default: api_check(L, 0);
+    }
+  }
   lua_unlock(L);
   return i;
 }
 
 
-
 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
   TValue n;
   const TValue *o = index2adr(L, idx);
@@ -366,7 +369,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
 
 LUA_API size_t lua_objlen (lua_State *L, int idx) {
   StkId o = index2adr(L, idx);
-  switch (basettype(o)) {
+  switch (ttnov(o)) {
     case LUA_TSTRING: return tsvalue(o)->len;
     case LUA_TUSERDATA: return uvalue(o)->len;
     case LUA_TTABLE: return luaH_getn(hvalue(o));
@@ -552,16 +555,17 @@ LUA_API int lua_pushthread (lua_State *L) {
 */
 
 
-LUA_API void lua_gettable (lua_State *L, int idx) {
+LUA_API int lua_gettable (lua_State *L, int idx) {
   StkId t;
   lua_lock(L);
   t = index2adr(L, idx);
   api_checkvalidindex(L, t);
   luaV_gettable(L, t, L->top - 1, L->top - 1);
   lua_unlock(L);
+  return ttnov(L->top - 1);
 }
 
-LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
+LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
   StkId t;
   TValue key;
   lua_lock(L);
@@ -573,20 +577,36 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
   luaV_gettable(L, t, &key, L->top);
   api_incr_top(L);
   lua_unlock(L);
+  return ttnov(L->top - 1);
 }
 
+LUA_API int lua_geti (lua_State *L, int idx, int n) {
+  StkId t;
+  TValue key;
+  lua_lock(L);
+  t = index2adr(L, idx);
+  api_checkvalidindex(L, t);
+  fixedstack(L);
+  setnvalue(&key, n);
+  unfixedstack(L);
+  luaV_gettable(L, t, &key, L->top);
+  api_incr_top(L);
+  lua_unlock(L);
+  return ttnov(L->top - 1);
+}
 
-LUA_API void lua_rawget (lua_State *L, int idx) {
+LUA_API int lua_rawget (lua_State *L, int idx) {
   StkId t;
   lua_lock(L);
   t = index2adr(L, idx);
   api_check(L, ttistable(t));
   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
   lua_unlock(L);
+  return ttnov(L->top - 1);
 }
 
 
-LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
+LUA_API int lua_rawgeti (lua_State *L, int idx, int n) {
   StkId o;
   lua_lock(L);
   o = index2adr(L, idx);
@@ -594,6 +614,21 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
   api_incr_top(L);
   lua_unlock(L);
+  return ttnov(L->top - 1);
+}
+
+
+LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
+  StkId t;
+  TValue k;
+  lua_lock(L);
+  t = index2adr(L, idx);
+  api_check(L, ttistable(t));
+  setpvalue(&k, cast(void *, p));
+  setobj2s(L, L->top, luaH_get(hvalue(t), &k));
+  api_incr_top(L);
+  lua_unlock(L);
+  return ttnov(L->top - 1);
 }
 
 
@@ -612,7 +647,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
   int res;
   lua_lock(L);
   obj = index2adr(L, objindex);
-  switch (basettype(obj)) {
+  switch (ttnov(obj)) {
     case LUA_TTABLE:
       mt = hvalue(obj)->metatable;
       break;
@@ -620,7 +655,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
       mt = uvalue(obj)->metatable;
       break;
     default:
-      mt = G(L)->mt[basettype(obj)];
+      mt = G(L)->mt[ttnov(obj)];
       break;
   }
   if (mt == NULL)
@@ -720,6 +755,23 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
 }
 
 
+LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
+  StkId o;
+  TValue k;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  o = index2adr(L, idx);
+  api_check(L, ttistable(o));
+  fixedstack(L);
+  setpvalue(&k, cast(void *, p))
+  setobj2t(L, luaH_set(L, hvalue(o), &k), L->top-1);
+  unfixedstack(L);
+  luaC_barriert(L, hvalue(o), L->top-1);
+  L->top--;
+  lua_unlock(L);
+}
+
+
 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
   TValue *obj;
   Table *mt;
@@ -750,7 +802,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
       break;
     }
     default: {
-      G(L)->mt[basettype(obj)] = mt;
+      G(L)->mt[ttnov(obj)] = mt;
       break;
     }
   }
@@ -901,7 +953,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
 }
 
 
-LUA_API int lua_dumpEx (lua_State *L, lua_Writer writer, void *data, int stripping) {
+LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int stripping) {
   int status;
   TValue *o;
   lua_lock(L);
@@ -916,6 +968,30 @@ LUA_API int lua_dumpEx (lua_State *L, lua_Writer writer, void *data, int strippi
 }
 
 
+LUA_API int lua_stripdebug (lua_State *L, int stripping){
+  TValue *o = L->top - 1; 
+  Proto *p = NULL;
+  int res = -1;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  if (isLfunction(o)) {
+    p = clvalue(o)->l.p;
+    if (p && !isLFSobject(p) && (unsigned) stripping < 3 ) {
+    // found a valid proto to strip
+      res = luaG_stripdebug(L, p, stripping, 1);
+    }
+  } else if (ttisnil(L->top - 1)) {
+    // get or set the default strip level
+    if ((unsigned) stripping < 3)
+      G(L)->stripdefault = stripping;
+    res = G(L)->stripdefault;
+  }
+  L->top--;
+  lua_unlock(L);
+  return res;
+}
+
+
 LUA_API int  lua_status (lua_State *L) {
   return L->status;
 }
@@ -1136,15 +1212,15 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
   return name;
 }
 
-LUA_API void lua_setegcmode( lua_State *L, int mode, int limit) {
+LUA_API void lua_setegcmode ( lua_State *L, int mode, int limit) {
   G(L)->egcmode = mode;
   G(L)->memlimit = limit;
 }
 
-LUA_API void legc_set_mode(lua_State *L, int mode, int limit) {
-   global_State *g = G(L);
-
-   g->egcmode = mode;
-   g->memlimit = limit;
+LUA_API void lua_getegcinfo (lua_State *L, int *totals) {
+  if (totals) {
+    totals[0] = G(L)->totalbytes;
+    totals[1] = G(L)->estimate;
+  }
 }
 

+ 1 - 1
app/lua/lauxlib.c

@@ -25,9 +25,9 @@
 */
 
 #define lauxlib_c
+#include "lauxlib.h"
 #define LUA_LIB
 
-#include "lauxlib.h"
 #include "lgc.h"
 #include "ldo.h"
 #include "lobject.h"

+ 16 - 5
app/lua/lauxlib.h

@@ -9,6 +9,9 @@
 #define lauxlib_h
 
 #include "lua.h"
+#ifdef LUA_LIB
+#include "lnodemcu.h"
+#endif
 
 #include <stdio.h>
 
@@ -73,7 +76,7 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
 
 LUALIB_API int (luaL_ref) (lua_State *L, int t);
 LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-#define luaL_unref2(l,t,r) luaL_unref(L, (t), (r)); r = LUA_NOREF
+#define luaL_unref2(l,t,r) do {luaL_unref(L, (t), (r)); r = LUA_NOREF;} while (0)
 LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
 
 LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
@@ -108,8 +111,8 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
 #define luaL_optint(L,n,d)	((int)luaL_optinteger(L, (n), (d)))
 #define luaL_checklong(L,n)	((long)luaL_checkinteger(L, (n)))
 #define luaL_optlong(L,n,d)	((long)luaL_optinteger(L, (n), (d)))
-#define luaL_checktable(L,n)	luaL_checktype(L, (n), LUA_TTABLE);
-#define luaL_checkfunction(L,n)	luaL_checktype(L, (n), LUA_TFUNCTION);
+#define luaL_checktable(L,n)	luaL_checktype(L, (n), LUA_TTABLE)
+#define luaL_checkfunction(L,n)	luaL_checktype(L, (n), LUA_TFUNCTION)
 
 #define luaL_typename(L,i)	lua_typename(L, lua_type(L,(i)))
 
@@ -162,8 +165,16 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
 
 /* }====================================================== */
 
-LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres);
-LUALIB_API int luaL_posttask( lua_State* L, int prio );
+LUALIB_API int  (luaL_pushlfsmodules) (lua_State *L);
+LUALIB_API int  (luaL_pushlfsmodule) (lua_State *L);
+LUALIB_API int  (luaL_pushlfsdts) (lua_State *L);
+
+LUALIB_API void (luaL_lfsreload) (lua_State *L);
+LUALIB_API int  (luaL_pcallx) (lua_State *L, int narg, int nres);
+LUALIB_API int  (luaL_posttask) ( lua_State* L, int prio );
+#define  LUA_TASK_LOW    0
+#define  LUA_TASK_MEDIUM 1
+#define  LUA_TASK_HIGH   2
 
 /* }====================================================== */
 

+ 0 - 1
app/lua/lbaselib.c

@@ -10,7 +10,6 @@
 #define LUA_LIB
 
 #include "lua.h"
-#include "lnodemcu.h"
 
 #include <stdio.h>
 #include <string.h>

+ 0 - 13
app/lua/lcode.c

@@ -780,8 +780,6 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
 }
 
 
-#ifdef LUA_OPTIMIZE_DEBUG
-
 /*
  * Attempted to write to last (null terminator) byte of lineinfo, so need
  * to grow the lineinfo vector and extend the fill bytes
@@ -828,10 +826,8 @@ static void generateInfoDeltaLine(FuncState *fs, int line) {
   fs->lastlineOffset = p - fs->f->packedlineinfo - 1;
 #undef addDLbyte
 }
-#endif
 
 void luaK_fixline (FuncState *fs, int line) {
-#ifdef LUA_OPTIMIZE_DEBUG
   /* The fixup line can be the same as existing one and in this case there's nothing to do */
   if (line != fs->lastline) {
     /* first remove the current line reference */
@@ -862,9 +858,6 @@ void luaK_fixline (FuncState *fs, int line) {
     /* Then add the new line reference */
     generateInfoDeltaLine(fs, line);
   }
-#else
-   fs->f->lineinfo[fs->pc - 1] = line;
-#endif
 }
 
 
@@ -876,7 +869,6 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
                   MAX_INT, "code size overflow");
   f->code[fs->pc] = i;
   /* save corresponding line information */
-#ifdef LUA_OPTIMIZE_DEBUG
   /* note that frst time fs->lastline==0 through, so the else branch is taken */
   if (fs->pc == fs->lineinfoLastPC+1) {
     if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) {
@@ -890,11 +882,6 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
     luaK_fixline(fs,line);
   }
   fs->lineinfoLastPC = fs->pc;
-#else
-  luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
-                  MAX_INT, "code size overflow");
-  f->lineinfo[fs->pc] = line;
-#endif
   return fs->pc++;
 }
 

+ 8 - 29
app/lua/ldblib.c

@@ -15,9 +15,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lstring.h"
-#include "lflash.h"
-#include "lnodemcu.h"
 
 #include "user_modules.h"
 
@@ -27,34 +24,16 @@ static int db_getregistry (lua_State *L) {
 }
 
 static int db_getstrings (lua_State *L) {
-  size_t i,n=0;
-  stringtable *tb;
-  GCObject *o;
-#ifndef LUA_CROSS_COMPILER
-  const char *opt = lua_tolstring (L, 1, &n);
-  if (n==3 && memcmp(opt, "ROM", 4) == 0) {
-    if (G(L)->ROstrt.hash == NULL)
-      return 0;
-    tb = &G(L)->ROstrt;
-  }
-  else
-#endif
-  tb = &G(L)->strt;
-  lua_settop(L, 0);
-  lua_createtable(L, tb->nuse, 0);          /* create table the same size as the strt */
-  for (i=0, n=1; i<tb->size; i++) {
-    for(o = tb->hash[i]; o; o=o->gch.next) {
-      TString *ts =cast(TString *, o);
-      lua_pushnil(L);
-      setsvalue2s(L, L->top-1, ts);
-      lua_rawseti(L, -2, n++);             /* enumerate the strt, adding elements */
+  static const char *const opts[] = {"RAM","ROM",NULL};
+  int opt = luaL_checkoption(L, 1, "RAM", opts);
+  if (lua_pushstringsarray(L, opt)) {
+    if(lua_getglobal(L, "table") == LUA_TTABLE) {
+      lua_getfield(L, -1, "sort");    /* look up table.sort function */
+      lua_replace(L, -2);             /* dump the table table */
+      lua_pushvalue(L, -2);           /* duplicate the strt_copy ref */
+      lua_call(L, 1, 0);              /* table.sort(strt_copy) */
     }
   }
-  lua_getfield(L, LUA_GLOBALSINDEX, "table");
-  lua_getfield(L, -1, "sort");             /* look up table.sort function */
-  lua_replace(L, -2);                      /* dump the table table */
-  lua_pushvalue(L, -2);                    /* duplicate the strt_copy ref */
-  lua_call(L, 1, 0);                       /* table.sort(strt_copy) */
   return 1;
 }
 

+ 12 - 25
app/lua/ldebug.c

@@ -182,8 +182,7 @@ static void info_tailcall (lua_Debug *ar) {
 #  define INFO_DELTA_7BITS 0x7F
 #  define INFO_MAX_LINECNT  126
 
-     Table *t = luaH_new(L, 0, 0);
-#ifdef LUA_OPTIMIZE_DEBUG
+    Table *t = luaH_new(L, 0, 0);
     int line = 0;
     unsigned char *p = f->l.p->packedlineinfo;
     if (p) {
@@ -203,18 +202,11 @@ static void info_tailcall (lua_Debug *ar) {
        setbvalue(luaH_setnum(L, t, line), 1);
       }
     }
-#else
-     int *lineinfo = f->l.p->lineinfo;
-     int i;
-     for (i=0; i<f->l.p->sizelineinfo; i++)
-       setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
-#endif
-     sethvalue(L, L->top, t);
+    sethvalue(L, L->top, t);
    }
    incr_top(L);
  }
 
-#ifdef LUA_OPTIMIZE_DEBUG
 /*
  * This may seem expensive but this is only accessed frequently in traceexec
  * and the while loop will be executed roughly half the number of non-blank
@@ -249,18 +241,17 @@ int luaG_getline (const Proto *f, int pc) {
 
 static int stripdebug (lua_State *L, Proto *f, int level) {
   int len = 0, sizepackedlineinfo;
-  TString* dummy;
   switch (level) {
-    case 3:
-      sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1;
-      f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
-      len += sizepackedlineinfo;
     case 2:
-      len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *));
+      if (f->packedlineinfo) {
+        sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1;
+        f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
+        len += sizepackedlineinfo;
+      }
+    case 1:
       f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
       f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
-      len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) +
-             f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *));
+      len += f->sizelocvars*sizeof(struct LocVar) + f->sizeupvalues*sizeof(TString *);
       f->sizelocvars = 0;
       f->sizeupvalues = 0;
   }
@@ -276,7 +267,6 @@ LUA_API int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){
   len += stripdebug (L, f, level);
   return len;
 }
-#endif
 
 
 static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
@@ -379,9 +369,6 @@ static int precheck (const Proto *pt) {
   check(!(pt->is_vararg & VARARG_NEEDSARG) ||
               (pt->is_vararg & VARARG_HASARG));
   check(pt->sizeupvalues <= pt->nups);
-#ifndef LUA_OPTIMIZE_DEBUG
-  check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
-#endif
   check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
   return 1;
 }
@@ -668,7 +655,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
 
 void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
   const char *name = NULL;
-  const char *t = luaT_typenames[basettype(o)];
+  const char *t = luaT_typenames[ttnov(o)];
   const char *kind = (isinstack(L->ci, o)) ?
                          getobjname(L, L->ci, cast_int(o - L->base), &name) :
                          NULL;
@@ -696,8 +683,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
 
 
 int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
-  const char *t1 = luaT_typenames[basettype(p1)];
-  const char *t2 = luaT_typenames[basettype(p2)];
+  const char *t1 = luaT_typenames[ttnov(p1)];
+  const char *t2 = luaT_typenames[ttnov(p2)];
   if (t1[2] == t2[2])
     luaG_runerror(L, "attempt to compare two %s values", t1);
   else

+ 0 - 6
app/lua/ldebug.h

@@ -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

+ 0 - 10
app/lua/ldump.c

@@ -228,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);
@@ -236,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);

+ 15 - 55
app/lua/lflash.c

@@ -194,21 +194,20 @@ static int loadLFS (lua_State *L);
 static int loadLFSgc (lua_State *L);
 static void procFirstPass (void);
 
-/* lua_lfsreload() and lua_lfsindex() are exported via lua.h */
+/* luaL_lfsreload() is exported via lauxlib.h */
 
 /*
  * Library function called by node.flashreload(filename).
  */
-LUALIB_API int lua_lfsreload (lua_State *L) {
+LUALIB_API void luaL_lfsreload (lua_State *L) {
   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;
   }
 
-
  /*
   * Do a protected call of loadLFS.
   *
@@ -237,7 +236,7 @@ LUALIB_API int lua_lfsreload (lua_State *L) {
     lua_cpcall(L, &loadLFSgc, NULL);
     lua_settop(L, 0);
     lua_pushstring(L, msg);
-    return 1;
+    return;
   }
 
   if (status == 0) {
@@ -257,60 +256,21 @@ LUALIB_API int lua_lfsreload (lua_State *L) {
   NODE_ERR(msg);
 
   while (1) {}  // Force WDT as the ROM software_reset() doesn't seem to work
-  return 0;
 }
 
 
-/*
- * 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 lua_lfsindex (lua_State *L) {
-  int n = lua_gettop(L);
+LUA_API void lua_getlfsconfig (lua_State *L, int *config) {
+  if (!config)
+    return;
+  config[0] = (int) 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 */
+}
 
-  /* 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;
-}
 /* =====================================================================================
  * The following routines use my uzlib which was based on pfalcon's inflate and
  * deflate routines.  The standard NodeMCU make also makes two host tools uz_zip
@@ -483,7 +443,7 @@ void procSecondPass (void) {
 }
 
 /*
- * 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) {

+ 0 - 3
app/lua/lflash.h

@@ -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
 

+ 0 - 9
app/lua/lfunc.c

@@ -125,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,13 +141,9 @@ void luaF_freeproto (lua_State *L, Proto *f) {
   luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
   luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
   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_free(L, f);
 }
 

+ 1 - 5
app/lua/lgc.c

@@ -327,11 +327,7 @@ static l_mem propagatemark (global_State *g) {
                              sizeof(LocVar) * p->sizelocvars +
                              sizeof(TString *) * p->sizeupvalues +
                              sizeof(Instruction) * p->sizecode +
-#ifdef LUA_OPTIMIZE_DEBUG
                                (p->packedlineinfo ?  strlen(cast(char *, p->packedlineinfo))+1 : 0);
-#else
-                               sizeof(int) * p->sizelineinfo;
-#endif
     }
     default: lua_assert(0); return 0;
   }
@@ -515,7 +511,7 @@ void luaC_freeall (lua_State *L) {
 
 static void markmt (global_State *g) {
   int i;
-  for (i=0; i<NUM_TAGS; i++)
+  for (i=0; i<LUA_NUMTAGS; i++)
     if (g->mt[i] && isrwtable(g->mt[i])) markobject(g, g->mt[i]);
 }
 

+ 1 - 1
app/lua/linit.c

@@ -61,7 +61,7 @@ extern LROT_TABLE(math);
 #if defined(LUA_CROSS_COMPILER)
 extern LROT_TABLE(base_func);
 LROT_BEGIN(rotables_meta, NULL, LROT_MASK_INDEX)
-  LROT_TABENTRY( _index, base_func)
+  LROT_TABENTRY( __index, base_func)
 LROT_END(rotables_meta, NULL, LROT_MASK_INDEX)
 
 extern LROT_TABLE(oslib);

+ 0 - 1
app/lua/lmathlib.c

@@ -14,7 +14,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 #undef PI
 #define PI (3.14159265358979323846)

+ 115 - 3
app/lua/lnodemcu.c

@@ -19,8 +19,10 @@
 #include "ltable.h"
 #include "ltm.h"
 #include "lnodemcu.h"
-#include "platform.h"
 
+//== NodeMCU lauxlib.h API extensions ========================================//
+#ifdef LUA_USE_ESP
+#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
@@ -99,8 +101,7 @@ static void do_task (platform_task_param_t task_fn_ref, uint8_t prio) {
 /*
 ** Schedule a Lua function for task execution
 */
-#include "lstate.h" /*DEBUG*/
-LUALIB_API int luaL_posttask( lua_State* L, int prio ) {            // [-1, +0, -]
+LUALIB_API int luaL_posttask( lua_State* L, int prio ) {          // [-1, +0, -]
   if (!task_handle)
     task_handle = platform_task_get_id(do_task);
 
@@ -115,6 +116,98 @@ LUALIB_API int luaL_posttask( lua_State* L, int prio ) {            // [-1, +0,
   }
   return task_fn_ref;
 }
+#else
+LUALIB_API int luaL_posttask( lua_State* L, int 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) platform_freeheap();
+#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;
@@ -142,3 +235,22 @@ LUA_API void lua_createrotable (lua_State *L, ROTable *t, const ROTable_entry *e
   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

+ 2 - 3
app/lua/loadlib.c

@@ -23,7 +23,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 /* prefix for open functions in C libraries */
 #define LUA_POF		"luaopen_"
@@ -474,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);
@@ -567,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);

+ 4 - 11
app/lua/lobject.h

@@ -17,7 +17,7 @@
 /* tags for values visible from Lua */
 #define LAST_TAG	LUA_TTHREAD
 
-#define NUM_TAGS	(LAST_TAG+1)
+#define LUA_NUMTAGS	(LAST_TAG+1)
 
 #define READONLYMASK    (1<<7)      /* denormalised bitmask for READONLYBIT and */
 #define LFSMASK         (1<<6)      /* LFSBIT to avoid include proliferation */
@@ -111,7 +111,7 @@ typedef struct lua_TValue {
 #define ttisnil(o)		(ttype(o) == LUA_TNIL)
 #define ttisnumber(o)		(ttype(o) == LUA_TNUMBER)
 #define ttisstring(o)		(ttype(o) == LUA_TSTRING)
-#define ttistable(o)		(basettype(o) == LUA_TTABLE)
+#define ttistable(o)		(ttnov(o) == LUA_TTABLE)
 #define ttisrwtable(o)		(type(o) == LUA_TTABLE)
 #define ttisrotable(o)		(ttype(o) & LUA_TISROTABLE)
 #define ttisboolean(o)		(ttype(o) == LUA_TBOOLEAN)
@@ -120,12 +120,12 @@ typedef struct lua_TValue {
 #define ttislightuserdata(o)	(ttype(o) == LUA_TLIGHTUSERDATA)
 #define ttislightfunction(o)	(ttype(o) == LUA_TLIGHTFUNCTION)
 #define ttisclfunction(o)	(ttype(o) == LUA_TFUNCTION)
-#define ttisfunction(o)		(basettype(o) == LUA_TFUNCTION)
+#define ttisfunction(o)		(ttnov(o) == LUA_TFUNCTION)
 
 /* Macros to access values */
 
 #define ttype(o)	((void) (o)->value, (o)->tt)
-#define basettype(o)	((void) (o)->value, ((o)->tt & LUA_TMASK))
+#define ttnov(o)	((void) (o)->value, ((o)->tt & LUA_TMASK))
 #define gcvalue(o)	check_exp(iscollectable(o), (o)->value.gc)
 #define pvalue(o)	check_exp(ttislightuserdata(o), (o)->value.p)
 #define fvalue(o)	check_exp(ttislightfunction(o), (o)->value.p)
@@ -277,20 +277,13 @@ typedef struct Proto {
   TValue *k;  /* constants used by the function */
   Instruction *code;
   struct Proto **p;  /* functions defined inside the function */
-#ifdef LUA_OPTIMIZE_DEBUG
   unsigned char *packedlineinfo;
-#else
-  int *lineinfo;  /* map from opcodes to source lines */
-#endif
   struct LocVar *locvars;  /* information about local variables */
   TString **upvalues;  /* upvalue names */
   TString  *source;
   int sizeupvalues;
   int sizek;  /* size of `k' */
   int sizecode;
-#ifndef LUA_OPTIMIZE_DEBUG
-  int sizelineinfo;
-#endif
   int sizep;  /* size of `p' */
   int sizelocvars;
   int linedefined;

+ 3 - 22
app/lua/lparser.c

@@ -343,12 +343,10 @@ static void open_func (LexState *ls, FuncState *fs) {
   fs->bl = NULL;
   f->source = ls->source;
   f->maxstacksize = 2;  /* registers 0/1 are always valid */
-#ifdef LUA_OPTIMIZE_DEBUG
   fs->packedlineinfoSize = 0;
   fs->lastline = 0;
   fs->lastlineOffset = 0;
   fs->lineinfoLastPC = -1;
-#endif
   fs->h = luaH_new(L, 0, 0);
   /* anchor table of constants and prototype (to avoid being collected) */
   sethvalue2s(L, L->top, fs->h);
@@ -366,15 +364,9 @@ static void close_func (LexState *ls) {
   luaK_ret(fs, 0, 0);  /* final return */
   luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
   f->sizecode = fs->pc;
-#ifdef LUA_OPTIMIZE_DEBUG
   f->packedlineinfo[fs->lastlineOffset+1]=0;
   luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize,
                      fs->lastlineOffset+2, unsigned char);
-#else
-  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
-  f->sizelineinfo = fs->pc;
-#endif
-
   luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
   f->sizek = fs->nk;
   luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
@@ -391,20 +383,11 @@ static void close_func (LexState *ls) {
   L->top -= 2;  /* remove table and prototype from the stack */
 }
 
-#ifdef LUA_OPTIMIZE_DEBUG
 static void compile_stripdebug(lua_State *L, Proto *f) {
-  int level;
-  lua_pushlightuserdata(L, &luaG_stripdebug );
-  lua_gettable(L, LUA_REGISTRYINDEX);
-  level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1);
-  lua_pop(L, 1);
-
-  if (level > 1) {
-    int len = luaG_stripdebug(L, f, level, 1);
-    UNUSED(len);
-  }
+  int level =  G(L)->stripdefault;
+  if (level > 0)
+    luaG_stripdebug(L, f, level, 1);
 }
-#endif
 
 
 Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
@@ -421,9 +404,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
   chunk(&lexstate);
   check(&lexstate, TK_EOS);
   close_func(&lexstate);
-#ifdef LUA_OPTIMIZE_DEBUG
   compile_stripdebug(L, funcstate.f);
-#endif
   L->top--; /* remove 'name' from stack */
   lua_assert(funcstate.prev == NULL);
   lua_assert(funcstate.f->nups == 0);

+ 0 - 2
app/lua/lparser.h

@@ -72,12 +72,10 @@ typedef struct FuncState {
   lu_byte nactvar;  /* number of active local variables */
   upvaldesc upvalues[LUAI_MAXUPVALUES];  /* upvalues */
   unsigned short actvar[LUAI_MAXVARS];  /* declared-variable stack */
-#ifdef LUA_OPTIMIZE_DEBUG
   int packedlineinfoSize; /* only used during compilation for line info */
   int lastline;           /* ditto */
   int lastlineOffset;     /* ditto */
   int lineinfoLastPC;     /* ditto */
-#endif
 } FuncState;
 
 

+ 2 - 1
app/lua/lstate.c

@@ -184,6 +184,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->memlimit = 0;
   g->gcpause = LUAI_GCPAUSE;
   g->gcstepmul = LUAI_GCMUL;
+  g->stripdefault = LUAI_OPTIMIZE_DEBUG;
   g->gcdept = 0;
 #ifdef EGC_INITIAL_MODE
   g->egcmode = EGC_INITIAL_MODE;
@@ -203,7 +204,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->LFSsize        = 0;
   g->error_reporter = 0;
 #endif
-  for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
+  for (i=0; i<LUA_NUMTAGS; i++) g->mt[i] = NULL;
   if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
     /* memory allocation error: free partial state */
     close_state(L);

+ 2 - 1
app/lua/lstate.h

@@ -87,12 +87,13 @@ typedef struct global_State {
   lu_mem gcdept;  /* how much GC is `behind schedule' */
   int gcpause;  /* size of pause between successive GCs */
   int gcstepmul;  /* GC `granularity' */
+  int stripdefault;  /* default stripping level for compilation */
   int egcmode;    /* emergency garbage collection operation mode */
   lua_CFunction panic;  /* to be called in unprotected errors */
   TValue l_registry;
   struct lua_State *mainthread;
   UpVal uvhead;  /* head of double-linked list of all open upvalues */
-  struct Table *mt[NUM_TAGS];  /* metatables for basic types */
+  struct Table *mt[LUA_NUMTAGS];  /* metatables for basic types */
   TString *tmname[TM_N];  /* array with tag-method names */
 #ifndef LUA_CROSS_COMPILER
   stringtable ROstrt;  /* Flash-based hash table for RO strings */

+ 11 - 4
app/lua/lstrlib.c

@@ -14,7 +14,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 /* macro to `unsign' a character */
 #define uchar(c)        ((unsigned char)(c))
@@ -141,17 +140,25 @@ static int writer (lua_State *L, const void* b, size_t size, void* B) {
 
 static int str_dump (lua_State *L) {
   luaL_Buffer b;
+  int strip, tstrip = lua_type(L, 2);
+  if (tstrip == LUA_TBOOLEAN) {
+    strip = lua_toboolean(L, 2) ? 2 : 0;
+  } else if (tstrip == LUA_TNONE || tstrip == LUA_TNIL) {
+    strip = -1;  /* This tells lua_dump to use the global strip default */
+  } else { 
+    strip = lua_tointeger(L, 2);
+    luaL_argcheck(L, (unsigned)(strip) < 3, 2, "strip out of range");
+  }
   luaL_checktype(L, 1, LUA_TFUNCTION);
   lua_settop(L, 1);
   luaL_buffinit(L,&b);
-  if (lua_dump(L, writer, &b) != 0)
-    luaL_error(L, "unable to dump given function");
+  if (lua_dump(L, writer, &b, strip) != 0)
+    return luaL_error(L, "unable to dump given function");
   luaL_pushresult(&b);
   return 1;
 }
 
 
-
 /*
 ** {======================================================
 ** PATTERN MATCHING

+ 0 - 5
app/lua/ltable.h

@@ -20,21 +20,16 @@
 #define isrwtable(t) (gettt(t)==LUA_TTABLE)
 
 LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
-LUAI_FUNC const TValue *luaH_getnum_ro (void *t, int key);
 LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
 LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
-LUAI_FUNC const TValue *luaH_getstr_ro (void *t, TString *key);
 LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
-LUAI_FUNC const TValue *luaH_get_ro (void *t, const TValue *key);
 LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
 LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
 LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
 LUAI_FUNC void luaH_free (lua_State *L, Table *t);
 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_getn (Table *t);
-LUAI_FUNC int luaH_getn_ro (void *t);
 LUAI_FUNC int luaH_isdummy (Node *n);
 
 #define LUA_MAX_ROTABLE_NAME  32

+ 0 - 1
app/lua/ltablib.c

@@ -12,7 +12,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 
 #define aux_getn(L,n)	(luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))

+ 1 - 1
app/lua/ltm.c

@@ -70,7 +70,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
       mt = uvalue(o)->metatable;
       break;
     default:
-      mt = G(L)->mt[basettype(o)];
+      mt = G(L)->mt[ttnov(o)];
   }
   return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
 }

+ 31 - 25
app/lua/lua.h

@@ -9,9 +9,9 @@
 #ifndef lua_h
 #define lua_h
 #include <stdint.h>
-#include "stdarg.h"
-#include "stddef.h"
-#include "ctype.h"
+#include <stdarg.h>
+#include <stddef.h>
+#include <ctype.h>
 
 #include "luaconf.h"
 
@@ -99,8 +99,8 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
 #include LUA_USER_H
 #endif
 
-#if defined(LUA_OPTIMIZE_DEBUG) && LUA_OPTIMIZE_DEBUG == 0
-#undef LUA_OPTIMIZE_DEBUG
+#ifndef LUAI_OPTIMIZE_DEBUG
+#define LUAI_OPTIMIZE_DEBUG 2
 #endif
 
 /* type of numbers in Lua */
@@ -125,6 +125,7 @@ LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
 /*
 ** basic stack manipulation
 */
+LUA_API int   (lua_absindex) (lua_State *L, int idx);
 LUA_API int   (lua_gettop) (lua_State *L);
 LUA_API void  (lua_settop) (lua_State *L, int idx);
 LUA_API void  (lua_pushvalue) (lua_State *L, int idx);
@@ -148,9 +149,11 @@ LUA_API int             (lua_type) (lua_State *L, int idx);
 LUA_API int             (lua_fulltype) (lua_State *L, int idx);
 LUA_API const char     *(lua_typename) (lua_State *L, int tp);
 
-LUA_API int            (lua_equal) (lua_State *L, int idx1, int idx2);
-LUA_API int            (lua_rawequal) (lua_State *L, int idx1, int idx2);
-LUA_API int            (lua_lessthan) (lua_State *L, int idx1, int idx2);
+LUA_API int             (lua_rawequal) (lua_State *L, int idx1, int idx2);
+#define LUA_OPEQ    0
+#define LUA_OPLT    1
+#define LUA_OPLE    2
+LUA_API int             (lua_compare) (lua_State *L, int idx1, int idx2, int op);
 
 LUA_API lua_Number      (lua_tonumber) (lua_State *L, int idx);
 LUA_API lua_Integer     (lua_tointeger) (lua_State *L, int idx);
@@ -183,10 +186,11 @@ LUA_API int   (lua_pushthread) (lua_State *L);
 /*
 ** get functions (Lua -> stack)
 */
-LUA_API void  (lua_gettable) (lua_State *L, int idx);
-LUA_API void  (lua_getfield) (lua_State *L, int idx, const char *k);
-LUA_API void  (lua_rawget) (lua_State *L, int idx);
-LUA_API void  (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API int   (lua_gettable) (lua_State *L, int idx);
+LUA_API int   (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API int   (lua_rawget) (lua_State *L, int idx);
+LUA_API int   (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API int   (lua_rawgetp) (lua_State *L, int idx, const void *p);
 LUA_API void  (lua_createtable) (lua_State *L, int narr, int nrec);
 LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
 LUA_API int   (lua_getmetatable) (lua_State *L, int objindex);
@@ -200,6 +204,7 @@ LUA_API void  (lua_settable) (lua_State *L, int idx);
 LUA_API void  (lua_setfield) (lua_State *L, int idx, const char *k);
 LUA_API void  (lua_rawset) (lua_State *L, int idx);
 LUA_API void  (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API void  (lua_rawsetp) (lua_State *L, int idx, const void *p);
 LUA_API int   (lua_setmetatable) (lua_State *L, int objindex);
 LUA_API int   (lua_setfenv) (lua_State *L, int idx);
 
@@ -212,8 +217,8 @@ LUA_API int   (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
 LUA_API int   (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
 LUA_API int   (lua_load) (lua_State *L, lua_Reader reader, void *dt,
                                         const char *chunkname);
-
-LUA_API int (lua_dumpEx) (lua_State *L, lua_Writer writer, void *data, int stripping);
+LUA_API int   (lua_dump) (lua_State *L, lua_Writer writer, void *data, int stripping);
+LUA_API int   (lua_stripdebug) (lua_State *L, int stripping);
 
 
 /*
@@ -273,9 +278,7 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
 #define lua_strlen(L,i)		lua_objlen(L, (i))
 
 #define lua_isfunction(L,n)	(lua_type(L, (n)) == LUA_TFUNCTION)
-#define lua_islightfunction(L,n) (lua_fulltype(L, (n)) == LUA_TLIGHTFUNCTION)
 #define lua_istable(L,n)	(lua_type(L, (n)) == LUA_TTABLE)
-#define lua_isrotable(L,n)	(lua_fulltype(L, (n)) == LUA_TROTABLE)
 #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
 #define lua_isnil(L,n)		(lua_type(L, (n)) == LUA_TNIL)
 #define lua_isboolean(L,n)	(lua_type(L, (n)) == LUA_TBOOLEAN)
@@ -291,9 +294,10 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
 
 #define lua_tostring(L,i)	lua_tolstring(L, (i), NULL)
 
-#define lua_dump(L,w,d)		lua_dumpEx(L,w,d,0)
+#define lua_equal(L,idx1,idx2)		lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2)	lua_compare(L,(idx1),(idx2),LUA_OPLT)
 
-/* error codes from cross-compiler returned by lua_dumpEx */
+/* error codes from cross-compiler returned by lua_dump */
 /* target integer is too small to hold a value */
 #define LUA_ERR_CC_INTOVERFLOW 101
 
@@ -382,14 +386,18 @@ struct lua_Debug {
 
 /* }====================================================================== */
 
+/* NodeMCU extensions to the standard API */
+
 typedef struct ROTable ROTable;
 typedef const struct ROTable_entry ROTable_entry;
 
 LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
 LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, ROTable_entry *e, ROTable *mt);
+LUA_API int  (lua_pushstringsarray) (lua_State *L, int opt);
+LUA_API int  (lua_freeheap) (void);
 
-LUAI_FUNC int  lua_lfsreload (lua_State *L);
-LUAI_FUNC int  lua_lfsindex (lua_State *L);
+LUA_API void (lua_getlfsconfig) (lua_State *L, int *);
+LUA_API int  (lua_pushlfsindex) (lua_State *L);
 
 #define EGC_NOT_ACTIVE        0   // EGC disabled
 #define EGC_ON_ALLOC_FAILURE  1   // run EGC on allocation failure
@@ -400,15 +408,13 @@ LUAI_FUNC int  lua_lfsindex (lua_State *L);
 
 #define LUA_QUEUE_APP   0
 #define LUA_QUEUE_UART  1
-#define LUA_TASK_LOW    0
-#define LUA_TASK_MEDIUM 1
-#define LUA_TASK_HIGH   2
 
 /**DEBUG**/extern void dbg_printf(const char *fmt, ...)
                        __attribute__ ((format (printf, 1, 2)));
-#define luaN_freearray(L,b,l)  luaM_freearray(L,b,l,sizeof(*b));
+#define luaN_freearray(L,b,l)  luaM_freearray(L,b,l,sizeof(*b))
 
-LUA_API void lua_setegcmode(lua_State *L, int mode, int limit);
+LUA_API void (lua_setegcmode) (lua_State *L, int mode, int limit);
+LUA_API void (lua_getegcinfo) (lua_State *L, int *totals);
 
 #else
 

+ 1 - 1
app/lua/luac_cross/Makefile

@@ -43,7 +43,7 @@ LUASRC  := lapi.c      lauxlib.c   lbaselib.c  lcode.c     ldblib.c    ldebug.c
            ldo.c       ldump.c     lfunc.c     lgc.c       linit.c     llex.c \
            lmathlib.c  lmem.c      loadlib.c   lobject.c   lopcodes.c  lparser.c \
            lstate.c    lstring.c   lstrlib.c   ltable.c    ltablib.c \
-           ltm.c       lundump.c   lvm.c       lzio.c
+           ltm.c       lundump.c   lvm.c       lzio.c      lnodemcu.c
 UZSRC   := uzlib_deflate.c crc32.c
 
 #

+ 0 - 10
app/lua/luac_cross/lflashimg.c

@@ -186,10 +186,8 @@ static void scanProtoStrings(lua_State *L, const Proto* f) {
   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))
@@ -355,11 +353,7 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
 }
 
 /* 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.
@@ -383,14 +377,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
   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));

+ 2 - 2
app/lua/luac_cross/mingw32-Makefile.mak

@@ -36,8 +36,8 @@ LUACSRC := luac.c      lflashimg.c liolib.c    loslib.c    print.c
 LUASRC  := lapi.c      lauxlib.c   lbaselib.c  lcode.c     ldblib.c    ldebug.c \
            ldo.c       ldump.c     lfunc.c     lgc.c       linit.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
+           lstate.c    lstring.c   lstrlib.c   ltable.c    ltablib.c \
+           ltm.c       lundump.c   lvm.c       lzio.c      lnodemcu.c
 UZSRC   := uzlib_deflate.c crc32.c
 #
 # This relies on the files being unique on the vpath

+ 0 - 6
app/lua/lundump.c

@@ -223,18 +223,12 @@ static void LoadDebug(LoadState* S, Proto* f)
  n=LoadInt(S);
  Align4(S);
 
-#ifdef LUA_OPTIMIZE_DEBUG
  if(n) {
    f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
    LoadBlock(S,f->packedlineinfo,n);
  } else {
    f->packedlineinfo=NULL;
  }
-#else
- f->lineinfo=luaM_newvector(S->L,n,int);
- LoadVector(S,f->lineinfo,n,sizeof(int));
- f->sizelineinfo=n;
- #endif
  n=LoadInt(S);
  f->locvars=luaM_newvector(S->L,n,LocVar);
  f->sizelocvars=n;

+ 3 - 3
app/lua/lvm.c

@@ -271,7 +271,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
 }
 
 
-static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
+int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
   int res;
   if (ttype(l) != ttype(r))
     return luaG_ordererror(L, l, r);
@@ -570,7 +570,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
       }
       case OP_LEN: {
         const TValue *rb = RB(i);
-        switch (basettype(rb)) {
+        switch (ttnov(rb)) {
           case LUA_TTABLE: {
             setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
             break;
@@ -620,7 +620,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
       }
       case OP_LE: {
         Protect(
-          if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
+          if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
             dojump(L, pc, GETARG_sBx(*pc));
         )
         pc++;

+ 1 - 0
app/lua/lvm.h

@@ -23,6 +23,7 @@
 
 
 LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
+LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
 LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
 LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
 LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);

+ 26 - 0
app/lua53/lapi.c

@@ -1031,6 +1031,8 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
   lua_lock(L);
   api_checknelems(L, 1);
   o = L->top - 1;
+  if (strip == -1)
+    strip = G(L)->stripdefault;
   if (isLfunction(o))
     status = luaU_dump(L, getproto(o), writer, data, strip);
   else
@@ -1040,6 +1042,30 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
 }
 
 
+LUA_API int lua_stripdebug (lua_State *L, int stripping){
+  TValue *o = L->top - 1; 
+  Proto *p = NULL;
+  int res = -1;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  if (isLfunction(o)) {
+    p = getproto(o);
+    if (p && !isLFSobj(p) && (unsigned) stripping < 3 ) {
+    // found a valid proto to strip
+      res = luaU_stripdebug(L, p, stripping, 1);
+    }
+  } else if (ttisnil(L->top - 1)) {
+    // get or set the default strip level
+    if ((unsigned) stripping < 3)
+      G(L)->stripdefault = stripping;
+    res = G(L)->stripdefault;
+  }
+  L->top--;
+  lua_unlock(L);
+  return res;
+}
+
+
 LUA_API int lua_status (lua_State *L) {
   return L->status;
 }

+ 3 - 55
app/lua53/lauxlib.c

@@ -5,7 +5,6 @@
 */
 
 #define lauxlib_c
-#define LUA_LIB
 
 #include "lprefix.h"
 
@@ -29,6 +28,8 @@
 #include "lua.h"
 
 #include "lauxlib.h"
+#define LUA_LIB
+
 #ifdef LUA_USE_ESP
 #include "platform.h"
 #include "user_interface.h"
@@ -651,7 +652,6 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
 
 
 LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
-  int reft;
 /*
  * If the ref is positive and the entry in table t exists then
  * overwrite the value otherwise fall through to luaL_ref()
@@ -659,8 +659,7 @@ LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
   if (ref) {
     if (*ref >= 0) {
       t = lua_absindex(L, t);
-      lua_rawgeti(L, t, *ref);
-      reft = lua_type(L, -1);
+      int reft = lua_rawgeti(L, t, *ref);
       lua_pop(L, 1);
       if (reft != LUA_TNIL) {
         lua_rawseti(L, t, *ref);
@@ -706,7 +705,6 @@ typedef struct LoadF {
   char buff[BUFSIZ];  /* area for reading file */
 } LoadF;
 
-#include "llimits.h"
 static const char *getF (lua_State *L, void *ud, size_t *size) {
   LoadF *lf = (LoadF *)ud;
   (void)L;  /* not used */
@@ -1187,54 +1185,4 @@ LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) {
     }
   return status;
 }
-
-extern void lua_main(void);
-/*
-** Task callback handler. Uses luaN_call to do a protected call with full traceback
-*/
-static void do_task (platform_task_param_t task_fn_ref, uint8_t prio) {
-  lua_State* L = lua_getstate();
-  if(task_fn_ref == (platform_task_param_t)~0 && prio == LUA_TASK_HIGH) {
-    lua_main();                   /* Undocumented hook for lua_main() restart */
-    return;
-  }
-  if (prio < LUA_TASK_LOW|| prio > LUA_TASK_HIGH)
-    luaL_error(L, "invalid posk task");
-/* Pop the CB func from the Reg */
-  lua_rawgeti(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
-  luaL_checktype(L, -1, LUA_TFUNCTION);
-  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, -]
-  static platform_task_handle_t task_handle = 0;
-  if (!task_handle)
-    task_handle = platform_task_get_id(do_task);
-  if (L == NULL && prio == LUA_TASK_HIGH+1) { /* Undocumented hook for lua_main */
-    platform_post(LUA_TASK_HIGH, task_handle, (platform_task_param_t)~0);
-    return -1;
-  }
-  if (lua_isfunction(L, -1) && prio >= LUA_TASK_LOW && prio <= LUA_TASK_HIGH) {
-    int task_fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-    if(!platform_post(prio, task_handle, (platform_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 {
-    return luaL_error(L, "invalid posk task");
-  }
-}
-#else
-/*
-** Task execution isn't supported on HOST builds so returns a -1 status
-*/
-LUALIB_API int luaL_posttask( lua_State* L, int prio ) {            // [-1, +0, -]
-  return -1;
-}
 #endif

+ 11 - 3
app/lua53/lauxlib.h

@@ -14,6 +14,9 @@
 
 #include "lua.h"
 
+#ifdef LUA_LIB
+#include "lnodemcu.h"
+#endif
 
 
 /* extra error code for 'luaL_loadfilex' */
@@ -79,7 +82,7 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
 
 LUALIB_API int (luaL_ref) (lua_State *L, int t);
 LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-#define luaL_unref2(l,t,r) luaL_unref(L, (t), (r)); r = LUA_NOREF
+#define luaL_unref2(l,t,r) do {luaL_unref(L, (t), (r)); r = LUA_NOREF;} while (0)
 LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
 
 LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
@@ -282,8 +285,13 @@ extern void dbg_printf(const char *fmt, ...);
 #define LUA_TASK_MEDIUM 1
 #define LUA_TASK_HIGH   2
 
-LUALIB_API int (luaL_posttask) (lua_State* L, int prio);
-LUALIB_API int (luaL_pcallx) (lua_State *L, int narg, int nres);
+LUALIB_API int  (luaL_pushlfsmodules) (lua_State *L);
+LUALIB_API int  (luaL_pushlfsdts) (lua_State *L);
+LUALIB_API void (luaL_lfsreload) (lua_State *L);
+LUALIB_API int  (luaL_posttask) (lua_State* L, int prio);
+LUALIB_API int  (luaL_pcallx) (lua_State *L, int narg, int nres);
+
+#define luaL_pushlfsmodule(l) lua_pushlfsfunc(L)
 
 /* }============================================================ */
 

+ 0 - 1
app/lua53/lbaselib.c

@@ -18,7 +18,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 
 static int luaB_print (lua_State *L) {

+ 0 - 1
app/lua53/lcorolib.c

@@ -16,7 +16,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 
 static lua_State *getco (lua_State *L) {

+ 8 - 10
app/lua53/ldblib.c

@@ -18,7 +18,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 
 /*
@@ -48,16 +47,15 @@ static int db_getregistry (lua_State *L) {
 static int db_getstrings (lua_State *L) {
   static const char *const opts[] = {"RAM","ROM",NULL};
   int opt = luaL_checkoption(L, 1, "RAM", opts);
-  int st = lua_getstrings(L, opt);    /* return the relevant strt as an array */
-  if (st) {
-    lua_pushvalue(L, -1);                             /* dup the array TValue */
-    lua_getglobal(L, "table");
-    lua_getfield(L, -1, "sort");               /* look up table.sort function */
-    lua_replace(L, -2);                               /* dump the table entry */
-    lua_insert(L, -2);               /* swap table/sort and the strings_table */
-    lua_call(L, 1, 0);                           /* table.sort(strings_table) */
+  if (lua_pushstringsarray(L, opt)) {
+    if(lua_getglobal(L, "table") == LUA_TTABLE) {
+      lua_getfield(L, -1, "sort");             /* look up table.sort function */
+      lua_pushvalue(L, -3);                   /* dup the strings_table to ToS */
+      lua_call(L, 1, 0);                         /* table.sort(strings_table) */
+      lua_pop(L, 1);                                  /* dump the table entry */
+    }
   }
-  return st ? 1 : 0;
+  return 1;
 }
 
 static int db_getmetatable (lua_State *L) {

+ 33 - 0
app/lua53/ldump.c

@@ -17,6 +17,7 @@
 #include "lauxlib.h"
 #include "llex.h"
 #include "lgc.h"
+#include "lmem.h"
 #include "lobject.h"
 #include "lstate.h"
 #include "lstring.h"
@@ -263,6 +264,36 @@ int luaU_dump (lua_State *L, const Proto *f, lua_Writer w, void *data,
   return D.status;
 }
 
+static int stripdebug (lua_State *L, Proto *f, int level) {
+  int i, len = 0;
+  switch (level) {
+    case 2:
+      if (f->lineinfo) {
+        f->lineinfo = luaM_freearray(L, f->lineinfo, f->sizelineinfo);
+        len += f->sizelineinfo;
+      }
+    case 1:
+      for (i=0; i<f->sizeupvalues; i++)
+        f->upvalues[i].name = NULL;
+      f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars);
+      len += f->sizelocvars * sizeof(LocVar);
+      f->sizelocvars = 0;
+  }
+  return len;
+}
+
+/* This is a recursive function so it's stack size has been kept to a minimum! */
+int luaU_stripdebug (lua_State *L, Proto *f, int level, int recv){
+  int len = 0, i;
+  if (recv != 0 && f->sizep != 0) {
+    for(i=0;i<f->sizep;i++) len += luaU_stripdebug(L, f->p[i], level, recv);
+  }
+  len += stripdebug (L, f, level);
+  return len;
+}
+
+
+
 /*============================================================================**
 **
 ** NodeMCU extensions for LFS support and dumping.  Note that to keep lua_lock
@@ -279,6 +310,8 @@ int luaU_dump (lua_State *L, const Proto *f, lua_Writer w, void *data,
 */
 static void addTS (TString *ts, DumpState *D) {
   lua_State *L = D->L;
+  if (!ts)
+    return;
   if (ttisnil(luaH_getstr(D->stringIndex, ts))) {
     TValue k, v, *slot;
     gettt(ts)<=LUA_TSHRSTR ? D->sTScnt++ : D->lTScnt++;

+ 11 - 0
app/lua53/lgc.c

@@ -1133,6 +1133,13 @@ static l_mem getdebt (global_State *g) {
 /*
 ** performs a basic GC step when collector is running
 */
+#ifdef LUA_USE_ESP8266 /*DEBUG*/
+extern void dbg_printf(const char *fmt, ...);
+#define CCOUNT_REG ({ int32_t r; asm volatile("rsr %0, ccount" : "=r"(r)); r;})
+#else                  /*DEBUG*/   
+#define dbg_printf(...)
+#define CCOUNT_REG 0
+#endif                 /*DEBUG*/
 void luaC_step (lua_State *L) {
   global_State *g = G(L);
   l_mem debt = getdebt(g);  /* GC deficit (be paid now) */
@@ -1141,15 +1148,19 @@ void luaC_step (lua_State *L) {
     return;
   }
   do {  /* repeat until pause or enough "credit" (negative debt) */
+/*DEBUG  int32_t start = CCOUNT_REG; */
     lu_mem work = singlestep(L);  /* perform one single step */
     debt -= work;
+/*DEBUG  dbg_printf("singlestep - %d, %d, %u \n", debt, lua_freeheap(), CCOUNT_REG-start); */
   } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
   if (g->gcstate == GCSpause)
     setpause(g);  /* pause until next cycle */
   else {
+/*DEBUG  int32_t start = CCOUNT_REG; */
     debt = (debt / g->gcstepmul) * STEPMULADJ;  /* convert 'work units' to Kb */
     luaE_setdebt(g, debt);
     runafewfinalizers(L);
+/*DEBUG  dbg_printf("new debt - %d, %d, %u \n", debt, lua_freeheap(), CCOUNT_REG-start); */
   }
 }
 

+ 1 - 3
app/lua53/linit.c

@@ -47,7 +47,6 @@ extern LROT_TABLE(dblib);
 extern LROT_TABLE(co_funcs);
 extern LROT_TABLE(mathlib);
 extern LROT_TABLE(utf8);
-extern LROT_TABLE(LFS);
 
 #define LROT_ROM_ENTRIES \
   LROT_TABENTRY( string, strlib ) \
@@ -56,7 +55,6 @@ extern LROT_TABLE(LFS);
   LROT_TABENTRY( coroutine, co_funcs ) \
   LROT_TABENTRY( math, mathlib ) \
   LROT_TABENTRY( utf8, utf8 ) \
-  LROT_TABENTRY( LFS, LFS ) \
   LROT_TABENTRY( ROM, rotables )
 
 #define LROT_LIB_ENTRIES \
@@ -75,7 +73,7 @@ extern LROT_TABLE(LFS);
 
 /* _G __index -> rotables __index -> base_func */
 extern LROT_TABLE(rotables_meta);
-LROT_TABLE(base_func);
+extern LROT_TABLE(base_func);
 
 LROT_BEGIN(rotables_meta, NULL, LROT_MASK_INDEX)
   LROT_TABENTRY( __index, base_func)

+ 2 - 3
app/lua53/lmathlib.c

@@ -17,8 +17,7 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
-#include "ldebug.h"
+
 #undef PI
 #define PI	(l_mathop(3.141592653589793238462643383279502884))
 
@@ -135,7 +134,7 @@ static int math_fmod (lua_State *L) {
       lua_pushinteger(L, lua_tointeger(L, 1) % d);
   } else {
     lua_Number m, a=luaL_checknumber(L, 1), b=luaL_checknumber(L, 2);
-    if (b==0) luaG_runerror(L,"modulo by zero");
+    if (b==0) luaL_error(L,"modulo by zero");
     m = a/b;
     lua_pushnumber(L, a - b*(m > 0.0 ? floor(m) : ceil(m)));
   }

+ 168 - 101
app/lua53/lnodemcu.c

@@ -30,21 +30,21 @@
 **    *  POSIX vs VFS file API abstraction
 **    *  Emulate Platform_XXX() API
 **    *  ESP and HOST lua_debugbreak() test stubs
-**    *  NodeMCU lua.h API extensions
-**    *  NodeMCU LFS Table emulator
+**    *  NodeMCU lua.h LUA_API extensions
+**    *  NodeMCU lauxlib.h LUALIB_API extensions
 **    *  NodeMCU bootstrap to set up and to reimage LFS resources
 **
 ** Just search down for //== or ==// to flip through the sections.
 */
 
-#define byte_addr(p) cast(char *,p)
+#define byte_addr(p)    cast(char *,p)
 #define byteptr(p)      cast(lu_byte *, p)
-#define byteoffset(p,q) (byteptr(p) - byteptr(q))
+#define byteoffset(p,q) ((int) cast(ptrdiff_t, (byteptr(p) - byteptr(q))))
 #define wordptr(p)      cast(lu_int32 *, p)
 #define wordoffset(p,q) (wordptr(p) - wordptr(q))
 
 
-//== Wrap POSIX and VFS file API =============================================//
+//====================== Wrap POSIX and VFS file API =========================//
 #ifdef LUA_USE_ESP
 int luaopen_file(lua_State *L);
 #  define l_file(f)   int f
@@ -62,7 +62,6 @@ int luaopen_file(lua_State *L);
 #  define l_rewind(f) rewind(f)
 #endif
 
-//== Emulate Platform_XXX() API ==============================================//
 #ifdef LUA_USE_ESP
 
 extern void dbg_printf(const char *fmt, ...);                // DEBUG
@@ -79,6 +78,8 @@ extern void dbg_printf(const char *fmt, ...);                // DEBUG
 
 #else // LUA_USE_HOST
 
+//==== Emulate Platform_XXX() API within host luac.cross -e environement =====//
+
 #include<stdio.h>                                             // DEBUG
 /*
 ** The ESP implementation use a platform_XXX() API to provide a level of
@@ -124,9 +125,9 @@ extern char  *LFSimageName;
 
 #define platform_rcr_write(id,rec,l) (128)
 #define platform_flash_phys2mapped(n) \
-    (byteptr(LFSaddr) + (n) - LFSbase)
+    ((ptrdiff_t)(((size_t)LFSaddr) - LFSbase) + (n))
 #define platform_flash_mapped2phys(n) \
-    (byteoffset(n, LFSaddr) + LFSbase)
+    ((size_t)(n) - ((size_t)LFSaddr) + LFSbase)
 #define platform_flash_get_sector_of_address(n) ((n)>>12)
 #define platform_rcr_delete(id) LFSimageName = NULL
 #define platform_rcr_read(id,s) \
@@ -170,7 +171,7 @@ static void platform_s_flash_write(const void *from, lu_int32 to, lu_int32 len)
 
 #endif
 
-//== ESP and HOST lua_debugbreak() test stubs ================================//
+//============= ESP and HOST lua_debugbreak() test stubs =====================//
 
 #ifdef DEVELOPMENT_USE_GDB
 /*
@@ -204,7 +205,7 @@ LUALIB_API void lua_debugbreak(void) {
 }
 #endif
 
-//== NodeMCU lua.h API extensions ============================================//
+//===================== NodeMCU lua.h API extensions =========================//
 
 LUA_API int lua_freeheap (void) {
 #ifdef LUA_USE_HOST
@@ -214,34 +215,39 @@ LUA_API int lua_freeheap (void) {
 #endif
 }
 
-LUA_API int lua_getstrings(lua_State *L, int opt) {
-  stringtable *tb = NULL;
-  Table *t;
-  int i, j, n = 0;
-
-  if (n == 0)
-    tb = &G(L)->strt;
+LUA_API int lua_pushstringsarray(lua_State *L, int opt) {
+  stringtable *strt = NULL;
+  int i, j = 1;
+ 
+  lua_lock(L);
+  if (opt == 0)
+    strt = &G(L)->strt;
 #ifdef LUA_USE_ESP
-  else if (n == 1 && G(L)->ROstrt.hash)
-    tb = &G(L)->ROstrt;
+  else if (opt == 1 && G(L)->ROstrt.hash)
+    strt = &G(L)->ROstrt;
 #endif
-  if (tb == NULL)
-   return 0;
+  if (strt == NULL) {
+    setnilvalue(L->top);
+    api_incr_top(L);
+    lua_unlock(L);
+    return 0;
+  }
 
-  lua_lock(L);
-  t = luaH_new(L);
+  Table *t = luaH_new(L);
   sethvalue(L, L->top, t);
   api_incr_top(L);
-  luaH_resize(L, t, tb->nuse, 0);
+  luaH_resize(L, t, strt->nuse, 0);
   luaC_checkGC(L);
   lua_unlock(L);
 
-  for (i = 0, j = 1; i < tb->size; i++) {
-    TString *o;
-    for(o = tb->hash[i]; o; o = o->u.hnext) {
+  /* loop around all strt hash entries */
+  for (i = 0, j = 1; i < strt->size; i++) {
+    TString *e;
+    /* loop around all TStings in this entry's chain */
+    for(e = strt->hash[i]; e; e = e->u.hnext) {
       TValue s;
-      setsvalue(L, &s, o);
-      luaH_setint(L, hvalue(L->top-1), j++, &s);  /* table[n] = true */
+      setsvalue(L, &s, e);
+      luaH_setint(L, hvalue(L->top-1), j++, &s);
     }
   }
   return 1;
@@ -274,72 +280,91 @@ LUA_API void lua_createrotable (lua_State *L, ROTable *t,
   t->entry     = cast(ROTable_entry *, e);
 }
 
-//== NodeMCU LFS Table emulator ==============================================//
+LUA_API void lua_getlfsconfig (lua_State *L, int *config) {
+  global_State *g = G(L);
+  LFSHeader *l = g->l_LFS;  
+  if (!config)
+    return;
+  config[0] = (int) (size_t) l;                  /* LFS region mapped address */
+  config[1] = platform_flash_mapped2phys(config[0]);    /* ditto phys address */
+  config[2] = g->LFSsize;                           /* LFS region actual size */
+  if (g->ROstrt.hash) {
+    config[3] = l->flash_size;                             /* LFS region used */
+    config[4] = l->timestamp;                         /* LFS region timestamp */
+  } else { 
+    config[3] = config[4] = 0;
+  }
+}
 
-static int lfs_func (lua_State* L);
+LUA_API int  (lua_pushlfsindex) (lua_State *L) {
+  lua_lock(L);
+  setobj2n(L, L->top, &G(L)->LFStable);
+  api_incr_top(L);
+  lua_unlock(L);
+  return  ttnov(L->top-1);
+}
 
-LROT_BEGIN(LFS_meta, NULL, LROT_MASK_INDEX)
-  LROT_FUNCENTRY( __index, lfs_func)
-LROT_END(LFS_meta, NULL, LROT_MASK_INDEX)
+/*
+ * In Lua 5.3 luac.cross generates a top level Proto for each source file with 
+ * one upvalue that must be the set to the _ENV variable when its closure is
+ * created, and as such this parallels some ldo.c processing.
+ */
+LUA_API int  (lua_pushlfsfunc) (lua_State *L) {
+  lua_lock(L);
+  const TValue *t = &G(L)->LFStable;
+  if (ttisstring(L->top-1) && ttistable(t)) {
+    const TValue *v = luaH_getstr (hvalue(t), tsvalue(L->top-1));
+    if (ttislightuserdata(v)) {
+      Proto *f = pvalue(v);   /* The pvalue is a Proto * for the Lua function */
+      LClosure *cl = luaF_newLclosure(L, f->sizeupvalues);
+      setclLvalue(L, L->top-1, cl);
+      luaF_initupvals(L, cl);
+      cl->p = f;
+      if (cl->nupvalues >= 1) {                   /* does it have an upvalue? */
+        UpVal *uv1 = cl->upvals[0];
+        TValue *val = uv1->v;
+        /* set 1st upvalue as global env table from registry */
+        setobj(L, val, luaH_getint(hvalue(&G(L)->l_registry), LUA_RIDX_GLOBALS));
+        luaC_upvalbarrier(L, uv1);
+      }
+      return 1;
+    }
+  }
+  setnilvalue(L->top-1);
+  lua_unlock(L);
+  return 0;
+}
 
-LROT_BEGIN(LFS, LROT_TABLEREF(LFS_meta), 0)
-LROT_END(LFS, LROT_TABLEREF(LFS_meta), 0)
 
+//================ NodeMCU lauxlib.h LUALIB_API extensions ===================//
 
-static int lfs_func (lua_State* L) {           /*T[1] = LFS, T[2] = fieldname */
-  const char *name = lua_tostring(L, 2);
-  LFSHeader *fh = G(L)->l_LFS;
-  Proto *f;
-  LClosure *cl;
-  lua_settop(L,2);
-  if (!fh) {                                  /* return nil if LFS not loaded */
-    lua_pushnil(L);
-    return 1;
-  }
-  if (!strcmp(name, "_config")) {
-    size_t ba = cast(size_t, fh);
-    lua_createtable(L, 0, 3);
-    lua_pushinteger(L, cast(lua_Integer, ba));
-    lua_setfield(L, -2, "lfs_mapped");
-    lua_pushinteger(L, cast(lua_Integer, platform_flash_mapped2phys(ba)));
-    lua_setfield(L, -2, "lfs_base");
-    lua_pushinteger(L, G(L)->LFSsize);
-    lua_setfield(L, -2, "lfs_size");
-    return 1;
-  } else if (!strcmp(name, "_list")) {
-    int i = 1;
-    setobjs2s(L, L->top-2, &G(L)->LFStable);  /* overwrite T[1] with LSFtable */
-    lua_newtable(L);                                /* new list table at T[3] */
-    lua_pushnil(L);                                 /* first key (nil) at T4] */
-    while (lua_next(L, 1) != 0) {         /* loop over LSFtable k,v at T[4:5] */
-      lua_pop(L, 1);                                            /* dump value */
-      lua_pushvalue(L, -1);                                        /* dup key */
-      lua_rawseti(L, 3, i++);                                 /* table[i]=key */
-    }
-    return 1;
-  } else if (!strcmp(name, "_time")) {
-    lua_pushinteger(L, fh->timestamp);
-    return 1;
-  }
-  setobjs2s(L, L->top-2, &G(L)->LFStable);    /* overwrite T[1] with LSFtable */
-  if (lua_rawget(L,1) != LUA_TNIL) {                    /* get LFStable[name] */
-    lua_pushglobaltable(L);
-    f = cast(Proto *, lua_topointer(L,-2));
-    lua_lock(L);
-    cl = luaF_newLclosure(L, f->sizeupvalues);
-    setclLvalue(L, L->top-2, cl);       /* overwrite f addr slot with closure */
-    cl->p = f;                                                /* bind f to it */
-    if (cl->nupvalues >= 1) {           /* does it have at least one upvalue? */
-      luaF_initupvals(L, cl );                            /* initialise upvals */
-      setobj(L, cl->upvals[0]->v, L->top-1);             /* set UV[1] to _ENV */
-    }
-    lua_unlock(L);
-    lua_pop(L,1);                          /* pop _ENV leaving closure at ToS */
+/*
+ * Return an array of functions in LFS
+ */
+LUALIB_API int  (luaL_pushlfsmodules) (lua_State *L) {
+  int i = 1;
+  if (lua_pushlfsindex(L) == LUA_TNIL)
+    return 0;                                 /* return nil if LFS not loaded */
+  lua_newtable(L);      /* create dest table and move above LFS index ROTable */
+  lua_insert(L, -2);
+  lua_pushnil(L);
+  while (lua_next(L, -2) != 0) {
+    lua_pop(L, 1);                       /* dump the value (ptr to the Proto) */
+    lua_pushvalue(L, -1);                            /* dup key (module name) */
+    lua_rawseti(L, -4, i++);
   }
+  lua_pop(L, 1);                                /* dump the LFS index ROTable */
   return 1;
 }
 
-//== NodeMCU bootstrap to set up and to reimage LFS resources ================//
+LUALIB_API int  (luaL_pushlfsdts) (lua_State *L) {
+  int config[5];
+  lua_getlfsconfig(L, config);
+  lua_pushinteger(L, config[4]);
+  return 1;
+}
+
+//======== NodeMCU bootstrap to set up and to reimage LFS resources ==========//
 /*
 ** This processing uses 2 init hooks during the Lua startup. The first is
 ** called early in the Lua state setup to initialize the LFS if present. The
@@ -494,9 +519,9 @@ LUAI_FUNC int luaN_init (lua_State *L) {
       if (n < 0) {
         global_State *g = G(L);
         g->LFSsize     = F->size;
+        g->l_LFS       = fh;
       /* Set up LFS hooks on normal Entry */
         if (fh->flash_sig   == FLASH_SIG) {
-          g->l_LFS       = fh;
           g->seed        = fh->seed;
           g->ROstrt.hash = cast(TString **, F->addr + fh->oROhash);
           g->ROstrt.nuse = fh->nROuse ;
@@ -565,9 +590,9 @@ LUAI_FUNC int luaN_init (lua_State *L) {
 #define getfield(L,t,f) \
   lua_getglobal(L, #t); luaL_getmetafield( L, 1, #f ); lua_remove(L, -2);
 
-LUAI_FUNC int  lua_lfsreload (lua_State *L) {
-  int n = 0;
+LUALIB_API void luaL_lfsreload (lua_State *L) {
 #ifdef LUA_USE_ESP
+  int n = 0;
   size_t l;
   int off = 0;
   const char *img = lua_tolstring(L, 1, &l);
@@ -579,30 +604,72 @@ LUAI_FUNC int  lua_lfsreload (lua_State *L) {
   lua_getglobal(L, "file");
   if (lua_isnil(L, 2)) {
     lua_pushstring(L, "No file system mounted");
-    return 1;
+    return;
   }
   lua_getfield(L, 2, "exists");
   lua_pushstring(L, img + off);
   lua_call(L, 1, 1);
   if (G(L)->LFSsize == 0 || lua_toboolean(L, -1) == 0) {
     lua_pushstring(L, "No LFS partition allocated");
-    return 1;
+    return;
   }
   n = platform_rcr_write(PLATFORM_RCR_FLASHLFS, img, l+1);/* incl trailing \0 */
-  if (n>0)
+  if (n>0) {
     system_restart();
+    luaL_error(L, "system restarting");
+  }
 #endif
-  lua_pushboolean(L, n>0);
-  return 1;
 }
 
-LUAI_FUNC int  lua_lfsindex (lua_State *L) {
-  lua_settop(L,1);
-  if (lua_isstring(L, 1)){
-    lua_getglobal(L, "LFS");
-    lua_getfield(L, 2, lua_tostring(L,1));
+
+#ifdef LUA_USE_ESP
+extern void lua_main(void);
+/*
+** Task callback handler. Uses luaN_call to do a protected call with full traceback
+*/
+static void do_task (platform_task_param_t task_fn_ref, uint8_t prio) {
+  lua_State* L = lua_getstate();
+  if(task_fn_ref == (platform_task_param_t)~0 && prio == LUA_TASK_HIGH) {
+    lua_main();                   /* Undocumented hook for lua_main() restart */
+    return;
+  }
+  if (prio < LUA_TASK_LOW|| prio > LUA_TASK_HIGH)
+    luaL_error(L, "invalid posk task");
+/* Pop the CB func from the Reg */
+  lua_rawgeti(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
+  luaL_checktype(L, -1, LUA_TFUNCTION);
+  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, -]
+  static platform_task_handle_t task_handle = 0;
+  if (!task_handle)
+    task_handle = platform_task_get_id(do_task);
+  if (L == NULL && prio == LUA_TASK_HIGH+1) { /* Undocumented hook for lua_main */
+    platform_post(LUA_TASK_HIGH, task_handle, (platform_task_param_t)~0);
+    return -1;
+  }
+  if (lua_isfunction(L, -1) && prio >= LUA_TASK_LOW && prio <= LUA_TASK_HIGH) {
+    int task_fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    if(!platform_post(prio, task_handle, (platform_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 {
-    lua_pushnil(L);
+    return luaL_error(L, "invalid posk task");
   }
-  return 1;
 }
+#else
+/*
+** Task execution isn't supported on HOST builds so returns a -1 status
+*/
+LUALIB_API int luaL_posttask( lua_State* L, int prio ) {            // [-1, +0, -]
+  return -1;
+}
+#endif

+ 3 - 3
app/lua53/lnodemcu.h

@@ -40,12 +40,12 @@
 #define LROT_ENTRYREF(rt)    (rt ##_entries)
 #define LROT_TABLEREF(rt)    (&rt ##_ROTable)
 #define LROT_BEGIN(rt,mt,f)  LROT_TABLE(rt); \
-  static const ROTable_entry rt ## _entries[] = {
+  static ROTable_entry rt ## _entries[] = {
 #define LROT_ENTRIES_IN_SECTION(rt,s) \
-  static const ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
+  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_TTBLROF, LROT_MARKED, \
+    (GCObject *)1, LUA_TTBLROF, 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)       };

+ 0 - 1
app/lua53/loadlib.c

@@ -22,7 +22,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 #ifndef LUA_USE_HOST
 #include <fcntl.h>

+ 0 - 6
app/lua53/lobject.h

@@ -584,12 +584,6 @@ typedef struct ROTable {
 */
 #define luaO_nilobject		(&luaO_nilobject_)
 
-/*
-** KeyCache used for resolution of ROTable entries and Cstrings
-*/
-typedef size_t KeyCache;
-typedef KeyCache KeyCacheLine[KEYCACHE_M];
-
 LUAI_DDEC const TValue luaO_nilobject_;
 
 /* size of buffer for 'luaO_utf8esc' function */

+ 9 - 1
app/lua53/lparser.c

@@ -23,9 +23,9 @@
 #include "lobject.h"
 #include "lopcodes.h"
 #include "lparser.h"
-#include "lstate.h"
 #include "lstring.h"
 #include "ltable.h"
+#include "lundump.h"
 
 
 
@@ -1633,6 +1633,13 @@ static void mainfunc (LexState *ls, FuncState *fs) {
 }
 
 
+static void compile_stripdebug(lua_State *L, Proto *f) {
+  int level =  G(L)->stripdefault;
+  if (level > 0)
+    luaU_stripdebug(L, f, level, 1);
+}
+
+
 LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
                        Dyndata *dyd, const char *name, int firstchar) {
   LexState lexstate;
@@ -1654,6 +1661,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
   lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
   /* all scopes should be correctly finished */
   lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
+  compile_stripdebug(L, funcstate.f);
   L->top--;  /* remove scanner's table */
   return cl;  /* closure is on the stack, too */
 }

+ 2 - 1
app/lua53/lstate.c

@@ -307,7 +307,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
   luaM_free(L, l);
 }
 
-LUA_API KeyCache *(lua_getcache) (int lineno) {
+LUAI_FUNC KeyCache *luaE_getcache (int lineno) {
   return &G(L0)->cache[lineno][0];
 }
 
@@ -347,6 +347,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->gcfinnum = 0;
   g->gcpause = LUAI_GCPAUSE;
   g->gcstepmul = LUAI_GCMUL;
+  g->stripdefault = LUAI_OPTIMIZE_DEBUG;
   g->ROstrt.size = 0;
   g->ROstrt.nuse = 0;
   g->ROstrt.hash = NULL;

+ 7 - 4
app/lua53/lstate.h

@@ -133,6 +133,11 @@ typedef struct CallInfo {
 #define setoah(st,v)	((st) = ((st) & ~CIST_OAH) | (v))
 #define getoah(st)	((st) & CIST_OAH)
 
+/*
+** KeyCache used for resolution of ROTable entries and Cstrings
+*/
+typedef size_t KeyCache;
+typedef KeyCache KeyCacheLine[KEYCACHE_M];
 
 /*
 ** 'global state', shared by all threads of this state
@@ -168,6 +173,7 @@ typedef struct global_State {
   unsigned int gcfinnum;  /* number of finalizers to call in each GC step */
   int gcpause;  /* size of pause between successive GCs */
   int gcstepmul;  /* GC 'granularity' */
+  int stripdefault;  /* default stripping level for compilation */
   l_mem gcmemfreeboard;  /* Free board which triggers EGC */
   lua_CFunction panic;  /* to be called in unprotected errors */
   struct lua_State *mainthread;
@@ -229,8 +235,6 @@ union GCUnion {
   struct Proto p;
   struct lua_State th;  /* thread */
 };
-
-
 #define cast_u(o)	cast(union GCUnion *, (o))
 
 /* macros to convert a GCObject into a specific value */
@@ -262,7 +266,6 @@ LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
 LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
 LUAI_FUNC void luaE_freeCI (lua_State *L);
 LUAI_FUNC void luaE_shrinkCI (lua_State *L);
-
+LUAI_FUNC KeyCache *luaE_getcache (int cl);
 
 #endif
-

+ 9 - 6
app/lua53/lstrlib.c

@@ -23,7 +23,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 
 /*
@@ -189,11 +188,16 @@ static int writer (lua_State *L, const void *b, size_t size, void *B) {
 
 static int str_dump (lua_State *L) {
   luaL_Buffer b;
-  int strip = lua_tointeger(L, 2);
-  if (lua_isboolean(L, 2) && lua_toboolean(L, 2))
-    strip = 2;
+  int strip, tstrip = lua_type(L, 2);
+  if (tstrip == LUA_TBOOLEAN) {
+    strip = lua_toboolean(L, 2) ? 2 : 0;
+  } else if (tstrip == LUA_TNONE || tstrip == LUA_TNIL) {
+    strip = -1;  /* This tells lua_dump to use the global strip default */
+  } else { 
+    strip = lua_tointeger(L, 2);
+    luaL_argcheck(L, (unsigned)(strip) < 3, 2, "strip out of range");
+  }
   luaL_checktype(L, 1, LUA_TFUNCTION);
-  luaL_argcheck(L, 3 > (unsigned)(strip), 1, "strip out of range");
   lua_settop(L, 1);
   luaL_buffinit(L,&b);
   if (lua_dump(L, writer, &b, strip) != 0)
@@ -203,7 +207,6 @@ static int str_dump (lua_State *L) {
 }
 
 
-
 /*
 ** {======================================================
 ** PATTERN MATCHING

+ 1 - 1
app/lua53/ltable.c

@@ -739,7 +739,7 @@ static const TValue* rotable_findentry(ROTable *t, TString *key, unsigned *ppos)
   const int tl = getlsizenode(t);
   const char *strkey = getstr(key);
   const int hash = HASH(t, key);
-  KeyCache *cl = lua_getcache(hash);
+  KeyCache *cl = luaE_getcache(hash);
   int i, j = 1, l;
 
   if (!e || gettt(key) != LUA_TSHRSTR)

+ 0 - 1
app/lua53/ltablib.c

@@ -18,7 +18,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 
 /*

+ 14 - 3
app/lua53/lua.c

@@ -238,9 +238,20 @@ static int pmain (lua_State *L) {
   * then attempting the open will trigger a file system format.
   */
   platform_rcr_read(PLATFORM_RCR_INITSTR, (void**) &init);
-  status = (init[0] == '@') ?
-           luaL_loadfile(L, init+1) :
-           luaL_loadbuffer(L, init, strlen(init), "=INIT");
+  if (init[0] == '!') { /* !module is a compile-free way of executing LFS module */
+    luaL_pushlfsmodule(L);
+    lua_pushstring(L, init+1);
+    lua_call(L, 1, 1);  /* return LFS.module or nil */
+    status = LUA_OK;
+    if (!lua_isfunction(L, -1)) {
+      lua_pushfstring(L, "cannot load LFS.%s", init+1);
+      status = LUA_ERRRUN;
+    }
+  } else {
+    status = (init[0] == '@') ?
+             luaL_loadfile(L, init+1) :
+             luaL_loadbuffer(L, init, strlen(init), "=INIT");
+  }
   if (status == LUA_OK)
     status = docall(L, 0);
   if (status != LUA_OK)

+ 12 - 9
app/lua53/lua.h

@@ -153,6 +153,10 @@ LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
 
 LUA_API const lua_Number *(lua_version) (lua_State *L);
 
+#ifndef LUAI_OPTIMIZE_DEBUG
+#define LUAI_OPTIMIZE_DEBUG 2
+#endif
+
 
 /*
 ** basic stack manipulation
@@ -282,7 +286,8 @@ LUA_API int   (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
 LUA_API int   (lua_load) (lua_State *L, lua_Reader reader, void *dt,
                           const char *chunkname, const char *mode);
 
-LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
+LUA_API int   (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
+LUA_API int   (lua_stripdebug) (lua_State *L, int stripping);
 
 
 /*
@@ -465,17 +470,17 @@ struct lua_Debug {
 
 typedef struct ROTable ROTable;
 typedef const struct ROTable_entry ROTable_entry;
-typedef size_t KeyCache;
 
 LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
 LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt);
 LUA_API lua_State *(lua_getstate) (void);
-LUA_API KeyCache *(lua_getcache) (int cl);
-LUA_API int (lua_getstrings) (lua_State *L, int opt);
+LUA_API int (lua_pushstringsarray) (lua_State *L, int opt);
 LUA_API int (lua_freeheap) (void);
 
-LUAI_FUNC int  lua_lfsreload (lua_State *L);
-LUAI_FUNC int  lua_lfsindex (lua_State *L);
+LUA_API void (lua_getlfsconfig) (lua_State *L, int *);
+LUA_API int  (lua_pushlfsindex) (lua_State *L);
+LUA_API int  (lua_pushlfsfunc) (lua_State *L);
+
 
 #define luaN_freearray(L,a,l) luaM_freearray(L,a,l)
 
@@ -487,14 +492,12 @@ typedef struct Proto Proto;
 
 #ifdef DEVELOPMENT_USE_GDB
 LUALIB_API void (lua_debugbreak)(void);
-#define ASSERT(s) if (!(s)) {lua_debugbreak();}
+#define ASSERT(s)  ((s) ? (void)0 : lua_debugbreak())
 #else
 #define lua_debugbreak() (void)(0)
 #define ASSERT(s) (void)(0)
 #endif
 
-LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
-
 
 // from undump.c
 #define LUA_ERR_CC_INTOVERFLOW 101

+ 1 - 0
app/lua53/lundump.h

@@ -48,6 +48,7 @@ LUAI_FUNC int luaU_DumpAllProtos(lua_State *L, const Proto *m, lua_Writer w,
                          void *data, int strip);
 
 LUAI_FUNC int luaU_undumpLFS(lua_State *L, ZIO *Z, int isabs);
+LUAI_FUNC int luaU_stripdebug (lua_State *L, Proto *f, int level, int recv);
 
 typedef struct FlashHeader LFSHeader;
 /*

+ 1 - 2
app/lua53/lutf8lib.c

@@ -19,7 +19,6 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
-#include "lnodemcu.h"
 
 #define MAXUNICODE	0x10FFFF
 
@@ -249,7 +248,7 @@ LROT_BEGIN(utf8_meta, NULL, LROT_MASK_INDEX)
 LROT_END(utf8_meta, NULL, LROT_MASK_INDEX)
 
 
-LROT_BEGIN(utf8, NULL, 0)
+LROT_BEGIN(utf8, LROT_TABLEREF(utf8_meta), 0)
   LROT_FUNCENTRY( offset, byteoffset )
   LROT_FUNCENTRY( codepoint, codepoint )
   LROT_FUNCENTRY( char, utfchar )

+ 104 - 62
app/modules/node.c

@@ -1,14 +1,9 @@
 // Module for interfacing with system
 #include "module.h"
 #include "lauxlib.h"
-#include "lstate.h"
 #include "lmem.h"
 
-
 #include "platform.h"
-#if LUA_VERSION_NUM == 501
-#include "lflash.h"
-#endif
 #include <stdint.h>
 #include <string.h>
 #include "user_interface.h"
@@ -163,14 +158,27 @@ static void add_string_field( lua_State* L, const char *s, const char *name) {
   lua_setfield(L, -2, name);
 }
 
-static int node_info( lua_State* L )
-{
-  const char* options[] = {"hw", "sw_version", "build_config", "legacy", NULL};
-  int option = luaL_checkoption (L, 1, options[3], options);
+static void get_lfs_config ( lua_State* L ){
+    int config[5];
+    lua_getlfsconfig(L, config);
+    lua_createtable(L, 0, 4);
+    add_int_field(L, config[0], "lfs_mapped");
+    add_int_field(L, config[1], "lfs_base");
+    add_int_field(L, config[2], "lfs_size");
+    add_int_field(L, config[3], "lfs_used");
+}
+
+static int node_info( lua_State* L ){
+  const char* options[] = {"lfs", "hw", "sw_version", "build_config", "legacy", NULL};
+  int option = luaL_checkoption (L, 1, options[4], options);
 
   switch (option) {
-    case 0: { // hw
-      lua_createtable (L, 0, 5);
+    case 0: { // lfs
+      get_lfs_config(L);
+      return 1;
+    }
+    case 1: { // hw
+      lua_createtable(L, 0, 5);
       add_int_field(L, system_get_chip_id(),             "chip_id");
       add_int_field(L, spi_flash_get_id(),               "flash_id");
       add_int_field(L, flash_rom_get_size_byte() / 1024, "flash_size");
@@ -178,8 +186,8 @@ static int node_info( lua_State* L )
       add_int_field(L, flash_rom_get_speed(),            "flash_speed");
       return 1;
     }
-    case 1: { // sw_version
-      lua_createtable (L, 0, 7);     
+    case 2: { // sw_version
+      lua_createtable(L, 0, 7);     
       add_int_field(L, NODE_VERSION_MAJOR,       "node_version_major");
       add_int_field(L, NODE_VERSION_MINOR,       "node_version_minor");
       add_int_field(L, NODE_VERSION_REVISION,    "node_version_revision");
@@ -189,8 +197,8 @@ static int node_info( lua_State* L )
       add_string_field(L, BUILDINFO_RELEASE_DTS, "git_commit_dts");
       return 1;
     }
-    case 2: { // build_config
-      lua_createtable (L, 0, 4);
+    case 3: { // build_config
+      lua_createtable(L, 0, 4);
       lua_pushboolean(L, BUILDINFO_SSL);
       lua_setfield(L, -2, "ssl");
       lua_pushnumber(L, BUILDINFO_LFS_SIZE);
@@ -199,8 +207,7 @@ static int node_info( lua_State* L )
       add_string_field(L, BUILDINFO_BUILD_TYPE, "number_type");
       return 1;
     }
-    default:
-    {
+    default: { // legacy
       platform_print_deprecation_note("node.info() without parameter", "in the next version");
       lua_pushinteger(L, NODE_VERSION_MAJOR);
       lua_pushinteger(L, NODE_VERSION_MINOR);
@@ -333,8 +340,6 @@ static int writer(lua_State* L, const void* p, size_t size, void* u)
 }
 
 #if LUA_VERSION_NUM == 501
-#undef lua_dump
-#define lua_dump lua_dumpEx
 #define getproto(o)	(clvalue(o)->l.p)
 #endif
 
@@ -461,8 +466,6 @@ static int node_restore (lua_State *L)
   return 0;
 }
 
-#if defined(LUA_OPTIMIZE_DEBUG) && LUA_VERSION_NUM == 501
-
 /* node.stripdebug([level[, function]]). 
  * level:    1 don't discard debug
  *           2 discard Local and Upvalue debug info
@@ -472,54 +475,36 @@ static int node_restore (lua_State *L)
  * If function is omitted, this is the default setting for future compiles
  * The function returns an estimated integer count of the bytes stripped.
  */
-LUA_API int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
 static int node_stripdebug (lua_State *L) {
 
   int n = lua_gettop(L);
-  if (n == 0) {
-    lua_pushlightuserdata(L, &luaG_stripdebug );
-    lua_gettable(L, LUA_REGISTRYINDEX);
-    if (lua_isnil(L, -1)) {
-      lua_pop(L, 1);
-      lua_pushinteger(L, LUA_OPTIMIZE_DEBUG);
-    }
-    return 1;
-  }
+  int strip = 0;
 
-  int level = luaL_checkint(L, 1);
-  luaL_argcheck(L, level > 0 && level < 4, 1, "must in range 1-3");
-
-  if (n == 1) {
-    /* Store the default level in the registry if no function parameter */
-    lua_pushlightuserdata(L, &luaG_stripdebug);
-    lua_pushinteger(L, level);
-    lua_settable(L, LUA_REGISTRYINDEX);
-    return 0;
-  }
-
-  if (level == 1) {
-    lua_pushinteger(L, 0);
-    return 1;
-  }
+  lua_settop(L, 2);
+  if (!lua_isnil(L, 1)) {
+    strip = lua_tointeger(L, 1);
+    luaL_argcheck(L, strip > 0 && strip < 4, 1, "Invalid strip level");
+  } 
 
   if (lua_isnumber(L, 2)) {
-    int scope = luaL_checkint(L, 2);
-    if (scope > 0) {
-      /* if the function parameter is a +ve integer then climb to find function */
+    /* Use debug interface to replace stack level by corresponding function */
+    int scope = luaL_checkinteger(L, 2);
+    if (scope > 0) { 
       lua_Debug ar;
-      lua_pop(L, 1); /* pop level as getinfo will replace it by the function */
+      lua_pop(L, 1);
       if (lua_getstack(L, scope, &ar)) {
-        lua_getinfo(L, "f", &ar);
+        lua_getinfo(L, "f", &ar);  /* put function at [2] (ToS) */
       }
     }
   }
+ 
+  int isfunc = lua_isfunction(L, 2);
+  luaL_argcheck(L, n < 2 || isfunc, 2, "not a valid function");
 
-  luaL_argcheck(L, lua_isfunction(L, 2), 2, "must be a Lua Function");
-  Proto *f = getproto(L->ci->func + 1);
-  lua_pushinteger(L, luaG_stripdebug(L, f, level, 1));
+  /* return result of lua_stripdebug, adding 1 if this is get/set level) */ 
+  lua_pushinteger(L, lua_stripdebug(L, strip - 1) + (isfunc ? 0 : 1));
   return 1;
 }
-#endif
 
 
 #if LUA_VERSION_NUM == 501
@@ -539,9 +524,10 @@ static int node_egc_setmode(lua_State* L) {
 }
 // totalallocated, estimatedused = node.egc.meminfo()
 static int node_egc_meminfo(lua_State *L) {
-  global_State *g = G(L);
-  lua_pushinteger(L, g->totalbytes);
-  lua_pushinteger(L, g->estimate);
+  int totals[2];
+  lua_getegcinfo(L, totals);
+  lua_pushinteger(L, totals[0]);
+  lua_pushinteger(L, totals[1]);
   return 2;
 }
 #endif
@@ -651,6 +637,64 @@ static int node_writercr (lua_State *L) {
 }
 #endif
 
+// Lua: n = node.LFS.reload(lfsimage)
+static int node_lfsreload (lua_State *L) {
+  lua_settop(L, 1);
+  luaL_lfsreload(L);
+  return 1;
+}
+
+// Lua: n = node.flashindex(module)
+// Lua: n = node.LFS.get(module)
+static int node_lfsindex (lua_State *L) {
+  lua_settop(L, 1);
+  luaL_pushlfsmodule(L);
+  return 1;
+}
+
+// Lua: n = node.LFS.list([option])
+// Note that option is ignored in this release
+static int node_lfslist (lua_State *L) {
+  lua_settop(L, 1);
+  luaL_pushlfsmodules(L);
+  if (lua_istable(L, -1) && lua_getglobal(L, "table") == LUA_TTABLE) {
+    lua_getfield(L, -1, "sort");
+    lua_remove(L, -2);       /* remove table table */
+    lua_pushvalue(L, -2);    /* dup array of modules ref to ToS */
+    lua_call(L, 1, 0);
+  }
+  return 1;
+}
+
+//== node.LFS Table emulator ==============================================//
+
+static int node_lfs_func (lua_State* L) {      /*T[1] = LFS, T[2] = fieldname */
+  lua_remove(L, 1);
+  lua_settop(L, 1);
+  const char *name = lua_tostring(L, 1);
+  if (!name) {
+    lua_pushnil(L);
+  } else if (!strcmp(name, "config")) {
+    get_lfs_config(L);
+  } else if (!strcmp(name, "time")) {
+    luaL_pushlfsdts(L);
+  } else {
+    luaL_pushlfsmodule(L);
+  }
+  return 1;
+}
+
+LROT_BEGIN(node_lfs_meta, NULL, LROT_MASK_INDEX)
+  LROT_FUNCENTRY( __index, node_lfs_func)
+LROT_END(node_lfs_meta, NULL, LROT_MASK_INDEX)
+
+LROT_BEGIN(node_lfs, LROT_TABLEREF(node_lfs_meta), 0)
+  LROT_FUNCENTRY( list, node_lfslist)
+  LROT_FUNCENTRY( get, node_lfsindex)
+  LROT_FUNCENTRY( reload, node_lfsreload )
+LROT_END(node_lfs, LROT_TABLEREF(node_lfs_meta), 0)
+
+
 typedef enum pt_t { lfs_addr=0, lfs_size, spiffs_addr, spiffs_size, max_pt} pt_t;
 
 LROT_BEGIN(pt_map, NULL, 0)
@@ -826,8 +870,8 @@ LROT_BEGIN(node, NULL, 0)
   LROT_FUNCENTRY( heap, node_heap )
   LROT_FUNCENTRY( info, node_info )
   LROT_TABENTRY( task, node_task )
-  LROT_FUNCENTRY( flashreload, lua_lfsreload )
-  LROT_FUNCENTRY( flashindex, lua_lfsindex )
+  LROT_FUNCENTRY( flashindex, node_lfsindex )
+  LROT_TABENTRY( LFS, node_lfs )
   LROT_FUNCENTRY( setonerror, node_setonerror )
   LROT_FUNCENTRY( startupcommand, node_startupcommand )
   LROT_FUNCENTRY( restart, node_restart )
@@ -856,9 +900,7 @@ LROT_BEGIN(node, NULL, 0)
   LROT_FUNCENTRY( bootreason, node_bootreason )
   LROT_FUNCENTRY( restore, node_restore )
   LROT_FUNCENTRY( random, node_random )
-#if LUA_VERSION_NUM == 501 && defined(LUA_OPTIMIZE_DEBUG)
   LROT_FUNCENTRY( stripdebug, node_stripdebug )
-#endif
 #if LUA_VERSION_NUM == 501
   LROT_TABENTRY( egc, node_egc )
 #endif

+ 0 - 1
app/modules/sjson.c

@@ -1,7 +1,6 @@
 #define LUA_LIB
 
 #include "lauxlib.h"
-#include "lstring.h"
 
 #ifndef LOCAL_LUA
 #include "module.h"

+ 6 - 6
app/platform/platform.c

@@ -5,7 +5,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include "llimits.h"
+#include <stdint.h>
 #include "gpio.h"
 #include "user_interface.h"
 #include "driver/gpio16.h"
@@ -215,7 +215,7 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){
   uint32_t j=0;
   uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   uint32_t now = system_get_time();
-  UNUSED(dummy);
+  (void)(dummy);
 
 #ifdef GPIO_INTERRUPT_HOOK_ENABLE
   if (gpio_status & platform_gpio_hook->all_bits) {
@@ -986,13 +986,13 @@ uint32_t platform_rcr_read (uint8_t rec_id, void **rec) {
 }
 
 uint32_t platform_rcr_delete (uint8_t rec_id) {
-  void *rec = NULL;
-  platform_rcr_read (rec_id, &rec);
+  uint32_t *rec = NULL;
+  platform_rcr_read(rec_id, (void**)&rec);
   if (rec) {
-    uint32_t *pHdr = cast(uint32_t *,rec)-1;
+    uint32_t *pHdr = rec - 1;  /* the header is the word proceeding the rec */ 
     platform_rcr_t hdr = {.hdr = *pHdr};
     hdr.id = PLATFORM_RCR_DELETED;
-    platform_s_flash_write(&hdr, platform_flash_mapped2phys(cast(uint32_t, pHdr)), WORDSIZE);
+    platform_s_flash_write(&hdr, platform_flash_mapped2phys((uint32_t) pHdr), WORDSIZE);
     return 0;
   }
   return ~0;

+ 0 - 1
app/websocket/websocketclient.c

@@ -26,7 +26,6 @@
 #include "user_interface.h"
 #include "espconn.h"
 #include "mem.h"
-#include "limits.h"
 #include <stdint.h>
 #include <stddef.h>
 #include <string.h>

+ 2 - 2
app/websocket/websocketclient.h

@@ -29,8 +29,8 @@
 #include "user_interface.h"
 #include "espconn.h"
 #include "mem.h"
-#include "limits.h"
-#include "stdlib.h"
+#include <limits.h>
+#include <stdlib.h>
 
 #if defined(USES_SDK_BEFORE_V140)
 #define espconn_send espconn_sent

File diff suppressed because it is too large
+ 3 - 27
docs/flash.md


File diff suppressed because it is too large
+ 16 - 0
docs/lfs.md


File diff suppressed because it is too large
+ 6 - 0
docs/lua53.md


+ 71 - 28
docs/modules/node.md

@@ -1,7 +1,7 @@
 # node Module
 | Since  | Origin / Contributor  | Maintainer  | Source  |
 | :----- | :-------------------- | :---------- | :------ |
-| 2014-12-22 | [Zeroday](https://github.com/funshine) | [Zeroday](https://github.com/funshine) | [node.c](../../app/modules/node.c)|
+| 2014-12-22 | [Zeroday](https://github.com/funshine) | [TerryE](https://github.com/TerryE) | [node.c](../../app/modules/node.c)|
 
 The node module provides access to system-level features such as sleep, restart and various info and IDs.
 
@@ -174,36 +174,13 @@ flash ID (number)
 
 ## node.flashindex()
 
-Returns the function reference for a function in the [LFS (Lua Flash Store)](../lfs.md).
+Deprecated synonym for [`node.LFS.get()`](#nodelfsget) to return an LFS function reference.
 
-#### Syntax
-`node.flashindex(modulename)`
-
-#### Parameters
-`modulename`  The name of the module to be loaded.  If this is `nil` or invalid then an info list is returned
-
-#### Returns
--  In the case where the LFS in not loaded, `node.flashindex` evaluates to `nil`, followed by the flash mapped base addresss of the LFS, its flash offset, and the size of the LFS.
--  If the LFS is loaded and the function is called with the name of a valid module in the LFS, then the function is returned in the same way the `load()` and the other Lua load functions do.
--  Otherwise an extended info list is returned: the Unix time of the LFS build, the flash and mapped base addresses of the LFS and its current length, and an array of the valid module names in the LFS.
-
-#### Example
-
-The `node.flashindex()` is a low level API call that is normally wrapped using standard Lua code to present a simpler application API.  See the module `_init.lua` in the `lua_examples/lfs` directory for an example of how to do this.
+Note that this returns `nil` if the function does not exist in LFS. 
 
 ## node.flashreload()
 
-Reload the [LFS (Lua Flash Store)](../lfs.md) with the flash image provided. Flash images are generated on the host machine using the `luac.cross`commnad.
-
-#### Syntax
-`node.flashreload(imageName)`
-
-#### Parameters
-`imageName` The name of a image file in the filesystem to be loaded into the LFS.
-
-#### Returns
-`Error message`  LFS images are now gzip compressed.  In the case of the `imagename` being a valid LFS image, this is expanded and loaded into flash.  The ESP is then immediately rebooted, _so control is not returned to the calling Lua application_ in the case of a successful reload.  This reload process internally makes two passes through the LFS image file; and on the first it validates the file and header formats and detects any errors.  If any is detected then an error string is returned.
-
+Deprecated synonym for [`node.LFS.reload()`](#nodelfsreload) to reload [LFS (Lua Flash Store)](../lfs.md) with the named flash image provided.
 
 ## node.flashsize()
 
@@ -278,7 +255,6 @@ system heap size left in bytes (number)
 
 Returns information about hardware, software version and build configuration.
 
-
 #### Syntax
 `node.info([group])`
 
@@ -294,6 +270,13 @@ If a `group` is given the return value will be a table containing the following
 	- `flash_size` (number)
 	- `flash_mode` (number) 0 = QIO, 1 = QOUT, 2 = DIO, 15 = DOUT.
 	- `flash_speed` (number)
+
+- for `group` = `"lfs"`
+	- `lfs_base` (number)	Flash offset of selected LFS region 
+	- `lfs_mapped` (number)	Mapped memory address of selected LFS region
+	- `lfs_size` (number)	size of selected LFS region
+	- `lfs_used` (number)	actual size used by current LFS image
+
 - for `group` = `"sw_version"`
 	- `git_branch` (string)
 	- `git_commit_id` (string)
@@ -302,6 +285,7 @@ If a `group` is given the return value will be a table containing the following
 	- `node_version_major` (number)
 	- `node_version_minor` (number)
 	- `node_version_revision` (number)
+
 - for `group` = `"build_config"`
 	- `ssl` (boolean)
 	- `lfs_size` (number) as defined at build time
@@ -361,6 +345,65 @@ See the `telnet/telnet.lua` in `lua_examples` for a more comprehensive example.
 #### See also
 [`node.output()`](#nodeoutput)
 
+
+## node.LFS
+
+Sub-table containing the API for [Lua Flash Store](../lfs.md)(**LFS**) access.  Programmers might prefer to map this to a global or local variable for convenience for example:
+```lua
+local LFS = node.LFS
+```
+This table contains the following methods and properties:
+
+Property/Method | Description
+-------|---------
+`config` | A synonym for [`node.info('lfs')`](#nodeinfo).  Returns the properties `lfs_base`, `lfs_mapped`, `lfs_size`, `lfs_used`.
+`get()` | See [node.LFS.get()](#nodelfsget).
+`list()` | See [node.LFS.list()](#nodelfslist).
+`reload()` |See [node.LFS.reload()](#nodelfsreload).
+`time` | Returns the Unix timestamp at time of image creation.
+
+
+## node.LFS.get() 
+
+Returns the function reference for a function in LFS.
+
+Note that unused `node.LFS` properties map onto the equialent `get()` call so for example: `node.LFS.mySub1` is a synonym for `node.LFS.get('mySub1')`.
+
+#### Syntax
+`node.LFS.get(modulename)`
+
+#### Parameters
+`modulename`  The name of the module to be loaded.
+
+#### Returns
+-  If the LFS is loaded and the `modulename` is a string that is the name of a valid module in the LFS, then the function is returned in the same way the `load()` and the other Lua load functions do
+-  Otherwise `nil` is returned.
+
+
+## node.LFS.list() 
+
+List the modules in LFS.
+
+
+#### Returns
+-  If no LFS image IS LOADED then `nil` is returned.
+-  Otherwise an sorted array of the name of modules in LFS is returned.
+
+## node.LFS.reload()
+
+Reload LFS with the flash image provided. Flash images can be generated on the host machine using the `luac.cross`command.
+
+#### Syntax
+`node.LFS.reload(imageName)`
+
+#### Parameters
+`imageName` The name of a image file in the filesystem to be loaded into the LFS.
+
+#### Returns
+-  In the case when the `imagename` is a valid LFS image, this is expanded and loaded into flash, and the ESP is then immediately rebooted, _so control is not returned to the calling Lua application_ in the case of a successful reload.
+-  The reload process internally makes multiple passes through the LFS image file. The first pass validates the file and header formats and detects many errors.  If any is detected then an error string is returned.
+
+
 ## node.output()
 
 Redirects the Lua interpreter to a `stdout` pipe when a CB function is specified (See  `pipe` module) and resets output to normal otherwise. Optionally also prints to the serial console.

File diff suppressed because it is too large
+ 13 - 0
docs/nodemcu-lrm.md


File diff suppressed because it is too large
+ 10 - 0
docs/nodemcu-pil.md


+ 6 - 2
mkdocs.yml

@@ -32,15 +32,19 @@ pages:
     - Uploading code: 'upload.md'
     - Compiling code: 'compiling.md'
     - Support: 'support.md'
+- Reference:
+    - NodeMCU Language Reference Manual: 'nodemcu-lrm.md'
+    - Programming in NodeMCU: 'nodemcu-pil.md'
 - FAQs:
     - Lua Developer FAQ: 'lua-developer-faq.md'
     - Extension Developer FAQ: 'extn-developer-faq.md'
     - Hardware FAQ: 'hardware-faq.md'
 - Whitepapers:
+    - Lua 5.3 Support: 'lua53.md'
+    - Lua Flash Store (LFS): 'lfs.md'
+    - Lua Compact Debug (LCD): 'lcd.md'
     - Filesystem on SD card: 'sdcard.md'
     - Internal filesystem: 'spiffs.md'
-    - Lua Compact Debug (LCD): 'lcd.md'
-    - Lua Flash Store (LFS): 'lfs.md'
 - Lua Modules:
     - 'Lua modules directory': 'lua-modules/README.md'
     - 'bh1750': 'lua-modules/bh1750.md'

+ 2 - 1
msvc/luac-cross/luac-cross.vcxproj

@@ -193,6 +193,7 @@
     <ClCompile Include="..\..\app\lua\llex.c" />
     <ClCompile Include="..\..\app\lua\lmathlib.c" />
     <ClCompile Include="..\..\app\lua\lmem.c" />
+    <ClCompile Include="..\..\app\lua\lnodemcu.c" />
     <ClCompile Include="..\..\app\lua\loadlib.c" />
     <ClCompile Include="..\..\app\lua\lobject.c" />
     <ClCompile Include="..\..\app\lua\lopcodes.c" />
@@ -250,4 +251,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 5 - 2
msvc/luac-cross/luac-cross.vcxproj.filters

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Source Files">
@@ -132,6 +132,9 @@
     <ClCompile Include="..\..\app\lua\lzio.c">
       <Filter>app\lua</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\app\lua\lnodemcu.c">
+      <Filter>app\lua</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\app\uzlib\uzlib.h">
@@ -228,4 +231,4 @@
       <Filter>app\include</Filter>
     </ClInclude>
   </ItemGroup>
-</Project>
+</Project>

Some files were not shown because too many files changed in this diff